Skip to Content
Symmio Trading-SDK — the SDK surface for builders on Arbitrum
CoreTP/SLplanGroupTpSl

planGroupTpSl

Diff a desired grouped TP/SL state against what the handler already holds, and decide per child whether to set, delete, or skip.

The conditional-order handler has no bulk endpoint — one signed request per quote — so on a merged position of N quotes a naive “apply” costs N signatures every time. This planner’s job is to make that fan-out as small as honestly possible:

  • a side whose rounded trigger price and price type already match the confirmed snapshot is dropped from the leg, so setQuoteTpSl receives only what changed; when both sides drop, the child is skipped as "unchanged";
  • a side cleared to "" while the handler holds a live order becomes a delete; cleared with nothing live, it is dropped;
  • unanchored or fully-closed children are skipped with a typed reason instead of throwing;
  • with referencePrice and config supplied, each child runs validateTpSl against its resulting pair — so raising a take profit still gets checked against an untouched stop loss — and a failure becomes "invalid" carrying the TpSlValidation for inline errors.

Rounding before comparing is what makes "100" and "100.0000" equal at pricePrecision: 4. Without it the handler’s own rounding would make every submit look like a change, and the SDK would resubmit unchanged orders forever.

A child can produce two actions — cancel one side, write the other — so actions is not one entry per child.

import { planGroupTpSl, setQuoteTpSl } from "@symmio/trading-core"; const plan = planGroupTpSl({ children, desired: Object.fromEntries(children.map((child) => [child.key, { tp: { triggerPrice: "150" } }])), pricePrecision: 4, referencePrice: markPrice, config: tpslConfig, }); if (plan.hasInvalid) return; for (const action of plan.sets) { await setQuoteTpSl(config, { ...action, subAccount, pricePrecision: 4 }); }

Parameters

The grouped position’s children with their confirmed snapshots.

desiredGroupTpSlDesiredMaprequired

Desired state per child key. A child with no entry is skipped as "nothing-to-do". An entry with an empty triggerPrice clears that side.

pricePrecisionnumberrequired

Market price precision. Trigger prices are rounded to it before diffing.

referencePricestringoptional

Reference price for validation (decimal string). Pass the live mark price — a grouped position is validated against what the trader is looking at, not against each child’s own open price. Omit (with config) to skip validation.

configTpSlConfigoptional

Live handler /configs/ rules. Required for validation to run.

onlyreadonly string[]optional

Restrict planning to these child keys — the retry-failed-only path. Others are omitted entirely.

Returns

Every decision in child order, plus pre-split sets / deletes / skips, a hasInvalid submit gate and an isNoop flag.

Last updated on