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
- Complete the BSL Direct TCP v2 handshake.
- Send a
MarketDataRequest(message kind20):
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
- The gateway replies, all wrapped in the session's
SequencedDataenvelope:MarketDataResponse(kind21):accepted,latest_seq,snapshot_seq, grantedheartbeat_ms.MarketBookSnapshot(kind22): the full book atsnapshot_seq.- then live
MarketBookDelta(kind23),MarketTrade(kind24), andMarketStatus(kind25) 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.
| Frame | Kind | Body |
|---|---|---|
MarketBookSnapshot | 22 | market_id, channel, snapshot_seq, state_version, count, level* |
MarketBookDelta | 23 | market_id, seq, prev_seq, full_replace, count, level* |
MarketTrade | 24 | market_id, seq, count, [book, price, qty, aggressor, ts_ms]* |
MarketStatus | 25 | market_id, status, ts_ms |
Recovery
- In-session gap (you see a sequence skip): send
ResendRequestfrom the expected sequence; the gateway replays the retained tail. - Source gap (the feed bus lagged): the gateway emits a fresh
MarketBookSnapshotautomatically — re-apply it as the new book. - Reconnect: re-send
MarketDataRequestwithresume_from_seqset 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.