Order Entry

Order Entry IDs

  • orderId: A customer-defined, per connectionId, unique order identifier. This ID stays the same across subsequent modifications of the specific order.

  • modifyId: A customer-defined, per orderId, unique modify identifier. This ID must be different across subsequent modifications of the specific order.

  • ackId: A matching engine-defined, per engine instance, unique identifier for messages successfully applied to the order book. This ID includes Ack, Fill, and Closed messages but excludes Reject messages.

  • The (ackId, orderId) pair uniquely identifies an order accepted by the matching engine and applied to the order book.

  • The (ackId, orderId, modifyId) triplet uniquely identifies a modify to the respective order.

Order Condition

From BTP version 4, Open, Attributed Open, and Modify requests carry a one-byte orderCondition field:

ValueConditionDescription
0x00UnconditionedNormal matching behavior.
0x01Post-onlyThe request is rejected with reason 0x14 (Post-only would cross) instead of matching if it would cross the opposite side's top of book.

Any other value fails to parse and the connection is disconnected with reason 0x05 (Failed to parse message). The condition applies to the individual request and is not stored on the resting order, so a Modify must re-assert the condition just as an Open does.

Order Entry Request

Open

Order types: All orders are limit orders. We do not support market orders, stops, stop limits, etc. We support Day and IOC orders for Time in Force.

BTP v2/v3 body:

Byte OffsetByte LengthTypeNameDescription
01charmessageTypeAlways O
18uint64orderIdOrder ID from customer
98uint64productIdProduct ID
171charsideSide: B = bid, A = ask
188int64pricePrice in ticks
264uint32quantityQuantity
301chartimeInForceTime in force: D = Day, I = IOC
31

BTP v4 body:

Byte OffsetByte LengthTypeNameDescription
01charmessageTypeAlways O
18uint64orderIdOrder ID from customer
98uint64productIdProduct ID
171charsideSide: B = bid, A = ask
188int64pricePrice in ticks
264uint32quantityQuantity
301chartimeInForceTime in force: D = Day, I = IOC
311uint8orderConditionSee Order Condition
32

Attributed Open

An Attributed Open is an Open that specifies which clearing account the order belongs to. This allows a single connection to submit orders on behalf of multiple clearing accounts associated with the connection's clearing firm. The accountId is the textual account code assigned by the clearing firm and is scoped to the clearingMemberFcmCode.

From BTP version 4, an Attributed Open may also carry a per-order Customer Type Indicator (CTI) code in the cti field. A non-zero cti value applies to the attributed order instead of the CTI configured for the connection's clearing account; a 0 value means the configured CTI applies. In earlier protocol versions the CTI cannot be specified per order and the configured CTI always applies. See Rule 511 for CTI code definitions.

BTP v2/v3 body:

Byte OffsetByte LengthTypeNameDescription
01charmessageTypeAlways T
18uint64orderIdOrder ID from customer
98uint64productIdProduct ID
171charsideSide: B = bid, A = ask
188int64pricePrice in ticks
264uint32quantityQuantity
301chartimeInForceTime in force: D = Day, I = IOC
311uint8clearingMemberFcmCodeLenLength, in bytes, of clearingMemberFcmCode
323byte[]clearingMemberFcmCode3-letter clearing firm code (ASCII, right-padded with NULL bytes)
351uint8accountIdLenLength, in bytes, of accountId
3616byte[]accountIdAccount code assigned by the clearing firm (ASCII, right-padded with NULL bytes)
52

BTP v4 body:

Byte OffsetByte LengthTypeNameDescription
01charmessageTypeAlways T
18uint64orderIdOrder ID from customer
98uint64productIdProduct ID
171charsideSide: B = bid, A = ask
188int64pricePrice in ticks
264uint32quantityQuantity
301chartimeInForceTime in force: D = Day, I = IOC
311uint8orderConditionSee Order Condition
321uint8ctiCTI code: 0 = use the connection's configured CTI, 1 = CTI 1, 2 = CTI 2, 3 = CTI 3, 4 = CTI 4
331uint8clearingMemberFcmCodeLenLength, in bytes, of clearingMemberFcmCode
343byte[]clearingMemberFcmCode3-letter clearing firm code (ASCII, right-padded with NULL bytes)
371uint8accountIdLenLength, in bytes, of accountId
3816byte[]accountIdAccount code assigned by the clearing firm (ASCII, right-padded with NULL bytes)
54

Replies follow the same Ack, Reject, Closed, and Fill messages as Open. An accountId that cannot be resolved against the connection's clearing firm produces a Reject with reason 0x01 (Account not found).

Modify

Cancels: A modify with a quantity less than or equal to the order's fill quantity cancels the order. A modify that changes the price and sets the quantity to less than or equal to the order's fill quantity cancels the order and the price change is ignored. A quantity = 0 will short circuit the price limit rules. A modify order with quantity > 0 must conform to the price limit rules regardless of order cancellation.

BTP v2/v3 body:

Byte OffsetByte LengthTypeNameDescription
01charmessageTypeAlways M
18uint64orderIdOrder ID from customer
98uint64modifyIdModify ID from customer
178int64pricePrice in ticks
254uint32quantityQuantity
29

BTP v4 body:

Byte OffsetByte LengthTypeNameDescription
01charmessageTypeAlways M
18uint64orderIdOrder ID from customer
98uint64modifyIdModify ID from customer
178int64pricePrice in ticks
254uint32quantityQuantity
291uint8orderConditionSee Order Condition
30

Note: NULL is indistinguishable from 0 in the case of modifyId. It is highly recommended to not use 0 as a modifyId to avoid this ambiguity.

Order Entry Reply

Ack

BTP v2/v3 body:

Byte OffsetByte LengthTypeNameDescription
01charmessageTypeAlways A
18uint64ackIdMatching engine acked sequence
98uint64orderIdOrder ID from customer
178uint64modifyIdModify ID from customer, NULL for open acks
25

BTP v4 body:

From BTP version 4, acks echo the authoritative state of the order after the acked request. For an open ack, quantity is the quantity as submitted and filled is always 0. For a modify ack, quantity is the post-modify quantity, clamped down to filled if the modify reduced the quantity to or below the filled quantity — so quantity == filled (zero leaves) on a modify ack indicates the order is closed.

Byte OffsetByte LengthTypeNameDescription
01charmessageTypeAlways A
18uint64ackIdMatching engine acked sequence
98uint64orderIdOrder ID from customer
178uint64modifyIdModify ID from customer, NULL for open acks
258uint64productIdProduct ID
331charsideSide: B = bid, A = ask
348int64priceOrder price, in ticks, after the acked request
424uint32quantityOrder quantity after the acked request
464uint32filledCumulative filled quantity of the order
501chartimeInForceTime in force: D = Day, I = IOC
51

Reject

Byte OffsetByte LengthTypeNameDescription
01charmessageTypeAlways R
18uint64orderIdOrder ID from customer
98uint64modifyIdModify ID from customer, NULL for open rejects
171uint8rejectReasonSee Reject Reason
18

Reject Reason

Request processing, and respective reject precedence, is as follows:

  1. Connection state (ex: enabled/disabled)
  2. Order state (ex: order closed)
  3. Quantity (a modify with a closing quantity is processed regardless of an invalid price modification)
  4. Price
ValueReason
0x01Account not found
0x02Product not found
0x03Order not found
0x04Order already exists
0x05Order already closed
0x06Order not changed by modify
0x07Quantity greater than max order size
0x08Quantity less than min order size
0x09Price outside price bands
0x0APrice outside price limits
0x0BPrice not tick aligned (reserved)
0x0CMarket halted. Only close requests accepted
0x0DMarket closed. No requests accepted
0x0EGive-up account not found
0x0FGive-up unauthorized
0x10Messaging rate exceeded
0x11Position limit exceeded
0x12Connection disabled
0x13Feature not supported
0x14Post-only would cross (BTP v4, See Order Condition)

Closed

A closed message will be sent when the order state cannot be inferred from the normal request-reply flow. This happens when an IOC is finished matching, self-match is prevented, or a customer cancels an order outside the order entry gateway connection.

A closed message will not be sent when an order is fully filled or a modify is acked, closing the order. For example, if an IOC misses or is partially filled, a closed message will be sent. If the IOC is fully filled, a closed message will not be sent.

BTP v2/v3 body:

Byte OffsetByte LengthTypeNameDescription
01charmessageTypeAlways C
18uint64ackIdMatching engine acked sequence
98uint64orderIdOrder ID from customer
171charcloseReasonSee Close Reason
18

BTP v4 body:

From BTP version 4, closed messages echo the closed order's product, side, and resting price so the closure can be attributed without local order state.

Byte OffsetByte LengthTypeNameDescription
01charmessageTypeAlways C
18uint64ackIdMatching engine acked sequence
98uint64orderIdOrder ID from customer
171charcloseReasonSee Close Reason
188uint64productIdProduct ID
261charsideSide: B = bid, A = ask
278int64priceResting price, in ticks, of the closed order
35

Close Reason

ValueReason
IIOC finished
GNon-connection cancel
SSelf-match prevention canceled

Fill

BTP v2 body:

Byte OffsetByte LengthTypeNameDescription
01charmessageTypeAlways F
18uint64ackIdMatching engine acked sequence
98uint64orderIdOrder ID from customer
178int64pricePrice in ticks
254uint32quantityQuantity
291charliquidityLiquidity: A = Add, R = Remove, S = Spread leg match
30

BTP v3 body:

From BTP version 3, fills carry the productId of the filled order.

Byte OffsetByte LengthTypeNameDescription
01charmessageTypeAlways F
18uint64productIdProduct ID
98uint64ackIdMatching engine acked sequence
178uint64orderIdOrder ID from customer
258int64pricePrice in ticks
334uint32quantityQuantity
371charliquidityLiquidity: A = Add, R = Remove, S = Spread leg match
38

BTP v4 body:

From BTP version 4, fills additionally carry the cumulative filled quantity of the order after this fill, so leaves can be tracked without counting fills locally.

Byte OffsetByte LengthTypeNameDescription
01charmessageTypeAlways F
18uint64productIdProduct ID
98uint64ackIdMatching engine acked sequence
178uint64orderIdOrder ID from customer
258int64pricePrice in ticks
334uint32quantityQuantity
371charliquidityLiquidity: A = Add, R = Remove, S = Spread leg match
384uint32filledCumulative filled quantity of the order after this fill
42

When dealing with calendar spreads, 3 Fill messages are sent for each match. One will have either A or R liquidity corresponding to the spread contract itself. Then there will be one Fill message for each leg with S liquidity and 0 quantity which have the implied price. The order of these fills is guaranteed, where the spread fill is always immediately followed by the leg 1 fill and the leg 2 fill in that order.

Message Rate Throttling

Order entry requests are limited using a sliding window throttle. Unless otherwise stated or negotiated, order entry gateways have a 500 message per 3 seconds messaging rate. Cancels are always allowed past the messaging rate throttle. Rejects are sent in response to messages exceeding the message rate limit with a reason code 0x10 (Message rate exceeded).

Start Trading

Leveraged spot, perpetuals, futures, options, and prediction markets, all on one CFTC-regulated exchange with crypto margin and settlement.