One Cancels Other (OCO)
An OCO order consists of multiple orders where the fill of any one order automatically cancels all other orders in the group.
All orders are placed simultaneously when the algo starts.
Cancel Behavior
When any order is fully filled, the remaining orders are immediately cancelled
If
cancel_in_proportionis true, partial fills trigger proportional cancellations of the remaining orders based on the fill quantityThis will be calculated based on "percent_done", which is SUM(filled_for_a_given_order/order_quantity) for all of the orders
For example, if you have three orders for quantities 10, 15, 20 and you have gotten filled on 1, 3, 10 respectively, you will have 1/10 + 3/15 + 10/20 = 80% done, so each order will have 20% left. Thus, the remaining order quantities will be 2, 3, 4
Any fractional orders are rounded to the nearest quantity increment
If
cancel_in_proportionis false, only a complete fill of one order triggers cancellation of all other orders
The OCO algo completes when:
all orders are fully outed/cancelled
You cannot modify the algo once it is sent, you must cancel and send a new one if you want different parameters.
You also cannot pause the algo, it will just cancel when you send a pause.
If an order is rejected, the algo will continue operating with the remaining orders.
Use Cases
Placing orders on multiple exchanges where you only want one to execute
Implementing profit target and stop loss orders simultaneously
Managing risk by ensuring only one side of a position is filled
OneCancelsOtherParams
orders (vec<OrderInfo>)
The orders in the OCO set
cancel_in_proportion (bool)
If true, orders are replaced proportionally based on the fill quantity of any given order. If false, orders are only cancelled once the an order is completely filled.
OrderInfo
OrderInfo is very similar to a PlaceOrderRequest. This contains the order information for each leg of the OCO algo.
symbol
Y
Tradable product
dir
Y
Order side; BUY or SELL
quantity
Y
Order quantity
order_type
Y
Order type
limit_price
N*
Required for certain order types
post_only
N*
Required for certain order types
trigger_price
N*
Required for certain order types
time_in_force
Y
Order time-in-force instruction
execution_venue
Y
Execution venue for the order. Unlike PlaceOrderRequest, this is required
Example
from architect_py import (
OneTriggersOtherParams,
OrderInfo,
OrderDir,
TimeInForce,
OrderType,
)
symbol1 = 'NQ 20251219 CME Future'
symbol2 = 'MNQ 20251219 CME Future'
tp1 = f"{symbol1}/USD"
tp2 = f"{symbol2}/USD"
account = "PAPER:[email protected]"
venue = "CME"
params = OneCancelsOtherParams.new(
orders=[OrderInfo.new(
symbol=tp1,
execution_venue=venue,
dir=OrderDir.BUY,
quantity=10,
limit_price=24940,
post_only=False,
time_in_force=TimeInForce.IOC,
order_type=OrderType.LIMIT,
),
OrderInfo.new(
symbol=tp2,
execution_venue=venue,
dir=OrderDir.SELL,
quantity=100,
limit_price=25000,
post_only=False,
time_in_force=TimeInForce.IOC,
order_type=OrderType.LIMIT,
)
],
cancel_in_proportion=True,
)
order = await client.place_algo_order(params=params, account=account)Last updated