Breakeven code in my momentum strategy

This is my code. My issue is that in execution, when T1 takes profit and T2 moves the stop the breakeven, the T2 breakeven order keeps the same number of contracts in the order. I need the contracts to equate to only the open trade of 1 contract.

#region Using declarations
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Gui.SuperDom;
using NinjaTrader.Gui.Tools;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
using NinjaTrader.Core.FloatingPoint;
using NinjaTrader.NinjaScript.Indicators;
using NinjaTrader.NinjaScript.DrawingTools;
#endregion

namespace NinjaTrader.NinjaScript.Strategies
{
public class StrategyMomoCode : Strategy
{
private Momentum Momentum1;
private ATR AtrEma;
private EMA EmaIntraday;
private EMA EmaDaily;

    private bool   breakevenMoved;
    private bool   t1Hit;

    protected override void OnStateChange()
    {
        if (State == State.SetDefaults)
        {
            Description                                 = @"Momentum strategy — 2-step take profit, daily EMA+ATR% filter, 15-min EMA filter. Supports ES and MES.";
            Name                                        = "StrategyMomoCode";
            Calculate                                   = Calculate.OnBarClose;
            EntriesPerDirection                         = 1;
            EntryHandling                               = EntryHandling.AllEntries;
            IsExitOnSessionCloseStrategy                = false;
            ExitOnSessionCloseSeconds                   = 30;
            IsFillLimitOnTouch                          = false;
            MaximumBarsLookBack                         = MaximumBarsLookBack.TwoHundredFiftySix;
            OrderFillResolution                         = OrderFillResolution.Standard;
            Slippage                                    = 0;
            StartBehavior                               = StartBehavior.WaitUntilFlat;
            TimeInForce                                 = TimeInForce.Gtc;
            TraceOrders                                 = false;
            RealtimeErrorHandling                       = RealtimeErrorHandling.StopCancelClose;
            StopTargetHandling                          = StopTargetHandling.PerEntryExecution;
            BarsRequiredToTrade                         = 20;
            IsInstantiatedOnEachOptimizationIteration   = true;

            // ── Core parameters ───────────────────────────────────────
            Stop           = 120;
            TotalContracts = 4;

            // ── Two-step take profit ──────────────────────────────────
            T1Ticks              = 40;
            T1Contracts          = 2;
            T2Ticks              = 460;
            BreakevenOffsetTicks = 4;

            // ── Momentum filter ───────────────────────────────────────
            Momo1          = 250;
            MomoThreshold1 = 0;
            MomoThreshold2 = 0;
            SlopePeriod    = 92;

            // ── Daily EMA + ATR% condition ────────────────────────────
            EmaDailyPeriod     = 21;
            EmaAtrPeriod       = 14;
            EmaAtrPctThreshold = 0.75;
            EmaFilterEnabled   = true;

            // ── 15-min intraday EMA filter ────────────────────────────
            EmaIntradayPeriod        = 5;
            EmaIntradayFilterEnabled = true;
        }
        else if (State == State.Configure)
        {
            // BarsArray[1] — daily bars for EMA filter + ATR stop
            AddDataSeries(Data.BarsPeriodType.Day, 1);
        }
        else if (State == State.DataLoaded)
        {
            Momentum1                = Momentum(Close, Momo1);
            Momentum1.Plots[0].Brush = Brushes.DarkCyan;
            AddChartIndicator(Momentum1);

            AtrEma = ATR(BarsArray[1], EmaAtrPeriod);

            EmaDaily                = EMA(BarsArray[1], EmaDailyPeriod);
            EmaDaily.Plots[0].Brush = Brushes.Gold;
            AddChartIndicator(EmaDaily);

            EmaIntraday                = EMA(Close, EmaIntradayPeriod);
            EmaIntraday.Plots[0].Brush = Brushes.DodgerBlue;
            AddChartIndicator(EmaIntraday);

            SetStopLoss(@"Entry", CalculationMode.Ticks, Stop, false);

            breakevenMoved = false;
            t1Hit          = false;
        }
    }

    protected override void OnBarUpdate()
    {
        if (BarsInProgress != 0)
            return;

        if (CurrentBars[0] < 92)
            return;

        if (CurrentBars[1] < Math.Max(EmaDailyPeriod, EmaAtrPeriod) + 1)
            return;

        // ── Partial take profit and stop management while long ─────────
        if (Position.MarketPosition == MarketPosition.Long)
        {
            double openProfitTicks = (Close[0] - Position.AveragePrice) / TickSize;
            int    remaining       = Position.Quantity;

            // T1 — exit T1Contracts; move stop to breakeven on the remaining contracts only
            if (!t1Hit && openProfitTicks >= T1Ticks)
            {
                int qty              = Math.Min(T1Contracts, remaining);
                int contractsAfterT1 = remaining - qty;

                // Move stop first so NT processes it before the partial exit
                // Only relevant to the contracts that will still be open after T1
                if (contractsAfterT1 > 0)
                {
                    double beStopPrice = Position.AveragePrice + (BreakevenOffsetTicks * TickSize);
                    SetStopLoss(@"Entry", CalculationMode.Price, beStopPrice, false);
                    breakevenMoved = true;
                }

                ExitLong(qty, @"T1", @"Entry");
                t1Hit = true;
            }
            // T2 — exit all remaining contracts
            else if (t1Hit && openProfitTicks >= T2Ticks)
            {
                ExitLong(@"T2", @"Entry");
            }
        }

        // ── Reset when flat ────────────────────────────────────────────
        if (Position.MarketPosition == MarketPosition.Flat
            && (breakevenMoved || t1Hit))
        {
            SetStopLoss(@"Entry", CalculationMode.Ticks, Stop, false);
            breakevenMoved = false;
            t1Hit          = false;
        }

        // ── Already in a position — no new entries ─────────────────────
        if (Position.MarketPosition != MarketPosition.Flat)
            return;

        // ── Daily EMA + ATR% condition ─────────────────────────────────
        if (EmaFilterEnabled)
        {
            double dailyClose = BarsArray[1].GetClose(0);
            double atrPct     = dailyClose > 0 ? (AtrEma[0] / dailyClose) * 100.0 : 0;
            if (atrPct >= EmaAtrPctThreshold && Close[0] < EmaDaily[0])
                return;
        }

        // ── 15-min intraday EMA filter ─────────────────────────────────
        if (EmaIntradayFilterEnabled && Close[0] < EmaIntraday[0])
            return;

        // ── Entry ──────────────────────────────────────────────────────
        if (Momentum1[0]                        >= MomoThreshold1
            && Slope(Momentum1, SlopePeriod, 0) >= MomoThreshold2)
        {
            EnterLong(TotalContracts, @"Entry");
        }
    }

    #region Properties

    // ── Core parameters ───────────────────────────────────────────────

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name = "Stop (Ticks)", Order = 1, GroupName = "Parameters")]
    public int Stop { get; set; }

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name = "Total Contracts", Order = 2, GroupName = "Parameters",
             Description = "Total contracts entered. Must be >= T1 contracts. Works for both ES and MES. Default 4.")]
    public int TotalContracts { get; set; }

    // ── Two-step take profit ──────────────────────────────────────────

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name = "T1 Ticks", Order = 1, GroupName = "Take Profit Levels",
             Description = "Profit in ticks to trigger first partial exit. Default 40. Optimize: 20, 30, 40, 50, 60.")]
    public int T1Ticks { get; set; }

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name = "T1 Contracts", Order = 2, GroupName = "Take Profit Levels",
             Description = "Number of contracts to exit at T1. Stop moves to breakeven on remaining contracts when T1 fires. Default 2.")]
    public int T1Contracts { get; set; }

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name = "T2 Ticks", Order = 3, GroupName = "Take Profit Levels",
             Description = "Profit in ticks to exit all remaining contracts. Default 460. Optimize: 200, 300, 460, 600.")]
    public int T2Ticks { get; set; }

    [NinjaScriptProperty]
    [Range(0, int.MaxValue)]
    [Display(Name = "Breakeven Offset (Ticks)", Order = 4, GroupName = "Take Profit Levels",
             Description = "When T1 fires, stop on remaining contracts moves to entry + this many ticks. Set to 0 for exact breakeven. Default 4.")]
    public int BreakevenOffsetTicks { get; set; }

    // ── Momentum filter ───────────────────────────────────────────────

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name = "Momo1 Period", Order = 1, GroupName = "Momentum Filter")]
    public int Momo1 { get; set; }

    [NinjaScriptProperty]
    [Range(-300, int.MaxValue)]
    [Display(Name = "MomoThreshold1 (Value)", Order = 2, GroupName = "Momentum Filter",
             Description = "Momentum1[0] must be >= this value for entry. Optimize: -300, -100, 0, 25, 50, 100.")]
    public int MomoThreshold1 { get; set; }

    [NinjaScriptProperty]
    [Range(0, int.MaxValue)]
    [Display(Name = "MomoThreshold2 (Slope)", Order = 3, GroupName = "Momentum Filter",
             Description = "Slope of Momentum1 must be >= this value for entry. Optimize: 0, 10, 25, 50, 75, 100.")]
    public int MomoThreshold2 { get; set; }

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name = "Slope Period (bars)", Order = 4, GroupName = "Momentum Filter",
             Description = "Number of bars used to measure the slope of Momentum1. Default 92.")]
    public int SlopePeriod { get; set; }

    // ── Daily EMA + ATR% condition ────────────────────────────────────

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name = "Daily EMA Period", Order = 1, GroupName = "Daily EMA + ATR% Condition",
             Description = "Period for the daily EMA. Optimize: 13, 21, 34, 50.")]
    public int EmaDailyPeriod { get; set; }

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name = "EMA ATR Period", Order = 2, GroupName = "Daily EMA + ATR% Condition",
             Description = "Lookback for the daily ATR in this condition. Optimize: 7, 10, 14, 20.")]
    public int EmaAtrPeriod { get; set; }

    [NinjaScriptProperty]
    [Range(0.0, 20.0)]
    [Display(Name = "EMA ATR% Threshold", Order = 3, GroupName = "Daily EMA + ATR% Condition",
             Description = "When daily ATR% >= this AND close < daily EMA, entry is blocked. Optimize: 0.5, 0.75, 1.0, 1.25.")]
    public double EmaAtrPctThreshold { get; set; }

    [NinjaScriptProperty]
    [Display(Name = "EMA Filter Enabled", Order = 4, GroupName = "Daily EMA + ATR% Condition",
             Description = "Master switch.")]
    public bool EmaFilterEnabled { get; set; }

    // ── 15-min intraday EMA filter ────────────────────────────────────

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name = "Intraday EMA Period", Order = 1, GroupName = "15-Min Intraday EMA Filter",
             Description = "Entry blocked when Close < this EMA. Optimize: 3, 5, 8, 13, 21.")]
    public int EmaIntradayPeriod { get; set; }

    [NinjaScriptProperty]
    [Display(Name = "Intraday EMA Enabled", Order = 2, GroupName = "15-Min Intraday EMA Filter",
             Description = "Master switch.")]
    public bool EmaIntradayFilterEnabled { get; set; }

    #endregion
}

}

I would move to using OnExecutionUpdate, and then everything is much easier to deal with. Check the OnOrderUpdate Reference Sample.