Bracket Orders (TP/SL) Integration
This library provides chart primitives and interaction events.
Bracket behavior (preview, pending, activation, OCO) is implemented in app state.
Use this guide as the canonical flow.
Conceptual Model#
Keep 3 layers in your app:
- Preview layer (before placement)
previewLimitPricepreviewTpPricepreviewSlPrice
- Pending bracket layer (entry not filled yet)
- keyed by
entryOrderId - stores pending TP/SL values
- keyed by
- Active order layer (entry filled)
- active
marketposition line - active TP/SL exit lines
- active
The chart only renders what you feed via setOrderLines(...).
Recommended Flow#
1) Create preview limit#
- From click/double-click in plot, set
previewLimitPrice. - Render preview order line with custom buttons:
Buy/Sell(action: "execute")TP(action: "previewTp",draggable: true)SL(action: "previewSl",draggable: true)
2) Set preview TP/SL#
- On
onOrderAction:action === "previewTp"-> set/updatepreviewTpPriceaction === "previewSl"-> set/updatepreviewSlPrice
- Use
event.dragging:true: live drag updatesfalse: drag end
3) Validate side rules before execute#
- Buy entry:
- TP must be
>limit - SL must be
<limit
- TP must be
- Sell entry:
- TP must be
<limit - SL must be
>limit
- TP must be
If invalid, disable execute action in your state/UI.
4) Execute preview#
On action === "execute":
- Create entry limit order.
- If TP/SL exists, store them as pending brackets tied to
entryOrderId. - Clear preview state.
5) Convert pending to active on fill#
When your fill logic marks entry as filled:
- Transition entry line to active position line (for example
market+followbehavior). - Create active TP/SL lines from pending bracket values.
- Remove pending bracket object.
6) OCO behavior#
If active TP or SL fills:
- Close/transition position as needed.
- Remove the sibling exit leg (OCO cleanup).
7) Position close behavior#
If user closes active position manually:
- Remove linked active TP/SL lines too.
- Remove any pending bracket bound to that entry id.
Useful OrderLineOptions for Brackets#
actionButtons(custom Buy/TP/SL controls)draggable(line dragging)connectorToPrice+connectorStyle+connectorAnchorPaddingRightfillToPrice+fillColor(drag preview zone)widgetPositionlabel,qty,pnl
Event Contract Essentials#
From onOrderAction(event):
event.action: open string for app-defined workflowsevent.price: provided for move/drag contextsevent.dragging: streaming drag state (truewhile dragging,falseon release)event.orderId: line identity to map back to app state
Use ids as your state join key.
Minimal State Skeleton#
type PreviewState = {
side: "buy" | "sell";
limit: number | null;
tp: number | null;
sl: number | null;
};
type PendingBracket = {
entryOrderId: string;
tpPrice: number | null;
slPrice: number | null;
};Keep this state in your app and regenerate chart lines from it each render/update tick.
