# tradestation-api
[](LICENSE)
[](https://crates.io/crates/tradestation-api)
[](https://docs.rs/tradestation-api)
Complete, typed TradeStation REST API v3 wrapper for Rust.
Provides async access to all TradeStation v3 endpoints with automatic OAuth2 token management, typed request/response models, and HTTP chunked-transfer streaming.
## Installation
```sh
cargo add tradestation-api
```
## Quick Start
```rust
use tradestation_rs::{Client, Credentials, Scope};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let creds = Credentials::new("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET");
// 1. Direct user to authorization URL
let url = creds.authorization_url(&Scope::defaults());
println!("Visit: {url}");
// 2. Exchange the callback code for tokens
let mut client = Client::new(creds);
client.authenticate("AUTH_CODE_FROM_CALLBACK").await?;
// 3. Fetch data
let quotes = client.get_quotes(&["AAPL", "MSFT"]).await?;
for q in "es {
println!("{}: last={}", q.symbol, q.last);
}
Ok(())
}
```
## Features
- **OAuth2 Authorization Code** flow with automatic token refresh
- **Market Data**: Historical bars (OHLCV), quotes, symbol info, crypto pairs, options data
- **Brokerage**: Accounts, balances, BOD balances, positions, orders, historical orders, wallets
- **Execution**: Place, replace, cancel orders; OCO/bracket groups; order preview; activation triggers; routes
- **Streaming**: HTTP chunked-transfer for live quotes, bars, market depth, option chains, orders, positions
- **Simulation**: Built-in support for TradeStation's sim API via `Client::with_sim()`
- **Typed models**: All API responses are strongly typed with serde deserialization
- **Convenience parsers**: `Bar::ohlcv()` and `Bar::timestamp()` for numeric/datetime conversion
## Endpoint Coverage
| **Auth** | `/oauth/token` (authorization code) | POST | `auth::exchange_code` |
| | `/oauth/token` (refresh) | POST | `auth::refresh_token` |
| | `/oauth/token` (revoke) | POST | `auth::revoke_token` |
| **Market Data** | `/v3/marketdata/barcharts/{symbol}` | GET | `Client::get_bars` |
| | `/v3/marketdata/quotes/{symbols}` | GET | `Client::get_quotes` |
| | `/v3/marketdata/symbols/{symbols}` | GET | `Client::get_symbol_info` |
| | `/v3/marketdata/symbollists/cryptopairs/symbolnames` | GET | `Client::get_crypto_pairs` |
| | `/v3/marketdata/options/expirations/{underlying}` | GET | `Client::get_option_expirations` |
| | `/v3/marketdata/options/strikes/{underlying}` | GET | `Client::get_option_strikes` |
| | `/v3/marketdata/options/spreadtypes` | GET | `Client::get_option_spread_types` |
| | `/v3/marketdata/options/riskreward` | POST | `Client::get_option_risk_reward` |
| **Brokerage** | `/v3/brokerage/accounts` | GET | `Client::get_accounts` |
| | `/v3/brokerage/accounts/{id}/balances` | GET | `Client::get_balances` |
| | `/v3/brokerage/accounts/{id}/bodbalances` | GET | `Client::get_bod_balances` |
| | `/v3/brokerage/accounts/{id}/positions` | GET | `Client::get_positions` |
| | `/v3/brokerage/accounts/{id}/orders` | GET | `Client::get_orders` |
| | `/v3/brokerage/accounts/{id}/orders/{orderId}` | GET | `Client::get_orders_by_id` |
| | `/v3/brokerage/accounts/{id}/historicalorders` | GET | `Client::get_historical_orders` |
| | `/v3/brokerage/accounts/{id}/historicalorders/{orderId}` | GET | `Client::get_historical_orders_by_id` |
| | `/v3/brokerage/accounts/{id}/wallets` | GET | `Client::get_wallets` |
| **Execution** | `/v3/orderexecution/orders` | POST | `Client::place_order` |
| | `/v3/orderexecution/orders/{id}` | PUT | `Client::replace_order` |
| | `/v3/orderexecution/orders/{id}` | DELETE | `Client::cancel_order` |
| | `/v3/orderexecution/orderconfirm` | POST | `Client::confirm_order` |
| | `/v3/orderexecution/ordergroups` | POST | `Client::place_order_group` |
| | `/v3/orderexecution/ordergroupconfirm` | POST | `Client::confirm_order_group` |
| | `/v3/orderexecution/activationtriggers` | GET | `Client::get_activation_triggers` |
| | `/v3/orderexecution/routes` | GET | `Client::get_routes` |
| **Streaming** | `/v3/marketdata/stream/quotes/{symbols}` | GET | `Client::stream_quotes` |
| | `/v3/marketdata/stream/barcharts/{symbol}` | GET | `Client::stream_bars` |
| | `/v3/marketdata/stream/marketdepth/quotes/{symbol}` | GET | `Client::stream_market_depth_quotes` |
| | `/v3/marketdata/stream/marketdepth/aggregates/{symbol}` | GET | `Client::stream_market_depth_aggregates` |
| | `/v3/marketdata/stream/options/chains/{underlying}` | GET | `Client::stream_option_chains` |
| | `/v3/marketdata/stream/options/quotes/{legs}` | GET | `Client::stream_option_quotes` |
| | `/v3/brokerage/stream/accounts/{id}/orders` | GET | `Client::stream_orders` |
| | `/v3/brokerage/stream/accounts/{id}/orders/{orderId}` | GET | `Client::stream_orders_by_id` |
| | `/v3/brokerage/stream/accounts/{id}/positions` | GET | `Client::stream_positions` |
**Total: 38 endpoints**
## Relationship to Other Crates
This is a **new, independent crate** -- not a fork of any existing TradeStation library. It was built from scratch against the [TradeStation v3 OpenAPI spec](https://api.tradestation.com/docs/) with a focus on:
- Complete endpoint coverage (all 38 v3 endpoints)
- Idiomatic async Rust with `tokio` and `futures`
- Typed streaming via HTTP chunked transfer (not WebSocket)
- Zero external runtime dependencies beyond `tokio` + `reqwest`
## Examples
See the [`examples/`](examples/) directory:
- [`quickstart.rs`](examples/quickstart.rs) -- OAuth2 flow and fetching quotes
- [`stream_quotes.rs`](examples/stream_quotes.rs) -- Real-time quote streaming
- [`place_order.rs`](examples/place_order.rs) -- Order placement (use sim API!)
## License
MIT -- see [LICENSE](LICENSE).