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

DataSeries.Count

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

    DataSeries.Count

    I am new to Ninja, and trying to fully understand how MaximumBarsLookBack works.

    To that effect, I created a simple indicator with a private DataSeries SS_State which was initialized this way (in Initialize()):

    SS_State = new DataSeries(this, MaximumBarsLookBack.TwoHundredFiftySix);


    Then, in OnBarUpdate(), I query the oldest value in SS_State:

    Print("BAR# " + CurrentBar + " ; SS_State[SS_State.Count-1] = " + SS_State[SS_State.Count-1]);


    This generates the following exception:
    Exception BAR# 2546 : System.ArgumentException: barsAgo needed to be between 0 and 255 but was 2546

    It turns out that SS_State.Count returns values up to CurrentBar, where I was expecting it to return values up to 256 (since that object was created with a max 256 bars LookBack.).

    Is this a bug? If not, how can I assess the number of datapoints in a DataSeries object?

    Thanks in advance

    #2
    Hello,

    Welcome to the forum! Thanks for the post. I am happy to help.

    The “MaximumBarsLookBack” is basically the maximum size that the data series will be allowed to be when looking back in historical data for your calculation in “OnBarUpdate()”. The data series will still be built up from the first bar on the chart. This is to help with the memory performance aspect of NinjaTrader. Whereas “count” is the total number of bars in a data series.

    Example: If you have a “1 Min” chart and the “Days to load” is set to “1” then you could possibly have up to 1440 total bars (“count”) or more on that chart, because there are 60 minutes in 1 hour and 24 hours in a day (60x24=1440). Starting from the start date at 12:00AM or 00:00 would be Bar 0 and 00:01 would be Bar 1. So “count” could possibly be up to 1440, and “CurrentBar” would only be up to 255 removing the oldest elements first.

    If you wanted to access a certain point in your Data Series you can use the Bracket symbols ‘[]’ access how many bars ago you want to access that data. Example: “SS_State[1]” would mean that you want to access SS_State data 1 bar ago, or if you want the current bar you can set it to 0.

    If you still are having some issues, post a code sample that you are working on so that we may take a look at it.

    For more information about "MaximumBarsLookBack" you may read our online help guide at the following link.


    For more information about "Count" you may read our online help guide at the following link.


    Make sure you have enough bars in the data series you are accessing. For more information you may view the following link.


    Please let me know if I can be of further assistance.
    JCNinjaTrader Customer Service

    Comment


      #3
      I am wondering if you read my post past the 1st sentence ?!

      Let me be more specific then: Amongst others, Count is a property of the DataSeries class. I was expecting it to return the number of datapoints in a particular instance of that class, however it seems to be always returning the total number of bars (minus 1) in the chart.

      If this is not a bug, then what is the way to know the number of datapoints in a DataSeries object? My problem is, when that DataSeries object is constrained by a MaximumBarsLookBack = 256, I cannot look for values past [255], so I'd better know that in advance, don't you think?

      As for an example, there you go:

      // This namespace holds all indicators and is required. Do not change it.
      namespace NinjaTrader.Indicator
      {
      /// <summary>
      /// Enter the description of your new custom indicator here
      /// </summary>
      [Description("Enter the description of your new custom indicator here")]
      public class TestIndicator : Indicator
      {
      #region Variables
      // Wizard generated variables
      // User defined variables (add any user defined variables below)
      private DataSeries aDataSerie;
      #endregion

      /// <summary>
      /// This method is used to configure the indicator and is called once before any bar data is loaded.
      /// </summary>
      protected override void Initialize()
      {
      Add(new Plot(Color.FromKnownColor(KnownColor.Orange), PlotStyle.Line, "Plot0"));
      Overlay = false;
      aDataSeries = new DataSeries(this, MaximumBarsLookBack.TwoHundredFiftySix);
      }

      /// <summary>
      /// Called on each bar update event (incoming tick)
      /// </summary>
      protected override void OnBarUpdate()
      {
      // Use this method for calculating your indicator values. Assign a value to each
      // plot below by replacing 'Close[0]' with your own formula.
      aDataSeries.Set( Close[0] );

      try
      {
      /* For this example sake I am trying to plot the 1st value (back in time)
      present in the "aDataSeries" object */
      Plot0.Set( aDataSeries[ aDataSeries.Count - 1] );
      }
      catch (Exception e)
      {
      Print("BAR# " + CurrentBar + " " + e.ToString());
      }

      }

      #region Properties
      [Browsable(false)] // this line prevents the data series from being displayed in the indicator properties dialog, do not remove
      [XmlIgnore()] // this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
      public DataSeries Plot0
      {
      get { return Values[0]; }
      }

      #endregion
      }
      }

      Comment


        #4
        Dom,

        This is to be expected. The DataSeries.Count returns the total number of times this series had an element added to it. MaximumBarsLookback will cause secondary added series to max out at 256 elements. It will remove the oldest elements but will not reset the count.

        There are only two options for MaximumBarsLookback. If its set to "Infinite", then the count will accurately report the size of this data series. If it is set to 256, beyond 256 elements cannot be accessed even though the count is increasing beyond this number. You can check to ensure you aren't accessing an invalid index by checking the following :

        if( MaximumBarsLookBack == MaximumBarsLookBack.TwoHundredFiftySix && MySeries.Count>=255)
        {
        last_element = 255;
        }
        else
        {
        last_element = MySeries.Count;
        }

        It's important to note however, that data series that are plots are overridden and essentially have MaximumBarsLookback set to infinite. This is so that the indicator plots will show up on your charts for all historical data.

        Please let us know if we may assist further.
        Adam P.NinjaTrader Customer Service

        Comment


          #5
          Adam,

          Thank you, this is making progress ... I still have questions, if you don't mind:

          I understand that a DataSeries object can be created to cap the number of datapoints maintained to 256, for example:

          aDataSeries = new DataSeries( this, MaximumBarsLookBack.TwoHundredFifySix);

          when I later use that object, MaximumBarsLookBack refers to current active instance (for simplicity, the TestIndicator I am using for this example), which might very well have its own MaximumBarsLookBack set to Infinite.

          When I use the test you suggested, I still get an error, because I cannot access the MaximumBarsLookBack value specific to the aDataSeries object.


          Here is the example: (of course, the example is to explain my point)

          namespace NinjaTrader.Indicator
          {
          /// <summary>
          /// Enter the description of your new custom indicator here
          /// </summary>
          [Description("Enter the description of your new custom indicator here")]
          public class TestIndicator : Indicator
          {
          #region Variables
          // Wizard generated variables
          // User defined variables (add any user defined variables below)
          private DataSeries aDataSeries;
          #endregion

          /// <summary>
          /// This method is used to configure the indicator and is called once before any bar data is loaded.
          /// </summary>
          protected override void Initialize()
          {
          Add(new Plot(Color.FromKnownColor(KnownColor.Orange), PlotStyle.Line, "Plot0"));
          Overlay = false;
          MaximumBarsLookBack = MaximumBarsLookBack.Infinite;
          aDataSeries = new DataSeries( this, MaximumBarsLookBack.TwoHundredFiftySix);
          }

          /// <summary>
          /// Called on each bar update event (incoming tick)
          /// </summary>
          protected override void OnBarUpdate()
          {
          // Use this method for calculating your indicator values. Assign a value to each
          // plot below by replacing 'Close[0]' with your own formula.
          aDataSeries.Set( Close[0] );

          try
          {
          /* For this example sake I am trying to plot the 1st value (back in time)
          present in the "aDataSeries" object */
          if( MaximumBarsLookBack == MaximumBarsLookBack.TwoHundredFiftySix && aDataSeries.Count>= 255)
          Plot0.Set( aDataSeries[ 255 ] );
          else
          Plot0.Set( aDataSeries[ aDataSeries.Count - 1] );

          }
          catch (Exception e)
          {
          Print("BAR# " + CurrentBar + " " + e.ToString());
          }
          }

          #region Properties
          [Browsable(false)] // this line prevents the data series from being displayed in the indicator properties dialog, do not remove
          [XmlIgnore()] // this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
          public DataSeries Plot0
          {
          get { return Values[0]; }
          }

          #endregion
          }
          }

          Comment


            #6
            To add to my prior post ... I revisited the example ; I created a new class (TestDataSeries) derived from DataSeries, which simply keeps track of the MaximumBarsLookBack as provided to the constructor.
            With this workaround, I can do what you suggested earlier.

            Now the question is, why do I have to create a workaround for this ???

            namespace NinjaTrader.Indicator
            {
            /// <summary>
            /// Enter the description of your new custom indicator here
            /// </summary>
            public class TestDataSeries : DataSeries
            {
            private MaximumBarsLookBack _MaximumBarsLookBack;

            public TestDataSeries( IndicatorBase ib, MaximumBarsLookBack m)
            : base( ib, m)
            {
            _MaximumBarsLookBack = m;
            }

            public MaximumBarsLookBack MaximumBarsLookBack()
            {
            return _MaximumBarsLookBack;
            }
            }

            [Description("Enter the description of your new custom indicator here")]
            public class TestIndicator : Indicator
            {
            #region Variables
            // Wizard generated variables
            // User defined variables (add any user defined variables below)
            private TestDataSeries aDataSeries;
            #endregion

            /// <summary>
            /// This method is used to configure the indicator and is called once before any bar data is loaded.
            /// </summary>
            protected override void Initialize()
            {
            Add(new Plot(Color.FromKnownColor(KnownColor.Orange), PlotStyle.Line, "Plot0"));
            Overlay = false;
            MaximumBarsLookBack = MaximumBarsLookBack.Infinite;
            aDataSeries = new TestDataSeries( this, MaximumBarsLookBack.TwoHundredFiftySix);
            }

            /// <summary>
            /// Called on each bar update event (incoming tick)
            /// </summary>
            protected override void OnBarUpdate()
            {
            // Use this method for calculating your indicator values. Assign a value to each
            // plot below by replacing 'Close[0]' with your own formula.
            aDataSeries.Set( Close[0] );

            try
            {
            /* For this example sake I am trying to plot the 1st value (back in time)
            present in the "aDataSeries" object */
            if( aDataSeries.MaximumBarsLookBack() == MaximumBarsLookBack.TwoHundredFiftySix && aDataSeries.Count>= 255)
            Plot0.Set( aDataSeries[ 255 ] );
            else
            Plot0.Set( aDataSeries[ aDataSeries.Count - 1] );

            }
            catch (Exception e)
            {
            Print("BAR# " + CurrentBar + " " + e.ToString());
            }
            }

            #region Properties
            [Browsable(false)] // this line prevents the data series from being displayed in the indicator properties dialog, do not remove
            [XmlIgnore()] // this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
            public DataSeries Plot0
            {
            get { return Values[0]; }
            }

            #endregion
            }
            }

            Comment


              #7
              Hello,

              This is Brett further assisting for Adam.

              Lets reset here to make sure we are on same page before moving forward.

              aDataSeries = new TestDataSeries( this, MaximumBarsLookBack.TwoHundredFiftySix);

              The question is why specifically are you using this and instancing out a data Series object. You do not need to do this in NinjaScript if all you need to do is host a secondary indicator in your indicator/strategy and how do this by calling the indicator name and its index value(SMA(14)[0]. NinjaTrader will automatically sync it to what the master indicator is that is hosting it. If the master is infinite then the secondary will be infinite and vice versa. If you need to define your own DataSeries object to store calculations then tt is not advisable to define your own hard coded lookback period as you want everything to match between the indicator/strategy and its hosted indicator so that you do not run into any strange issues. That may be the solution in the end for you is to not define your own Maximum bars look back. We have the same issue with users that manually set calculate on bar close and having on bar close on a primary be set to true and on a hosted be hard set to false and then you run into syncing issues.

              -Brett

              Comment


                #8
                Hi Brett,

                Thanks for jumping in ... to answer your question about "why" would I do that, it is a matter of memory preservation ... I am working on a pretty complex indicator, which need many intermediate calculations (and their history), some of which don't need more than a few bars worth of history, while others need pretty much the entire chart worth of history.

                Of course, using MaximumBarsLookBack.Infinite for all these intermediate calculations would be a way to do it, at the expense of lots of memory, which is a real concern.

                So I am trying to use NinjaTrader 7 advanced memory management, to the best of its abilities.

                Comment


                  #9
                  I see, thanks for the clarification.

                  You can deploy the workaround this should do the trick however by default with NinjaTrader we expect the hosted indicator and the primary indicator to have the same settings. COBC and MaximumBarsLookBack.

                  -Brett

                  Comment

                  Latest Posts

                  Collapse

                  Topics Statistics Last Post
                  Started by DJ888, 04-16-2024, 06:09 PM
                  3 responses
                  10 views
                  0 likes
                  Last Post NinjaTrader_Erick  
                  Started by RookieTrader, Today, 07:41 AM
                  0 responses
                  3 views
                  0 likes
                  Last Post RookieTrader  
                  Started by maybeimnotrader, Yesterday, 05:46 PM
                  1 response
                  18 views
                  0 likes
                  Last Post NinjaTrader_ChelseaB  
                  Started by Perr0Grande, Yesterday, 08:16 PM
                  1 response
                  7 views
                  0 likes
                  Last Post NinjaTrader_Jesse  
                  Started by f.saeidi, Yesterday, 08:12 AM
                  3 responses
                  27 views
                  0 likes
                  Last Post NinjaTrader_Jesse  
                  Working...
                  X