Documentation

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:

  1. Preview layer (before placement)
    • previewLimitPrice
    • previewTpPrice
    • previewSlPrice
  2. Pending bracket layer (entry not filled yet)
    • keyed by entryOrderId
    • stores pending TP/SL values
  3. Active order layer (entry filled)
    • active market position line
    • active TP/SL exit lines

The chart only renders what you feed via setOrderLines(...).


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/update previewTpPrice
    • action === "previewSl" -> set/update previewSlPrice
  • Use event.dragging:
    • true: live drag updates
    • false: drag end

3) Validate side rules before execute#

  • Buy entry:
    • TP must be > limit
    • SL must be < limit
  • Sell entry:
    • TP must be < limit
    • SL must be > limit

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 + follow behavior).
  • 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 + connectorAnchorPaddingRight
  • fillToPrice + fillColor (drag preview zone)
  • widgetPosition
  • label, qty, pnl

Event Contract Essentials#

From onOrderAction(event):

  • event.action: open string for app-defined workflows
  • event.price: provided for move/drag contexts
  • event.dragging: streaming drag state (true while dragging, false on release)
  • event.orderId: line identity to map back to app state

Use ids as your state join key.


Minimal State Skeleton#

ts
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.