Predicting stock prices with DeepLOB

Building a DeepLOB limit order book prediction and backtesting pipeline from IEX DEEP packet captures

Published on August 3, 20265 min read

stonks

Introduction

Kairos is a reimplementation and adaptation of DeepLOB (Zhang, Zohren & Roberts, 2019), a convolutional-recurrent neural network for predicting short-horizon price direction from raw limit order book data. This project takes the architecture beyond its original benchmark and runs it on live exchange data end to end: reconstructing the order book from raw packet captures, labelling price movement, training the model, and backtesting the resulting trading signal.

The data source was IEX DEEP, full order book depth from IEX (Investors Exchange). This ended up being the central complication of the project, since IEX carries a small share of total US trading volume — which breaks an assumption the original DeepLOB paper relies on. Most of this post is about that problem, the fix, and what the results do and don't show.

Background

A limit order book is the live record of resting buy and sell orders for a stock, organized by price. The core idea behind LOB-based prediction is that the balance of volume on the bid and ask sides carries information about where price is headed next: more volume on the bid side than the ask makes an upward move more likely, and vice versa. This is called order book imbalance, and it's a well-studied signal in market microstructure research.

DeepLOB's premise is that a neural network can learn this kind of pattern directly from raw order book snapshots — across all price levels and across time.

Data

The dataset covers three liquid tickers — AAPL, SPY, NVDA — over 30 trading days in mid-to-late 2024, split chronologically into training, validation, and test sets (no shuffling across days, to avoid leaking future information into training).

The flat-price problem

The original DeepLOB paper used London Stock Exchange data, where the price moves constantly throughout the day. IEX is a much smaller exchange — it handles only about 2–3% of US equity volume. For large-cap stocks like AAPL and NVDA, this means IEX's own best bid/ask barely moves; some sessions saw only two or three price changes all day.

That's a real problem for this kind of model. If the price is flat 99.9% of the time, the only sensible strategy the model can learn is to always predict flat. It'll look accurate and be completely useless. This is exactly what happened in early runs — the model collapsed to a single predicted class.

The fix

The fix was to stop looking only at the best bid/ask and instead weight the price by volume across all ten visible levels of the book, not just the top one. This "deep-book" price moves thousands of times a day, instead of a handful, because it reacts to volume shifting anywhere in the book — even when the top price hasn't changed. It's the same underlying idea (imbalance predicts price), just measured at the resolution the data actually supports.

Labels were also built from smoothed price trends over short windows rather than single price ticks (to cut down noise), and classes were balanced by construction — ranking all price moves and splitting them into thirds (down / flat / up) — rather than using a fixed threshold, which would have collapsed to all-flat again on this sparse data.

The model

The architecture has three stages:

  • Convolutional layers that compress the order book's price and volume structure into learned features, level by level.
  • An Inception module that scans the resulting sequence at multiple time scales at once.
  • An LSTM that summarizes the whole sequence into a single representation, which a final layer turns into a prediction: up, down, or flat, at three different time horizons simultaneously.

It's a small model by modern standards. The bottleneck was never model size; it was getting a usable signal out of a sparse data source.

Results

The model reached a Macro-F1 score of roughly 0.59–0.63 on held-out test data, well above the 0.33 you'd get from random guessing, with predictions spread across all three classes rather than collapsing to one. For comparison, the original DeepLOB paper reports 0.77–0.87 on its denser benchmark. Given that IEX carries a fraction of the market's real activity, 0.6-ish is the number worth being satisfied with here.

Backtesting

A trading simulator was built to test whether the model's predictions could actually make money — using only information available at each moment, sizing positions by model confidence (fractional Kelly), and running a small ensemble of automated risk managers.

Starting from $10M in simulated capital, the backtest ended the 10-day test period at $52.9M — a total return of +429%.

That number needs context. Three trading sessions — all during periods of major market turmoil — account for almost the entire return; the other seven days were flat or slightly negative. The win rate was actually below 50%. In other words, this isn't a strategy with a steady daily edge. The backtest also assumed zero trading fees and perfect fills, both of which flatter the result.

What's missing

The project stops at research and backtesting — a real trading system would also need much faster infrastructure (reading market data and placing orders in milliseconds instead of seconds), which was designed on paper but not built, due to the cost and complexity involved.

Beyond that, the honest limitations are: more trading days of data would meaningfully strengthen everything else, transaction costs need to be modeled realistically, the model's confidence scores aren't currently calibrated to real probabilities, and none of this has been tested with real money in a live market.

Sources