Every number on this page was produced by a program.
Not one of them was typed in by a person. A single command runs the checks and writes the data this page renders from, so each figure below can be traced to the run that produced it, on the machine that ran it, at the minute it ran.
The same input produces the same output, bit for bit.
The engine is a pure state machine: no clock reads, no random numbers, no floating point, no database calls in the middle of a decision. Feed it the same ordered log of commands and it lands in exactly the same state, every time, on any machine.
That is not a nice property to have. It is the entire failover story (a replica is a process replaying the same log), the entire audit story (any past state can be reconstructed and proved), and the reason the rest of this page is checkable at all.
The actual hashes
These are the real values from the run stamped at the top of this page. Re-run the checks on another machine, on another day, and you get these same strings.
Checked, command by command, against a second engine.
An engine that agrees with itself proves nothing. So the same order flow runs through Clobber and through exchange-core, the Java matching engine built on the LMAX Disruptor that most teams reach for first, and the two are compared after every single command.
exchange-core was written by people who never saw our specification. That is the point: our own tests can only encode our own misunderstandings, and a second implementation cannot.
Their test data, too
Beyond the random flow, exchange-core's own order book test fixture is replayed order for order: the book their test suite asserts before every one of its cases, rebuilt on our engine and checked against their expected result. 23 commands producing 9 price levels, from exchange-core OrderBookBaseTest, ported (Apache 2.0, 2022-05-14).
An entire trading day of a major US equities market, checked against that market itself.
A major US equities market publishes one full day of its own feed openly (January 30, 2020: 419,034,639 messages, every displayed order for all 8,915 symbols). It is translated into engine commands and replayed. The feed names which resting order each execution hit, so that exchange's own matching engine becomes the oracle: ours must pick the same order theirs picked, hundreds of millions of decisions later.
Where the remainder goes, exactly:
- The public feed reports 5,130,446 partial cancels and price adjusted executions that can only be rebuilt as a cancel plus a new order, which loses the original queue position. Every book that needed one (88 of 8,915) is excluded from the byte identical claim, and those queue positions account for the maker picks that differ.
- Zero books diverged without such a translation in their history. A divergence with no approximation to blame would be a bug; the day produced none.
The money adds up, and it is checked rather than assumed.
The ledger is double entry and it lives inside the engine, not in a database behind it. Every movement of value is two equal and opposite entries, so the sum of every entry, for every currency, is always exactly zero.
A venue whose ledger can drift has to reconcile. This one cannot drift, because a command that would unbalance it fails the check and never becomes state. There is no end of day job that finds the discrepancy the next morning.
The honest limits.
Numbers with no stated limits are marketing. These are the restrictions on the comparison above, and each one exists because the two engines model something differently, not because the result was inconvenient.
The differential comparison runs on a restricted subset:
- pair markets, the only model both engines share
- lot size 1 and tick size 1, so a price means the same number on both sides
- zero fees: theirs are per lot, ours in basis points
- one side per account, since exchange-core has no self trade prevention
- gtc and ioc: their fill or kill is a budget test and ours is a quantity test
Everything the subset excludes, our binary and scalar markets, fees, self trade prevention, settlement, is covered by our own property tests and by a second reference engine written for the purpose. Those are real checks, but they are ours, and a check you wrote against your own design is worth less than one you did not. The comparison on this page is the one we did not write both sides of, so it is the one published here.
You never run any of this. That is the product.
Every check on this page runs against the engine that serves your markets, on every build, before anything reaches a cell. They are the gate, not a launch exercise, and the page is regenerated from the run rather than edited afterwards.
The alternative is the one most teams take: fork an engine, and inherit the ledger, the durability, the failover and the audit trail as your problem, permanently. That is the two year detour this exists to remove. You call an API and place orders; the determinism, the conservation invariant and the comparison against a second engine are ours to keep green.
The reasoning behind the design is in the whitepaper, the claims are stated formally with their proofs in Fundamentals, and the API is documented in full.