Bracket orders
Overview
Bracket orders (brackets) are orders that protect positions. In other words, brackets help users limit their losses and secure their profits by bracketing positions with two opposing stop-loss and take-profit orders.
The term parent refers to an order or position for which brackets are created.
Bracket orders are linked to the parent order/position via the parentId and parentType properties.
The quantity of the bracket order always matches the parent quantity.
Brackets always have the opposite side compared to their parent, for example:
- A buy order is bracketed by a sell-limit order or a sell-stop order.
- A sell order is bracketed by a buy-stop order or a buy-limit order.
Brackets can exist either in a pair as stop-loss and take-profit or independently. This means that an order or position can have only one bracket order: stop-loss or take-profit.
This article requires a thorough understanding of the Trading Platform components and their interactions. Before continuing with this article, we recommend reading the Core concepts article for a better understanding.
UI interactions
Users can add brackets to a new or existing order or to a position.
- Place order with brackets
- Add brackets via buttons
- Add brackets via Protect position



Order brackets
To enable adding order brackets in the UI, set the supportOrderBrackets flag to true.
Refer to the Trading features configuration section for more information about configuration flags.
Place order with brackets
Users can place orders with two brackets or only one — either a stop-loss or take-profit.
When users place orders with brackets, the library calls the placeOrder method and passes a PreOrder object as a parameter.
This object contains the stopLoss and takeProfit fields.
Additionally, if a user places a limit order or stop orders, the PreOrder object should contain the following fields:
- For limit order, the
limitPricefield. - For stop order, the
stopPricefield.
Example
Consider the following example: a user places a market order with two brackets.
The library calls the placeOrder method, requesting to create an order.
You should implement this method within the Broker API.
Refer to the Order creation section for a detailed explanation.
After your backend server handles the order creation, it responds to your Broker API implementation with updated information.
Your Broker API implementation then calls the orderUpdate method three times.
-
The first call provides the
PlacedOrderobject that contains information about the parent order. The status of the parent order should beWorking. Other object values must be identical to the data provided within theplaceOrdermethod.{
"id": "1",
"symbol": "NasdaqNM:AAPL",
"qty": 100,
"side": 1, // Side.Buy
"status": 6, // Status.Working
"type": 2, // Type.Market
"takeProfit": 174.5,
"stopLoss": 173.32
}
For limit and stop orders, make sure to include the limitPrice and stopPrice fields respectively in the PlacedOrder object
when updating the parent order using the orderUpdate method.
-
The second call provides the
BracketOrderobject that contains information about the take-profit order. The status of the take-profit order should beInactive, and theqtyandsymbolvalues must be identical to the parent order values. The data object must also include:- The
parentIdfield with a value equal to theidvalue of the parent order. - The
parentTypefield, indicating that the parent type is order. - The
sidefield with a value opposite to thesidevalue of the parent order. - The
limitPricefield with a value equal to thetakeProfitvalue of the parent order. - The
typevalue, indicating that the order type is limit.
- The
{
"id": "2",
"symbol": "NasdaqNM:AAPL",
"qty": 100,
"parentId": "1",
"parentType": 1, // ParentType.Order
"side": -1, // Side.Sell
"status": 3, // Status.Inactive
"type": 1, // Type.Limit
"limitPrice": 174.5
}
-
The third call provides the
BracketOrderobject that contains information about the stop-loss order. The status of the stop-loss order should beInactive, and theqtyandsymbolvalues must be identical to the parent order values. The data object must also include:- The
parentIdfield with a value equal to theidvalue of the parent order. - The
parentTypefield, indicating that the parent type is order. - The
sidefield with a value opposite to thesidevalue of the parent order. - The
stopPricefield with a value equal to thestopLossvalue of the parent order. - The
typevalue, indicating that the order type is stop.
- The
{
"id": "3",
"symbol": "NasdaqNM:AAPL",
"qty": 100,
"parentId": "1",
"parentType": 1, // ParentType.Order
"side": -1, // Side.Sell
"status": 3, // Status.Inactive
"type": 3, // Type.Stop
"stopPrice": 173.32
}
Execute parent order
Bracket orders are linked to the parent order by the Order-Sends-Order (OSO) condition.
This means that once the parent order is executed and its status transitions to Filled,
the bracket order statuses should change to Working.
When the parent order is executed, it turns into a position.
Therefore, you should update the parentId and parentType fields in the bracket order objects to be associated with this new parent position.
Along with changing the order statuses, change the values of the following fields:
parentIdshould be equal to theidvalue of the position that resulted from the execution of the parent order.parentTypeshould be changed to2, indicating that the parent type is position.
Example
Consider the following example: a user has placed a market order with two brackets. Following this, your backend server is responsible for executing the order, creating a position, and updating the information within the bracket orders.
Your Broker API implementation calls the executionUpdate and positionUpdate methods.
Refer to the Execution update section for a detailed explanation for these methods.
Then, your Broker API implementation calls the orderUpdate method three times to provide the library with updated information.
-
The first call provides updated information about the parent order. Its status should be
Filled.{
"id": "1",
"symbol": "NasdaqNM:AAPL",
"qty": 100,
"side": 1, // Side.Buy
"status": 2, // Status.Filled
"type": 2, // Type.Market
"takeProfit": 174.5,
"stopLoss": 173.32
} -
The second call provides the
BracketOrderobject that contains updated information about the take-profit order. The data object must contain the following changed values, while other fields should remain the same:- The
parentIdfield with a value equal to theidvalue of the position (NasdaqNM:AAPLin this example). - The
parentTypefield, indicating that the parent type is position. - The
statusvalue, indicating that the order status is working.
- The
{
"id": "2",
"symbol": "NasdaqNM:AAPL",
"qty": 100,
"parentId": "NasdaqNM:AAPL",
"parentType": 2, // ParentType.Position
"status": 6, // Status.Working
"side": -1, // Side.Sell
"type": 1, // Type.Limit
"limitPrice": 174.5
}
- The third call provides the
BracketOrderobject that contains information about the stop-loss order. The data object must contain the following changed values, while other fields should remain the same:- The
parentIdfield with a value equal to theidvalue of the position. - The
parentTypefield, indicating that the parent type is position. - The
statusvalue, indicating that the order status is working.
- The
{
"id": "3",
"symbol": "NasdaqNM:AAPL",
"qty": 100,
"parentId": "NasdaqNM:AAPL",
"parentType": 2, // ParentType.Position
"status": 6, // Status.Working
"side": -1, // Side.Sell
"type": 3, // Type.Stop
"stopPrice": 173.32
}
To keep the UI data up-to-date, you should constantly provide updates of users' entity and P&L values whenever changes occur. Refer to the Equity update section for more information.
Position brackets
To enable adding position brackets in the UI, set the supportPositionBrackets or supportIndividualPositionBrackets flag to true.
This activates buttons for creating brackets on the chart and enables the Protect position button.
For more details on configuration flags, check the Trading features configuration section.
Add position brackets
By default, users can add two brackets at the same time or only one of them.
However, you can set the supportOnlyPairPositionBrackets flag to true, so users can add two brackets together only.
When users add brackets to the existing position, the library calls the editPositionBrackets method. In this method, the library provides the stopLoss and takeProfit fields.
After that, the library expects you to call the positionUpdate method within 10 seconds.
Note that the library will return a timeout issue if it fails to receive a timely position update.
Example
Consider the following example: the user has an APPL position and decides to place two bracket orders for this position.
The library calls the editPositionBrackets method, providing the stopLoss and takeProfit fields.
You should implement this method within your Broker API implementation
and handle the user's request to add bracket orders.
Note that the position update and order creation might be processed on external sources, such as exchanges.
However, your backend server is expected to manage this information and provide it in the format required by the library.
After your backend server handles the position update and order creation, it responds to your Broker API implementation with updated information.
Your Broker API implementation then calls the positionUpdate and orderUpdate methods.
- The
positionUpdatecall updates a Position object with thestopLossandtakeProfitfields.
{
"id": "NasdaqNM:AAPL",
"qty": 100,
"side": 1, // Side.Buy
"symbol": "NasdaqNM:AAPL",
"takeProfit": 174.5,
"stopLoss": 173.32
}
-
The first
orderUpdatecall provides theBracketOrderobject that contains information about the take-profit order. The status of the take-profit order should beWorking, and theqtyandsymbolvalues must be identical to the parent position values. The data object must also include:- The
parentIdfield with a value equal to theidvalue of the parent position. - The
parentTypefield, indicating that the parent type is position. - The
sidefield with a value opposite to thesidevalue of the parent position. - The
limitPricefield with a value equal to thetakeProfitvalue of the parent position. - The
typevalue, indicating that the order type is limit.
- The
{
"symbol": "NasdaqNM:AAPL",
"qty": 100,
"id": "2",
"parentId": "NasdaqNM:AAPL",
"parentType": 2, // ParentType.Position
"side": -1, // Side.Sell
"status": 6, // Status.Working
"type": 1, // Type.Limit
"limitPrice": 174.5
}
-
The second
orderUpdatecall provides theBracketOrderobject that contains information about the stop-loss order. The status of the stop-loss order should beWorking, and theqtyandsymbolvalues must be identical to the parent position values. The data object must also include:- The
parentIdfield with a value equal to theidvalue of the parent position. - The
parentTypefield, indicating that the parent type is position. - The
sidefield with a value opposite to thesidevalue of the parent position. - The
stopPricefield with a value equal to thestopLossvalue of the parent position. - The
typevalue, indicating that the order type is stop.
- The
{
"symbol": "NasdaqNM:AAPL",
"qty": 100,
"id": "3",
"parentId": "NasdaqNM:AAPL",
"parentType": 2, // ParentType.Position
"side": -1, // Side.Sell
"status": 6, // Status.Working
"type": 3, // Type.Stop
"stopPrice": 173.32
}
Execute bracket order
Bracket orders are linked to each other by the One-Cancels-the-Other (OCO) condition. This means that when one of the bracket orders is executed, the other one gets canceled. In this case, the position linked to the executed bracket order should change its quantity to zero, closing the position.
Example
Consider the following example: the user has a position with two bracket orders. You broker server executes a stop-loss order and returns updated information.
Your Broker API implementation then calls two consequent orderUpdate methods and then positionUpdate.
- The first
orderUpdatecall provides information about the executed stop-loss order. The status of the order should beFilled.
{
"symbol": "NasdaqNM:AAPL",
"qty": 100,
"id": "3",
"parentId": "NasdaqNM:AAPL",
"parentType": 2, // ParentType.Position
"side": -1, // Side.Sell
"status": 2, // Status.Filled
"type": 3, // Type.Stop
"stopPrice": 173.32
}
- The second
orderUpdatecall provides information about the canceled stop-loss order. The status of the order should beCanceled.
{
"symbol": "NasdaqNM:AAPL",
"qty": 100,
"id": "3",
"parentId": "NasdaqNM:AAPL",
"parentType": 2, // ParentType.Position
"side": -1, // Side.Sell
"status": 1, // Status.Canceled
"type": 1, // Type.Limit
"limitPrice": 174.5
}
- The
positionUpdatecall changes theqtyproperty to0.
{
"id": "NasdaqNM:AAPL",
"qty": 0,
"side": 1, // Side.Buy
"symbol": "NasdaqNM:AAPL",
"takeProfit": 174.5,
"stopLoss": 173.32
}