# Matching Logic

The matching engine implements a continuous limit order book with price-time priority.

#### Order Book Structure

```rust
Orderbook {
    bids: BTreeMap<OrderbookKey, Order>,  // Sorted high-to-low
    asks: BTreeMap<OrderbookKey, Order>,  // Sorted low-to-high
}

OrderbookKey {
    price: i64,      // Negated for bids
    timestamp: u64,
    order_id: OrderId,
}
```

* **Bids**: Price negated so `BTreeMap` iteration yields highest prices first
* **Asks**: Price as-is so iteration yields lowest prices first
* **Tie-breaking**: Secondary sort by `(timestamp, order_id)` for FIFO at same price level

#### Matching Algorithm

```
while best_bid.price >= best_ask.price:
    1. Prune any zero-quantity orders at top of book
    2. Check crossing conditions (price, market_id, self-trade)
    3. Determine maker (earlier timestamp wins)
    4. Execute at maker's price
    5. Update quantities; remove exhausted orders
```

#### Maker Determination

```rust
maker_is_bid = (bid.timestamp, bid.order_id) <= (ask.timestamp, ask.order_id)
price = if maker_is_bid { bid.price } else { ask.price }
```

The order that arrived first is the maker; the match executes at the maker's price. This protects passive liquidity providers.

#### Partial Fills

When order quantities differ:

```rust
fill_quantity = bid.quantity.min(ask.quantity)
```

* Smaller order is fully filled and removed
* Larger order has quantity decremented; remains in book
* Multiple trades may result from a single aggressive order

#### Trade Output

```rust
Trade {
    market_id: MarketId,
    maker_order_id: OrderId,
    taker_order_id: OrderId,
    price: i64,
    quantity: u64,
    timestamp: u64,  // max(maker.timestamp, taker.timestamp)
}
```

#### Safety Checks

* **Cross-market prevention**: Matching stops if `bid.market_id != ask.market_id`
* **Self-trade prevention**: Optional flag stops matching if `bid.account_id == ask.account_id`

***


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs-v2.fermilabs.xyz/trading/matching-logic.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
