Trading

Price-time priority matching, every trade.

The internal order book, order types, fee tiers, self-trade prevention, and the atomic convert ledger.

Last updated: May 18, 2026
01

Internal matching engine

Cooud runs an in-process matching engine per symbol. Orders are matched on strict price-time priority: best price wins, ties broken by arrival time at the engine. The engine is single-threaded per symbol — message ordering is the source of truth and there is no intra-symbol race condition.

The engine is fed by a durable command log. Every order, cancel, and modify event is written before the engine state mutates; replaying the log from any checkpoint reaches the same book state deterministically. This is also how we run shadow upgrades — the new engine binary replays from yesterday's checkpoint and we compare every print before cutting over.

External venues (Binance, Coinbase, OKX) are reachable through the mirror layer for symbols we mirror, but the internal book is always consulted first; users prefer self-matched fills because they settle instantly with no on-chain dependency.

02

Order types

The engine accepts four order types. All four respect the same fee schedule and self-trade prevention.

  • LIMIT. Resting at a specific price. Honours the tif parameter:GTC (default), IOC, FOK, orPOST_ONLY. POST_ONLY orders that would cross the book are rejected, not crossed and posted.
  • MARKET. Takes the top of book up to the requested size or the safety slippage cap, whichever is reached first. Slippage cap defaults to 5% but is configurable per request via slippage_bps.
  • STOP_LIMIT. Rests off-book until the trigger price is touched, then enters as a LIMIT. The trigger uses the public mark price, not the user's local quote.
  • TAKE_PROFIT_LIMIT. Mirror of STOP_LIMIT in the opposite direction. Useful for closing positions automatically when a target is hit.
POST /v1/orders
{
  "symbol":       "ETH/USDT",
  "side":         "buy",
  "type":         "stop_limit",
  "trigger":      "3100.00",
  "price":        "3105.00",
  "size":         "0.5",
  "tif":          "GTC"
}
03

Order lifecycle

An order moves through a small set of states. As with withdrawals, every transition is durable — written to the ledger before the engine acknowledges the move.

new
 │  validation ok
 ▼
open  ──►  filled (terminal)
 │
 │  partial fills tick down "remaining" but stay in "open"
 │
 ▼
cancelled (terminal)
expired   (terminal, IOC/FOK that did not fill or TIF window passed)
rejected  (terminal, e.g. self-trade prevention block)

The user-stream WebSocket emits a message at every transition with the diff (remaining size, average price, last fill). Polling the REST endpoint is supported but unnecessary if you keep a socket open.

04

Trading pairs and tick sizes

Each pair declares a tick size (minimum price increment) and a step size (minimum quantity increment). Submitting outside these grids returns 422 business_rule_violation with the violated rule named in the error payload.

Tick and step sizes are exposed via GET /v1/markets and updated quarterly to keep the book tight without surfacing micro-pip noise on illiquid pairs. The current snapshot:

  • BTC/USDT — tick 0.01, step 0.00001
  • ETH/USDT — tick 0.01, step 0.0001
  • SOL/USDT — tick 0.001, step 0.001
  • ARB/USDT — tick 0.0001, step 0.1
  • OP/USDT — tick 0.0001, step 0.1
05

Self-trade prevention

Two orders from the same account cannot match each other. When an incoming order would cross a resting order from the same account, the engine applies the account-configured STP rule:

  • CANCEL_TAKER (default) — the incoming order is rejected.
  • CANCEL_MAKER — the resting order is cancelled and the incoming order continues.
  • CANCEL_BOTH — both sides are cancelled.

This sidesteps wash trading at the protocol level. The chosen rule is sent back on the order ack so clients can log it.

06

Fee schedule

Fees are charged in quote currency on every fill. Maker rebates are credited at fill time. Volume tiers refresh daily based on a rolling 30-day window of all your fills across spot symbols.

Tier30-day volumeMakerTaker
Tier 0< $100k0.00%0.10%
Tier 1$100k – $1M-0.01%0.08%
Tier 2$1M – $10M-0.02%0.05%
Tier 3$10M – $50M-0.03%0.04%
Tier 4$50M+-0.035%0.03%

Negative maker fees indicate a rebate. The rebate is credited into the same balance as the asset received on the fill (quote for sells, base for buys), and is taxable in your local jurisdiction — we do not withhold.

07

Convert flow

The convert surface offers an atomic swap between two assets at a quoted price, without consuming order book depth. Convert is built on a 4-entry ledger transaction that debits the source asset, credits the destination, debits the fee, and credits the platform fee account — all in a single atomic write.

-- inside one BEGIN/COMMIT
DEBIT  user.balance.USDT  100.00
CREDIT user.balance.BTC     0.00162
DEBIT  user.balance.USDT    0.10        -- fee
CREDIT platform.fees.USDT   0.10

The quote is locked at the moment you confirm. If we cannot honour the locked quote — usually because the upstream market moved more than the quote tolerance — the entire transaction is rolled back and you keep the original balance.

See the convert audit row exposed under Operations — convert is hash-chained alongside every other balance-changing write.

Exchange — Premium Crypto Trading