Skip to main content

BSL Binary Market Data

The binary market-data feed delivers full-depth book snapshots, incremental book deltas, and trade prints over the same v2 recoverable BSL Direct TCP session as order entry — true fixed-field binary (little-endian u64 micro-prices and quantities straight off the engine), not JSON. Heartbeats, gap-fill resend, and sequence tracking come from the shared recoverable-session machinery, so a slow or dropped consumer recovers cleanly (ITCH/MDP style: snapshot + delta).

This is the low-latency counterpart to the public WebSocket feed; the WebSocket JSON feed remains the retail/compatibility path.

Session flow

  1. Complete the BSL Direct TCP v2 handshake.
  2. Send a MarketDataRequest (message kind 20):
u64_le market_id
u8 channel # 0 = Book, 1 = Trades, 2 = Bbo
u32_le snapshot_depth
u64_le resume_from_seq # 0 = full snapshot; >0 = reconnect from a feed sequence
  1. The gateway replies, all wrapped in the session's SequencedData envelope:
    • MarketDataResponse (kind 21): accepted, latest_seq, snapshot_seq, granted heartbeat_ms.
    • MarketBookSnapshot (kind 22): the full book at snapshot_seq.
    • then live MarketBookDelta (kind 23), MarketTrade (kind 24), and MarketStatus (kind 25) messages.

Every market-data message rides inside SequencedData with a per-session sequence, so a detected gap is filled with a ResendRequest, and a source-side gap re-snapshots automatically.

Binary frames

All integers are little-endian. Price is micro-USDC (u64); quantity is atomic units (u64). A book level is book(u8) side(u8) price_micros(u64) qty(u64) (book: 0 = YES, 1 = NO, 2 = SPOT; side: 0 = bid, 1 = ask). In a delta a level with qty == 0 removes that price.

FrameKindBody
MarketBookSnapshot22market_id, channel, snapshot_seq, state_version, count, level*
MarketBookDelta23market_id, seq, prev_seq, full_replace, count, level*
MarketTrade24market_id, seq, count, [book, price, qty, aggressor, ts_ms]*
MarketStatus25market_id, status, ts_ms

Recovery

  • In-session gap (you see a sequence skip): send ResendRequest from the expected sequence; the gateway replays the retained tail.
  • Source gap (the feed bus lagged): the gateway emits a fresh MarketBookSnapshot automatically — re-apply it as the new book.
  • Reconnect: re-send MarketDataRequest with resume_from_seq set to the highest feed sequence you applied. The gateway replays the missed updates, or re-snapshots if that sequence has aged out of the retention window.

SDK support

The Rust SDK decodes these frames directly (senticore_sdk::market_data): decode_market_book_snapshot, decode_market_book_delta, decode_market_trade, decode_market_status, plus encode_market_data_request. A BslTcpEvent::MarketData { kind, body } from the session carries the raw frame body to pass into the matching decoder.