I'm seeing a bizarre sequence of events in Market Replay. Here's my entry code:
EntrySignalName, TargetPrice, and StopLossPrice are my own variables.
SetProfitTarget(EntrySignalName, CalculationMode.Price, TargetPrice, false);
SetStopLoss(EntrySignalName, CalculationMode.Price, StopLossPrice, false);
EnterLong(Quantity, EntrySignalName);
Here's the scenario of the price on the chart, along with relative positions of the orders.
I understand that using a market order means that the order may be filled at any price. In the diagram above, the yellow arrow is simply the expected price (give or take a few ticks) for getting filled, that is, near the close of the green bar / open of the new bar. This happens 99% of the time. However, when the next bar is news event, the order could get filled out of the expected range.
In this situation, the order is filled below the range. This results in the Stop Loss and Profit Target orders getting rejected. The Stop Loss is at an invalid price, so it is rejected. Once the Stop Loss order is rejected, the Profit Target order is rejected due to the OCO connection between the two.
Understanding this scenario, I set Error Handling to RealtimeErrorHandling = RealtimeErrorHandling.StopCancelCloseIgnoreRejects and have code to handle the rejected orders.
Here is the sequence I'm seeing in my OnOrderUpdate and OnExecutionUpdate:
- OnOrderUpdate
- Order State is Rejected
- Stop Loss order is identified and associated with the Entry Signal order
- Exit Long is immediately called with an Exit Signal Order associated with the Entry Signal order
- OnOrderExecution
- Exit Long is identified and filled with the Exit Signal Order set in Step 1.3 above.
- OnOrderUpdate
- Order State is Rejected
- Profit Target order is identified and associated with the same Entry Signal order in 1.1 above.
- Since the original order was exited this order rejection is ignored.
- OnOrderExecution
- Order State is Filled
- Order is identified at the same Entry Signal order from 1.2 above
Here's the trace from the sequence:
2023-03-31 8:30:01 AM Strategy 'RyanPivotor01/291669901': Entered internal SetStopTarget() method: Type=Target FromEntrySignal='eL-1t1-0048' Mode=Price Value=13089.5 IsSimulatedStop=False IsMarketIfTouched=False
2023-03-31 8:30:01 AM Strategy 'RyanPivotor01/291669901': Entered internal SetStopTarget() method: Type=Stop FromEntrySignal='eL-1t1-0048' Mode=Price Value=13059.5 IsSimulatedStop=False IsMarketIfTouched=False
2023-03-31 8:30:01 AM Strategy 'RyanPivotor01/291669901': Entered internal SubmitOrderManaged() method at 2023-03-31 8:30:01 AM: BarsInProgress=0 Action=Buy OrderType=Market Quantity=1 LimitPrice=0 StopPrice=0 SignalName='eL-1t1-0048' FromEntrySignal=''
2023-03-31 8:30:01 AM Strategy 'RyanPivotor01/291669901': Entered internal SubmitOrderManaged() method at 2023-03-31 8:30:01 AM: BarsInProgress=0 Action=Sell OrderType=Market Quantity=0 LimitPrice=0 StopPrice=0 SignalName='xL-1t1-0048' FromEntrySignal='eL-1t1-0048'
2023-03-31 8:30:01 AM Strategy 'RyanPivotor01/291669901': Entered internal SetStopTarget() method: Type=Target FromEntrySignal='eL-1t1-0048' Mode=Price Value=13085.75 IsSimulatedStop=False IsMarketIfTouched=False
2023-03-31 8:30:01 AM Strategy 'RyanPivotor01/291669901': Entered internal SetStopTarget() method: Type=Target FromEntrySignal='eL-1t1-0048' Mode=Price Value=13085.75 IsSimulatedStop=False IsMarketIfTouched=False
Questions:
Is that to be expected?
Should I have the SetStopLoss and SetProfitTarget be in the OnOrderUpdate or OnExecutionUpdate and only be called when the entry order is filled?
Thanks!
Matt
Comment