An ergonomic Rust client for the TradeStation API empowering you to build fast, scalable, and production ready trading systems and applications.
Features
- 🧮 Accounting: Monitor your risk, positions, balances, order history, and more
across multiple accounts.
- 📈 Market Data: Easily fetch and stream real time and historic market data
on thousands of assets and derivatives.
- ⚡ Execution: Lightning fast trade execution allowing you to place, update,
and cancel orders with all kinds of custom configuration.
- 🧪 Testing: Supports mocking so you can seamlessly build out environments to test
your trading systems and applications.
Install
Use cargo CLI:
cargo install tradestation
Or manually add it into your Cargo.toml:
[dependencies]
tradestation = "0.0.5"
Usage
For more thorough information, read the docs.
Simple example for streaming bars of trading activity:
use futures::StreamExt;
use tradestation::{
responses::MarketData::StreamBarsResp,
ClientBuilder, Error,
MarketData::{self, BarUnit},
};
#[tokio::main]
async fn main() -> Result<(), Error> {
let mut client = ClientBuilder::new()?
.credentials("YOUR_ACCESS_KEY", "YOUR_SECRET_KEY")?
.token(Token {
access_token: "YOUR_ACCESS_TOKEN".into(),
refresh_token: "YOUR_REFRESH_TOKEN".into(),
id_token: "YOUR_ID_TOKEN".into(),
token_type: String::from("Bearer"),
scope: vec![
Scope::OpenId,
Scope::Profile,
Scope::ReadAccount,
Scope::OfflineAccess,
Scope::MarketData,
],
expires_in: 1200,
})?
.build()
.await?;
let stream_bars_query = MarketData::StreamBarsQueryBuilder::new()
.set_symbol("CLX30")
.set_unit(BarUnit::Minute)
.set_interval("240")
.build()?;
let mut bars_stream = client.stream_bars(&stream_bars_query);
tokio::pin!(bars_stream);
while let Some(stream_resp) = bars_stream.next().await {
match stream_resp {
StreamBarsResp::Bar(bar) => {
println!("{bar:?}");
}
StreamBarsResp::Heartbeat(heartbeat) => {
if heartbeat.heartbeat > 10 {
return Err(Error::StopStream);
}
}
StreamBarsResp::Status(status) => {
println!("{status:?}");
}
StreamBarsResp::Error(err) => {
eprintln!("{err:?}");
}
Err(err) => {
eprintln!("{err:?}");
}
}
}
Ok(())
}
Contributing
There are many ways to contribute like reporting issues, writing documentation, building
out new features and abstractions, refactoring to improve on current abstractions, or
fixing bugs.
Keep an eye out on open issues :)