Skip to content

Orders

Orders go over the trading socket. Each has a client_order_id you choose, which comes back on every update about it. Use a new one for each order in a market. Do not reuse one, even after its order has filled or been cancelled: a second place with the same id is rejected with duplicate_client_order_id.

You sign every place, modify and cancel with a session key. See Signing orders.

  • A limit order (the default) trades at price_bps or better. Whatever does not fill straight away rests on the book, unless its time in force says otherwise.
  • A market order takes whatever is on the book, up to quantity. It never rests. Set time_in_force to ioc or fok.
    • price_bps is its worst price. The order fills at that price or better. It does not have to be a whole cent.
    • What cannot fill inside the worst price is dropped with order_unfilled, as for an ioc order. A fok order that cannot fill completely inside it is rejected with market_would_not_fully_execute.
    • Leave out price_bps, or send 0, to take any price.
time_in_force
gtc Rests until it fills, you cancel it, or the market closes. The default.
ioc Fills what it can now. The rest is dropped with order_unfilled.
fok Fills completely now, or is rejected.
{"gtd": {"expiry_ms": ...}} Rests until expiry_ms, at least 4 seconds ahead of the gateway’s clock. It never fills at or after expiry_ms.

post_only: true rejects the order if any of it would fill on arrival, so you only ever add to the book.

quantity_unit: "cash" sizes a buy in money: quantity is then units, 1,000,000 to the dollar, and the order buys as many lots as that pays for. Only bids can be sized in cash.

Before an order reaches the book, it is checked against your account’s worst case: what you would have if every market went against you, with all your resting orders filled. If the order would take that below zero, it is rejected with insufficient_collateral. A bid needs price_bps × quantity units; an ask you can’t cover from what you hold needs (10000 - price_bps) × quantity. A new order also holds the most taker fee its fills can pay. See Fees.

Your account’s /equity route returns this worst case as admissible, less any cash held for a pending timed exit.

modify sets a resting order’s price and remaining size.

  • Lowering the size at the same price keeps your place in the queue. order_modified comes back with retained_priority: true.
  • Anything else replaces the order. It loses its place and is matched again at the new price, so it can fill. order_modified comes back with retained_priority: false, followed by any fills or a new rest.

A modify names the version it makes: the order’s current version plus 1. A place makes version 0, and each modify that the exchange applies adds 1. The exchange rejects any other version with version_changed.

Every order_modified carries the new version, and open_orders carries the version of each order, so you can change an order after you reconnect. See Signing orders.

For a new order, in order:

  1. order_accepted, or order_rejected and nothing more.
  2. A fill for each trade on arrival.
  3. order_rested for what is left on the book, or order_unfilled for what was dropped.

Later, while it rests: a fill for each trade against it, and order_cancelled when it leaves the book. Each fill says what is left in remaining_quantity; at 0 the order is done.

order_cancelled gives a reason:

reason
client_request You cancelled it.
expired A gtd order reached its expiry_ms. It is cancelled when another order would match it, or when you modify it.
market_closed The market closed at the end of its window.
self_trade Your own new order would have traded with it, so it was cancelled instead.
replaced A modify replaced it.
held_for_withdrawal Your cash is held for a pending timed exit and no longer covers it. See below.

Part of your cash can be held for a pending timed exit from the vault. Your resting orders must still be covered by the cash that is left. If they are not, the exchange cancels resting orders, newest first, until the rest are covered. Each one gets order_cancelled with held_for_withdrawal. If cancelling the orders that free collateral does not cover the rest, it cancels all your resting orders.

The held amount shows as held_for_withdrawals on /balance, /equity and the account event of the account stream. The field is always present. It is 0 when nothing is held.

The other figures leave the held amount out, so they show what you can use:

Figure Where Value
balance /balance cash - held_collateral - held_for_withdrawals
free account event The same as balance.
equity /balance cash - held_for_withdrawals + the worst case of your positions and resting orders.
admissible /equity, account event The same as equity.

Every message is listed in the trading socket reference, and every rejection in Errors.