Skip to main content

Orders

TradingOrderDraft is a financial intent. TradingOrder is the broker-owned record that later appears in controller state. Keep those contracts separate.

Order statuses

TradingOrderStatus describes records in controller state. It is a status vocabulary, not an SDK-enforced transition graph. Arrows below show common progressions; a backend may skip a box or publish a record directly in any status it can report truthfully.

placing, modifying, and cancelling are optional transient statuses; the controller does not synthesize them before it calls the adapter. inactive represents a dormant broker order, such as a bracket child waiting for its parent to fill, and is not terminal.

An accepted placeOrder result is only an acknowledgement. It does not add an order record or move one to working; publish the broker-owned record through an orders or state event. The controller applies the confirmed return from modifyOrder through order-modified, and applies cancelled only after the adapter's cancellation call resolves.

Draft and broker record

Reuse the exact symbol returned by market-data resolution.

order.ts
import type {
SdkSymbolInfo,
TradingEvent,
TradingOrder,
TradingOrderDraft,
} from '@tradescript/pro/sdk';

declare const symbol: SdkSymbolInfo;

export const draft = {
accountId: 'acct-1',
symbol,
side: 'buy',
type: 'limit',
quantity: 300,
price: 184.98,
duration: { type: 'day' },
} satisfies TradingOrderDraft;

export const partialOrder: TradingOrder = {
...draft,
id: 'ord-9',
accountId: 'acct-1',
status: 'partially-filled',
filledQuantity: 200,
remainingQuantity: 100,
};

export const update = {
type: 'orders',
orders: [partialOrder],
} satisfies TradingEvent;

An accepted placeOrder result acknowledges the request. Publish the broker record in an orders or state event before expecting a line or table row.

Transition contract

Backend factPublishVisible result
Working order acceptedComplete current orders listWorking row and chart line appear.
Partial fillUpdated order plus execution and position factsRemaining quantity and exposure update.
Final fillTerminal order, final execution, resulting positionWorking line disappears.
CancellationCurrent orders update or order-cancelledWorking line disappears; a focused cancellation also upserts the cached order into history.
ExpiryExpired record with stable event identityHistory shows the expiry.

Use one full state event when a fill must update orders, executions, and positions atomically. See State and events.

Mutations and support

  • previewOrder validates a draft without placement.
  • placeOrder is required and returns acceptance or rejection.
  • previewModifyOrder and modifyOrder use TradingOrderPatch.
  • cancelOrder, cancelOrders, and cancelAllOrders are optional.
  • getOrdersHistory loads broker-owned history.

Render an action only when trading.getOperationSupport() declares it. cancelAllOrders is an atomic broker operation; the SDK never reconstructs it as a client-side list-and-loop fallback.

Mutation completion

Controller-generated events complete local mutation handling. Broker streams remain authoritative for reconnects and replacement snapshots.

MethodCompletion behavior
placeOrderReturns acceptance or rejection. The controller emits order-accepted or order-rejected; acceptance does not add an order. Publish the broker record separately.
modifyOrderReturns the updated order. The controller applies it through order-modified.
cancelOrderResolves after confirmation. The controller applies order-cancelled.
cancelOrdersUses the batch method when supplied, otherwise confirmed single cancels, then applies one order-cancelled event per id.
cancelAllOrdersReturns the cancelled count. The controller immediately calls getState() and applies that snapshot.

Your backend stream may independently report the same mutation. Reconcile it with stable ids and replacement snapshots; do not emit a duplicate focused event merely to mirror a method return.

Order-history windows

getOrdersHistory(request) passes the requested account, symbol, status, time, limit, and cursor filters to the adapter. The returned array becomes the controller's entire cached ordersHistory slice. A later call with another scope replaces that slice; consumers do not receive independent caches.

The current result has no nextCursor. Treat each adapter response as one complete documented history window. Use a backend-owned paginated Account Manager table when the product needs independent or long-running pagination.

Identity and retries

Reuse one stable order id for every version, and make it globally unique within the controller. Prefix a provider id with its account or venue when the native id is only scoped there. previewOrder may return a confirmId, which the caller can copy to the draft. When placeOrder receives an operationId, the controller uses it as the outgoing draft's confirmId and also passes it in the mutation options; it therefore takes precedence over a preview confirmId. The current contract has no separate adapter field that preserves both values. Supplying an operationId also requires origin; both remain mutation metadata.

Give every mutation a backend idempotency or correlation key. A timeout or transport failure has an unknown outcome, not a rejected outcome. Reconcile by that key and the order stream before retrying, and reuse the same key rather than issuing a blind retry with a new identity. The SDK does not make ordinary retries exactly-once.

Verify the contract

  • Rejection creates no working order.
  • Acceptance alone creates no order row or line.
  • A partial fill retains the same order id and correct remaining quantity.
  • Cancelling a remainder preserves completed executions.
  • Reconnect restores the same logical orders without duplicate ids.

Next steps

  • Executions — publish the prints linked to filled quantity.
  • Positions — publish resulting exposure without client-side netting.
  • Order Ticket — submit the drafts described here.