Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

Partner 728x90

Collapse

Code commented out still can't find the "outside the bounds of the array."

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

    Code commented out still can't find the "outside the bounds of the array."

    Hi folks,

    Sry about this since I know it's a common newbie mistake...I'm getting the out-of-bounds error but can't figure out why. Commented everything out in my custom indicator except for one print statement that is just a string, and still, the exception is thrown. I don't have a VS license. Any ideas?

    This is from the log panel:

    "okay init we got this far
    8/31/2021 3:00:00 PM hi
    8/31/2021 3:00:00 PM dema is 15609
    Strategy 'SuperTrend': Error on calling 'OnBarUpdate' method on bar 0: Index was outside the bounds of the array."​


    Strategy code:


    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
    
    //This namespace holds Strategies in this folder and is required. Do not change it.
    namespace NinjaTrader.NinjaScript.Strategies
    {
        public class SuperTrend : Strategy
        {
            private DEMA dema;
            private bool moveStop = false;
            private _SuperTrend superTrend;
    
            protected override void OnStateChange()
            {
                if (State == State.SetDefaults)
                {
                    Description                                    = @"Enter the description for your new custom Strategy here.";
                    Name                                        = "SuperTrend";
                    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;
                    // Disable this property for performance gains in Strategy Analyzer optimizations
                    // See the Help Guide for additional information
                    IsInstantiatedOnEachOptimizationIteration    = true;
                }
                else if (State == State.Configure)
                {
                }
                else if (State == State.DataLoaded)
                {
    
                    // Best practice is to instantiate indicators in State.DataLoaded.
                    dema = DEMA(200);
                    superTrend = _SuperTrend(14,3);
                }
            }
    
            protected override void OnBarUpdate()
            {
    
                Print(string.Format("{0} hi", Time[0]));
                Print(string.Format("{0} dema is {1}", Time[0], dema[0]));
    
                // error is thrown at this time, if I comment it out I'll get all print statements
                double ST = superTrend[0];
    
            }
        }
    }
    ​
    Indicator code:



    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.DrawingTools;
    
    #endregion
    
    //This namespace holds Indicators in this folder and is required. Do not change it.
    namespace NinjaTrader.NinjaScript.Indicators
    {
        public class _SuperTrend : Indicator
        {
    //        private ATR atr;
    //        private double currentFinalLowerBand = 0;
    //        private double currentFinalUpperBand = 0;
    //        private double currentBasicUpperBand = 0;
    //        private double currentBasicLowerBand = 0;
    //        private double previousFinalUpperBand = 0;
    //        private double previousFinalLowerBand = 0;
    //        public double currentSuperTrend = 0;
    //        private double previousSuperTrend = 0;
    
            public bool isDownTrend = true;
            protected override void OnStateChange()
            {
                if (State == State.SetDefaults)
                {
                    Description                                    = @"_SuperTrend Bih";
                    Name                                        = "_SuperTrend";
                    Calculate                                    = Calculate.OnBarClose;
                    IsOverlay                                    = false;
                    DisplayInDataBox                            = true;
                    DrawOnPricePanel                            = true;
                    DrawHorizontalGridLines                        = true;
                    DrawVerticalGridLines                        = true;
                    PaintPriceMarkers                            = true;
                    ScaleJustification                            = NinjaTrader.Gui.Chart.ScaleJustification.Right;
                    //Disable this property if your indicator requires custom values that cumulate with each new market data event.
                    //See Help Guide for additional information.
                    IsSuspendedWhileInactive                    = true;
            //        atr = ATR(14);
                    Print(string.Format("okay init we got this far"));
                }
                else if (State == State.Configure)
                {
    
                }
            }
    
            protected override void OnBarUpdate()
            {
    
                 Print("In bar update");
    
            }
    
    //        private void log(TimeSeries time, double basicUpper, double basicLower, double finalUpper, double finalLower, double prevST, double finalST, double high, double low, double close, double atr)
    //        {
    //            Print(string.Format("{0} high {1}", Time[0],  high));
    //            Print(string.Format("{0} low {1}", Time[0],  low));
    //            Print(string.Format("{0} close {1}", Time[0],  close));
    //            Print(string.Format("{0} atr {1}", Time[0],  atr));            
    
    //            Print(string.Format("{0} basic upper {1}", Time[0],  basicUpper));
    //            Print(string.Format("{0} basic lower {1}", Time[0],  basicLower));
    //            Print(string.Format("{0} final upper {1}", Time[0],  finalUpper));
    //            Print(string.Format("{0} final lower {1}", Time[0],  finalLower));
    ////            Print(string.Format("{0} prev ST {1}", Time[0],  prevST));
    
    //            Print(string.Format("{0} current ST {1}", Time[0],  finalST));
    
    //        }
    
            #region Properties
            [NinjaScriptProperty]
            [Range(1, int.MaxValue)]
            [Display(Name="ATRPeriod", Description="ATR Period", Order=1, GroupName="Parameters")]
            public int ATRPeriod
            { get; set; }
    
            [NinjaScriptProperty]
            [Range(1, int.MaxValue)]
            [Display(Name="ATRMultiplier", Description="ATR Multiplier", Order=2, GroupName="Parameters")]
            public int ATRMultiplier
            { get; set; }
            #endregion
    
        }
    }
    
    #region NinjaScript generated code. Neither change nor remove.
    
    namespace NinjaTrader.NinjaScript.Indicators
    {
        public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
        {
            private _SuperTrend[] cache_SuperTrend;
            public _SuperTrend _SuperTrend(int aTRPeriod, int aTRMultiplier)
            {
                return _SuperTrend(Input, aTRPeriod, aTRMultiplier);
            }
    
            public _SuperTrend _SuperTrend(ISeries<double> input, int aTRPeriod, int aTRMultiplier)
            {
                if (cache_SuperTrend != null)
                    for (int idx = 0; idx < cache_SuperTrend.Length; idx++)
                        if (cache_SuperTrend[idx] != null && cache_SuperTrend[idx].ATRPeriod == aTRPeriod && cache_SuperTrend[idx].ATRMultiplier == aTRMultiplier && cache_SuperTrend[idx].EqualsInput(input))
                            return cache_SuperTrend[idx];
                return CacheIndicator<_SuperTrend>(new _SuperTrend(){ ATRPeriod = aTRPeriod, ATRMultiplier = aTRMultiplier }, input, ref cache_SuperTrend);
            }
        }
    }
    
    namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
    {
        public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
        {
            public Indicators._SuperTrend _SuperTrend(int aTRPeriod, int aTRMultiplier)
            {
                return indicator._SuperTrend(Input, aTRPeriod, aTRMultiplier);
            }
    
            public Indicators._SuperTrend _SuperTrend(ISeries<double> input , int aTRPeriod, int aTRMultiplier)
            {
                return indicator._SuperTrend(input, aTRPeriod, aTRMultiplier);
            }
        }
    }
    
    namespace NinjaTrader.NinjaScript.Strategies
    {
        public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
        {
            public Indicators._SuperTrend _SuperTrend(int aTRPeriod, int aTRMultiplier)
            {
                return indicator._SuperTrend(Input, aTRPeriod, aTRMultiplier);
            }
    
            public Indicators._SuperTrend _SuperTrend(ISeries<double> input , int aTRPeriod, int aTRMultiplier)
            {
                return indicator._SuperTrend(input, aTRPeriod, aTRMultiplier);
            }
        }
    }
    
    #endregion
    ​

    #2
    In your strategy, as the first line in OnBarUpdate() try if (CurrentBar < 20) return; // wait until the 20th bar before processing below this line.

    Comment


      #3
      Hello shorty,

      Thank you for your post.

      Although this is a common error, it is usually a simple fix. As Tasker-182 mentioned, it appears that you will simply need to add a CurrentBar check to ensure that the bars you are trying to reference exist before trying to access their values. The line below requires that superTrend[0] has a value, so you will have to make sure there are enough bars on the chart to calculate that value:

      double ST = superTrend[0];

      By adding a CurrentBar check, this should be resolved. Please see the page below for more details:


      Please let us know if we may be of further assistance.
      Emily C.NinjaTrader Customer Service

      Comment


        #4
        Thank you thank you NinjaTrader_Emily and Tasker-182 ! Although I'm still curious - since in the code above the only line in the indicator OnBarUpdate is: Print("In bar update"); So, where is the exception being thrown? I'm glad that I can continue coding now! I'm so rusty in C#, thanks for the support.

        Comment


          #5
          The issue occurs on Bar 0 (in this case) which is the very first bar of the data series. Typically an error will occur when there is a lookback that exceeds the current bar. The SuperTrends indicator requires 14 bars (at least). The CurrentBar check is used to wait until the script has processed x bars before trying to lookback.

          A simple example that would cause an error on Bar 0: If (Close[0] > Close[1]) because there is no previous bar of 1 bars ago, the error would be generated.

          Note that by default, most indicators do not plot until the 20th bar on the chart so in most cases waiting for 20 bars works out.

          Comment


            #6
            Hello shorty and thank you Tasker-182,

            As mentioned, it looks like the indicator requires at least 14 bars because of this line of code:

            superTrend = _SuperTrend(14,3);

            For that period of 14, at least 14 bars must be processed on the chart already. When the indicator starts to process historical data, it will try to run this line of code:
            double ST = superTrend[0];

            If the 14 bars don't exist on the chart yet to get the superTrend value, then you run into the error. If you adjust your OnBarUpdate() logic to the following, it should be successful:

            protected override void OnBarUpdate()
            {

            Print(string.Format("{0} hi", Time[0]));
            Print(string.Format("{0} dema is {1}", Time[0], dema[0]));

            // to prevent the error, check that there are enough bars on the chart before accessing the superTrend[0] value (checking for 14 bars, could be any number greater than that if desired)
            if (CurrentBar < 14)
            return;
            // now this line of code should be successful since there are enough bars on the chart to access superTrend[0]
            double ST = superTrend[0];

            }

            Please don't hesitate to reach out if we may be of further assistance.​
            Emily C.NinjaTrader Customer Service

            Comment


              #7
              Oh interesting - but, the value of 14 is the ATR period - but the ATR instantiation wasn't used. You can see above that it's commented out: // atr = ATR(14);
              So I still don't understand where the exception is thrown. Is it thrown from some base class?

              Comment


                #8
                Hello shorty,

                Thank you for your reply.

                I am pulling that value of 14 from superTrend. At the class level, you create a private _SuperTrend:

                private _SuperTrend superTrend;

                Then in State.DataLoaded you instantiate superTrend as _SuperTrend(14,3):

                else if (State == State.DataLoaded)
                {

                // Best practice is to instantiate indicators in State.DataLoaded.
                dema = DEMA(200);
                superTrend = _SuperTrend(14,3);
                }​

                You may certainly test using the CurrentBar check with different values, but the idea is that if superTrend does not have a value yet at the time that it is referenced in the script, you will get an error. You have to add a check to make sure there are enough bars to calculate a value for superTrend in your script.

                The same idea could be illustrated with the EMA indicator:

                double ST = EMA(14)[0];

                If this were the line in your code, you would get an error unless there are actually 14 bars on the chart for the EMA to make its calculation based on. You would need to add a CurrentBar check as follows:

                if (CurrentBar < 14)
                return:
                double ST = EMA(14)[0];

                I hope this helps to clarify how to make sure you have enough bars in the data series you are accessing. Please let us know if we may be of further assistance.
                Emily C.NinjaTrader Customer Service

                Comment

                Latest Posts

                Collapse

                Topics Statistics Last Post
                Started by funk10101, Today, 09:43 PM
                0 responses
                6 views
                0 likes
                Last Post funk10101  
                Started by pkefal, 04-11-2024, 07:39 AM
                11 responses
                37 views
                0 likes
                Last Post jeronymite  
                Started by bill2023, Yesterday, 08:51 AM
                8 responses
                44 views
                0 likes
                Last Post bill2023  
                Started by yertle, Today, 08:38 AM
                6 responses
                26 views
                0 likes
                Last Post ryjoga
                by ryjoga
                 
                Started by algospoke, Yesterday, 06:40 PM
                2 responses
                24 views
                0 likes
                Last Post algospoke  
                Working...
                X