- Introduction
- Features
- Project Structure
- Setup Instructions
- Library Usage
- Usage Examples
- Development
- Contribution and Contact
tradier is a comprehensive Rust library for managing trades and market data using the Tradier broker API. This powerful toolkit enables developers, traders, and financial applications to:
- Execute trades efficiently
- Retrieve real-time quotes
- Manage portfolios
- Access historical market data
The library leverages Rust's performance and concurrency advantages, making it suitable for high-frequency trading applications and data-intensive financial processing.
- Trade Execution: Implement order placement, modification, and cancellation.
- Real-time Market Data: Access live quotes, option chains, historical OHLCV bars,
intraday time-and-sales, market clock / calendar, and ETB / lookup / search endpoints
via typed REST bindings (
MarketDatatrait). - Fundamentals (beta): Company profiles, corporate calendars (earnings / IPOs),
dividend history, corporate actions (splits / mergers), financial ratios (P/E,
EPS, margins), income / balance / cash-flow statements, and price statistics
via the
Fundamentalstrait. Seeexamples/fundamentals_company/main.rs. - Portfolio Management: Retrieve account information, positions, and performance metrics.
- Historical Data: Fetch and analyze historical price and volume data.
- Streaming Data: Utilize WebSocket connections for real-time data feeds.
- Authentication: Securely manage API keys and authentication tokens.
- Error Handling: Robust error handling and logging for reliability.
- Rate Limiting: Implement rate limiting to comply with API usage restrictions.
- Concurrent Processing: Leverage Rust's async capabilities for efficient data handling.
- Data Serialization: Use Serde for efficient JSON parsing and serialization.
The project is structured as follows:
-
Root Directory:
Cargo.lockandCargo.toml: Rust package manager files for dependency management.Docker: Directory containing Docker-related files for containerization.LICENSE: The license file for the project.Makefile: Contains commands for common development tasks.README.md: The main documentation file you're currently reading.coverage: Directory for test coverage reports.rust-toolchain.toml: Specifies the Rust toolchain version for the project.tarpaulin-report.html: HTML report of test coverage generated by cargo-tarpaulin.
-
Documentation (
doc/):images/: Directory for storing images used in documentation.
-
Examples (
examples/):auth_example.rs: Example of how to use authentication in the library.auth_websocket_example.rs: Example of using authenticated WebSocket connections.
-
Source Code (
src/):- Configuration (
config/):base.rs: Defines the base configuration structure for the library.mod.rs: Module declaration file for the config module.
constants.rs: Defines constant values used throughout the library.lib.rs: The main library file that exposes the public API.- Utilities (
utils/):error.rs: Defines custom error types for the library.logger.rs: Sets up logging functionality.mod.rs: Module declaration file for the utils module.tests.rs: Contains tests for utility functions.
- WebSocket Session (
wssession/):account.rs: Handles account-related WebSocket sessions.market.rs: Manages market data WebSocket sessions.mod.rs: Module declaration file for the wssession module.session.rs: Defines the base WebSocket session structure and functionality.
- Configuration (
-
Tests (
tests/):- Unit Tests (
unit/):mod.rs: Module file for unit tests.
- Unit Tests (
This structure organizes the project into logical components:
- The root directory contains project-wide configuration and documentation files.
- The
examplesdirectory provides sample code for users to understand how to use the library. - The
srcdirectory contains the main library code, divided into modules for configuration, utilities, and WebSocket session management. - The
testsdirectory is set up for containing unit tests, ensuring the reliability of the library's components.
Each module and file has a specific purpose, contributing to a well-organized and maintainable codebase for the TradierRust library.
-
Add tradier to your
Cargo.toml:[dependencies] tradier = "0.1.0"
-
Set up your Tradier API credentials:
- Create a
.envfile in your project root:TRADIER_ACCESS_TOKEN=your_api_key_here TRADIER_CLIENT_ID=your_account_id_here
- Create a
-
Build your project:
cargo build
To use the library in your project:
use tradier::config::base::Config;
use tradier::utils::logger::setup_logger;
use tradier::wssession::market::MarketSession;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
setup_logger();
let config = Config::new();
let market_session = MarketSession::new(&config).await?;
// Use the market_session to interact with the Tradier API
Ok(())
}Here's an example of how to use the library for streaming market data:
use std::error::Error;
use tracing::{error, info};
use tradier::config::base::Config;
use tradier::utils::logger::setup_logger;
use tradier::wssession::account::AccountSession;
use tradier::wssession::market::{MarketSession, MarketSessionFilter, MarketSessionPayload};
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
setup_logger();
let config = Config::new();
loop {
match MarketSession::new(&config).await {
Ok(market_session) => {
info!(
"Market streaming session created with id: {}",
market_session.get_session_id()
);
let payload = MarketSessionPayload {
symbols: vec!["AAPL".to_string(), "MSFT".to_string()],
filter: Some(vec![MarketSessionFilter::QUOTE, MarketSessionFilter::TRADE]),
session_id: market_session.get_session_id().to_string(),
linebreak: Some(true),
valid_only: Some(true),
advanced_details: None,
};
if let Err(e) = market_session.ws_stream(payload).await {
error!("Streaming error: {}. Reconnecting...", e);
}
}
Err(e) => {
error!(
"Failed to create market streaming session: {}. Retrying...",
e
);
}
}
tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
}
}When WebSockets are not reachable (strict corporate egress, aggressive
NAT timeouts, …) the same event stream is available over HTTP
chunked transfer. The helpers under tradier::streaming::http_stream
reuse the pooled reqwest::Client on the existing REST client, so
there is no extra connection pool to configure.
use futures_util::StreamExt;
use tradier::non_blocking::Client;
use tradier::streaming::http_stream;
use tradier::wssession::MarketSession;
use tradier::Config;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = Config::new();
let rest = Client::new(config.clone());
// Bootstrap a session id the usual way.
let session = MarketSession::new(&config).await?;
let symbols = ["AAPL".to_string(), "MSFT".to_string()];
let events =
http_stream::market_events(&rest, session.get_session_id(), &symbols, None, None, None, None)
.await?;
futures_util::pin_mut!(events);
while let Some(event) = events.next().await {
match event {
Ok(e) => println!("event: {:?}", e),
Err(e) => eprintln!("stream error: {e}"),
}
}
Ok(())
}A matching http_stream::account_events helper streams
AccountEvent values. Both helpers surface non-2xx responses as
Error::NetworkError and per-line decode failures as
Error::StreamDecodeError without aborting the stream.
See examples/http_stream_market/main.rs for a runnable demo.
This project includes a Makefile for common development tasks:
make build: Build the projectmake test: Run testsmake fmt: Format the codemake lint: Run Clippy for lintingmake clean: Clean the projectmake check: Run pre-push checks (test, format check, lint)make coverage: Generate test coverage reportmake doc: Generate and open documentation
To run a specific task, use make <task_name>. For example:
make testThis project uses Conventional Commits
(feat:, fix:, docs:, refactor:, perf:, test:, ci:, build:,
chore:). The CHANGELOG.md is generated by
git-cliff from the commit history.
On each release tag (vX.Y.Z), a GitHub Actions workflow
(.github/workflows/changelog.yml) regenerates CHANGELOG.md and
pushes the update to main. You can preview what the next entry will
look like locally:
git cliff --unreleasedWe welcome contributions to this project! If you would like to contribute, please follow these steps:
- Fork the repository.
- Create a new branch for your feature or bug fix.
- Make your changes and ensure that the project still builds and all tests pass.
- Commit your changes and push your branch to your forked repository.
- Submit a pull request to the main repository.
If you have any questions, issues, or would like to provide feedback, please feel free to contact the project maintainer:
Joaquín Béjar García
- Email: jb@taunais.com
- GitHub: joaquinbejar
We appreciate your interest and look forward to your contributions !