pricetimeC++20 · MIT

Every trade in the world passes through a matching engine.Almost every first one is quietly wrong.

It decides who trades with whom, at what price, in what order. Simple enough to describe in a sentence and unforgiving enough that the mistakes are measured in hundreds of millions of dollars. This one is built to be proven correct rather than claimed correct, and the proof is running below, in this tab, compiled from the same C++ the benchmarks measure.

events compared, live
00 divergent

Two implementations run on the same input in this tab: the fast one, and a deliberately slow one written to be obviously correct. Every event is compared.

bids
·
·
·
·
·
·
·
·
asks
·
·
·
·
·
·
·
·
spread
n/a
messages
0
trades
0
resting
0
surveillance, on the same event stream

nothing flagged yet

last event emitted
loading WebAssembly

Why it is hard

2012

Knight Capital

A deployment reached seven of eight servers. The firm lost $460 million in 45 minutes and did not survive as an independent company.

2012

Nasdaq, Facebook's IPO

The opening auction entered a loop it could not exit, because a validation step could never converge under load. 38,000 orders were excluded.

2026

NYSE, fined $9M

Primary and backup ran at once, and 2,800 opening auctions were silently treated as already done. No policy required anyone to check whether they had.

Two of those three were not matching bugs. They were recovery failures: state existed in one place and there was no way to rebuild it somewhere else and prove the rebuild was right.

What is actually claimed, and how it is shown

500,000
operations, both engines

Written twice, on purpose

Once slow and obviously correct, once fast and not obviously anything. A fuzz test drives roughly 500,000 random operations through both and demands byte-identical output after every single one. It is running above.

1,499
of 1,499 executions matched

Graded against the exchange's own records

The engine replays 50,163,616 real orders from one trading day at a live US exchange, reconstructs what must have happened, and checks itself. For Apple: 1,499 of 1,499 executions matched exactly.

16,807
crash points, all recovered

Killed at every possible instant

Every input is journalled before it is applied, so the inputs are the state. The process was killed at all 16,807 byte offsets in the journal; 16,406 of those cuts landed mid-record. All recovered to byte-identical state.

1
model, kept out of the engine

A language model reads the output, never the book

Market abuse detectors run in C++ on the same event stream the engine emits, and their findings are deterministic. A language model then writes the compliance case note from those findings, in a separate process, told it may not invent a figure. It is not allowed near a matching decision, a price, or a fill, because an engine has to give the same answer every time and a model does not.

4x
wrong, and left in the README

Wrong guesses left in

A prediction about which workload would be slowest turned out to be the fastest by four times. It stayed in the README. A refuted prediction is worth as much as a confirmed one.

The measurement that changed the design

Real data ran thirty times slower than synthetic tests. The algorithm was not the problem.

The price table had grown to 27.7 MB and this CPU's fast cache holds 20. Restructuring so the hot data stays resident took one symbol from 1,986 ns per order to 50, and another from 4,634 to 62, with the output unchanged.

So the structure is not simply fast. It is fast on the condition that its working set fits in cache, and that condition is a design constraint rather than a footnote. Every latency figure published here says which machine produced it and what it excludes.

Run it

No package manager and no framework. Two commands you almost certainly already have. Every number on this page is reproducible in about a minute.

git clone https://github.com/Minifigures/pricetime
cd pricetime

make test      # 101 tests, ~600,000 fuzzed operations
make bench     # latency percentiles, four flow regimes
make recover   # journal a run, crash it, recover, prove it
make replay    # the book, in your terminal