Hi! I'd like feedback on exchange, a limit order book and matching engine in Rust: orders go in, trades and an event stream come out.

Repo: GitHub - Wandalen/exchange · GitHub

The problem

A matching engine is easy to get almost right. The hard part is what must never happen:

  • Spending money you don't have: a buy order rests on the book before its funds are actually held.
  • Money appearing or vanishing: a trade where the buyer's payment and the seller's proceeds don't match to the last cent.
  • A different result on replay: the same orders produce different trades because of a hash-map order, a clock read or thread timing.
  • Silent losses: a full queue or a full book quietly drops an order instead of refusing it.

What exchange does

  • Price-time priority: best price first; at the same price, the earliest order wins. Partial fills across many resting orders.
  • Funds held before an order rests: every order reserves its funds first through an EscrowPort trait, which a wallet system can implement.
  • Every trade balances: each settlement must net to exactly zero, or it's refused. All money math is exact; no floats anywhere.
  • Deterministic: orders arrive through a lock-free ring and are processed in one fixed sequence, never by wall-clock time or thread timing. Running the same input twice gives the same checksum.
  • Refuses instead of dropping: a full ring, a full book, a duplicate order id, an off-grid price, a halted market, a self-trade, a failed fill-or-kill or a failed fund hold each come back as a named reject.
  • Order rules: good-till-cancelled, immediate-or-cancel, fill-or-kill (never partially fills) and post-only; three self-trade policies; per-instrument halt; tick and lot sizes; top-of-book depth without walking the whole book.

One demo runs all of it and prints a fixed result:

$ cargo run -p smoke_exchange_book fills=10@1.00,2@1.00 fok_rej=1 dup=1 halt=1 overflow=1 conserve=0 a=0xda7a45e0d20c8fed b=0xda7a45e0d20c8fed ok 

(conserve=0 means the books net to zero; a and b are two runs of the same input with the same result.)

Not built yet

Stop orders, more than one asset pair, amending an order, fees, and rebuilding state from the event log after a restart.

Compared to existing crates

orderbook-rs and matchcore already cover more order types, and orderbook-rs has the same three self-trade modes. What none of the crates I looked at offer is a hook to hold funds before an order rests. Exchange also uses exact money types and has no external dependencies.

Thanks!

1 post - 1 participant

Read full topic