Positions
TradingState.positions contains broker-owned net exposure. Optional
individualPositions contains per-entry or per-lot rows. The SDK renders these
facts but never reconstructs them from executions.
Position states
Opening or fully closing a position moves through flat. A reversal moves directly between long and short; resizing or partially closing a position keeps the same side. A flat or non-positive record is not shown as open. Omitting the closed row from the next replacement snapshot has the same visible result.
Minimal position
import type { SdkSymbolInfo, TradingPosition } from '@tradescript/pro/sdk';
declare const symbol: SdkSymbolInfo;
export const position: TradingPosition = {
id: 'pos-3',
accountId: 'acct-1',
symbol,
side: 'long',
quantity: 200,
averagePrice: 184.98,
marketPrice: 185,
unrealizedPnl: 4,
currency: 'USD',
};
Keep the same globally unique id while quantity, average price, market price,
and P&L change. Prefix native account-scoped ids before publishing them.
actionable: false hides close, protection, and reverse actions on the chart
position line. Account Manager does not read this flag; omit those rowActions
from the positions table metadata when that surface must be read-only.
P&L ownership
Prefer broker-calculated unrealizedPnl and realizedPnl. A chart overlay can
display a fallback from average price, market price, side, and quantity. That
display calculation never alters controller state.
Account Manager displays broker-provided money P&L or -. Its percent, tick,
and pip views use declared price facts such as minTick and pipSize.
For frequent updates, emit position-pl. Publish a complete positions or
state snapshot when a field must be removed or exposure changes.
Position actions
Position operations are optional adapter capabilities:
| User action | Adapter method |
|---|---|
| Preview close | previewClosePosition |
| Add or edit protection | modifyPosition |
| Full or partial close | closePosition |
| Close an individual row | closeIndividualPosition |
| Reverse | reversePosition |
| Flatten an account or scope | flattenPositions |
| Edit individual brackets | editIndividualPositionBrackets |
Chart action visibility also reads adapter method presence, chart display
overrides, and actionable. If risk wiring or production entitlements narrow
trading.getOperationSupport(), set positionCloseActionVisible,
positionProtectActionVisible, and positionReverseActionVisible from that
filtered map. Otherwise a visible chart action can still be rejected by the
controller boundary.
For an actionable chart position, the close control is available by default
when the adapter implements closePosition. Set
positionCloseActionVisible: false to hide it, or set
positionCloseConfirmationVisible: true to require an inline confirmation
before the adapter call. The controller supplies the position id, symbol, and
account context; the adapter remains responsible for the actual exit order.
Each method has a defined local completion path:
| Method | Completion behavior |
|---|---|
modifyPosition | Returns the updated position. The controller applies it through position-modified. |
Full closePosition | Resolves after confirmation. The controller applies position-closed and removes the id. |
Partial closePosition | Preserves options.quantity, then calls getState() after the adapter resolves. The snapshot must contain the reduced or closed exposure. |
reversePosition | Resolves after confirmation, then the controller calls getState(). |
flattenPositions | Returns the flattened count, then the controller calls getState(). |
Do not silently convert a partial request into full liquidation.
Net and individual rows use different methods. Declare
supportsPositionNetting and supportsIndividualPositions to match the
backend model.
Protection
modifyPosition accepts typed stop-loss and take-profit levels. Stable
exitLevelId values let broker state, placed orders, and editors reconcile
levels without relying on array position.
Chart-side protection defaults can prefill an editor, but the broker remains the authority for level limits, supported stop types, validation, modification, and the resulting position and order state.
Enable the chart action explicitly and provide defaults when the native editor should start with a generated protection ladder:
import type { ChartApi } from '@tradescript/pro/sdk';
declare const chart: ChartApi;
chart.customization().applyOverrides({
trading: {
display: {
positionProtectActionVisible: true,
positionProtectionEditorVisible: true,
positionProtectionDefaults: {
stopDistanceTicks: 20,
takeProfitRiskRatio: 2,
stopLevels: [
{ id: 'initial-risk', distanceTicks: 20, quantityRatio: 0.5 },
{ id: 'runner-risk', distanceTicks: 40, quantityRatio: 0.5 },
],
takeProfitLevels: [
{ id: 'target-1', riskRatio: 2, quantityRatio: 0.5 },
{ id: 'target-2', riskRatio: 4, quantityRatio: 0.5 },
],
limits: {
maxStopLossLevels: 2,
maxTakeProfitLevels: 2,
maxTotalLevels: 4,
},
},
},
},
});
positionProtectionEditorVisible: false routes the action through a
position-protect-requested event for a host-owned editor.
positionProtectConfirmationVisible: true instead skips the editor and asks
for inline confirmation before submitting the generated patch. The request
includes resolved limits and, when price and quantity facts are sufficient, a
TradingPositionProtectionSummary with coverage, risk, reward, and per-level
P&L. The resolver applies the strictest valid limits declared by defaults,
runtime features, account capabilities, and symbol rules.
Verify the contract
- A fill changes exposure only after the adapter publishes a position update.
- A partial close retains the position id with the correct reduced quantity.
- Missing P&L renders unavailable rather than zero.
- A read-only surface hides chart actions and omits Account Manager row actions.
- Reversal publishes the backend's new side, quantity, and average price.
Next steps
- Test a broker integration — prove position completion, reconnect, and teardown behavior.
- Executions — publish the fills related to exposure changes.
- Account Manager — configure net and individual position tables.