Model three states instead of one
- Treat request receipt as sequencing confirmation only.
- Persist receipt identifiers, trader/strategy context, timestamps, and nonce immediately.
- Track execution outcomes separately from sequencing receipts. Use
ORDER_UPDATE,STRATEGY_UPDATE, andTRADER_UPDATEas the execution-state surfaces. - Treat checkpoint/finality progression as a third concern that matters later for settlement-sensitive behavior, not for immediate fill handling.
Run one client loop for receipts and another for outcomes
- When a request is submitted, create a local record in a “submitted” or “awaiting sequencing” state.
- When the request is acknowledged, move it to a sequenced/accepted state without assuming fill success.
- Subscribe to the relevant realtime feeds and apply ordered updates as the authority for live execution outcomes.
- Move the request to terminal status only when the update stream shows a terminal result such as full fill, cancellation, rejection, liquidation, or ADL-resolved closure.
- After reconnects or uncertainty, reconcile the affected order and strategy state from REST plus the update-history surfaces before resuming normal live processing.
Guardrails that prevent bad state machines
- Never mark an order as filled only because the request was accepted.
- Keep idempotent update handlers keyed by stable order identity and lifecycle correlation fields.
- Distinguish rejection-at-admission from rejection-inside-lifecycle updates.
- Apply feed ordering according to the documented ordinal semantics, not local wall-clock arrival order.
- Reconcile strategy and trader updates alongside order updates when the request can affect balances, fees, liquidation state, or DDX balances.
What to do when something goes wrong
| Situation | Response |
|---|---|
| Receipt arrived but no terminal execution yet | Keep the order in a live intermediate state and continue consuming updates |
| Websocket reconnect or packet loss | Reconnect, resubscribe, and reconcile from REST and update history |
Rejection appears inside ORDER_UPDATE | Treat it as an execution-domain result, not as a transport failure |
| Strategy/trader state changed without a new order fill | Reconcile those updates; not every important account change is a trade-print event |