Order Routing
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.
Client Order Messages
| 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. |
Submit, Revise, Pull
Submit
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.
Revise
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" }
}
}
Pull
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"
}
}
Routing Orders on Behalf of Another User
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.
Margin Inquiry
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.
Order Types
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 |
Market Order
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" }
}
}
Limit Order
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" }
}
}
Stop Market Order
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" }
}
}
Stop Limit Order
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" }
}
}
Trailing Stop Order
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" }
}
}
Fill or Kill (FOK) Order
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" }
}
}
Immediate or Cancel (IOC) Order
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" }
}
}
Good Till Cancelled (GTC) Order
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" }
}
}
Linked Orders
Order Cancels Order (OCO)
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" }
}
}
AutoOCO
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
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
}
}
Flatten Position
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.
Batch
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.
What You Receive
OrderUpdate
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.
OrderTrade
Each fill is also delivered as OrderTrade.
Key fields: volume, price, residual_volume, exchange_trade_id, exchange_time, and leg_index for strategy legs.
Order Status Summary Reference
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. |