Handling Events
Every streaming update reaches your callback as one typed event. There are five data events and a set of control events covering session lifecycle; your callback narrows on the event type and reads typed fields — no JSON, no string parsing.
Narrowing
rust
use thetadatadx::streaming::{StreamControl, StreamData, StreamEvent};
client.stream().start_streaming(|event: &StreamEvent| {
match event {
StreamEvent::Data(StreamData::Quote { contract, bid, ask, .. }) => {
println!("{} bid={bid} ask={ask}", contract.symbol);
}
StreamEvent::Data(StreamData::Trade { contract, price, size, .. }) => {
println!("{} {price} x {size}", contract.symbol);
}
StreamEvent::Control(StreamControl::Disconnected { .. }) => {
eprintln!("disconnected; automatic reconnect underway");
}
_ => {}
}
})?;Data events
| Kind | Fields | Delivered for |
|---|---|---|
quote | Best bid and offer (BBO for stocks, NBBO for options): bid / ask price, size, exchange, condition; ms_of_day, date, received_at_ns | Quote streams |
trade | price, size, exchange, condition, sequence, ms_of_day, date, received_at_ns | Trade, full-trade, and index price streams |
open_interest | open_interest, ms_of_day, date, received_at_ns | Open-interest streams |
ohlcvc | open, high, low, close, volume, count, ms_of_day, date, received_at_ns | Bars that arrive from upstream automatically — one per traded contract, ahead of that contract's trade |
market_value | market_price (calculated value), market_bid / market_ask (stocks and options only), ms_of_day, date, received_at_ns | Index market value and per-contract market-value streams |
Each stream-type page in the sidebar lists its event's complete field table.
The contract on every data event
Data events carry a resolved, typed contract — read identity straight off the event, no lookup table:
| Field | Type | Notes |
|---|---|---|
symbol | string | Underlying or ticker. |
sec_type | string | STOCK / OPTION / INDEX / RATE. |
expiration | int? | YYYYMMDD; options only. |
right | string? | C / P; options only. |
strike | int? | Over the server's WebSocket, the terminal's 1/10-cent integer (a $570 strike is 570000), matching the terminal wire; options only. The native SDK bindings resolve it to dollars on event.contract (Rust strike_dollars(); the C ABI field is dollars). |
Control events
Lifecycle and session events share the callback. The ones worth handling:
| Kind | Meaning |
|---|---|
connected / login_success | Session is up and authenticated. |
contract_assigned | The server bound a contract to the session (informational). |
req_response | Acknowledgement for a subscribe/unsubscribe, with its request id. |
market_open / market_close | Session boundary notices. |
disconnected / reconnecting / reconnected | Automatic-reconnect progress; see Reconnection & Monitoring. |
reconnects_exhausted | The retry budget is spent; the session is down for good until you intervene. |
server_error / parse_error | Server-reported (ServerError) or protocol-level parse (ParseError) error with a message payload. |
ping, restart, reconnected_server, unknown_frame, unknown_control | Heartbeats, server restarts, and forward-compatibility fallbacks. |
Unrecognized future event types arrive as unknown_* rather than being dropped, so a callback written today keeps working against newer servers.