~/problems / Trading systems / Order books and matching engines

Price-level book from order callbacks

medium ~35 min Optiver

A market-data feed for a single stock sends you order-level events. Build PriceLevelBook, which turns them into an aggregated price-level view.

  • on_order_insert(order_id: int, side: str, price: int, qty: int) -> None: a new resting order. side is "BUY" or "SELL". Prices are integer ticks; qty > 0.
  • on_order_modify(order_id: int, price: int, qty: int) -> None: the order now has this price and quantity (same side). Its old contribution must be removed before the new one is added; the price may or may not change.
  • on_order_cancel(order_id: int) -> None: the order is gone.
  • get_price_level(side: str, level_index: int) -> tuple[int, int] | None: the (price, total_qty) of the level at zero-based depth level_index, or None if that side has fewer levels.

A price level is the sum of qty over all live orders on that side at that price. For "BUY", level 0 is the highest price; for "SELL", level 0 is the lowest. A level with no live orders doesn't exist and must not be counted.

Feeds are noisy: ignore an insert whose order_id is already live, and ignore a modify or cancel for an unknown order_id. Once cancelled, an id may be reused by a later insert.

Queries are frequent and mostly near the top of the book, while the book can hold tens of thousands of levels. Don't re-sort every price on each query.

Constraints: up to 10**5 events; order_id is an integer in 0..2**31 - 1; price and qty are integers in 1..10**9; level_index >= 0. A level's total_qty can exceed 32 bits (it is a 64-bit integer in C++/Java).

book = PriceLevelBook()
book.on_order_insert(1, "BUY", 100, 5)
book.on_order_insert(2, "BUY", 101, 3)
book.on_order_insert(3, "BUY", 100, 2)
book.on_order_insert(4, "SELL", 103, 7)
book.get_price_level("BUY", 0)    # (101, 3)
book.get_price_level("BUY", 1)    # (100, 7)
book.get_price_level("BUY", 2)    # None
book.on_order_modify(2, 100, 4)   # moves from 101 to 100
book.get_price_level("BUY", 0)    # (100, 11)
book.on_order_cancel(4)
book.get_price_level("SELL", 0)   # None

Topic: Order books and matching engines. Price levels, price-time priority, partial fills, cancels.

0:00
Ctrl ' run · Ctrl ↵ submit
esc