Introducing order book snapshots for live data

June 26, 2024
Title picture for Introducing order book snapshots for live data

We're excited to announce that order book ( MBO ) snapshots are now available for live data using our Raw API or client libraries. Databento generates a snapshot every minute, providing users with the latest order book state without the overhead of replaying the entire trading session.

Updated September 2024: Our MBO snapshot feature was initially released for CME in June 2024 and has since been extended to include Databento Equities Basic, Nasdaq TotalView-ITCH, ICE Futures Europe, and ICE Endex.

When subscribing to a live data stream, set schema="mbo" and snapshot=True to receive the latest order book snapshot available at the start of your session. Regardless of your start time, this snapshot will have been captured within the last minute.

A snapshot includes all resting buy and sell orders in the order book for a specific instrument at the moment it's taken. It's transmitted as a sequence of records:

  • The snapshot begins with a cleaR action (action='R') record to reset the order book state and includes the snapshot's generation timestamp.
  • Subsequent snapshot records insert every outstanding order with an Add action (action='A') to reconstruct the order book.

Each snapshot record maintains the priority order at every price level for an accurate representation of market depth and can be identified by its SNAPSHOT flag. The example below shows the live stream for a single instrument's MBO snapshot, which includes two resting buy orders, followed by a live record.

SymbolMappingMsg { hd: RecordHeader { length: 44, rtype: SymbolMapping, publisher_id: 0, instrument_id: 183748, ts_event: 1718195003964966562 }, stype_in: 255, stype_in_symbol: "ESZ4", stype_out: 255, stype_out_symbol: "ESZ4", start_ts: 18446744073709551615, end_ts: 18446744073709551615 }

MboMsg { hd: RecordHeader { length: 14, rtype: Mbo, publisher_id: GlbxMdp3Glbx, instrument_id: 183748, ts_event: 1718194972186437045 }, order_id: 0, price: UNDEF_PRICE, size: 0, flags: SNAPSHOT | BAD_TS_RECV (40), channel_id: 0, action: 'R', side: 'N', ts_recv: 1718194972186437045, ts_in_delta: 0, sequence: 0 }

MboMsg { hd: RecordHeader { length: 14, rtype: Mbo, publisher_id: GlbxMdp3Glbx, instrument_id: 183748, ts_event: 1718189480104800023 }, order_id: 6413361531750, price: 5514.500000000, size: 1, flags: LAST | SNAPSHOT | BAD_TS_RECV (170), channel_id: 0, action: 'A', side: 'B', ts_recv: 1718194972186437045, ts_in_delta: 0, sequence: 18833956 }
...
MboMsg { hd: RecordHeader { length: 14, rtype: Mbo, publisher_id: GlbxMdp3Glbx, instrument_id: 183748, ts_event: 1718194969316032829 }, order_id: 6413361615961, price: 5514.750000000, size: 1, flags: LAST | SNAPSHOT | BAD_TS_RECV (170), channel_id: 0, action: 'A', side: 'B', ts_recv: 1718194972186437045, ts_in_delta: 0, sequence: 19066397 }

MboMsg { hd: RecordHeader { length: 14, rtype: Mbo, publisher_id: GlbxMdp3Glbx, instrument_id: 183748, ts_event: 1718194973777593177 }, order_id: 6413361643902, price: 5518.750000000, size: 1, flags: LAST (130), channel_id: 0, action: 'C', side: 'A', ts_recv: 1718194973778681785, ts_in_delta: 12067, sequence: 19066561 }
...

A snapshot is especially useful when subscribing to live data in the middle of a trading session or for recovery purposes in the event of a dropped connection. Previously, users needed to specify start=0 to process all data from the start of the trading session, which incurs costs and can involve a significant volume of messages, particularly for CME's weekly session or any liquid instruments.

This Python example demonstrates how to use Databento's live client to request a snapshot and can be found in our documentation , alongside C++ and Rust examples. You can also visit our Live MBO snapshot guide for more details.

import databento as db

# First, create a live client and connect
live_client = db.Live(key="YOUR_API_KEY")

# Next, subscribe and request an MBO snapshot with snapshot=True
live_client.subscribe(
    dataset="GLBX.MDP3",
    schema="mbo",
    stype_in="continuous",
    symbols="ES.c.0",
    snapshot=True,
)

# Finally, iterate over the live client to process all snapshot records and stop at the first MBO record with F_LAST flag
for record in live_client:
    if isinstance(record, db.MBOMsg):
        if record.flags & db.RecordFlags.F_SNAPSHOT:
            print(f"Snapshot: {record}")
        elif record.flags & db.RecordFlags.F_LAST:
            print(f"Incremental: {record}")
            break