Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

How to set stoploss step by step

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    How to set stoploss step by step

    Hello, NT traders and supports.
    I want to set a stoploss step by step.
    There is an initial stoploss and a profit target.
    What I want is a step-by-step stop loss.
    For long, when the price reaches MoveTSToLong, I want to set the stoploss to MoveTSAfterLong, when the price reaches MoveTSToLong2, I want to set the stoploss to MoveTSAfterLong2, and when the price reaches MoveTSToLong3, I want to set the stoploss to MoveTSAfterLong3.
    is this possible?

    I wrote the code like this;​

    Code:
    #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 XXX: Strategy
        {
            private double entryPrice;
            private double currentPrice;        
            
            public enum MovingAverageType
            {
                SMA,
                EMA,
                DEMA,
                HMA,
                TEMA,
                TMA,
                VWMA,
                WMA
            }
            
            private SMA fastsma;
            private SMA slowsma;
            private EMA ema;
            private DEMA dema;
            private HMA hma;
            private TEMA tema;
            private TMA tma;
            private VWMA vwma;
            private WMA wma;
            
            protected override void OnStateChange()
            {
                if (State == State.SetDefaults)
                {
                    Description    = "";
                    Name = "";
                    FastMA = 3;
                    SlowMA = 135;
                    SlowMAIndicatorType = MovingAverageType.HMA;
                    
                    TakeProfitLong = 0;
                    StopLossLong = 0;
                    TakeProfitShort = 0;
                    StopLossShort = 0;
                    
                    MoveTSAfterLong        = 0;
                    MoveTSToLong        = 0;
                    MoveTSAfterLong2nd    = 0;
                    MoveTSToLong2nd        = 0;
                    MoveTSAfterLong3rd    = 0;
                    MoveTSToLong3rd        = 0;
                    
                    MoveTSAfterShort    = 75;
                    MoveTSToShort        = 10;
                    MoveTSAfterShort2nd    = 0;
                    MoveTSToShort2nd    = 0;
                    MoveTSAfterShort3rd    = 0;
                    MoveTSToShort3rd    = 0;
                    
                    AddPlot(Brushes.Red, "FastMAPlot");
                    AddPlot(Brushes.Blue, "SlowMAPlot");
                }
                else if (State == State.Configure)
                {
    //                if (TakeProfitLong > 0)
    //                    SetProfitTarget("buy", CalculationMode.Ticks, TakeProfitLong);
    //                if (StopLossLong > 0)
    //                    SetStopLoss("buy", CalculationMode.Ticks, StopLossLong, false);
    //                if (TakeProfitShort > 0)
    //                    SetProfitTarget("sell", CalculationMode.Ticks, TakeProfitShort);
    //                if (StopLossShort > 0)
    //                    SetStopLoss("sell", CalculationMode.Ticks, StopLossShort, false);    
                }
                else if (State == State.DataLoaded){                
                    fastsma = SMA(FastMA);
                    slowsma = SMA(SlowMA);
                    ema = EMA(SlowMA);
                    dema = DEMA(SlowMA);
                    hma = HMA(SlowMA);
                    tema = TEMA(SlowMA);
                    tma = TMA(SlowMA);
                    vwma = VWMA(SlowMA);
                    wma = WMA(SlowMA);
                }
            }
            protected override void OnBarUpdate()
            {
                if (BarsInProgress != 0 || CurrentBars[0] < SlowMA)     return;            
                // determind FastMA and SlowMA
                FastMAPlot[0] = fastsma[0];            
                switch (SlowMAIndicatorType)
                {
                    case MovingAverageType.SMA:
                           SlowMAPlot[0] = slowsma[0];
                        break;
                    case MovingAverageType.EMA:
                        SlowMAPlot[0] = ema[0];
                        break;
                    case MovingAverageType.DEMA:
                        SlowMAPlot[0] = dema[0];
                        break;
                    case MovingAverageType.HMA:                    
                        SlowMAPlot[0] = hma[0];
                        break;
                    case MovingAverageType.TEMA:
                        SlowMAPlot[0] = tema[0];
                        break;
                    case MovingAverageType.TMA:
                        SlowMAPlot[0] = tma[0];
                        break;
                    case MovingAverageType.VWMA:
                        SlowMAPlot[0] = vwma[0];
                        break;
                    case MovingAverageType.WMA:
                        SlowMAPlot[0] = wma[0];
                        break;
                    default:
                        throw new ArgumentException("Unsupported Moving Average Type: " + SlowMAIndicatorType.ToString());
                }
                
                // Resets the stop loss to the original value when all positions are closed
                if (Position.MarketPosition == MarketPosition.Flat)
                {
    //                if (TakeProfitLong > 0)
    //                    SetProfitTarget("buy", CalculationMode.Ticks, TakeProfitLong);
    //                if (StopLossLong > 0)
    //                    SetStopLoss("buy", CalculationMode.Ticks, StopLossLong, false);
    //                if (TakeProfitShort > 0)
    //                    SetProfitTarget("sell", CalculationMode.Ticks, TakeProfitShort);
    //                if (StopLossShort > 0)
    //                    SetStopLoss("sell", CalculationMode.Ticks, StopLossShort, false);    
                }
                // If a long position is open, allow for stop loss modification to breakeven
                else if (Position.MarketPosition == MarketPosition.Long)
                {
                    Print(" ");
                    Print("@@@@@@@@@@@@@@@@@@@");
                    Print("EntryPriceLong : {" + Position.AveragePrice + "}");
                    Print("MoveTSAfterLongPrice : {" + (Position.AveragePrice + MoveTSAfterLong * TickSize).ToString() + "}");
                    Print("MoveTSToLongPrice : {" + (Position.AveragePrice + MoveTSToLong * TickSize).ToString() + "}");
                    Print("MoveTSAfterLong2Price : {" + (Position.AveragePrice + MoveTSAfterLong2nd * TickSize).ToString() + "}");
                    Print("MoveTSToLong2Price : {" + (Position.AveragePrice + MoveTSToLong2nd * TickSize).ToString() + "}");
                    Print("MoveTSAfterLong3Price : {" + (Position.AveragePrice + MoveTSAfterLong3rd * TickSize).ToString() + "}");
                    Print("MoveTSToLong3Price : {" + (Position.AveragePrice + MoveTSToLong3rd * TickSize).ToString() + "}");
                    Print("@@@@@@@@@@@@@@@@@@@");
                    
                    // Once the price is greater than entry price + MoveTSAfterLong, set stop loss to breakeven
                    if ((Close[0] > Position.AveragePrice + MoveTSAfterLong * TickSize) && (MoveTSAfterLong != 0))
                    {
                        Print("MoveTSAfterLong");
    //                    SetStopLoss("buy", CalculationMode.Price, Position.AveragePrice + MoveTSToLong * TickSize, false);
                        ExitLongMIT(Convert.ToInt32(DefaultQuantity), Position.AveragePrice + MoveTSToLong * TickSize, "buy-stoploss1", "buy");
                    }
                    // Once the price is greater than entry price + MoveTSAfterLong2nd , set stop loss to breakeven
                    if ((Close[0] > Position.AveragePrice + MoveTSAfterLong2nd * TickSize) && (MoveTSAfterLong2nd !=0))                    
                    {
                        Print("MoveTSAfterLong2");
    //                    SetStopLoss("buy", CalculationMode.Price, Position.AveragePrice + MoveTSToLong2nd * TickSize, false);
                        ExitLongMIT(Convert.ToInt32(DefaultQuantity), Position.AveragePrice + MoveTSToLong2nd * TickSize, "buy-stoploss2", "buy");
                    }
                    // Once the price is greater than entry price + MoveTSAfterLong3rd , set stop loss to breakeven
                    if ((Close[0] > Position.AveragePrice + MoveTSAfterLong3rd * TickSize) && (MoveTSAfterLong3rd != 0))
                    {
                        Print("MoveTSAfterLong3");
    //                    SetStopLoss("buy", CalculationMode.Price, Position.AveragePrice + MoveTSToLong3rd * TickSize, false);        
                        ExitLongMIT(Convert.ToInt32(DefaultQuantity), Position.AveragePrice + MoveTSToLong3rd * TickSize, "buy-stoploss3", "buy");
                    }
                    
                    if ((Close[0] > Position.AveragePrice + TakeProfitLong * TickSize) && (TakeProfitLong > 0))
                    {
                        Print("TakeProfitLong");
                        ExitLong("buy-takeprofit", "buy");
                    }
                    
                    if ((Close[0] > Position.AveragePrice + StopLossLong * TickSize) && (StopLossLong > 0))
                    {
                        Print("StopLossLong");
                        ExitLong("buy-stoploss", "buy");
                    }
                }
                else if (Position.MarketPosition == MarketPosition.Short)
                {                
                    Print(" ");
                    Print("@@@@@@@@@@@@@@@@@@@");
                    Print("EntryPriceShort : {" + Position.AveragePrice + "}");
                    Print("MoveTSAfterShortPrice : {" + (Position.AveragePrice - MoveTSAfterShort * TickSize).ToString() + "}");
                    Print("MoveTSToShortPrice : {" + (Position.AveragePrice - MoveTSToShort * TickSize).ToString() + "}");
                    Print("MoveTSAfterShort2Price : {" + (Position.AveragePrice - MoveTSAfterShort2nd * TickSize).ToString() + "}");
                    Print("MoveTSToShort2Price : {" + (Position.AveragePrice - MoveTSToShort2nd * TickSize).ToString() + "}");                
                    Print("MoveTSAfterShort3Price : {" + (Position.AveragePrice - MoveTSAfterShort3rd * TickSize).ToString() + "}");
                    Print("MoveTSToShort3Price : {" + (Position.AveragePrice - MoveTSToShort3rd * TickSize).ToString() + "}");
                    Print("@@@@@@@@@@@@@@@@@@@");
                    
                    if ((Close[0] < Position.AveragePrice - MoveTSAfterShort * TickSize) && (MoveTSAfterShort != 0))
                    {
                        Print("MoveTSAfterShort");
    //                    SetStopLoss("sell", CalculationMode.Price, Position.AveragePrice - MoveTSToShort * TickSize, false);
                        ExitShortMIT(Convert.ToInt32(DefaultQuantity), Position.AveragePrice - MoveTSToShort * TickSize, "sell-shortexit1", "sell");
                    }
                    if ((Close[0] < Position.AveragePrice - MoveTSAfterShort2nd * TickSize) && (MoveTSAfterShort2nd != 0))
                    {
                        Print("MoveTSToShort2");
    //                    SetStopLoss("sell", CalculationMode.Price, Position.AveragePrice - MoveTSToShort2nd * TickSize, false);
                        ExitShortMIT(Convert.ToInt32(DefaultQuantity), Position.AveragePrice - MoveTSAfterShort2nd * TickSize, "sell-shortexit2", "sell");
                    }
                    if ((Close[0] < Position.AveragePrice - MoveTSAfterShort3rd * TickSize) && (MoveTSAfterShort3rd != 0))
                    {
                        Print("MoveTSToShort3");
    //                    SetStopLoss("sell", CalculationMode.Price, Position.AveragePrice - MoveTSToShort3rd * TickSize, false);
                        ExitShortMIT(Convert.ToInt32(DefaultQuantity), Position.AveragePrice - MoveTSAfterShort3rd * TickSize, "sell-shortexit3", "sell");
                    }
                    
                    if ((Close[0] < Position.AveragePrice - TakeProfitShort * TickSize) && (TakeProfitShort > 0))
                    {
                        Print("TakeProfitShort");
                        ExitShort("sell-takeprofit", "sell");
                    }
                    
                    if ((Close[0] < Position.AveragePrice - StopLossShort * TickSize) && (StopLossShort > 0))
                    {
                        Print("StopLossShort");
                        ExitShort("sell-stoploss", "sell");
                    }
                }
                
                // create position            
                if (CrossAbove(FastMAPlot, SlowMAPlot, 1))
                {
                    EnterLong(Convert.ToInt32(DefaultQuantity), "buy");      
                }
                
                if (CrossBelow(FastMAPlot, SlowMAPlot, 1))
                {
                    EnterShort(Convert.ToInt32(DefaultQuantity), "sell");
                }
            }            
    
            }    
    }
    ​
    But it does not work as I want. What did I do wrong? I hope for your kind help. Thanks.
    Last edited by truepenny; 05-06-2024, 03:50 AM.

    #2
    Hello,

    Implementing a step-by-step stop loss in NinjaTrader as you described is definitely possible. It seems you're attempting to adjust the stop loss dynamically based on the price reaching certain levels after the entry. Let’s review some key parts of your existing code and suggest corrections to ensure it functions as intended.
    1. ExitLongMIT/ExitShortMIT Usage: You're using the ExitLongMIT and ExitShortMIT (market if touched) methods to adjust your stop loss. Instead, you should use the SetStopLoss method which is more suitable for adjusting stop losses dynamically as the price moves.
    2. Commented Out SetStopLoss: The SetStopLoss methods are commented out. If you want to dynamically manage the stop loss, these should be actively managed within your logic.
    3. Handling of Price Levels: You are correctly calculating the new stop loss levels but not effectively applying them.
    ​Here is a corrected approach, focusing on a dynamic stop loss adjustment for long positions (you can mirror this logic for short positions):

    Code:
    protected override void OnBarUpdate()
    {
        if (BarsInProgress != 0 || CurrentBars[0] < SlowMA) return;
    
        // Assuming entry logic is defined elsewhere
    
        // If a long position is open, allow for stop loss modification
        if (Position.MarketPosition == MarketPosition.Long)
        {
            double newStopLossLevel = Position.AveragePrice; // Default to entry price for safety
    
            // Adjust stop loss as price reaches new thresholds
            if (Close[0] > Position.AveragePrice + MoveTSToLong * TickSize)
                newStopLossLevel = Position.AveragePrice + MoveTSAfterLong * TickSize;
            if (Close[0] > Position.AveragePrice + MoveTSToLong2nd * TickSize)
                newStopLossLevel = Position.AveragePrice + MoveTSAfterLong2nd * TickSize;
            if (Close[0] > Position.AveragePrice + MoveTSToLong3rd * TickSize)
                newStopLossLevel = Position.AveragePrice + MoveTSAfterLong3rd * TickSize;
    
            // Apply the new stop loss level
            SetStopLoss("Long", CalculationMode.Price, newStopLossLevel, false);
        }
    }
    ​
    Please let us know if you have any further questions.
    Ryan S.NinjaTrader Customer Service

    Comment


      #3
      Hello, Ryan. Thanks very much for your reply.
      But I have more questions.

      As already I mentioned, there are initial SL and TP.
      Where and how do you set it up?
      Is it correct to set it in if (State == State.Configure){}?
      Or is it correct to set it when entering a position in OnBarUpdate(){}?

      And I understand that when using SetStopLoss(), the initial SL and TP must be reset when the position is flat.
      Do you think your code will work even if the initial loss and profit are set to 0 (my strategy ignores ST if when 0)?
      (I mean when using the input of my code)

      I have commented out all SetStopLoss() calls.
      That's because I saw somewhere here that once you set the initial SL and TP, you can't manage it dynamically.
      Please be more careful to make my code work.
      Salute to your kind service!​

      **Please let me know if my question is not clear.
      Last edited by truepenny; 05-06-2024, 08:54 AM.

      Comment


        #4
        When working with initial Stop Loss (SL) and Take Profit (TP) in NinjaTrader using NinjaScript, it's important to understand the lifecycle and when to set these values. Setting Initial SL and TP
        1. In State.Configure: This state is ideal for setting initial parameters that apply to the entire strategy and don't need to change dynamically based on market data. If your SL and TP are fixed throughout the lifetime of any position, you can set them here. However, typically in dynamic trading strategies, these values might change as the market moves, so setting them up initially in State.Configure is not always flexible enough.
        2. In OnBarUpdate(): This method is called on every tick or at the close of every bar (depending on the Calculate setting). Setting your SL and TP here gives you the flexibility to adjust these values dynamically based on new market conditions. This is the preferred location if your SL and TP need to adjust based on the strategy's entry points or if they are calculated dynamically.
        Dynamic SL and TP Management


        You mentioned that once SL and TP are set, they cannot be managed dynamically. This isn't entirely accurate. With NinjaTrader, you can modify SL and TP at any time during the life of a position using methods like SetStopLoss() and SetProfitTarget(). What is crucial is that any changes to these orders need to be handled correctly to ensure that they are updated and not just added on top of the existing orders. Resetting SL and TP


        If you need to reset the SL and TP when positions are flat, you would typically handle this within OnBarUpdate() by checking Position.MarketPosition == MarketPosition.Flat. However, setting them to 0 might not be the most appropriate unless your strategy explicitly uses 0 as a flag to disable SL or TP. Instead, you might consider setting them to a sensible default or recalculating based on the new entry conditions. Example Code


        Here’s how you might handle setting initial SL and TP dynamically upon entry and resetting them:

        Code:
        protected override void OnBarUpdate()
        {
            // Entry logic, assume we're entering long
            if (ShouldEnterLong())
            {
                EnterLong("LongEntry"); // Enters a long position with a unique identifier
        
                // Set initial SL and TP dynamically
                SetStopLoss("LongEntry", CalculationMode.Ticks, InitialStopLossTicks, false);
                SetProfitTarget("LongEntry", CalculationMode.Ticks, InitialProfitTargetTicks);
            }
        
            // Reset SL and TP when no position is held
            if (Position.MarketPosition == MarketPosition.Flat)
            {
                // Here you might choose to reset them to a default or disable by setting to 0 or using another method
                // Example: Disabling SL and TP
                if (InitialStopLossTicks == 0 || InitialProfitTargetTicks == 0)
                {
                    DisableStopLoss();
                    DisableProfitTarget();
                }
            }
        
            // Dynamic adjustment of SL and TP can be handled similarly by calling SetStopLoss and SetProfitTarget with new values
        }
        
        private void DisableStopLoss()
        {
            SetStopLoss("LongEntry", CalculationMode.Ticks, 0, false);
        }
        
        private void DisableProfitTarget()
        {
            SetProfitTarget("LongEntry", CalculationMode.Ticks, 0);
        }
        
        private bool ShouldEnterLong()
        {
            // Your logic to determine if a long entry should occur
            return CrossAbove(SMA(20), SMA(50), 1);
        }
        ​
        • Initial SL and TP are set right after the entry order is placed.
        • If your strategy logic sets these values to 0 for disabling, additional methods (DisableStopLoss and DisableProfitTarget) handle these cases.
        • This approach allows for dynamic management of SL and TP based on changing market conditions or strategy phases.

        Remember, this is just a template, and the exact implementation would depend heavily on the specifics of your trading strategy and logic
        Ryan S.NinjaTrader Customer Service

        Comment


          #5
          Thanks for your kind reply.
          Its becoming increasingly clear.
          I have one more.

          Code:
                  if (State == State.Configure){}
          
          ...
          
                  protected override void OnBarUpdate()
                  {
          
                      // Resets the stop loss to the original value when all positions are closed
                      if (Position.MarketPosition == MarketPosition.Flat)
                      {
          //                if (TakeProfitLong > 0)
          //                    SetProfitTarget("buy", CalculationMode.Ticks, TakeProfitLong);
          //                if (StopLossLong > 0)
          //                    SetStopLoss("buy", CalculationMode.Ticks, StopLossLong, false);
          //                if (TakeProfitShort > 0)
          //                    SetProfitTarget("sell", CalculationMode.Ticks, TakeProfitShort);
          //                if (StopLossShort > 0)
          //                    SetStopLoss("sell", CalculationMode.Ticks, StopLossShort, false);    
                      }
          
                      // If a long position is open, allow for stop loss modification to breakeven
                      if (Position.MarketPosition == MarketPosition.Long)
                      {                
                         double newStopLossLevel = Position.AveragePrice; // Default to entry price for safety
          
                        // Adjust stop loss as price reaches new thresholds
                        if (Close[0] > Position.AveragePrice + MoveTSToLong * TickSize)
                               newStopLossLevel = Position.AveragePrice + MoveTSAfterLong * TickSize;
                        if (Close[0] > Position.AveragePrice + MoveTSToLong2nd * TickSize)
                               newStopLossLevel = Position.AveragePrice + MoveTSAfterLong2nd * TickSize;
                        if (Close[0] > Position.AveragePrice + MoveTSToLong3rd * TickSize)
                               newStopLossLevel = Position.AveragePrice + MoveTSAfterLong3rd * TickSize;
          
                        // Apply the new stop loss level
                               SetStopLoss("Long", CalculationMode.Price, newStopLossLevel, false);​
                      }
          
                      // create position            
                      if (CrossAbove(FastMAPlot, SlowMAPlot, 1))
                      {
                          EnterLong(Convert.ToInt32(DefaultQuantity), "buy");
                          if (TakeProfitLong > 0)
                              SetProfitTarget("buy", CalculationMode.Ticks, TakeProfitLong);
                          if (StopLossLong > 0)
                              SetStopLoss("buy", CalculationMode.Ticks, StopLossLong, false);
                      }
                  }            
                  
          }
          ​
          SetStopLoss() only works if StopLossLong is greater than 0 when you create the position as you can see.
          If we assume it is 0, there is a problem with it keeping after SetStopLoss() is triggered in if (Position.MarketPosition == MarketPosition.Long) {}.
          In that case, how should I initialize SetStopLoss() in if (Position.MarketPosition == MarketPosition.Flat){}?​

          Comment


            #6
            To initialize the SetStopLoss() method properly when all positions are closed (i.e., when the market position is flat), you can set up the initial stop loss settings directly within the block where you check for a flat position. Here's how you can modify the code:​

            Code:
            protected override void OnBarUpdate()
            {
                // Resets the stop loss to the original value when all positions are closed
                if (Position.MarketPosition == MarketPosition.Flat)
                {
                    if (StopLossLong > 0)
                        SetStopLoss("buy", CalculationMode.Ticks, StopLossLong, false);
                    if (StopLossShort > 0)
                        SetStopLoss("sell", CalculationMode.Ticks, StopLossShort, false);
                }
            
                // Existing code for other conditions
            }
            ​
            This code snippet ensures that the stop loss for both long and short positions is set immediately when the position is closed and the market position returns to flat. This is critical to ensure that the stop loss is correctly re-established when a new position is entered after all positions have been closed.
            Ryan S.NinjaTrader Customer Service

            Comment

            Latest Posts

            Collapse

            Topics Statistics Last Post
            Started by smartromain, Today, 02:52 AM
            0 responses
            4 views
            0 likes
            Last Post smartromain  
            Started by Marklhc1988, 04-19-2023, 11:11 AM
            12 responses
            569 views
            1 like
            Last Post victor68133  
            Started by nicthe, Yesterday, 02:58 PM
            1 response
            9 views
            0 likes
            Last Post nicthe
            by nicthe
             
            Started by percy3687, 05-17-2024, 12:28 AM
            3 responses
            30 views
            0 likes
            Last Post percy3687  
            Started by SilverSurfer1, Yesterday, 01:33 PM
            0 responses
            13 views
            0 likes
            Last Post SilverSurfer1  
            Working...
            X