Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Stop loss seems inconsistent

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

    Stop loss seems inconsistent

    I have a test strategy built with the wizard. Using FXCM's data for JPN225, I have attached the trades output.

    I don't understand why the stop loss is inconsistent, ranging from -200 to -3000.

    Below is the script of the wizard created strategy:


    ========== START ==============


    // This namespace holds all strategies and is required. Do not change it.
    namespace NinjaTrader.Strategy
    {
    /// <summary>
    /// Enter the description of your strategy here
    /// </summary>
    [Description("Enter the description of your strategy here")]
    public class MyCustomStrategy2 : Strategy
    {
    #region Variables
    // Wizard generated variables
    private int barsUp = 5; // Default setting for BarsUp
    private int barsDown = 5; // Default setting for BarsDown
    private int sL = 20; // Default setting for SL
    private int buySellSig = 1; // Default setting for BuySellSig
    // User defined variables (add any user defined variables below)
    #endregion

    /// <summary>
    /// This method is used to configure the strategy and is called once before any strategy method is called.
    /// </summary>
    protected override void Initialize()
    {
    SetStopLoss("NBarsUp", CalculationMode.Ticks, SL, false);
    SetStopLoss("NBarsDown", CalculationMode.Ticks, SL, false);

    CalculateOnBarClose = false;
    }

    /// <summary>
    /// Called on each bar update event (incoming tick)
    /// </summary>
    protected override void OnBarUpdate()
    {
    // Condition set 1
    if (NBarsUp(BarsUp, true, false, false)[0] == BuySellSig)
    {
    EnterLong(DefaultQuantity, "NBarsUp");
    ExitShort("NBarsDown", "NBarsDown");
    }

    // Condition set 2
    if (NBarsDown(BarsDown, true, false, false)[0] == BuySellSig)
    {
    EnterShort(DefaultQuantity, "NBarsDown");
    ExitLong("NBarsUp", "NBarsUp");
    }
    }

    #region Properties
    [Description("BarsUp")]
    [GridCategory("Parameters")]
    public int BarsUp
    {
    get { return barsUp; }
    set { barsUp = Math.Max(0, value); }
    }

    [Description("BarsDown")]
    [GridCategory("Parameters")]
    public int BarsDown
    {
    get { return barsDown; }
    set { barsDown = Math.Max(0, value); }
    }

    [Description("Stop loss")]
    [GridCategory("Parameters")]
    public int SL
    {
    get { return sL; }
    set { sL = Math.Max(0, value); }
    }

    [Description("If buy / sell signals equal this...")]
    [GridCategory("Parameters")]
    public int BuySellSig
    {
    get { return buySellSig; }
    set { buySellSig = Math.Max(1, value); }
    }
    #endregion
    }
    }


    ========== END ===========
    Attached Files

    #2
    James,

    Thank you for your post.

    Could you please attach a screenshot of the back test with the dates that are showing the incorrect StopLoss exit value?

    To send a screenshot press Alt + PRINT SCREEN to take a screen shot of the selected window. Then go to Start--> Accessories--> Paint, and press CTRL + V to paste the image. Lastly, save as a jpeg file, Click Reply -> Go Advanced -> Click the Paperclip Icon in the toolbar.

    For detailed instructions please visit the following link

    http://take-a-screenshot.org/
    Cal H.NinjaTrader Customer Service

    Comment


      #3
      Here it is...

      I've sorted it with the greatest loss at the top. The .csv I attached with my first post had all this information too.
      Attached Files

      Comment


        #4
        James,

        What I wanted was the chart and bars and where the discrepancy was.
        However, I was able to take your code and apply it on my end.

        What the issue here is the gap in the price from one bar to the next.

        Take a look at screenshot attached at the first order.

        What you will see is the small gap from the last bar before the StopLoss to the bar of the StopLoss. Additionally, with this jump in price the Exit order filled out at the open price that would be expected as in a live market.

        This is more than likely why some of your StopLosses have higher losses than the assigned 20 ticks.
        Attached Files
        Cal H.NinjaTrader Customer Service

        Comment


          #5
          OK. So how best to get round the gapping of stop losses? Have 3 at different levels?

          Comment


            #6
            Cal

            I'm afraid I'm still not seeing what's not working here.

            On the attached screen shots a long position was taken at 15198 on 11/03/2014, at 13:22:00 hrs. Image Clipboard02.jpg is a zoomed in view of the chart price action of Clipboard01.jpg.

            At 14746 on 12/03/2014, 09:31:00 hrs it was stopped out.

            Also from the screen shot you will see I have 3 stop loss levels set:
            SL = 20 ticks
            SL_fail_safe1 = 80 ticks
            SL_fail_safe2 = 200 ticks

            From the price action it looks to me as if SL should have been triggered, but wasn't.

            Can you explain where I'm going wrong?
            Attached Files

            Comment


              #7
              James,

              How did you set these new SetStopLoss() in your script?
              Cal H.NinjaTrader Customer Service

              Comment


                #8
                Cal

                Here's the code:


                /// <summary>
                /// Enter the description of your strategy here
                /// </summary>
                [Description("Enter the description of your strategy here")]
                public class MyCustomStrategy2 : Strategy
                {
                #region Variables
                // Wizard generated variables
                private int barsUp = 5; // Default setting for BarsUp
                private int barsDown = 5; // Default setting for BarsDown
                private int sL = 20; // Default setting for SL
                private int buySellSig = 1; // Default setting for BuySellSig
                private int sL_fail_safe1 = 30; // Default setting for SL_fail_safe1
                private int sL_fail_safe2 = 40; // Default setting for SL_fail_safe2
                // User defined variables (add any user defined variables below)
                #endregion

                /// <summary>
                /// This method is used to configure the strategy and is called once before any strategy method is called.
                /// </summary>
                protected override void Initialize()
                {
                SetStopLoss("NBarsUp", CalculationMode.Ticks, SL, false);
                SetStopLoss("NBarsDown", CalculationMode.Ticks, SL, false);
                SetStopLoss("NBarsUp", CalculationMode.Ticks, SL_fail_safe1, false);
                SetStopLoss("NBarsDown", CalculationMode.Ticks, SL_fail_safe1, false);
                SetStopLoss("NBarsUp", CalculationMode.Ticks, SL_fail_safe2, false);
                SetStopLoss("NBarsDown", CalculationMode.Ticks, SL_fail_safe2, false);

                CalculateOnBarClose = false;
                }

                /// <summary>
                /// Called on each bar update event (incoming tick)
                /// </summary>
                protected override void OnBarUpdate()
                {
                // Condition set 1
                if (NBarsUp(BarsUp, true, false, false)[0] == BuySellSig)
                {
                EnterLong(DefaultQuantity, "NBarsUp");
                ExitShort("NBarsDown", "NBarsDown");
                }

                // Condition set 2
                if (NBarsDown(BarsDown, true, false, false)[0] == BuySellSig)
                {
                EnterShort(DefaultQuantity, "NBarsDown");
                ExitLong("NBarsUp", "NBarsUp");
                }
                }

                #region Properties
                [Description("BarsUp")]
                [GridCategory("Parameters")]
                public int BarsUp
                {
                get { return barsUp; }
                set { barsUp = Math.Max(0, value); }
                }

                [Description("BarsDown")]
                [GridCategory("Parameters")]
                public int BarsDown
                {
                get { return barsDown; }
                set { barsDown = Math.Max(0, value); }
                }

                [Description("Stop loss")]
                [GridCategory("Parameters")]
                public int SL
                {
                get { return sL; }
                set { sL = Math.Max(0, value); }
                }

                [Description("If buy / sell signals equal this...")]
                [GridCategory("Parameters")]
                public int BuySellSig
                {
                get { return buySellSig; }
                set { buySellSig = Math.Max(1, value); }
                }

                [Description("")]
                [GridCategory("Parameters")]
                public int SL_fail_safe1
                {
                get { return sL_fail_safe1; }
                set { sL_fail_safe1 = Math.Max(0, value); }
                }

                [Description("")]
                [GridCategory("Parameters")]
                public int SL_fail_safe2
                {
                get { return sL_fail_safe2; }
                set { sL_fail_safe2 = Math.Max(0, value); }
                }
                #endregion
                }
                }

                Comment


                  #9
                  James,

                  You are submitting multiple instances of the StopLoss() for the NBarsDown and Up

                  With the Set() orders, it will use the last one that is submitted for the StopLoss, in this case, the 200 tick SL that you are setting will be applied to all orders with Entry signal of NBarsDown or NBarsUp
                  Code:
                  SetStopLoss("NBarsUp", CalculationMode.Ticks, SL_fail_safe2, false);
                  SetStopLoss("NBarsDown", CalculationMode.Ticks, SL_fail_safe2, false);
                  Cal H.NinjaTrader Customer Service

                  Comment


                    #10
                    OK. Thanks. So... there is no way of setting a stop loss and a further fail safe stop loss to cope with possible gapping?

                    Comment


                      #11
                      James,

                      You would need to use the Unmanaged approach for that kind of exiting.

                      This would require unlocking the code to manually code this.

                      Please understand that this kind of gapping with the CFD can happen in the live and are subject to the same kind of fills as you are seeing in the backtest.
                      Cal H.NinjaTrader Customer Service

                      Comment


                        #12
                        Cal

                        I'm sorry to be on again, but the stop loss thing is really eluding me.

                        To try to get around the gapping problem, I decided to try setting a trailing stop loss by price using the MAEnvelope indicator. I think I've managed to place the price level of the upper line of the MAEnvelope indicator in Variable0 and the lower in Variable1, at the point when the position is opened.

                        On the attached chart you'll see a BarsDown entry was made on 12/12/14 at 04:15 hrs. Using the cross-hairs, it looks like that at 05:11 hrs the trailing stop (started by price on the upper line of the MAEnvelope) was breached, and should, I think, have resulted in a stop loss.

                        Where am I going wrong?

                        The amended code is as follows:



                        #region Using declarations
                        using System;
                        using System.ComponentModel;
                        using System.Diagnostics;
                        using System.Drawing;
                        using System.Drawing.Drawing2D;
                        using System.Xml.Serialization;
                        using NinjaTrader.Cbi;
                        using NinjaTrader.Data;
                        using NinjaTrader.Indicator;
                        using NinjaTrader.Gui.Chart;
                        using NinjaTrader.Strategy;
                        #endregion

                        // This namespace holds all strategies and is required. Do not change it.
                        namespace NinjaTrader.Strategy
                        {
                        /// <summary>
                        /// Enter the description of your strategy here
                        /// </summary>
                        [Description("Enter the description of your strategy here")]
                        public class MyCustomStrategy2 : Strategy
                        {
                        #region Variables
                        // Wizard generated variables
                        private int barsUp = 5; // Default setting for BarsUp
                        private int barsDown = 5; // Default setting for BarsDown
                        private double sLMAEnvPercent = 0.2; // Default setting for SLMAEnvPercent
                        private int buySellSig = 1; // Default setting for BuySellSig
                        // User defined variables (add any user defined variables below)
                        #endregion

                        /// <summary>
                        /// This method is used to configure the strategy and is called once before any strategy method is called.
                        /// </summary>
                        protected override void Initialize()
                        {
                        Add(MAEnvelopes(SLMAEnvPercent, 3, 14));
                        Add(MAEnvelopes(SLMAEnvPercent, 3, 14));
                        SetTrailStop("NBarsUp", CalculationMode.Price, Variable0, false);
                        SetTrailStop("NBarsDown", CalculationMode.Price, Variable1, false);

                        CalculateOnBarClose = false;
                        }

                        /// <summary>
                        /// Called on each bar update event (incoming tick)
                        /// </summary>
                        protected override void OnBarUpdate()
                        {
                        // Condition set 1
                        if (NBarsUp(BarsUp, true, false, false)[0] == BuySellSig)
                        {
                        EnterLong(DefaultQuantity, "NBarsUp");
                        ExitShort("NBarsDown", "NBarsDown");
                        Variable0 = MAEnvelopes(SLMAEnvPercent, 3, 14).Lower[0];
                        }

                        // Condition set 2
                        if (NBarsDown(BarsDown, true, false, false)[0] == BuySellSig)
                        {
                        EnterShort(DefaultQuantity, "NBarsDown");
                        ExitLong("NBarsUp", "NBarsUp");
                        Variable1 = MAEnvelopes(SLMAEnvPercent, 3, 14).Upper[0];
                        }
                        }

                        #region Properties
                        [Description("BarsUp")]
                        [GridCategory("Parameters")]
                        public int BarsUp
                        {
                        get { return barsUp; }
                        set { barsUp = Math.Max(0, value); }
                        }

                        [Description("BarsDown")]
                        [GridCategory("Parameters")]
                        public int BarsDown
                        {
                        get { return barsDown; }
                        set { barsDown = Math.Max(0, value); }
                        }

                        [Description("Stop loss")]
                        [GridCategory("Parameters")]
                        public double SLMAEnvPercent
                        {
                        get { return sLMAEnvPercent; }
                        set { sLMAEnvPercent = Math.Max(0, value); }
                        }

                        [Description("If buy / sell signals equal this...")]
                        [GridCategory("Parameters")]
                        public int BuySellSig
                        {
                        get { return buySellSig; }
                        set { buySellSig = Math.Max(1, value); }
                        }
                        #endregion
                        }
                        }
                        Attached Files

                        Comment


                          #13
                          James,

                          We have to understand here that Initialize() only gets called once. Since, these values are not set when Initialize is called they are defaulted to 0. This will cause the Trail Stops to get ignored due to a 0 value, since this would place the Stop Loss at the same price as your entry.

                          If you are wanting to challenge in modifying the Stop Loss in OnBarUpdate() you will want to take a look at the sample below. Again, this more advanced technique will require unlocking the code to do this -
                          http://www.ninjatrader.com/support/f...ead.php?t=3222

                          Let me know if I can be of further assistance.
                          Cal H.NinjaTrader Customer Service

                          Comment


                            #14
                            It doesn't have to be a trailing stop. A fixed one will do.

                            So in the attached screen shot, are you saying Variable0 remains at 0?

                            And are you saying that the wizard has no way of filling Variable0?
                            Attached Files

                            Comment


                              #15
                              James,

                              No. The Trail Stop is getting set in the Initialize(). This only gets called once when you start the strategy.

                              Once that is set you need to call it again in OnBarUpdate() in order to change the Trail Stop value for the Variable0

                              This can only be done by unlocking the code in the Wizard.
                              Cal H.NinjaTrader Customer Service

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by argusthome, 03-08-2026, 10:06 AM
                              0 responses
                              65 views
                              0 likes
                              Last Post argusthome  
                              Started by NabilKhattabi, 03-06-2026, 11:18 AM
                              0 responses
                              41 views
                              0 likes
                              Last Post NabilKhattabi  
                              Started by Deep42, 03-06-2026, 12:28 AM
                              0 responses
                              23 views
                              0 likes
                              Last Post Deep42
                              by Deep42
                               
                              Started by TheRealMorford, 03-05-2026, 06:15 PM
                              0 responses
                              26 views
                              0 likes
                              Last Post TheRealMorford  
                              Started by Mindset, 02-28-2026, 06:16 AM
                              0 responses
                              52 views
                              0 likes
                              Last Post Mindset
                              by Mindset
                               
                              Working...
                              X