AllTick
A Complete Guide to the Order Matching Engine
quantitative tradingBacktestingOrder Matching EngineAlgorithmic Trading

A Complete Guide to the Order Matching Engine

Learn how an order matching engine works, compare FIFO, pro-rata, and hybrid algorithms, and test basic matching logic with Python. Discover how order priority, partial fills, and execution costs affect quantitative trading backtests.

AllTick5 min read

An order matching engine determines how buy and sell orders are paired in an electronic market. For quantitative traders, understanding its rules is essential for estimating execution costs, modeling partial fills, and building more realistic backtests.

A trading strategy may identify the right entry price but still perform poorly if its execution assumptions ignore order priority, available liquidity, or slippage. This guide explains how matching engines work, compares three common matching algorithms, and demonstrates how to test basic matching logic with Python.

How an Order Matching Engine Works

A typical limit order book follows four stages:

  1. Order submission: A trader submits an order containing the instrument, side, price, quantity, and order type.
  2. Order validation: The system checks the order against applicable trading rules.
  3. Order matching: The engine identifies eligible opposing orders and applies its matching algorithm.
  4. Execution and updates: Filled quantities, remaining orders, and trade records are updated.

Consider a stock with a best ask of $100.00. A trader submits a buy limit order at $101.00 for 10 shares. If at least 10 shares are available at $100.00, the order can execute at that price under the assumed market conditions.

If only six shares are available, the order may receive a partial fill, leaving four shares unfilled. Whether the remaining quantity stays in the book depends on the order instructions and applicable market rules.

How the Order Book Determines Priority

A limit order book records outstanding buy and sell orders.

ComponentTypical orderingRelevance to quantitative trading
Bid sideHighest price firstIdentifies the best displayed buying price
Ask sideLowest price firstIdentifies the best displayed selling price
Orders at the same priceVenue-specific priority rulesInfluences queue position and fill probability
Remaining quantityUpdated after executionsHelps estimate available liquidity

The difference between the best ask and best bid is the bid-ask spread. Displayed quantities at different prices provide information about market depth.

However, displayed liquidity is not guaranteed to remain available. Orders can be canceled or modified before a strategy reaches the market. Historical quotes alone also cannot establish exactly where a hypothetical order would have stood in the queue.

Market Orders vs. Limit Orders

FeatureMarket orderLimit order
Price controlNo specified limit priceSets a maximum buy or minimum sell price
ExecutionDepends on available liquidityRequires an eligible price and available liquidity
Main riskSlippage and uncertain execution pricePartial fill or no fill
Typical purposePrioritize executionControl the acceptable price

For backtesting, a common mistake is assuming that a limit order fills whenever the market touches its price. A price touch does not prove that the order would have executed. Other orders may have priority, or the available trading volume may be insufficient.

Three Common Order Matching Algorithms

Price-Time Priority (FIFO)

Price-time priority ranks orders by price first and arrival time second. Better-priced orders receive priority, while earlier orders take precedence among orders at the same price.

Suppose two buy orders are submitted at $100.00. Order A requests 10 shares and arrives first; Order B requests 20 shares and arrives second. If 15 eligible shares become available to sell at that price level, Order A may receive 10 shares and Order B the remaining five.

FIFO is relatively straightforward to model, but traders must verify the actual rules of the venue being studied.

Pro-Rata Allocation

Pro-rata matching allocates available volume proportionally among eligible orders at a price level, subject to the venue's rules.

Suppose two orders contain 10 and 30 contracts, and 20 contracts are available for allocation. Under a simple proportional model, the orders receive five and 15 contracts, respectively.

Real implementations may include minimum allocations, rounding rules, priority tiers, or other conditions. This simplified calculation should not be treated as a universal description of futures markets.

Hybrid Matching

Hybrid algorithms combine priority mechanisms. For example, a venue may allocate some volume according to priority and distribute the remainder proportionally.

The precise rules depend on the venue and instrument. Quantitative traders should model the applicable allocation method rather than assume that one algorithm applies across every market.

Test a Basic FIFO Matching Model in Python

The following educational example sorts orders by price and arrival time, matches crossing orders, and records partial fills. It also returns the remaining quantities for verification.

text
def match_orders(buys, sells):
    buys = sorted(
        (dict(o) for o in buys),
        key=lambda o: (-o["price"], o["time"])
    )
    sells = sorted(
        (dict(o) for o in sells),
        key=lambda o: (o["price"], o["time"])
    )

    trades = []

    while buys and sells:
        buy, sell = buys[0], sells[0]

        if buy["price"] < sell["price"]:
            break

        qty = min(buy["qty"], sell["qty"])

        trades.append({
            "buy_id": buy["id"],
            "sell_id": sell["id"],
            "price": sell["price"],
            "qty": qty,
        })

        buy["qty"] -= qty
        sell["qty"] -= qty

        if buy["qty"] == 0:
            buys.pop(0)
        if sell["qty"] == 0:
            sells.pop(0)

    return trades, buys, sells


buys = [
    {"id": "B1", "price": 100, "qty": 10, "time": 1},
    {"id": "B2", "price": 100, "qty": 20, "time": 2},
]
sells = [
    {"id": "S1", "price": 99, "qty": 15, "time": 0},
]

trades, remaining_buys, remaining_sells = match_orders(
    buys, sells
)

print(trades)
print(remaining_buys)
print(remaining_sells)

Expected result: B1 matches 10 shares with S1, and B2 matches the remaining five shares. B2 retains 15 unfilled shares, while S1 is fully filled.

The example assumes positive quantities, integer timestamps, a simple price-time order book, and the sell order as the resting order whose price determines execution. This is an illustrative pricing convention, not a universal exchange rule.

It is not production-ready. A real matching engine needs order validation, cancellation and amendment handling, concurrency controls, failure recovery, and venue-specific execution logic. The example also uses list sorting and removal for clarity rather than high-performance data structures.

How to Validate Matching Assumptions in a Backtest

A useful execution test should check more than whether two prices cross.

  • Priority: Verify that better-priced orders execute before worse-priced orders and that same-price orders follow the assumed priority rule.
  • Partial fills: Confirm that traded quantities never exceed either order's remaining quantity.
  • Execution costs: Test the effect of spreads, fees, and slippage on net strategy performance.
  • Sensitivity: Compare results under different fill assumptions to determine whether apparent profitability depends on optimistic execution.

For example, run the same strategy under two scenarios: one where eligible limit orders fill immediately and another where fills require sufficient opposing volume. A large performance difference signals that execution assumptions deserve closer scrutiny.

Connecting Market Data to Execution Analysis

An order matching engine executes orders, whereas a market data API supplies observations of market activity. The two serve different purposes.

For quantitative traders, AllTick provides REST and WebSocket APIs for supported market data, including available quote and historical data. These data can help researchers examine price movements, reconstruct observed market conditions, and test execution assumptions. They do not independently reveal every order's queue position or guarantee that a simulated trade would have filled.

Before building a research pipeline, consult the AllTick API documentation to verify supported instruments, data types, and integration details.

A realistic backtest depends on both reliable market data and defensible execution assumptions. Understanding how an order matching engine assigns priority is an important step toward evaluating whether a strategy's simulated performance could translate into actual trading conditions.

Start streaming market data today

Generate a free API key in seconds and connect to every market from one endpoint.