Skip to main content

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:

  1. 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).
  2. 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​

  1. The engine looks at the sell side of the orderbook, sorted by price ascending (lowest first).
  2. 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.
  3. The trade executes at the ask price (the seller's price).
  4. If the buy order's budget is not fully spent, the engine continues matching against the next lowest ask.
  5. Any remaining budget (for limit orders) stays in the orderbook as a standing bid.

Sell Order Arrives​

  1. The engine looks at the buy side of the orderbook, sorted by price descending (highest first).
  2. 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.
  3. The trade executes at the bid price (the buyer's price).
  4. If the sell order's shares are not fully sold, the engine continues matching against the next highest bid.
  5. 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​