1 unstable release
new 0.1.2 | Mar 8, 2025 |
---|---|
0.1.1 |
|
0.1.0 |
|
#46 in WebSocket
55 downloads per month
160KB
2K
SLoC
dxlink
dxlink
dxlink
is a Rust client library for the DXLink WebSocket protocol used by tastytrade
for real-time market data. This library provides a clean and type-safe API for connecting
to DXLink servers, subscribing to market events, and processing real-time market data.
Features
- Full implementation of the DXLink WebSocket protocol (AsyncAPI 2.4.0)
- Strongly typed event definitions for Quote, Trade, Greeks, and more
- Async/await based API for efficient resource usage
- Automatic handling of authentication and connection maintenance
- Support for multiple subscription channels
- Callback and stream-based APIs for event processing
- Robust error handling and reconnection logic
ref: https://raw.githubusercontent.com/dxFeed/dxLink/refs/heads/main/dxlink-specification/asyncapi.yml
Example
Here's a basic example of using the library to connect to a DXLink server and subscribe to market data:
use std::error::Error;
use dxlink::{DXLinkClient, EventType, FeedSubscription, MarketEvent};
use tokio::time::sleep;
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
// Create a new DXLink client with the API token
// (typically obtained from tastytrade API)
use tracing::info;
let token = "your_api_token_here";
let url = "wss://tasty-openapi-ws.dxfeed.com/realtime";
let mut client = DXLinkClient::new(url, token);
// Connect to the DXLink server
client.connect().await?;
// Create a feed channel with AUTO contract type
let channel_id = client.create_feed_channel("AUTO").await?;
// Configure the channel for Quote and Trade events
client.setup_feed(channel_id, &[EventType::Quote, EventType::Trade]).await?;
// Register a callback for specific symbol
client.on_event("SPY", |event| {
info!("Event received for SPY: {:?}", event);
});
// Get a stream for all events
let mut event_stream = client.event_stream()?;
// Process events in a separate task
tokio::spawn(async move {
while let Some(event) = event_stream.recv().await {
match &event {
MarketEvent::Quote(quote) => {
info!(
"Quote: {} - Bid: {} x {}, Ask: {} x {}",
quote.event_symbol,
quote.bid_price,
quote.bid_size,
quote.ask_price,
quote.ask_size
);
},
MarketEvent::Trade(trade) => {
info!(
"Trade: {} - Price: {}, Size: {}, Volume: {}",
trade.event_symbol,
trade.price,
trade.size,
trade.day_volume
);
},
_ => info!("Other event type: {:?}", event),
}
}
});
// Subscribe to some symbols
let subscriptions = vec![
FeedSubscription {
event_type: "Quote".to_string(),
symbol: "SPY".to_string(),
from_time: None,
source: None,
},
FeedSubscription {
event_type: "Trade".to_string(),
symbol: "SPY".to_string(),
from_time: None,
source: None,
},
];
client.subscribe(channel_id, subscriptions).await?;
// Keep the connection active for some time
sleep(Duration::from_secs(60)).await;
// Cleanup
client.disconnect().await?;
Ok(())
}
Working with historical data
DXLink supports subscribing to historical data through Candle events. When subscribing to candle events, you need to specify the period, type, and a timestamp from which to fetch the data:
use dxlink::FeedSubscription;
use std::time::{SystemTime, UNIX_EPOCH};
// Get current timestamp in milliseconds
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_millis() as i64;
// Timestamp for 24 hours ago
let one_day_ago = now - (24 * 60 * 60 * 1000);
// Subscribe to 5-minute candles for SPY for the last 24 hours
let candle_subscription = FeedSubscription {
event_type: "Candle".to_string(),
symbol: "SPY{=5m}".to_string(), // 5-minute candles
from_time: Some(one_day_ago),
source: None,
};
Error Handling
The library uses a custom error type DXLinkError
that encompasses
various error cases that can occur when interacting with the DXLink API:
use tracing::{error, info};
use dxlink::{DXLinkClient, DXLinkError};
async fn example_error_handling() {
let mut client = DXLinkClient::new("wss://example.com", "token");
match client.connect().await {
Ok(_) => info!("Connected successfully!"),
Err(DXLinkError::Authentication(e)) => error!("Authentication failed: {}", e),
Err(DXLinkError::Connection(e)) => error!("Connection error: {}", e),
Err(e) => error!("Other error: {}", e),
}
}
Available Event Types
The library supports the following event types:
Quote
- Current bid/ask prices and sizesTrade
- Last trade informationGreeks
- Option greeks data (delta, gamma, theta, etc.)Summary
- Daily summary informationProfile
- Instrument profile informationCandle
- OHLC (Open, High, Low, Close) data for time periods- And more!
License
This project is licensed under the MIT License. See the LICENSE file for details.
Setup Instructions
- Clone the repository:
git clone https://github.com/joaquinbejar/DXlink
cd DXlink
- Build the project:
make build
- Run tests:
make test
- Format the code:
make fmt
- Run linting:
make lint
- Clean the project:
make clean
- Run the project:
make run
- Fix issues:
make fix
- Run pre-push checks:
make pre-push
- Generate documentation:
make doc
- Publish the package:
make publish
- Generate coverage report:
make coverage
Testing
To run unit tests:
make test
To run tests with coverage:
make coverage
Contribution and Contact
We 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!
License: MIT
Dependencies
~6–17MB
~233K SLoC