developers:apiv2:orders

Order Routing

◀ WebSocket API (V2)

Prerequisite: subscribe to the account first, and hold a Trading role. Orders into an unsubscribed account are rejected.

Prices and Volumes are Decimal Strings — for example “5”, “1.50”, “4200.50”. See Prices & Data Types.

Message Purpose
OrderSubmit Place one or more orders into a single account+market.
OrderRevise Change working orders: price, volume, max show, stop price, trail price, tag or activation data.
OrderPull Cancel working orders.
OrderBatch Submit several orders as an all-or-nothing batch.
CreateUDS Define a user-defined strategy.

Send OrderSubmit to place one or more orders into a single account+market.

order_submit {
  account_id: "ACCT1"
  market_id:  "XCME_C ZC (H25)"
  order_link: ORDER_LINK_NONE
  manual_order_indicator: false

orders {
buy_sell:   BUY_SELL_BUY
price_type: PRICE_TYPE_LIMIT
time_type:  TIME_TYPE_NORMAL
volume:      { value: "5" }
limit_price: { value: "4200.50" }
ClOrdId: "my-order-1"
}
} 

Multiple orders in one OrderSubmit share the same account_id and market_id.

Send OrderRevise to change one or more working orders. Address the order by unique_id from OrderUpdate, or by your original ClOrdId. Set only the fields you are changing.

order_revise {
  account_id: "ACCT1"
  market_id:  "XCME_C ZC (H25)"
  manual_order_indicator: false

revisions {
unique_id: "a3b1c5f2-7d43-4f9b-88e2-1e2f75c6d9a1"
volume:      { value: "10" }
limit_price: { value: "4250.00" }
}
} 

Send OrderPull to cancel one or more working orders. Address the order by unique_id or ClOrdId.

order_pull {
  account_id: "ACCT1"
  market_id:  "XCME_C ZC (H25)"
  manual_order_indicator: false

pulls {
unique_id: "a3b1c5f2-7d43-4f9b-88e2-1e2f75c6d9a1"
}
} 

Set user_id to route for another user. Omit it, or leave it empty, to trade as the authenticated user.

Requirements:

* The authenticated user must have the Order Routing role. * The routed user must belong to the authenticated user's firm or child firm, and must be enabled. * The account must be one the routed user is entitled to trade. * The account must already be subscribed by the authenticated session.

Example OrderSubmit on behalf of another user:

order_submit {
  user_id: "efda0709-af12-4b65-8971-5089edb4aaf0"
  account_id: "ACCT1"
  market_id:  "XCME_C ZC (H25)"
  manual_order_indicator: true

orders {
buy_sell:   BUY_SELL_BUY
price_type: PRICE_TYPE_LIMIT
time_type:  TIME_TYPE_NORMAL
volume:      { value: "5" }
limit_price: { value: "4200.50" }
ClOrdId: "customer-order-1"
}
} 

The same field is available on OrderRevise and OrderPull:

order_pull {
  user_id: "efda0709-af12-4b65-8971-5089edb4aaf0"
  account_id: "ACCT1"
  market_id:  "XCME_C ZC (H25)"
  manual_order_indicator: true

pulls {
unique_id: "a3b1c5f2-7d43-4f9b-88e2-1e2f75c6d9a1"
}
} 

Order validation uses the routed user's own roles, accounts, exchange permissions and permitted order types. OrderUpdate identifies both parties using user_name and routing_user_name.

Set margin_inquiry: true on a submitted Order to receive a MarginInquiryResponse. No order is sent to the exchange.

order_submit {
  account_id: "ACCT1"
  market_id:  "XCME_C ZC (H25)"

orders {
buy_sell:   BUY_SELL_BUY
price_type: PRICE_TYPE_LIMIT
time_type:  TIME_TYPE_NORMAL
volume:      { value: "1" }
limit_price: { value: "4200.50" }

```
margin_inquiry: true
margin_inquiry_id: "margin-check-1"
```

}
} 

The response includes current margin, margin with the hypothetical order, and the margin impact.

Full enum lists are in proto/t4/v2/common/enums.proto.

Price type Time in force
PRICE_TYPE_MARKET TIME_TYPE_NORMAL
PRICE_TYPE_LIMIT TIME_TYPE_IMMEDIATE_AND_CANCEL
PRICE_TYPE_STOP_MARKET TIME_TYPE_COMPLETE_VOLUME
PRICE_TYPE_STOP_LIMIT TIME_TYPE_GOOD_TILL_CANCELLED
PRICE_TYPE_FLATTEN TIME_TYPE_MARKET_ON_OPEN / TIME_TYPE_MARKET_ON_CLOSE
PRICE_TYPE_RFQ

A market order executes immediately at the best available price.

order_submit {
  account_id: "ACCT1"
  market_id:  "XCME_C ZC (H25)"

orders {
buy_sell:   BUY_SELL_BUY
price_type: PRICE_TYPE_MARKET
time_type:  TIME_TYPE_NORMAL
volume:     { value: "1" }
}
} 

A limit order executes at the specified price or better.

order_submit {
  account_id: "ACCT1"
  market_id:  "XCME_C ZC (H25)"

orders {
buy_sell:   BUY_SELL_BUY
price_type: PRICE_TYPE_LIMIT
time_type:  TIME_TYPE_NORMAL
volume:      { value: "1" }
limit_price: { value: "2376.50" }
}
} 

A stop market order becomes a market order when the stop price is reached.

order_submit {
  account_id: "ACCT1"
  market_id:  "XCME_C ZC (H25)"

orders {
buy_sell:   BUY_SELL_BUY
price_type: PRICE_TYPE_STOP_MARKET
time_type:  TIME_TYPE_NORMAL
volume:     { value: "1" }
stop_price: { value: "2376.50" }
}
} 

A stop limit order becomes a limit order when the stop price is reached.

order_submit {
  account_id: "ACCT1"
  market_id:  "XCME_C ZC (H25)"

orders {
buy_sell:    BUY_SELL_BUY
price_type:  PRICE_TYPE_STOP_LIMIT
time_type:   TIME_TYPE_NORMAL
volume:      { value: "1" }
stop_price:  { value: "2375.00" }
limit_price: { value: "2375.00" }
}
} 

A trailing stop order moves the stop price automatically based on price movement.

order_submit {
  account_id: "ACCT1"
  market_id:  "XCME_C ZC (H25)"

orders {
buy_sell:       BUY_SELL_BUY
price_type:     PRICE_TYPE_STOP_MARKET
time_type:      TIME_TYPE_NORMAL
volume:         { value: "1" }
stop_price:     { value: "2375.00" }
trail_distance: { value: "50" }
}
} 

A Fill or Kill order must execute immediately in full or it is canceled.

order_submit {
  account_id: "ACCT1"
  market_id:  "XCME_C ZC (H25)"

orders {
buy_sell:   BUY_SELL_BUY
price_type: PRICE_TYPE_LIMIT
time_type:  TIME_TYPE_COMPLETE_VOLUME
volume:      { value: "1" }
limit_price: { value: "2375.00" }
}
} 

An Immediate or Cancel order executes immediately for the available quantity and cancels the rest.

order_submit {
  account_id: "ACCT1"
  market_id:  "XCME_C ZC (H25)"

orders {
buy_sell:   BUY_SELL_BUY
price_type: PRICE_TYPE_LIMIT
time_type:  TIME_TYPE_IMMEDIATE_AND_CANCEL
volume:      { value: "1" }
limit_price: { value: "2375.00" }
}
} 

A Good Till Cancelled order remains working until filled or canceled.

order_submit {
  account_id: "ACCT1"
  market_id:  "XCME_C ZC (H25)"

orders {
buy_sell:   BUY_SELL_BUY
price_type: PRICE_TYPE_LIMIT
time_type:  TIME_TYPE_GOOD_TILL_CANCELLED
volume:      { value: "1" }
limit_price: { value: "2375.00" }
}
} 

An OCO is a pair of orders submitted together. Both orders are placed at the same time. When one fills, the other is automatically canceled. If one order partially fills, the remaining volume of the other order is adjusted.

OCO orders must use the same account_id and market_id.

order_submit {
  account_id: "ACCT1"
  market_id:  "XCME_C ZC (H25)"
  order_link: ORDER_LINK_OCO

orders {
buy_sell:   BUY_SELL_BUY
price_type: PRICE_TYPE_LIMIT
time_type:  TIME_TYPE_NORMAL
volume:      { value: "1" }
limit_price: { value: "2375.00" }
}

orders {
buy_sell:   BUY_SELL_BUY
price_type: PRICE_TYPE_STOP_MARKET
time_type:  TIME_TYPE_NORMAL
volume:     { value: "1" }
stop_price: { value: "2380.00" }
}
} 

An AutoOCO is three orders:

* A trigger order. * A take-profit order. * A stop-loss order.

When the trigger order fills, the take-profit and stop-loss orders are submitted as an OCO pair. Child prices are differentials from the trigger fill price.

order_submit {
  account_id: "ACCT1"
  market_id:  "XCME_Eq ES (H26)"
  order_link: ORDER_LINK_AUTO_OCO
  manual_order_indicator: true

// Trigger order
orders {
buy_sell:   BUY_SELL_BUY
price_type: PRICE_TYPE_LIMIT
time_type:  TIME_TYPE_NORMAL
volume:      { value: "1" }
limit_price: { value: "6858.00" }
}

// Take profit: 25.00 points above the trigger fill
orders {
buy_sell:       BUY_SELL_SELL
price_type:     PRICE_TYPE_LIMIT
time_type:      TIME_TYPE_GOOD_TILL_CANCELLED
volume:         { value: "0" }
limit_price:    { value: "25.00" }
activation_type: ACTIVATION_TYPE_HOLD
}

// Stop loss: 12.50 points below the trigger fill
orders {
buy_sell:       BUY_SELL_SELL
price_type:     PRICE_TYPE_STOP_MARKET
time_type:      TIME_TYPE_GOOD_TILL_CANCELLED
volume:         { value: "0" }
stop_price:     { value: "12.50" }
activation_type: ACTIVATION_TYPE_HOLD
}
} 

Take profit and stop loss is the common AutoOCO bracket: the first order opens the position, then a profit target and stop loss are placed after the trigger fills.

order_submit {
  account_id: "ACCT1"
  market_id:  "XCME_C ZC (H25)"
  order_link: ORDER_LINK_AUTO_OCO

// Trigger order
orders {
buy_sell:   BUY_SELL_BUY
price_type: PRICE_TYPE_LIMIT
time_type:  TIME_TYPE_NORMAL
volume:      { value: "1" }
limit_price: { value: "2375.00" }
}

// Take profit
orders {
buy_sell:       BUY_SELL_SELL
price_type:     PRICE_TYPE_LIMIT
time_type:      TIME_TYPE_GOOD_TILL_CANCELLED
volume:         { value: "0" }
limit_price:    { value: "10.00" }
activation_type: ACTIVATION_TYPE_HOLD
}

// Stop loss
orders {
buy_sell:       BUY_SELL_SELL
price_type:     PRICE_TYPE_STOP_MARKET
time_type:      TIME_TYPE_GOOD_TILL_CANCELLED
volume:         { value: "0" }
stop_price:     { value: "15.00" }
activation_type: ACTIVATION_TYPE_HOLD
}
} 

A flatten order closes the entire position in the specified market using an offsetting market order.

order_submit {
  account_id: "ACCT1"
  market_id:  "XCME_C ZC (H25)"

orders {
price_type: PRICE_TYPE_FLATTEN
}
} 

The server determines the side and volume from the current position. Clip size limits are ignored so the entire position can be closed.

OrderBatch groups multiple OrderSubmit messages and validates them together.

order_batch {
  batch_id: "batch-1"

submissions {
account_id: "ACCT1"
market_id:  "XCME_C ZC (H25)"
orders {
buy_sell:   BUY_SELL_BUY
price_type: PRICE_TYPE_LIMIT
time_type:  TIME_TYPE_NORMAL
volume:      { value: "1" }
limit_price: { value: "2375.00" }
ClOrdId: "batch-order-1"
}
}

submissions {
account_id: "ACCT2"
market_id:  "XCME_Eq ES (H26)"
orders {
buy_sell:   BUY_SELL_SELL
price_type: PRICE_TYPE_LIMIT
time_type:  TIME_TYPE_NORMAL
volume:      { value: "1" }
limit_price: { value: "6858.00" }
ClOrdId: "batch-order-2"
}
}
} 

* All pass → OrderBatchAcknowledge, then normal per-order OrderUpdate messages follow. * Any fails → OrderBatchReject and nothing is submitted.

batch_id is echoed as tag_relation_id on the resulting updates.

V2 delivers all order lifecycle events through one OrderUpdate message. Read update_type first.

update_type Meaning
SNAPSHOT Existing order sent on account subscribe.
STATUS Working, revised, pulled or rejected state change.
TRADE A fill occurred.
TRADE_LEG A fill on a strategy leg.
FAILED The request failed.

Key fields:

* unique_id — server order id. * status — high-level state: ORDER_STATUS_WORKING, ORDER_STATUS_FINISHED, ORDER_STATUS_REJECTED, ORDER_STATUS_HELD. * change — fine-grained lifecycle transition. * status_detail — human-readable reason, including reject/failure text. * current_volume, new_volume, working_volume, total_fill_volume — decimal strings. * current_limit_price, new_limit_price, current_stop_price, new_stop_price — prices. * tag_cl_ord_id — echo of your ClOrdId. * tag_relation_id — batch or linked-order correlation id.

Each fill is also delivered as OrderTrade.

Key fields: volume, price, residual_volume, exchange_trade_id, exchange_time, and leg_index for strategy legs.

When displaying order status to users, combine OrderUpdate.status, OrderUpdate.change and fill volume.

The table below omits the common enum prefixes to keep it readable:

* ORDER_STATUS_ * ORDER_CHANGE_

Status Change Display message Notes
Finished states
FINISHED PULL_FAILED, PULL_REJECTED, PULL_RISK_FAILED Cancel Failed Include status_detail.
FINISHED PULL_SUCCESS, PULL_SENT, PULL_RISK_SUCCESS Completed, Partial Fill When total_fill_volume is not zero.
FINISHED PULL_SUCCESS, PULL_SENT, PULL_RISK_SUCCESS Canceled When total_fill_volume is zero.
FINISHED TRADE_COMPLETED Completed, Partial Fill When total_fill_volume is less than the original volume.
FINISHED TRADE_COMPLETED Completed, Filled When total_fill_volume equals the original volume.
FINISHED STATUS_REQUEST_FAILED, STATUS_REQUEST_REJECTED, STATUS_REQUEST_RISK_FAILED, STATUS_REQUEST_RISK_SUCCESS, STATUS_REQUEST_SENT, STATUS_REQUEST_SUCCESS, TAG_FAILED, TAG_SUCCESS Completed, Partial Fill, {change} When partially filled.
FINISHED STATUS_REQUEST_FAILED, STATUS_REQUEST_REJECTED, STATUS_REQUEST_RISK_FAILED, STATUS_REQUEST_RISK_SUCCESS, STATUS_REQUEST_SENT, STATUS_REQUEST_SUCCESS, TAG_FAILED, TAG_SUCCESS Completed, Filled, {change} When fully filled.
FINISHED REVISION_RISK_FAILED Completed, Filled, {change} When fully filled.
FINISHED TRADE_BUSTED Completed, {change}
FINISHED SUBMISSION_SUCCESS Completed RFQ only.
Rejected states
REJECTED STATUS_REQUEST_FAILED, STATUS_REQUEST_REJECTED, STATUS_REQUEST_RISK_FAILED, STATUS_REQUEST_RISK_SUCCESS, STATUS_REQUEST_SENT, STATUS_REQUEST_SUCCESS Rejected, {change} Include status_detail.
REJECTED Other changes Rejected Include status_detail.
Working states
WORKING PULL_RISK_SUCCESS, PULL_SENT, PULL_SUCCESS Canceling…
WORKING REVISION_SENT, REVISION_RISK_SUCCESS Revising…
WORKING REVISION_SUCCESS Working, Revised
WORKING REVISION_FAILED, REVISION_REJECTED, REVISION_RISK_FAILED Working, Revision Failed Include status_detail.
WORKING PULL_FAILED, PULL_REJECTED, PULL_RISK_FAILED Working, Cancel Failed Include status_detail.
WORKING TRADE, SUBMISSION_SENT, SUBMISSION_SUCCESS, SUBMISSION_RISK_SUCCESS Working…
WORKING HANDOVER Working, Handover
WORKING ROLLOVER Working, Rollover
WORKING STATUS_REQUEST_FAILED, STATUS_REQUEST_REJECTED, STATUS_REQUEST_RISK_FAILED, STATUS_REQUEST_RISK_SUCCESS, STATUS_REQUEST_SENT, STATUS_REQUEST_SUCCESS, TAG_FAILED, TAG_SUCCESS Working, {change}
WORKING Any change with fills {base message}, Partial Fill Append when total_fill_volume is greater than zero.
Pre-submission states
NONE NONE Submitting…
NONE SUBMISSION_RISK_SUCCESS Submitting to Exchange
NONE SUBMISSION_REJECTED, SUBMISSION_RISK_REJECTED Submission Rejected Include status_detail.
NONE SUBMISSION_FAILED Submission Failed Include status_detail.
NONE SUBMISSION_SENT, SUBMISSION_SUCCESS Submission Sent
Held states
HELD Any change Held on Server… / Held on Client… Server-held for real markets; client-held for non-real markets.
  • developers/apiv2/orders.txt
  • Last modified: 2026/09/08 00:06
  • by chad