The key signal is never submitted. That is earlier than broker latency. First prove whether NinjaTrader ignored the request.
Turn on TraceOrders and log these from OnBarUpdate, OnOrderUpdate, and OnExecutionUpdate: signal name, returned order ID, state, error/native error, filled/remaining quantity, and position before/after. With the Managed approach, internal order-handling rules can ignore a request; TraceOrders should state why.
I would implement the reversal as a small state machine:
- Set
reversalRequestedand block every other entry path. - Track the current protective orders explicitly.
- Submit the reversal only after the expected prior order state is confirmed by a callback.
- Create the new protection from actual reversal fills in
OnExecutionUpdate, not from the assumed six-contract request.
Also search for any fallback branch that can submit an unnamed flatten order or clear reversalRequested. The nameless Sell 3 in the live run suggests that cleanup logic fired after the intended ORREV path did not submit.
A good replay acceptance case is: long 3 becomes short 3, exactly one protective bracket exists for the filled short quantity, and no orphan order remains after a delayed callback or reconnect.