Stock Exchange

Matching Engine

Understanding the order matching algorithm

Overview

The matching engine is the core component of the stock exchange that matches buy and sell orders. It uses a price-time priority algorithm to ensure fair and efficient order execution.

How It Works

Price-Time Priority

The matching engine follows two fundamental rules:

  1. Price Priority: Orders with better prices are matched first

    • For buy orders: Higher prices have priority
    • For sell orders: Lower prices have priority
  2. Time Priority: Among orders at the same price, earlier orders are matched first (FIFO - First In, First Out)

This is the same matching algorithm used by major stock exchanges worldwide, including NYSE and NASDAQ.

Order Types

Limit Orders

A limit order specifies the maximum price you're willing to pay (buy) or minimum price you'll accept (sell).

{
  "type": "LIMIT",
  "bid": true,
  "price": 1000,
  "size": 10
}

Characteristics:

  • ✅ Price protection
  • ✅ May not execute immediately
  • ✅ Remains in orderbook until filled or cancelled

Market Orders

A market order executes immediately at the best available price.

{
  "type": "MARKET",
  "bid": true,
  "size": 10
}

Characteristics:

  • ✅ Immediate execution
  • ❌ No price protection
  • ✅ Never remains in orderbook

Matching Process

Order Received

When a new order arrives, the matching engine determines if it can be immediately matched.

Check Opposite Side

The engine looks at the opposite side of the orderbook:

  • Buy orders check the ask side
  • Sell orders check the bid side

Match at Best Price

If there's a matching order:

  • The trade executes at the maker's price (the order already in the book)
  • Both orders are reduced by the matched quantity
  • A trade record is created

Partial Fills

If the incoming order is larger than available liquidity:

  • Multiple matches occur at different price levels
  • The order is partially filled
  • Remaining quantity stays in the orderbook (for limit orders)

Add to Orderbook

If unmatched quantity remains (limit orders only):

  • The order is added to the appropriate side of the orderbook
  • It becomes available for matching with future orders

Example Scenarios

Scenario 1: Full Match

Orderbook State:

Asks:  1005 (50 shares)
       1010 (30 shares)

Bids:  995 (40 shares)
       990 (50 shares)

New Order: Market Buy 50 shares

Result:

  • Executes 50 shares at 1005
  • Trade recorded: 50 @ 1005
  • Ask at 1005 is removed from book

Scenario 2: Partial Fill

Orderbook State:

Asks:  1005 (30 shares)
       1010 (50 shares)

Bids:  995 (40 shares)

New Order: Market Buy 70 shares

Result:

  • Executes 30 shares at 1005
  • Executes 40 shares at 1010
  • Two trades recorded
  • Both asks partially filled

Scenario 3: No Match

Orderbook State:

Asks:  1010 (50 shares)

Bids:  995 (40 shares)

New Order: Limit Buy 20 @ 1000

Result:

  • No immediate match (1000 < 1010)
  • Order added to bid side at 1000

Performance Characteristics

The matching engine is optimized for high performance:

OperationTime Complexity
Place OrderO(1) amortized
Match OrderO(k) where k = number of matches
Get Best Bid/AskO(1)
Cancel OrderO(1)

The engine can process thousands of orders per second with minimal latency.

Data Structures

The orderbook uses efficient data structures:

  • Price Levels: Hash map for O(1) access to each price level
  • Order Queue: Linked list for FIFO ordering at each price
  • Price Tree: Ordered structure for finding best bid/ask
type Orderbook struct {
    asks []*Limit
    bids []*Limit
    Orders map[int64]*Order
}

type Limit struct {
    Price       float64
    Orders      []*Order
    TotalVolume int
}

Trade Generation

When orders match, the engine generates trade records:

type Trade struct {
    Price     float64
    Size      int
    Timestamp int64
    Bid       bool
}

These trades represent actual executions and are used for:

  • Trade history
  • Price charts
  • Volume calculations
  • Market data feeds

Next Steps

On this page