What Is a Stock Exchange System?
A stock exchange matching engine pairs buy and sell orders in real time, executing trades at the best available price. Core requirements: strict price-time priority (FIFO at each price level), sub-millisecond matching latency, full audit trail, and deterministic replay. NYSE and NASDAQ process 8–10 billion shares per day; modern exchanges target single-digit microsecond matching latency.
Order Types
- Market order: execute immediately at best available price
- Limit order: execute only at specified price or better
- Stop order: becomes a market order when a trigger price is reached
- IOC (Immediate or Cancel): fill as much as possible immediately, cancel remainder
- FOK (Fill or Kill): fill entire order immediately or cancel entirely
Order Book Data Structure
The order book maintains all outstanding limit orders organized by price level. Two sides:
- Bids: buy orders, sorted by price descending (best bid = highest price buyer will pay)
- Asks: sell orders, sorted by price ascending (best ask = lowest price seller will accept)
Data structure: price-level map using a sorted structure (TreeMap / SortedDict) keyed by price. Each price level holds a queue (FIFO) of orders. Operations:
add_order(order) → O(log P) # P = number of price levels
cancel_order(order_id) → O(1) # with order_id → order pointer map
match_order(order) → O(M log P) # M = number of fills
Matching Algorithm
Price-time priority (most common): orders at better prices fill first; at the same price, earlier orders fill first.
def match(incoming_buy_order, asks):
while incoming_buy_order.qty > 0 and asks:
best_ask_price, best_ask_queue = asks.peekmin()
if incoming_buy_order.price 0:
add to bids[incoming_buy_order.price]
Performance Optimizations
For sub-millisecond latency:
- CPU pinning: matching engine thread pinned to a dedicated CPU core — no context switching
- DPDK networking: bypass kernel network stack, process packets directly in userspace
- Lock-free data structures: SPSC (single-producer, single-consumer) ring buffers for order ingestion
- Memory pre-allocation: object pool for Order structs — no GC pauses (Java GC is a killer), use C++ or Rust
- Cache locality: order book stored in contiguous memory; L1 cache hit vs. heap allocation matters at microsecond latency
Trade Matching Log and Replay
Every order event (submit, cancel, modify, fill) is appended to an immutable trade log (journal). The journal is the single source of truth. The in-memory order book is derived state — it can be fully reconstructed by replaying the journal from the beginning. Benefits: disaster recovery (rebuild from log), audit compliance (full history), and deterministic simulation (backtest by replaying historical order flow).
Market Data Distribution
After each match, the exchange broadcasts market data: Level 1 (best bid/ask), Level 2 (full order book depth), and time-and-sales (trade tape). Disseminated via multicast UDP to market data subscribers. UDP used (not TCP) because packet loss is preferable to latency — recipients request retransmission or use sequence number gaps to detect missed data.
Interview Framework
- Order book: TreeMap of price levels, each level is a FIFO queue
- Matching: price-time priority, greedy match against opposite side
- Durability: append-only journal before modifying in-memory book
- Latency: single-threaded matching, CPU pinning, kernel bypass
- Market data: multicast UDP broadcast of level 1/2 and trades