OUTPUT
=====
VALID Trend -- Strength: Strongest Direction Down Bar Index: 97
bar index: 97 short: price 3952.5, limit 3952.25, stop 3952
1/3/2023 6:56:42 AM Strategy 'MySecondEntryStrategy/-1': Entered internal SubmitOrderManaged() method at 1/3/2023 6:56:42 AM: BarsInProgress=0 Action=SellShort OrderType=StopLimit Quantity=1 LimitPrice=3952.25 StopPrice=3952.00 SignalName='short97' FromEntrySignal=''
FILLED Order -- (Name: short97 Limit: 3952.25 Stop: 3952) was filled for 3952.25
1/3/2023 7:00:25 AM Strategy 'MySecondEntryStrategy/-1: Cancelled pending exit order, since associated position is closed, orderId='NT-00005-156' account='Backtest' name='Profit target' orderState=Working instrument='ES SEP23' orderAction=BuyToCover orderType='Limit' limitPrice=3951.25 stopPrice=0 quantity=1 tif=Gtc oco='NT-00002-156' filled=0 averageFillPrice=0 onBehalfOf='' id=-1 time='2023-01-03 07:00:25' gtd='2099-12-01' statementDate='2023-09-05'
1/3/2023 7:00:25 AM Strategy 'MySecondEntryStrategy/-1': Cancelled OCO paired order: BarsInProgress=0, orderId='NT-00005-156' account='Backtest' name='Profit target' orderState=Cancelled instrument='ES SEP23' orderAction=BuyToCover orderType='Limit' limitPrice=3951.25 stopPrice=0 quantity=1 tif=Gtc oco='NT-00002-156' filled=0 averageFillPrice=0 onBehalfOf='' id=-1 time='2023-01-03 07:00:25' gtd='2099-12-01' statementDate='2023-09-05'
CODE
====
protected override void OnStateChange() {
if (State == State.SetDefaults) {
SetDefaults();
}
else if (State == State.Configure) {
ClearOutputWindow();
TraceOrders = TraceMyOrders;
_direction = Direction;
_positionSize = PositionSize;
_entryIndicator = MySecondEntryIndicator(Direction);
_entryIndicator.EntryAlertEvent += EntryAlertEvent;
AddChartIndicator(_entryIndicator);
SetStopLoss(CalculationMode.Ticks, 8);
SetProfitTarget(CalculationMode.Ticks, 4);
}
}
private void EntryAlertEvent(object sender, EntryAlertEventArgs e) {
var price = e.Price.Value;
var barIndex = e.Price.BarIndex;
double entryStopPrice = 0;
double entryLimitPrice = 0;
string signalName = "{0}" + barIndex;
switch (Direction) {
case PositionDirection.Long:
// implement later
break;
case PositionDirection.Short:
entryLimitPrice = price - TickSize;
entryStopPrice = (price - (2 * TickSize));
signalName = string.Format(signalName, "short");
if (_shortEntryOrder != null) {
Print(string.Format(
"CANCELLED Order -- (Name: {0} Limit: {1} Stop: {2}) was cancelled because it was not filled prior to entering a
new short position.",
_shortEntryOrder.Name,
_shortEntryOrder.LimitPrice,
_shortEntryOrder.StopPrice
));
CancelOrder(_shortEntryOrder);
_shortEntryOrderName = string.Empty;
_shortEntryOrder = null;
}
_shortEntryOrderName = signalName;
_shortEntryOrder = EnterShortStopLimit(0, true, PositionSize, entryLimitPrice, entryStopPrice, signalName);
Print(string.Format("bar index: {0} short: price {1}, limit {2}, stop {3} ",
e.Price.BarIndex, price, entryLimitPrice, entryStopPrice));
break;
}
}
protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice,
int quantity, int filled, double averageFillPrice, OrderState orderState,
DateTime time, ErrorCode error, string nativeError) {
if (order.Name == _shortEntryOrderName && orderState == OrderState.Filled)
Print(string.Format("FILLED Order -- (Name: {0} Limit: {1} Stop: {2}) was filled for {3}",
order.Name,
order.LimitPrice,
order.StopPrice,
order.AverageFillPrice
));
// One time only, as we transition from historical. Convert any old historical order object
// references to the live order submitted to the real-time account.
if (_shortEntryOrder != null && _shortEntryOrder.IsBacktestOrder && State == State.Realtime)
_shortEntryOrder = GetRealtimeOrder(_shortEntryOrder);
// Assign entryOrder in OnOrderUpdate() to ensure the assignment occurs when expected.
// This is more reliable than assigning Order objects in OnBarUpdate, as the assignment
// is not gauranteed to be complete if it is referenced immediately after submitting
else if (order.Name == _shortEntryOrderName && orderState != OrderState.Filled)
_shortEntryOrder = order;
// Null Entry order if filled or cancelled. We do not use the Order objects after the order is
// filled, so we can null it here
if (_shortEntryOrder != null && _shortEntryOrder == order) {
if (order.OrderState == OrderState.Cancelled && order.Filled == 0) {
_shortEntryOrderName = string.Empty;
_shortEntryOrder = null;
}
if (order.OrderState == OrderState.Filled)
_shortEntryOrderName = string.Empty;
_shortEntryOrder = null;
}
}
Comment