codejump
HardPro challengePythonJavaScriptTypeScript

System Design — Limit Order Book

System DesignMatching EnginePriority QueueFinance

The heart of an exchange: buyers and sellers post limit orders, and the engine matches them
by price-time priority.

solve(args, ops) builds new OrderBook() and replays ops:

  • submit(id, side, price, qty) — side is "buy" or "sell", id is unique. The new order

(the taker) is matched against the opposite side while it can trade:
- a buy trades with the lowest-priced asks priced `<=` its limit; a sell trades with
the highest-priced bids priced `>=` its limit;
- among resting orders at the same price, the one submitted first trades first;
- each trade is [takerId, makerId, price, qty] where price is the **resting (maker)
order's price** and qty is the smaller of the two remaining quantities;
- whatever quantity is left after matching rests in the book at the taker's limit price.
Returns the list of trades, in the order they happened ([] if none).

  • cancel(id) — remove a resting order. Returns true if it was resting, else false.
  • depth(side) — the resting quantity per price level on that side as [price, totalQty]

pairs, best price first (highest first for "buy", lowest first for "sell").

Example

submit(1,"sell",101,5) submit(2,"sell",100,3)   depth("sell") → [[100,3],[101,5]]
submit(3,"buy",100,2)  → [[3,2,100,2]]          depth("sell") → [[100,1],[101,5]]
submit(4,"buy",101,10) → [[4,2,100,1],[4,1,101,5]]    // 4 units are left and rest as a bid at 101

Sample tests

Test #1Partial fills, sweeping levels and cancelling
Input: [[],[["submit",1,"sell",101,5],["submit",2,"sell",100,3],["depth","sell"],["submit",3,"buy",100,2],["depth","sell"],["submit",4,"buy",101,10],["depth","buy"],["depth","sell"],["submit",5,"sell",99,6],["depth","sell"],["cancel",5],["cancel",5],["depth","sell"]]]
Output: [[],[],[[100,3],[101,5]],[[3,2,100,2]],[[100,1],[101,5]],[[4,2,100,1],[4,1,101,5]],[[101,4]],[],[[5,4,101,4]],[[99,2]],true,false,[]]
Test #2Time priority at the same price
Input: [[],[["submit",6,"sell",100,2],["submit",7,"sell",100,2],["submit",8,"buy",100,3],["depth","sell"]]]
Output: [[],[],[[8,6,100,2],[8,7,100,1]],[[100,1]]]
Test #3Orders that do not cross just rest
Input: [[],[["submit",1,"buy",99,5],["submit",2,"sell",100,5],["depth","buy"],["depth","sell"]]]
Output: [[],[],[[99,5]],[[100,5]]]