Matching Engine
The Intotes orderbook matching engine is responsible for pairing buy and sell orders in orderbook-type markets. It uses price-time priority and supports partial fills, automatic liquidity provision, and real-time balance updates.
Price-Time Priorityβ
Orders are matched according to two rules, applied in order:
- Price priority: The best-priced orders are matched first.
- Buy orders match against the lowest ask (cheapest sell order).
- Sell orders match against the highest bid (most expensive buy order).
- Time priority: When multiple orders exist at the same price, the order that was placed first gets filled first (FIFO).
Matching Processβ
When a new order arrives, the engine attempts to match it immediately:
Buy Order Arrivesβ
- The engine looks at the sell side of the orderbook, sorted by price ascending (lowest first).
- If the lowest ask price is less than or equal to the buy order's price (for limit) or any price (for market), a match occurs.
- The trade executes at the ask price (the seller's price).
- If the buy order's budget is not fully spent, the engine continues matching against the next lowest ask.
- Any remaining budget (for limit orders) stays in the orderbook as a standing bid.
Sell Order Arrivesβ
- The engine looks at the buy side of the orderbook, sorted by price descending (highest first).
- If the highest bid price is greater than or equal to the sell order's price (for limit) or any price (for market), a match occurs.
- The trade executes at the bid price (the buyer's price).
- If the sell order's shares are not fully sold, the engine continues matching against the next highest bid.
- Any remaining shares (for limit orders) stay in the orderbook as a standing ask.
Partial Fillsβ
Orders do not need to fill in a single match. A large buy order may match against multiple smaller sell orders, and vice versa. Each individual match creates a separate trade record. The order's status transitions from pending to partial after the first incomplete fill, and to filled once the full amount is consumed.
Trade Creationβ
Each match between a buy order and a sell order produces a trade with:
- Price: The execution price (the resting order's price).
- Amount: The number of shares exchanged in this match.
- Buyer fee:
price * fee%charged to the buyer. - Seller fee:
price * fee%charged to the seller. - Timestamps: Exact time of execution.
Trades are broadcast in real time over the WebSocket feed at /api/v1/ws/trades.
Balance Updatesβ
On each trade, balances are updated atomically:
- Buyer: Balance decreases by
price * (1 + fee%) * shares. Position increases by the number of shares acquired. - Seller: Balance increases by
price * (1 - fee%) * shares. Position decreases by the number of shares sold.
All balance operations are transactional to prevent inconsistencies.
Automatic Liquidityβ
To ensure markets remain tradeable even with low organic volume, the platform maintains automatic liquidity:
Spread Controlβ
The system keeps the spread between the best bid and best ask at 2 cents or less. If the spread widens beyond this threshold, the system places orders to tighten it.
Volume Floorβ
If either side of the orderbook (bids or asks) has less than $200 equivalent in total volume, the system automatically adds orders to bring it above the threshold.
Refresh Cadenceβ
Automatic liquidity is recalculated:
- After every trade -- to immediately replenish consumed liquidity.
- Every 5 minutes -- as a periodic sweep to maintain the spread and volume floor even in quiet markets.
These system-placed orders behave identically to user orders in the matching engine. They follow the same price-time priority rules and generate the same trade records.
Orderbook Dataβ
The current state of the orderbook (all resting bids and asks) is available via the market detail endpoints. Each level shows the price and total volume at that price.
See Alsoβ
- Placing Orders -- How to submit orders to the engine
- Order Types -- Limit vs. market order behavior
- Fees and Commissions -- Fee calculations on matched trades
- AMM Trading -- Alternative mechanism for LMSR markets