v0.14.0: The Order-Book Recorder Works — and Calls 100% of Its Orders Cancelled
We recorded a full session of Rithmic order-by-order depth with our own recorder: 5,711 events on MNQU6, entitlement present, no gaps. Then we asked the obvious research question — how many resting orders were executed rather than pulled — and got 0%. Not a recorder bug: the MBO channel carries adds, changes and cancels, and execution arrives separately, aggregated at the price level. Nine unit tests stayed green because their fixtures hand-built a message shape production has never emitted. The counts, the plumbing, and the test we wrote to bless the defect until we fix it properly.
v0.14.0 ships the recorder that keeps what every other chart throws away: the order book itself, event by event, rather than the trades it produces. The recorder works. The first research question we pointed at it came back with an answer that cannot be true.
The measurement
One session, recorded by our own software on a live Rithmic feed — MNQU6 on CME, 7 September 2026. Entitlement present, queue priority populated on 93.2% of events, no gap markers. 5,711 events, broken down by what they do to the book:
- 2,363 cancels — 41.4%. An order leaves the book.
- 2,330 adds — 40.8%. An order joins it.
- 630 modifications — 11.0%.
- 388 aggregated trades — 6.8%. Something traded at a price.
- 0 per-order fills — 0.0%. Not a rounding artefact. Zero.
Feed that corpus to an order-lifecycle analysis and it reports that 100% of orders were pulled and none were executed. Which inverts the one distinction the whole exercise exists to make.
Why it is zero
Rithmic’s order-by-order channel describes the book, not the outcome. Its updates translate to three things — new, change, delete — and nothing else. Execution travels separately, as a trade aggregated at the price level, on the same ordered channel. Both facts are correct and documented; they simply live in different messages.
So the information is there. What is not there is the join. When an order disappears from the book, the delete alone cannot tell you whether it was cancelled by its owner or consumed by an aggressor. You have to attribute the aggregated trade back to the resting orders at that price, first in, first out, respecting which side was the aggressor. That is a design decision, not a missing field.
Why our tests were green
Nine lifecycle tests passed throughout. Their fixtures built the fill records by hand — a message shape our production path has never once emitted. The tests were checking that we handle data we do not receive.
This is the fourth time this exact pattern has cost us on this project, and it is worth saying plainly: a module that has never touched the real resource has green tests that measure nothing. The corpus above took an afternoon to decode. It falsified in one table what nine passing tests had been asserting for weeks.
What we shipped instead of a quick fix
Attributing trades to orders in a hurry produces a number that is differently wrong, and a differently wrong number is harder to catch than an obviously absent one. So v0.14.0 ships the recorder and not the verdict.
What it does ship is a characterisation test: it feeds the tracker a corpus with the shape production actually produces, and asserts that every death comes out classified as pulled. It blesses the defect rather than validating it — and when the attribution lands, that test must turn red. A test going red as the proof a fix worked is unusual enough to be written in the file, next to the assertion.
Also in v0.14.0
- 139.7 MB → 69.8 MB — heatmap buffer memory, halved without losing a second of history.
- A DOM ladder on the chart itself, in the space the depth profile used to occupy, with width, thickness and opacity you can set — and a volume profile that finally knows the session instead of counting from whenever you opened the app.
- A liquidity tracker showing what resting size actually did, wired to the live feed. Off by default.
- The backtest report stops being a list of trades: verdict, distributions, fill history.
- Prop-firm rule engine — drawdown, daily loss, custom rule sets, Monte-Carlo — and syntax highlighting in the script editor.
One fix nobody reported
Dragging a window edge to resize it did nothing. Not an error, not a dialog — the handle was simply inert, because a Tauri permission for resize-dragging was missing from the capability list while its neighbour, move-dragging, was present. Two names close enough that the omission survived two releases.
It reached us as five automatic crash reports and zero human ones, the oldest from 18 August. Nobody files a ticket about a handle that will not grab; you assume you missed the edge and try the corner. Silent defects have no constituency — they exist only if your instrumentation sees them.
v0.14.0 ships through the auto-updater on Windows, macOS and Linux. The next chapter of this log is the attribution above: turning 388 aggregated trades into an honest answer about which resting orders were actually hit. If you want the mechanics of the book rebuild that made this recording possible, that is the v0.7.4 log.
Frequently asked questions
- Does this mean Rithmic order-book data is unusable?
- No. The book itself rebuilds correctly — adds, changes and cancels arrive on an ordered channel and the depth you see is right. What is missing is the per-order execution flag. Trades do arrive, on the same ordered channel, aggregated at the price level. Attributing them back to individual resting orders is work you have to do; it is not data you are handed.
- Would buying historical MBO data have caught this?
- It would have hidden it. A purchased DBN corpus carries explicit per-order fill records, so code written against it works perfectly — right up to the moment it meets a live feed that never sends one. The trap is exactly that the module works on the data you did not record yourself.
- Is the pulled-vs-filled number shown anywhere in the app today?
- No, and that is deliberate. The lifecycle tracker is not wired to any screen. A wrong statistic that nobody can see is a defect; a wrong statistic on a chart is a lie. It stays off until the attribution is designed properly.
Order Flow on a Prop-Firm Account: What Actually Works on Apex, Topstep and 4PropTrader
The rules, the feeds and the drawdown maths nobody writes about because they trade their own money.
v0.15.0: 26 of Our 27 Backtests Were Identical — and the Optimiser Ranked Them Anyway
Our parameter sweep was reading keys the strategy never used. 27 runs, 26 identical, a winner picked by rounding — and a green test suite throughout.