Engineering note · Reversal order state
A Reversal Order Can Fail Before It Ever Reaches the Broker
Diagnose a missing NinjaTrader reversal before blaming broker latency, then protect the filled position with an explicit callback-driven state machine and three acceptance tests.
Visible symptom
A sell-short reversal works in simulation, but the live log contains no named reversal order.
First boundary
Never submitted is earlier than exchange latency, fills and broker routing.
Hard rule
Submit once from a confirmed state, then build protection from actual execution quantities.
Start at the first missing event
A reversal can fail before any request reaches a broker. The useful distinction is simple: was the order submitted and rejected, submitted and left uncertain, or never submitted at all? Those are different defects and need different evidence.
In the source case, a long position of three contracts should have received a six-contract sell-short reversal. The simulation submitted and filled the named reversal. The live run never showed that submission, then later flattened the long with an unnamed sell order. That sequence points first to strategy state, Managed approach handling or fallback cleanup logic, not to slow exchange routing.
One transition owns the strategy
A reversal is not one button press. It is a position transition with several asynchronous events. Give that transition an explicit state and block every unrelated entry path until it reaches a protected terminal state or a recorded failure.
LONG_PROTECTED
Long three and its current protection are known.
REVERSAL_REQUESTED
New entry paths are blocked while the transition owns the strategy.
PRIOR_STATE_CONFIRMED
The required cancel, fill or order-state callback has arrived.
REVERSAL_SUBMITTED
One named sell-short request has a returned order identity.
REVERSAL_FILLING
Actual execution quantities drive position and protection state.
SHORT_PROTECTED
Short three has exactly one bracket for the filled quantity.
Log the decision and every callback
Enable TraceOrders, then write one structured record from OnBarUpdate, OnOrderUpdate and OnExecutionUpdate. Use the callback arguments as the event evidence. Do not assume that a strategy-level position property has already caught up with the callback.
- strategy state before and after
- signal name and returned order ID
- order state and native error
- filled and remaining quantity
- position quantity before and after
- callback type and timestamp
Three acceptance tests
These cases separate an ignored request, a timing defect and an incomplete fill transition. Run them with controlled simulation or playback evidence before considering any live deployment.
Test 1
Managed-rule rejection
Input: A reversal request conflicts with an active order or another Managed approach rule.
Pass: TraceOrders or the order callback records the exact rejection. No unnamed flatten order fires and the existing position remains protected.
Test 2
Delayed callback sequence
Input: The prior protective-order callback is delayed while the strategy still receives market updates.
Pass: The strategy submits one reversal only after the required prior state is confirmed. Repeated bars and callbacks cannot submit it again.
Test 3
Partial fill and reconnect
Input: The six-contract reversal fills in parts or the connection changes during the transition from long three to short three.
Pass: Protection follows the actual filled short quantity, the final position is short three, and no orphan entry or bracket remains.
What this contract does not prove
A correct reversal state machine does not prove profitable entries, favorable fills or consistent live performance. It proves only that one requested transition has explicit states, evidence and protection boundaries.
Broker-specific order types, exchange rules, session settings and connection behavior remain separate inputs. Freeze the exact platform version, account mode, instrument, order approach and callback evidence before changing code.
Free next step
Freeze the reversal before requesting a repair
Use the free scope builder to record the current position, intended reversal quantity, active protection, allowed callback states and the three pass cases. That turns a missed live order into a bounded engineering problem.