TraderSDKdocs

Guides

Order updates#

Polling get_order_status works, but fills arrive late and cost requests. subscribe_order_updates opens a private WebSocket and pushes events to you as they happen.

Subscribe#

You give the SDK a tokio::sync::broadcast::Sender. It spawns a background task that holds the connection, reconnects with exponential backoff, and sends each OrderUpdateEvent on your channel. You get back a JoinHandle to stop it.

use tokio::sync::broadcast;

let (tx, mut rx) = broadcast::channel::<OrderUpdateEvent>(1024);
let handle = trader.subscribe_order_updates(tx).await?;

while let Ok(ev) = rx.recv().await {
    println!("{} {} {:?} filled {}/{} ({:.0}%)",
        ev.exchange, ev.symbol, ev.status, ev.filled_quantity, ev.quantity, ev.fill_percentage());
    if ev.is_filled() { break; }
}

handle.abort();   // graceful shutdown of the background task

Because it is a broadcast channel, you can call tx.subscribe() to give several consumers their own receiver. A slow receiver can lag and miss events (RecvError::Lagged), so size the buffer for your burst rate and handle that error.

OrderUpdateEvent#

Field Type Meaning
exchange String Adapter name.
order_id String
client_order_id Option<String>
symbol String
status OrderStatus New, PartiallyFilled, Filled, Cancelled, Rejected, Expired, Pending.
side, order_type
price f64 Order price.
quantity f64 Order quantity.
filled_quantity f64 Cumulative filled.
avg_fill_price Option<f64>
fee, fee_currency Option<f64>, Option<String>
exchange_timestamp i64 Milliseconds, set by the exchange.
received_at i64 Milliseconds, set locally on receipt.
raw Option<serde_json::Value> Raw exchange payload.

Helpers: latency_ms() (received_at - exchange_timestamp), is_filled(), remaining_quantity(), fill_percentage().

Support#

The default implementation returns an error. Adapters that implement it declare ws_orders in their capabilities. See the exchange matrix for which ones do today.

if trader.capabilities().is_supported("ws_orders") {
    let handle = trader.subscribe_order_updates(tx).await?;
}

Patterns#

  • Track your own orders. Keep a map from order_id to your strategy state and update it from events. Use OrderStatus::is_final() to know when to drop an entry.
  • Reconcile after reconnects. Events during a disconnect are not replayed. After a long outage, check open orders with get_order_status.
  • Latency. latency_ms() includes clock skew between your machine and the exchange. Compare it against get_server_time if you need precision.

Edit this page on GitHub ↗