Software companion
Order-Book Imbalance as a One-Second Predictor
Overview
The pipeline reconstructs a limit order book from raw message and snapshot files, builds imbalance features, and tests whether they predict the sign of the next second’s price change. Its design problem is that a single day of a single symbol can support an impressive-looking AUC while supporting no trading claim at all, so most of the engineering goes into keeping that gap visible rather than letting it close quietly.
Two decisions carry that weight. Spread quintiles are computed per venue and per run and never pooled, so a diagnostic slice cannot borrow its definition from another dataset. And the post-cost overlay is a pipeline stage with its own command rather than an appendix: the report cannot present discrimination without also presenting what it is worth after crossing the spread.
Implementation
- Core libraries
- NumPy, pandas, SciPy, pyarrow, Matplotlib; requests and websockets for the optional Binance path
- Data sources
- The free 10-level LOBSTER sample, pinned to AAPL on 2012-06-21; Binance depth data is optional and off the default path
- Interface
- A stage CLI —
python -m src.cli run-all --source fixture|raw— with every stage also runnable on its own - Offline path
- A built-in LOBSTER-shaped fixture, so the whole pipeline runs end to end with no downloads
- Split
- Chronological 50/50, chosen so the held-out window spans at least three hours of a standard session
- Tests
- 8 modules across unit, integration, notebook-smoke and report-contract layers
Components
src/lobster.py- Message and order-book file parsing and event replay
src/book.py- Book state and top-of-book extraction at each event
src/features.py- Depth-imbalance and spread features at the configured level count
src/labels.py- The one-second-ahead direction label, with ties dropped and counted rather than assigned
src/modeling.py- The chronological split and logistic-regression fitting
src/evaluation.py- Global AUC and calibration, plus the time-of-day and spread-quintile slices
src/costs.py- The post-cost overlay separating discrimination from tradeable edge
src/validation.py- The fail-closed data check behind
validate-data src/binance.py- The optional crypto depth path, kept off the default run
src/pipeline.py- Stage orchestration shared by the CLI and the replication notebook
src/report.py, src/plots.py- Report assembly and the three published figures
Stages
validate-dataCheck that the raw LOBSTER files are present and well formed; exit non-zero naming the missing file if not.build-featuresReplay the book and write processed parquet features and labels.fit-modelFit the logistic model on the chronological first half.evaluateScore the held-out half globally and by time of day and spread quintile.cost-overlayApply round-trip costs to the same predictions.make-reportRender the report and its three figures.run-allThe full sequence, against either the fixture or the raw sample.
Reproducibility and validation
- The held-out window covers at least three hours of a 6.5-hour session by construction, because the time-of-day diagnostic is meaningless on a shorter block.
- Label ties are dropped and their count written to run metadata, so the effective sample is auditable rather than implied.
- A report-contract test asserts that the published document still carries the single-day caveat and the post-cost numbers.
- The replication notebook is smoke-tested and calls the same pipeline functions as the CLI, so the two cannot drift apart.
Availability
Not publicly released, and the data could not travel with it in any case: the LOBSTER sample is redistributed under its own terms and the repository expects the user to place the files. The fixture path exists precisely so the implementation can be exercised without them.