Level-2 Snapshot-and-Delta Reconstruction
Install and import
npm install fintech-algorithmsimport { reconstructL2 } from "fintech-algorithms/market-data-engineering/order-book-feed-engineering/level-2-snapshot-and-delta-reconstruction";Signature
reconstructL2(snapshot)Rebuilds an aggregated price-level book from a snapshot plus the deltas that follow it. Level 2 shows quantity per price, not individual orders — the distinction matters because a delta that is applied twice corrupts the book invisibly.
Parameters
| Name | Type | Notes |
|---|---|---|
snapshot | L2Snapshot | The starting snapshot with its sequence number, followed by the incremental updates to apply in order. |
Returns
{ book, applied, gaps, state }
The reconstructed book with the updates applied and any sequence gaps encountered — a book rebuilt across a gap is wrong and must be said so.
Errors
- When a delta's sequence precedes the snapshot — reported as a gap rather than thrown
Complexity: time O(updates × levels),
space O(levels).
Worked example
executed Captured by running this function on the input its own test provides. Real output of real code — but not asserted against a published figure.
Input
{
"bids": [
{
"price_ticks": 10000,
"quantity": 20
},
{
"price_ticks": 9999,
"quantity": 25
},
{
"price_ticks": 9998,
"quantity": 30
}
],
"asks": [
{
"price_ticks": 10002,
"quantity": 18
},
{
"price_ticks": 10003,
"quantity": 22
},
{
"price_ticks": 10004,
"quantity": 26
}
]
}{
"snapshot_sequence": 500,
"deltas": [
{
"sequence": 501,
"side": "bid",
"price_ticks": 10000,
"quantity": 12
},
{
"sequence": 502,
"side": "ask",
"price_ticks": 10002,
"quantity": 19
},
{
"sequence": 503,
"side": "bid",
"price_ticks": 9999,
"quantity": 26
}
]
}Call
reconstructL2(snapshot)Returns
object with 12 fields: quantity_semantics, snapshot_sequence, last_sequence, applied_sequences, applied_count, discarded_sequences, discarded_count, bids, …
{
"quantity_semantics": "absolute-replacement",
"snapshot_sequence": 500,
"last_sequence": 524,
"applied_sequences": [501, 502, 503, 504, 505, 506],
"applied_count": 24,
"discarded_sequences": [],
"discarded_count": 0,
"bids": [
{
"price_ticks": 10000,
"quantity": 17
},
{
"price_ticks": 9998,
"quantity": 14
},
{
"price_ticks": 9997,
"quantity": 28
}
],
"asks": [
{
"price_ticks": 10002,
"quantity": 24
},
{
"price_ticks": 10003,
"quantity": 38
},
{
"price_ticks": 10004,
"quantity": 21
}
],
"best_bid_ticks": 10000,
"best_ask_ticks": 10002,
"state": "current"
}Other exports
This module also exports
normalizeEvents, aggregatePriceLevels, reconstructL3, recoverSequenceStream, reconcileSnapshotIncrementals, consolidateVenues, calculate. Every module additionally exports run as an alias of its
primary function, and a meta object carrying its catalog id, domain, family,
shape and article URL.
Diagrams
How it works
This page states the contract — how to call it correctly. The article explains the concept: why it works, and where it breaks.
References
- Topic-specific source roles
- Nasdaq TotalView-ITCH 5.0 — Nasdaq
- Nasdaq GLIMPSE 5.0 — Nasdaq
- MoldUDP64 protocol — Nasdaq
- FIX recommended practices for book management — FIX Trading Community
- Cboe Multicast PITCH specification — Cboe Global Markets
- Coinbase Exchange WebSocket channels — Coinbase
- UTP Quote Data Feed — UTP Plan
- UTP odd-lot data service update — UTP Plan / Nasdaq Trader
- UTP Data Feed Services Specification — UTP Plan