Order lifecycle
From a condition becoming true to a position appearing on your dashboard. This page is the map you want open when something did not happen that you expected to.
The path
Before placement, in order:
| Step | Stage | Detail |
|---|---|---|
| 1 | Candle closes | |
| 2 | Evaluate the strategy's conditions | Entry true, exit true, or neither. Neither means no action, and the engine waits for the next candle |
| 3 | Signal produced | Carrying an idempotency key |
| 4 | Trading window check | Outside the window, no entry |
| 5 | Kill switch and halt check | Halted means no entry. Fail-closed |
| 6 | Position sizing | Risk budget, then quantity, then step or lot rounding |
| 7 | Nine risk gates | The first violation stops the order |
| 8 | Margin validation | Margined instruments only |
The nine gates run in this order: max_order_value, per_trade_risk, max_open_positions,
max_trades_per_day, max_consecutive_losses, daily_loss_limit, mark_to_market_loss,
max_capital_allocation, available_capital.
Then the two modes diverge:
| Paper | Live | |
|---|---|---|
| Order construction | None needed | The broker adapter builds the order |
| Where it goes | The internal simulator, against live prices | Your venue, which accepts or rejects it |
| Fills | Recorded immediately | One or more fills, possibly partial |
After the fill, both modes rejoin: the position ledger is updated on FIFO lots, and P&L, risk metrics and notifications follow from it.
Evaluation
At candle close, on the strategy's timeframe. Not intra-candle, not per tick.
Three possible outcomes: an entry signal, an exit signal, or no action. Most bars are no action, and that is normal.
For a strategy with higher-timeframe gates, every gate must pass on its most recently closed higher-timeframe bar before a lower-timeframe entry is allowed through.
Idempotency
Every signal carries a stable idempotency key, and the orders table enforces uniqueness on (user, idempotency key).
This is what prevents a duplicate order from a retry, a restart, or a redelivered signal. A signal without a stable key is refused rather than sent, because an order that could be placed twice is a worse outcome than an order not placed at all.
Duplicate detection surfaces as DUPLICATE_ORDER or DUPLICATE_STRATEGY_EXECUTION. Those are not
risk violations; they are the deduplication working.
Pre-placement checks, in order
| Order | Check | Blocks |
|---|---|---|
| 1 | Trading window | Entries outside the time-of-day range |
| 2 | Kill switch / halt | New entries when halted. Fail-closed, an unreadable halt state blocks |
| 3 | Position sizing | Nothing; it computes the quantity |
| 4-12 | The nine risk gates | The first violation stops the order |
| 13 | Margin validation | Margined orders without sufficient margin |
Why the gate order matters
Cheapest and most decisive first. max_order_value and per_trade_risk need nothing but the order
itself; the gates that need position counts, today's P&L or capital figures declare that requirement and
those reads happen only if the order survives the cheap checks.
An order failing on shape never costs a database query.
Entries are gated; exits are not
Every exposure and velocity gate applies to entries only. A strategy at its position cap must still be able to close a position.
The consequence: a breached daily-loss cap stops new trades and leaves the open position running to its own stop. See Alerts & breaches
Order states
What you will see on the live terminal and in the order history:
| State | Meaning |
|---|---|
PENDING / PENDING_NEW | Submitted, awaiting venue acknowledgement |
NEW / OPEN | Live on the book |
TRIGGER_PENDING | A stop or trigger order waiting for its level |
PARTIALLY_FILLED | Some quantity filled, the rest still working |
FILLED | Complete |
PENDING_CANCEL | Cancellation submitted |
CANCELLED | Cancelled |
REJECTED | The venue or a pre-placement check refused it |
EXPIRED | Aged out at the venue |
PARTIALLY_FILLED deserves attention: the backtest never produces it. A partial fill leaves you
with less exposure than the strategy intended, and the remaining quantity is still working.
See Backtest limitations.
Fills and the position ledger
Fills update a FIFO lot ledger. Open exposure is derived from open buy lots plus fully-unfilled working buy entries.
Two things that follow from FIFO accounting:
Working orders count toward max_open_positions. An entry sitting unfilled occupies a slot, so the
cap cannot be exceeded by racing two entries.
Short-side exposure is asymmetric in one place. The mark_to_market_loss gate derives open exposure
from the buy-lot ledger, so a short position contributes quantity but not a mirrored unrealised sign.
That narrowing is documented rather than hidden.
See The nine order gates.
Rejection reasons
| Code | Cause |
|---|---|
MAX_ORDER_VALUE_EXCEEDED | Gate 1 |
PER_TRADE_RISK_EXCEEDED | Gate 2 |
MAX_OPEN_POSITIONS_REACHED | Gate 3 |
MAX_TRADES_PER_DAY_REACHED | Gate 4 |
MAX_CONSECUTIVE_LOSSES_REACHED | Gate 5 |
DAILY_LOSS_LIMIT_EXCEEDED | Gate 6 |
MARK_TO_MARKET_LOSS_EXCEEDED | Gate 7 |
MAX_CAPITAL_ALLOCATION_EXCEEDED | Gate 8 |
INSUFFICIENT_AVAILABLE_CAPITAL | Gate 9 |
INSUFFICIENT_BROKER_BALANCE | Funds at the broker |
INSUFFICIENT_MARGIN | Margin validator |
DUPLICATE_ORDER | Deduplication, not a risk violation |
Every violation reports the rule, the current value and the limit, so "which rule and by how much" is always answerable.
Reconciliation
The platform reconciles its view of orders and positions against the broker's, because the two can diverge, a fill the platform did not see, a cancellation it missed, a position that exists at the venue and not in the ledger.
For your positions, your balance and your obligations, the broker's statement is authoritative. Reconcile against it rather than against the platform's view.
Debugging: what to check, in order
| Symptom | Check |
|---|---|
| No orders at all | Is the strategy running? Is the entry condition ever true? Is it inside the trading window? |
| Orders rejected | The risk panel for a violation, and the reason code |
| Rejected on funds | Broker balance, and whether other strategies hold the capital |
| Rejected on auth | Token expiry, key revocation, IP allowlist |
| Entries stopped but the position is still open | A gate tripped. Gates block entries, never exits |
| Fewer shares than expected | Quantity step or lot rounding, or a partial fill |
| Nothing after a restart | Cooldown may still be elapsing, it is computed, not persisted |
| Duplicate-looking signal did nothing | Idempotency deduplication working correctly |