I was following an example of ProfitChaseStopTrailExitOrdersExample to add second order and breakeven and I have trouble
breakevenShort:20882.25
7/11/2024 6:17:00 AM | OOU | order | 7/11/2024 6:16:13 AM | orderId='24b7847733cd4ac991f398c828409341' account='Playback101' name='MyTargetShort' orderState=Filled instrument='NQ 09-24' orderAction=BuyToCover orderType='Limit' limitPrice=20877.25 stopPrice=0 quantity=1 tif=Gtc oco='' filled=1 averageFillPrice=20877.25 onBehalfOf='' id=184901 time='2024-07-11 06:16:13' gtd='2099-12-01' statementDate='2024-07-11'
7/11/2024 6:17:00 AM | OOU | stop or target filled, preventing oco actions until reset Primary
7/11/2024 6:16:13 AM Strategy '312671451/jockey: Cancelled pending exit order, since associated position is closed, orderId='f8b64bedada54717b4d9ab0bfdeecc3e' account='Playback101' name='MyStopShort' orderState=Accepted instrument='NQ 09-24' orderAction=BuyToCover orderType='Stop Market' limitPrice=0 stopPrice=20886.5 quantity=1 tif=Gtc oco='' filled=0 averageFillPrice=0 onBehalfOf='' id=184902 time='2024-07-11 06:13:32' gtd='2099-12-01' statementDate='2024-07-11'
Often as a result I am getting Error on calling 'OnBarUpdate' method on bar " ": Object reference not set to an instance of an object. when order is left hanging. I notice it when breakeven is used. maybe my breakeven part is wrong? Any Help would be appriciated
------------------
In my strategy I want to use two entry orders(entryOrderS, entryOrderR, same entry price and stop loss but different take profits. However if breakeven is used, it onply applies to runner order(entryOrderR).
private Order entryOrderS,entryOrderR, exitFlatS, exitFlatR;
private Order placeHolderOrderS, profitTargetS, stopLossS, placeHolderOrderR, profitTargetR, stopLossR;
private void AssignOrderToVariable(ref Order order)
{
// Assign Order variable in OnOrderUpdate() to ensure the assignment occurs when expected.
// This is more reliable than assigning Order objects in OnBarUpdate, as the assignment is not guaranteed to be complete if it is referenced immediately after submitting
//if (PrintDetails)
// Print(string.Format("{0} | assigning {1} to variable", Time[0], order.Name));
if ((order.Name == "MyEntryLong" || order.Name == "MyEntryShort") && entryOrderS != order)
entryOrderS = order;
if ((order.Name == "MyTargetLong" || order.Name == "MyTargetShort") && profitTargetS != order)
profitTargetS = order;
if ((order.Name == "MyStopLong" || order.Name == "MyStopShort") && stopLossS != order)
stopLossS = order;
if (order.Name == exitNameS && exitFlatS != order)
exitFlatS = order;
// Runner
if ((order.Name == "MyEntryLongRunner" || order.Name == "MyEntryShortRunner") && entryOrderR != order)
entryOrderR = order;
if ((order.Name == "MyTargetLongRunner" || order.Name == "MyTargetShortRunner") && profitTargetR != order)
profitTargetR = order;
if ((order.Name == "MyStopLongRunner" || order.Name == "MyStopShortRunner") && stopLossR != order)
stopLossR = order;
if (order.Name == exitNameR && exitFlatR != order)
exitFlatR = order;
}
-----------My Entry for longs
(condition)
if(longPrice >= GetCurrentAsk() && entryOrderS == null && profitTargetS == null && stopLossS == null)
{
entryOrderS = placeHolderOrderS;
suppressOcoS = false;
EnterLongStopMarket(0,true, PositionSize, longPrice, "MyEntryLong");
if(TradeRunner && entryOrderR == null && profitTargetR == null && stopLossR == null)
{
entryOrderR = placeHolderOrderR;
suppressOcoR = false;
EnterLongStopMarket(0,true, PositionSizeRunner, longPrice, "MyEntryLongRunner");
if(TradeRunner && entryOrderR == null && profitTargetR == null && stopLossR == null)
{
entryOrderR = placeHolderOrderS;
suppressOcoR = false;
EnterShortStopMarket(0,true, PositionSizeRunner, shortPrice, "MyEntryShortRunner");
}
}
----------My Take Profit Stop Loss and breakeven
if (UseProfitTargetS && entryOrderS != null && entryOrderS.Name == "MyEntryLong" &&
profitTargetS != null && (profitTargetS.OrderState == OrderState.Accepted || profitTargetS.OrderState == OrderState.Working) &&
longTarget > GetCurrentBid())
{
ExitLongLimit(0, true, entryOrderS.Quantity, longTarget, "MyTargetLong", "MyEntryLong");
}
// trigger the trail action when the current price is further than the set distance to the stop loss
if (UseStopLossS &&
stopLossS != null && (stopLossS.OrderState == OrderState.Accepted || stopLossS.OrderState == OrderState.Working) &&
longStop < GetCurrentBid())
{
ExitLongStopMarket(0, true, entryOrderS.Quantity, longStop, "MyStopLong", "MyEntryLong");
}
if (SetBreakeven )
{
if(
stopLossR != null && (stopLossR.OrderState == OrderState.Accepted || stopLossR.OrderState == OrderState.Working) &&
Close[0] >= breakevenTriggerLong
)
{
breakevenLong = Position.AveragePrice; //Define what a breakeven is. (We set it at the average filled price)
ExitLongStopMarket(0, true, PositionSizeRunner, breakevenLong, "MyStopLong", "MyEntryLongRunner");
myFreeBELong = false; //BE bool is false after setting stop. You can now move it around freely.
Print("BreakEvenLong:" + breakevenLong);
}
}
--------- on Execution
protected override void OnExecutionUpdate(Cbi.Execution execution, string executionId, double price, int quantity,
Cbi.MarketPosition marketPosition, string orderId, DateTime time)
{
Print(string.Format("{0} | OEU | execution | {1} | {2}", Time[0], time, execution.ToString()));
if (execution.Order.OrderState != OrderState.Filled)
return;
if (entryOrderR != null && execution.Order != entryOrderS && execution.Order == entryOrderR)
{
if (UseProfitTargetS)
{
if (PrintDetails)
Print(string.Format("{0} | OEU | placing profit target Runner", execution.Time));
if (execution.Name == "MyEntryLongRunner" && (execution.Order.AverageFillPrice + (ProfitTargetTicks*TickSize)) >= GetCurrentBid())
{
profitTargetR = placeHolderOrderR;
ExitLongLimit(0, true, entryOrderR.Quantity, execution.Order.AverageFillPrice + (ProfitTargetTicks*TickSize), "MyTargetLongRunner", "MyEntryLongRunner");
}
if (execution.Name == "MyEntryShortRunner" && (execution.Order.AverageFillPrice - (ProfitTargetTicks*TickSize)) <= GetCurrentAsk())
{
profitTargetR = placeHolderOrderR;
ExitShortLimit(0, true, entryOrderR.Quantity, execution.Order.AverageFillPrice - (ProfitTargetTicks*TickSize), "MyTargetShortRunner", "MyEntryShortRunner");
}
}
if (UseStopLossS)
{
if (PrintDetails)
Print(string.Format("{0} | OEU | placing stop loss Runner", execution.Time));
if(execution.Name == "MyEntryLongRunner" && longStop <= GetCurrentBid())
{
stopLossR = placeHolderOrderR;
ExitLongStopMarket(0, true, entryOrderR.Quantity, longStop, "MyStopLongRunner", "MyEntryLongRunner");
}
if(execution.Name == "MyEntryShortRunner" && shortStop >= GetCurrentAsk())
{
stopLossR = placeHolderOrderR;
ExitShortStopMarket(0, true, entryOrderR.Quantity, shortStop, "MyStopShortRunner", "MyEntryShortRunner");
}
}
}
-------- OnOrderUpdate
protected override void OnOrderUpdate(Cbi.Order order, double limitPrice, double stopPrice,
int quantity, int filled, double averageFillPrice,
Cbi.OrderState orderState, DateTime time, Cbi.ErrorCode error, string comment)
{
if (PrintDetails)
Print(string.Format( "{0} | OOU | order | {1} | {2}", Time[0], time, order.ToString() ));
AssignOrderToVariable(ref order);
if (orderState == OrderState.Filled && ((profitTargetR != null && order == profitTargetR) ||
(stopLossR != null && order == stopLossR)))
{
Print(string.Format( "{0} | OOU | stop or target filled, preventing oco actions until reset Runner", Time[0] ));
suppressOcoR = true;
}
if (!suppressOcoR && profitTargetR != null && order == profitTargetR &&
(orderState == OrderState.Cancelled || orderState == OrderState.Rejected) &&
stopLossR != null &&
(stopLossR.OrderState == OrderState.Accepted || stopLossR.OrderState == OrderState.Working) )
{
Print(string.Format( "{0} | OOU | cancelling stop Runner", Time[0] ));
CancelOrder(stopLossR);
}
else if (!suppressOcoR && stopLossR != null && order == stopLossR &&
(orderState == OrderState.Cancelled || orderState == OrderState.Rejected) &&
profitTargetR != null &&
(profitTargetR.OrderState == OrderState.Accepted ||
profitTargetR.OrderState == OrderState.Working) )
{
Print(string.Format( "{0} | OOU | cancelling target Runner", Time[0] ));
CancelOrder(profitTargetR);
}
else if ( entryOrderR != null && order != entryOrderR &&
(!UseProfitTargetS || (profitTargetR != null &&
(profitTargetR.OrderState == OrderState.Cancelled ||
profitTargetR.OrderState == OrderState.Rejected))) &&
(!UseStopLossS || (stopLossR != null &&
(stopLossR.OrderState == OrderState.Cancelled ||
stopLossR.OrderState == OrderState.Rejected))) )
{
// if either the stop or target is cancelled, wait 1 tick in OBU to check
// to see if this was because of the Exit on close occurring or if manually cancelled
ordersCancelledR = true;
if (PrintDetails)
Print(string.Format( "{0} | OOU | stop or target cancelled or rejected Runner", Time[0] ));
}
if ( (profitTargetR != null && profitTargetR.OrderState == OrderState.Filled && (stopLossR == null || stopLossR.OrderState == OrderState.Cancelled)) ||
(stopLossR != null && stopLossR.OrderState == OrderState.Filled && (profitTargetR == null || profitTargetR.OrderState == OrderState.Cancelled))
|| stopLossR != null && stopLossR.OrderState == OrderState.Cancelled
|| profitTargetR != null && profitTargetR.OrderState == OrderState.Cancelled)
{
Print(string.Format( "{0} | OOU | resetting Runner", Time[0] ));
entryOrderR = null;
profitTargetR = null;
stopLossR = null;
}

Comment