Stop not getting moved to BE

I am trying to move my stop to BE after price moves past a certain threshold, not sure what i am doing wrong but it doesn’t seem to be working despite my print statements are printing. This is my method (i know i have an extra criteria in the long side, i removed it on the short side just for testing)

I am using this method CheckAndMoveToBreakEven(currentPrice) to move stops

        private void CheckAndMoveToBreakEven(double currentPrice)
    {
        if (Position.MarketPosition == MarketPosition.Flat)
        {
            _stopMovedToBE = false;
            return;
        }

        double averagePrice = Position.AveragePrice;
        string positionType = Position.MarketPosition == MarketPosition.Long ? "Long" : "Short";

        if (Position.MarketPosition == MarketPosition.Long && !_stopMovedToBE)
        {
            double beTriggerPrice = averagePrice + breakEven;

            Print($"[{positionType}] Checking BE | Avg Price: {averagePrice} | Current Price: {currentPrice} | BE Trigger Price: {beTriggerPrice}");

            if (currentPrice >= beTriggerPrice)
            {
                double newStopPrice = averagePrice + breakEvenOffset;
                Print($"LONG | Moving stop to BE: {newStopPrice}");
                ExitLongStopMarket(0, true, Position.Quantity, newStopPrice, "BE Stop", "Long Level");
                _stopMovedToBE = true;
            }
            else
            {
                Print($"LONG | Not at BE yet. Current: {currentPrice}, Target: {beTriggerPrice}");
            }
        }
        else if (Position.MarketPosition == MarketPosition.Short && !_stopMovedToBE)
        {
            double beTriggerPrice = averagePrice - breakEven;

            Print($"[{positionType}] Checking BE | Avg Price: {averagePrice} | Current Price: {currentPrice} | BE Trigger Price: {beTriggerPrice}");

            if (currentPrice <= beTriggerPrice)
            {
                double newStopPrice = averagePrice - breakEvenOffset;
                Print($"SHORT | Moving stop to BE: {newStopPrice}");
                ExitShortStopMarket(0, true, Position.Quantity, newStopPrice, "BE Stop", "Short Level");
                _stopMovedToBE = true;
            }
            else
            {
                Print($"SHORT | Not at BE yet. Current: {currentPrice}, Target: {beTriggerPrice}");
            }
        }
    }

I am calling this in OnBarUpdate()

    double currentPrice = Input[0]; // or Bid / Ask depending on strategy

    if (!(Position.MarketPosition == MarketPosition.Flat))
    {
        Print($"Checking for BE, current price: {currentPrice}");
        CheckAndMoveToBreakEven(currentPrice);
    }

In the print statement it seems everythingshould be working, and even shows it making some change to the order, but in fact the order never changes. Any ideas why?
image

Sent DM with potential fix. No guarantees.

ExitLong/ShortStopMarket is used to exit positions, so you wouldn’t use that to move to breakeven. I’ve been using ChangeOrder() on the stop order that was originally created.

https://ninjatrader.com/support/helpGuides/nt8/NT%20HelpGuide%20English.html?managed_changeorder.htm

Yeah i tried that also but no luck.
My SL order gets created but for some reason those print statements dont print.

            if (order.OrderState == OrderState.Filled)
            {
                if (order.Name.Contains("Long"))
                {
                    exitOrder = ExitLongLimit(0, true, order.Quantity, averageFillPrice + takeProfit, "Long TP", "Long Level");
                    stopOrder = ExitLongStopMarket(0, true, order.Quantity, averageFillPrice - stopLoss, "Long SL", "Long Level");
                    Print($"ExitOrderLong in onOrderUPdate: {exitOrder}");
                    Print($"StoporderLong in onOrderUPdate: {stopOrder}");
                }
                else
                {
                    exitOrder = ExitShortLimit(0, true, order.Quantity, averageFillPrice - takeProfit, "Short TP", "Short Level");
                    stopOrder = ExitShortStopMarket(0, true, order.Quantity, averageFillPrice + stopLoss, "Short SL", "Short Level");
                    Print($"ExitOrderShort in onOrderUPdate: {exitOrder}");
                    Print($"StoporderShort in onOrderUPdate: {stopOrder}");
                }

And stopOrder is returning Null here, so that seems to be the main problem but not sure why…

        if (Position.MarketPosition == MarketPosition.Long && currentPrice >= beTriggerPrice)
        {
            double newStopPrice = averagePrice + BreakEvenOffsetTicks * TickSize;
            if (stopOrder != null && stopOrder.OrderState == OrderState.Working)
            {
                ChangeOrder(stopOrder, Position.Quantity, 0, newStopPrice);
                _stopMovedToBE = true;
            }
            else
            {
                Print($"Failed to change order: stopOrder is null or not working. StopOrder: {stopOrder}");
            }
        }

Are you trying this in OnOrderUpdate? I usually do my stop orders and targets in OnExecutionUpdate. I think after the order is filled it goes back to being null, but that could be how I have it set up, it’s been a while since I’ve looked at my strategy code.

With the managed approach you don’t need ChangeOrder for this: call the same exit method again with the same signal names and the new price, e.g. ExitLongStopMarket(0, true, quantity, newStopPrice, “Long SL”, “Long Level”), and NinjaTrader amends the working order. On stopOrder being null: assign your order references in OnOrderUpdate by matching order.Name, as NinjaTrader’s samples do, rather than from the method’s return value, and clear them when the order fills or is cancelled. Also check the new stop is valid (below the bid for a long) before sending it; TraceOrders will show whether each change was sent or ignored.