on_book_deltas parity between live and backtest #4928
Replies: 1 comment
|
Thanks for raising this. You're right about the expected behavior: we want backtest/live parity, including the event boundaries visible to a strategy. This gap has come up before and remains outstanding as part of the V2 transition and catalog work. As you noted, the data engine already supports buffering through For deltas stored as flat, unbatched rows, I think the likely direction is a backtest data client that reconstructs the batches an adapter such as Binance would deliver. This would move the reconstruction further upstream in the backtest flow, before both simulated exchange processing and strategy delivery, then feed those That still allows us to keep individual delta rows on disk, with their ordering and |
Uh oh!
There was an error while loading. Please reload this page.
Live: nautilus's Binance adapter (crates/adapters/binance/src/futures/websocket/streams/parse_data.rs:190-245)
parses one Binance depthUpdate WS message into a Vec covering every bid+ask entry in that message, flags only the last one with RecordFlag::F_LAST, and wraps the whole thing into one OrderBookDeltas. The data engine (crates/data/src/engine/mod.rs:2468-2489) dispatches that as one on_book_deltas call. If deltas arrive individually and buffer_deltas is on, the engine buffers them itself and only publishes once it sees F_LAST
Backtest/catalog replay: OrderBookDelta (the individual item) is what has an Arrow encode/decode impl — the OrderBookDeltas container has none. So the compacted Parquet catalog stores one row per delta, and replaying it reconstructs one OrderBookDeltas-of-exactly-one per row
Is this difference in behaviour a feature or a bug? I would have assumed that the backtest replay would also batch the updates for a single F_LAST and this would provide live/backtest parity
If any calculation is done inside on_book_deltas it will be duplicated multiple times in a backtest (giving us partial changed results as the order book would differ after every update from the same nanosecond updates) while it will only run once in live (the correct way is of live)
All reactions