Orders

Order behavior, time-in-force, execution controls, and rejection rules

Order Types

Limit

Executes at the specified price or better. Unfilled quantity rests on the order book when using GTC or GTT. Supports all time-in-force options and post_only.

Market

Executes immediately against available liquidity.

  • price is required and acts as a slippage cap: a buy will not match makers priced above it; a sell will not match makers priced below it
  • Only FOK or IOC time-in-force is accepted
  • post_only is not permitted

Market orders may experience slippage in low-liquidity conditions.

Stop

A conditional order that sits in an untriggered state until a price condition is met, then enters the matching engine as a limit or market order.

Required fields:

  • stop_price — the trigger level (must match market price accuracy)
  • order_stop_typeprofit (take-profit) or loss (stop-loss)
  • stop_price_optionlast_price or mark_price (defaults to last_price if omitted)

Allowed time-in-force: GTC, FOK, IOC (GTT is not permitted).

Margin is not reserved while the order is untriggered. It is reserved only after the trigger fires and the order enters the matching engine.

Trigger conditions by position side and stop type:

PositionStop typeSideTriggers when price…
LongTake-profit (profit)SellRises to or above stop_price
LongStop-loss (loss)SellFalls to or below stop_price
ShortTake-profit (profit)BuyFalls to or below stop_price
ShortStop-loss (loss)BuyRises to or above stop_price

Use mark_price as the trigger source for stronger manipulation resistance.

TWAP

TWAP splits execution of a large order into a series of smaller sub-orders scheduled at fixed intervals, reducing market impact. TWAP batches are submitted via a dedicated endpoint (POST /orders/twap); each sub-order carries its own price, size, nonce, signature, and scheduled timestamp.

TWAP batch validation rules (any violation returns 400):

  • All sub-orders must share the same price and size (uniform slicing)
  • Nonce values must be strictly increasing across the batch
  • Intervals between consecutive sched_ts values must be positive, equal, and divisible by 60 seconds
  • The first sched_ts must be at least 10 seconds in the future
  • At most 100 sub-orders per batch

Allowed time-in-force: GTC, FOK, IOC (GTT is not permitted).

Unlike stop orders, TWAP orders do reserve margin while untriggered.

Time-in-Force (TIF)

TIFDescriptionSupported order types
GTCRest on book until filled or canceled (default)Limit, Stop, TWAP
IOCFill as much as possible immediately; cancel remainderLimit, Market, Stop, TWAP
FOKFill fully now or cancel entirely (no partial fills)Limit, Market, Stop, TWAP
GTTExpire at expired_at timestampLimit only

GTT requires expired_at > 0 and at most 30 days in the future; requests with an out-of-range value are rejected. All other order types must have expired_at = 0.

Field Defaults

When optional fields are omitted, the engine applies these defaults:

FieldDefault
Order typeLIMIT
Time-in-forceGTC
STP policycancel_taker
Stop price sourcelast_price

STP is always active — omitting the field does not disable self-trade prevention.

Matching Behavior

The engine uses price-time priority (FIFO within a price level). For each incoming taker order:

  1. Price bound check — iterates the opposite side of the book. A buy stops matching when maker ask price exceeds taker price; a sell stops when maker bid price is below taker price.
  2. Post-only check — if the taker has post_only = true and would cross the book, the entire order is canceled with reason canceled: post-only.
  3. Liquidity check — if both sides of the book are not present, the order is canceled with reason canceled: insufficient liquidity.
  4. Self-trade prevention — applies the configured STP policy before executing a match.
  5. Match cap — a single order may produce at most 1,000 matches. If this limit is reached, the entire order is rejected and no fills are booked (canceled: too many matches).

After matching, post-match margin validation runs. If the resulting portfolio is under-margined (cross or isolated), the order is canceled with reason canceled: insufficient margin.

Partial fills are not a separate order status — filled_sz is updated in place while the order remains open. The order transitions to done only when fully filled or canceled.

Execution Controls

Reduce-only

A reduce_only order can only decrease an existing position.

Pre-match checks:

  • Position must exist; rejected if already closed
  • Order side must be opposite to the position side
  • For non-IOC orders: if order size exceeds position size, the order is rejected
  • For IOC orders: if order size exceeds position size, the size is clipped to the remaining position before matching

After matching, any lower-priority resting reduce-only orders that would exceed the remaining position are auto-canceled (canceled: reduce-only auto canceled due to position reduction).

Reduce-only orders do not reserve margin.

Post-only

If set, the order is canceled immediately if it would cross the book at placement time rather than rest as a maker. Not available for market orders. Guarantees maker-fee treatment when the order does rest.

Self-Trade Prevention (STP)

If an incoming order would match your own resting order, STP applies. The default policy is cancel_taker:

ValueBehavior
cancel_takerCancel the incoming order; keep the resting order
cancel_makerCancel the resting order; continue matching the incoming order
cancel_bothCancel both orders

Client Order ID (cl_oid)

You may attach a client-assigned identifier to any order (max 32 characters; alphanumeric plus -, _, :). This is useful for correlating orders across your own systems without relying solely on the exchange-assigned order ID.

Synchronous Submission (await)

For LIMIT and MARKET orders, setting await: true causes the placement request to block until the matching engine has processed the order before returning. Useful when you need an immediate fill confirmation before taking further action.

Bracket Orders

A bracket order links a parent entry order to one or two conditional exit orders (take-profit and/or stop-loss), submitted together via POST /orders/group. The children remain untriggered until the parent fills, at which point they become active. When one child triggers and fills, the other is automatically canceled.

Bracket validation rules:

RuleConstraint
Order countExactly 2 or 3 (parent + 1–2 children)
Parent typeLIMIT, MARKET, or STOP
Parent reduce_onlyMust be false (or omitted)
Children typeMust be STOP
Children per stop typeAt most one take-profit and one stop-loss
Children marketSame as parent
Children sizeSame as parent
Children sideOpposite of parent
Children reduce_onlyMust be true
Children time-in-forceMust be IOC
Take-profit stop_priceAbove parent price for buy parent; below for sell parent
Stop-loss stop_priceBelow parent price for buy parent; above for sell parent

Order Statuses

StatusDescription
pendingReceived by the sequencer, awaiting matching engine processing
openResting on the order book
untriggeredStop or TWAP order waiting for its trigger condition
doneTerminal state: filled or canceled

Status lifecycle:

  • LIMIT / MARKET: pendingopendone
  • STOP / TWAP: untriggeredopendone

Market Mode Restrictions

Order placement is validated against the market's current mode before any other checks. See Market Lifecycle for the full mode reference.

modeRegular userMarket makerCancel
tradingAll order typesAll order typesyes
post_onlyPost-only onlyPost-only onlyyes
wind_downReduce-only onlyReduce-only + post-onlyyes
haltedBlockedBlockedyes
delistedBlockedBlockedblocked

In wind_down, market makers may also place post-only orders to provide counterparty liquidity for users closing positions. Cancellations are accepted in all modes except delisted.

Cancellation Reasons

done_reasonCause
filledOrder fully executed
canceled: userCanceled by the user
canceled: adminCanceled by an admin
canceled: post-onlyPost-only order would have crossed the book
canceled: insufficient liquidityNo matching orders on the opposite side
canceled: insufficient marginPortfolio under-margined after matching
canceled: time in force IOCUnfilled remainder after IOC matching
canceled: time in force FOKOrder not fully filled; entire order voided
canceled: time in force GTTOrder expired at expired_at
canceled: stpSelf-trade prevention triggered
canceled: too many matchesExceeded 1,000 matches per order
canceled: reduce-only position already closedNo open position at pre-match time
canceled: reduce-only invalid side (...)Order side matches position side
canceled: reduce-only exceeds pos (...)Order size exceeds position for non-IOC
canceled: reduce-only auto canceled due to position reductionResting reduce-only order excess after position reduced
canceled: tpsl position closedParent position closed before stop order triggered
canceled: parent order canceled unfilledParent order (bracket) canceled before fill
canceled: liquidationCanceled by liquidation engine

On this page