Reconstructing Order Books from Historical Market Data
Summary
The document explains why feeding historical order-book updates into a fresh matching engine can produce cancellations or executions for orders the engine never saw. The underlying issue is incomplete initial state or limited market-by-order coverage: a data file may begin after some live orders were placed, or a depth-limited feed may omit orders outside its reported levels.
Suggested approaches include obtaining full market-by-order data, carrying state forward from earlier periods, initializing from vendor or exchange snapshots, and reconciling snapshots with incremental updates. The discussion also notes that some strategies may tolerate occasional state errors when orders turn over quickly, though this depends on the signal and instrument. One practitioner reports starting from the deepest available snapshot, while acknowledging that this does not maintain state indefinitely. The best method depends on feed type, session structure, coverage, and the accuracy needed; the document gives practical options rather than a benchmark comparing them.
Key ideas
- Historical updates require a valid starting order-book state to replay correctly.
- Depth-limited feeds can omit orders that later appear in cancellations or executions.
- Full market-by-order data, carried state, and periodic snapshots are ways to establish book state.
- Occasional missing orders may be tolerable for some liquid instruments, but strategy robustness must be assessed.
- Starting from a deep snapshot can help, though it may not preserve accurate state over long periods.
Tags
Full text
# How to test an orderbook using real data # How to test an orderbook using real data I'm pretty new to all this but haven't found anything online on my issue (the answer may be very obvious since I'm a beginner) - I'm currently coding up a very generic orderbook in C++ for fun, just matching bids to asks at the moment - I was wondering if there was a way to test my code on real orderbook data. I took a look at LOBSTER and tried downloading some sample message data and running it through my book, but the issue is that there are a lot of orders being executed from previous periods which breaks my code: there are orders being cancelled with an orderid not in my system, and how am I meant to model the orderbook when I don't have the current list of all bids and asks from previous days/years? I could write up some mock data from the 'beginning of time' to test, but everyone else seems to be doing fine with modelling real data using LOBSTER. What am I doing wrong here? (I am also open to not using LOBSTER, if that's the issue) Thanks all :) ## Answer by databento (score 0, accepted) https://quant.stackexchange.com/a/80365 This seems to be a LOBSTER support and vendor recommendation question and not a question that we can help you with ultimately. In general, the issue that you've described is a solved problem. Solutions include: - Use a MBO data source (has all levels) instead of MBL/MBP (has limited number of levels). This ensures that every update is tracked and you don't have "out of scope" orders that are outside the 50 levels that you're capped at. Examples of historical sources of MBO data: Databento, BMLL, Quincy. - Hold over the order book state from past periods. You've described this in your question. - Vendor or upstream publisher gives you order snapshots. For example, some exchanges do this on a periodic loop for their MBO data. Some vendors like Iress will publish a new MBL snapshot periodically and you can technically drop all of the incremental MBL updates up to that point and restart over using the snapshot. Databento gets around this by giving a UTC midnight snapshot of all orders and real-time snapshots. Some exchanges like Nasdaq have daily sessions, so the max you can go with incorrect state is 1 day. Other exchanges with weekly sessions like CME will republish all GTC orders at the start of the new session, so the max yo can go with incorrect state is 1 week. - Natural refresh. The impact of missing an order and canceling/executing an order that was previously not on your book could be negligible. Your business logic (strategy, signal, model, etc.) should usually be robust to this, i.e. your PnL should be quite stable even if your signal values get perturbed by the occasional missing order. This is especially OK if the instrument is very liquid and their orders turnover very quickly—explained here. - Synthesize multiple sources. e.g. Use MBL/MBP/L2 data as a snapshot and reconcile it with your state acquired from incremental MBO data. This is usually too tedious, but a possibility that's worth throwing out there. ## Answer by cocode (score 0) https://quant.stackexchange.com/a/76239 I am OP - the way I'm doing it right now is just taking an orderbook of the highest amount of price levels I can (currently 50), and just populating my orderbook with those as the very first step. It won't hold properly long-term, but there's not much way around it.
Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.