My strategy takes a trade and places a stoploss order. If I change the stoploss order then the whole position gets cancelled by ninjatrader. In playback mode it’s no problem to do that. This is how I place the order:
if (_stopPriceLong < GetCurrentBid())
{
_stopLong = ExitLongStopMarket(0,true,_longFilled,_stopPriceLo ng,“LongStop”,"LongEntry "+StrategyIdentifier);
}
Eventhough LiveUntilCancel is set to true I can’t move the order on the chart manually.
Question 1: How can I move the stoploss order once it was placed by the strategy?
Question 2: Why does it work in Playback but not in Sim/Live trading?
Thank you!
1 Like
happytrader76:
Question 1: How can I move the stoploss order once it was placed by the strategy? So when you enter SL is “-10 ticks” when price rises “+40 ticks” adjust SL to “+20 ticks”? If I’m understanding properly see below, may not be what you need / I don’t remember if it worked 100% but should get you on the right track - its from an old code I don’t use anymore.
Q uestion 2: Why does it work in Playback but not in Sim/Live trading? - no idea, it might not actually be working in playback and it just looks like it is.
// ────────────────────────────────────────────────
// Add these near the top of your class (variables)
// ────────────────────────────────────────────────
private double entryPrice = 0;
private Order stopLossOrder = null;
private bool hasMovedStop = false; // prevents moving it again and again
// TP/SL tick values
private double initialRiskTicks = 10; // initial stop = entry ± 10 ticks
private double triggerProfitTicks = 25; // when up 25 ticks → move stop
private double newStopOffsetTicks = 5; // move stop to +5 ticks profit (locked in)
// ────────────────────────────────────────────────
// When your entry order fills (in OnOrderUpdate)
// ────────────────────────────────────────────────
if (order == entryOrder && orderState == OrderState.Filled)
{
entryPrice = averageFillPrice;
double stopPrice;
if (Position.MarketPosition == MarketPosition.Long)
{
stopPrice = entryPrice - (initialRiskTicks * TickSize);
}
else // Short
{
stopPrice = entryPrice + (initialRiskTicks * TickSize);
}
// Submit the initial stop loss
stopLossOrder = SubmitOrderUnmanaged(
0,
Position.MarketPosition == MarketPosition.Long ? OrderAction.Sell : OrderAction.BuyToCover,
OrderType.StopMarket,
Position.Quantity,
0, stopPrice,
"", "Initial Stop"
);
hasMovedStop = false; // reset for this trade
Print($"Entered @ {entryPrice:F2} | Stop placed @ {stopPrice:F2}");
}
// ────────────────────────────────────────────────
// Check & move stop (put this in OnMarketData or OnBarUpdate)
// ────────────────────────────────────────────────
if (Position.MarketPosition != MarketPosition.Flat && stopLossOrder != null)
{
// Only try to move if we haven't already moved it
if (!hasMovedStop)
{
double profitInTicks = Position.GetUnrealizedProfitLoss(PerformanceUnit.Ticks);
if (profitInTicks >= triggerProfitTicks)
{
double newStopPrice;
if (Position.MarketPosition == MarketPosition.Long)
{
newStopPrice = entryPrice + (newStopOffsetTicks * TickSize);
}
else // Short
{
newStopPrice = entryPrice - (newStopOffsetTicks * TickSize);
}
// Move the stop (only if it's actually better)
if (Position.MarketPosition == MarketPosition.Long && newStopPrice > stopLossOrder.StopPrice ||
Position.MarketPosition == MarketPosition.Short && newStopPrice < stopLossOrder.StopPrice)
{
ChangeOrder(stopLossOrder, stopLossOrder.Quantity, 0, newStopPrice);
hasMovedStop = true;
Print($"Trade up {profitInTicks:F1} ticks → moved stop to {newStopPrice:F2} (+{newStopOffsetTicks} ticks locked)");
}
}
}
}