A cross-exchange trading engine where correctness is the feature.
Project
Systems engineering
Year
2025
Our focus
GoTrading engineReliability
How do you stop an arbitrage engine from acting on a stale order book?
Check every update for a sequence gap and refuse to trade until the book is whole. If a message is missing, the engine resyncs from a snapshot before that venue's book is used again. Combined with decimal-only money math, that removes the two ways this class of system quietly loses money.
System architecture · Arbitrage Engine
01 /What is a sequence gap and why does it matter so much?
Exchange order-book feeds number their updates. If you receive update 41 and then 43, you have missed one, and your local book is now wrong in a way that will not announce itself.
An arbitrage engine acting on that book sees a spread that does not exist and trades into it. The trade is real, the opportunity was not. Detecting the gap and forcing a snapshot resync before the book is trusted again is the difference between a system that works and one that bleeds.
02 /Why is floating point banned from the price path?
Because binary floating point cannot represent most decimal fractions exactly, and the errors accumulate. In ordinary software that is a rounding curiosity; in a system computing spreads and position sizes it is money.
The engine uses decimal arithmetic end to end in the price path. No float anywhere in it, so a computed size is the size, not an approximation that drifts across a few thousand operations.
03 /What happens when only one leg fills?
You are no longer arbitraging, you are holding a directional position you never intended. This is the scenario that turns a small edge into a large loss.
Partial-fill recovery handles it explicitly: the remaining exposure is either re-priced to complete the pair or unwound, and a position reconciler checks balances against the venue so the engine's view and reality stay in step.
04 /What do the circuit breakers actually watch?
Loss, latency and error rate. Each can independently halt trading, because each signals a different kind of wrongness.
The reasoning is that a bug in a trading system does not present as an exception, it presents as an unusual number. A breaker that stops trading on cumulative loss will catch a whole category of faults nobody anticipated, which is precisely what you want from a last line of defence.
05 /Why Go, and why pluggable adapters?
Go for predictable latency and straightforward concurrency on a workload that is mostly many simultaneous socket feeds.
Each venue sits behind a common adapter interface, so adding an exchange means writing an adapter rather than touching the decision path. Prometheus metrics run on every path, which is the only way to tell a latency problem from a venue problem.
06 /What we delivered
Decimal-only money math end to end
L20 order-book sync with gap detection
Partial-fill recovery across legs
Loss, latency and error-rate circuit breakers
07 /The outcome
A latency-sensitive engine with pluggable exchange adapters and Prometheus metrics on every path.
08 /Build at a glance
Language
Go
Money math
Decimal only, no floating point in the price path
Book depth
L20 per venue, held in memory
Integrity
Sequence-gap detection with snapshot resync
Execution
Two-leg, with partial-fill re-price or unwind
Reconciliation
Position reconciler against venue balances
Safety
Loss, latency and error-rate circuit breakers
Venues
Pluggable adapters behind one interface
Observability
Prometheus metrics on every path
COMMON QUESTIONS
Questions people actually ask
What is order book sequence gap detection?
Checking that the numbered updates from an exchange feed arrive without holes. Receiving update 41 then 43 means the local book is missing a change and is now wrong. Detecting that and resyncing from a snapshot prevents the engine trading on a spread that does not actually exist.
Why should trading systems avoid floating point?
Binary floating point cannot represent most decimal fractions exactly, so small errors accumulate across operations. In a system computing spreads, sizes and balances those errors are money. Decimal arithmetic keeps a computed value exact rather than approximately right.
What happens when one leg of an arbitrage trade fills and the other does not?
You hold an unintended directional position, which is how a small edge becomes a large loss. The engine handles this explicitly by either re-pricing to complete the pair or unwinding the filled leg, then reconciling positions against the venue's own balances.
What should a trading circuit breaker monitor?
Cumulative loss, latency and error rate, each able to halt trading on its own. Bugs in trading systems rarely surface as exceptions; they surface as unusual numbers. A loss-based breaker catches a whole category of faults nobody predicted, which is what a last line of defence is for.