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

Access data from AddDataSeries

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

    Access data from AddDataSeries

    I intend to develop an indicator which will use data on a different timeframe from the chart, how do I gain access to alternate timeframe data? I am writing a 'daily sma' indicator, I see the 'AddDataSeries' method, but I see no clear way to access the data in this time series. For instance, in this example I see reference to using the Close array, but It is not clear which data this is referring to : the current time frame or the custom one.


    #2
    Hello nentimiglia,

    Thanks for your post.

    The AddDataSeries() method is used to add an additional data series to a NinjaScript. This added series could be a different timeframe or a different instrument.

    An example of adding a Daily data series for the primary instrument would look something like this:

    // Add a Daily Bars object - BarsInProgress index = 1
    AddDataSeries(BarsPeriodType.Day, 1);

    Data could be accessed from the added series by creating a condition checking if the BarsInProgress index processing is equal to the BarsInProgress index of the added series. If we have 1 added series, the series would have a BarsInProgress index of 1.The primary series that the script is running on would have a BarsInProgress index of 0.

    if (BarsInProgress == 1)
    {
    //do something here
    }

    Note that you could use the plural of Open, High, Low, Close, Volume, and Time to get information from the added series. Note that we check for the BarsInProgress index of the series we want to access. In this case, we use an index of 1 to get data from the added Daily series.

    Print("Open of Daily series is " + Opens[1][0]);
    Print("High of Daily series is " + Highs[1][0]);
    Print("Low of Daily series is " + Lows[1][0]);
    Print("Close of Daily series is " + Closes[1][0]);

    See the help guide documentation below for more information about working with multi-timeframe multi-instrument NinjaScripts.

    Working with Multi-Timeframe / Multi-Instrument NinjaScripts: https://ninjatrader.com/support/help...nstruments.htm
    PriceSeries: https://ninjatrader.com/support/help...riceseries.htm

    Also, view the SampleMultiTimeframe and SampleMultiInstrument strategies that come default with NinjaTrader for an example of working with these types of scripts. To view the script, open a New > NinjaScript Editor window, open the Strategies folder, and double-click on the strategy file.

    Please let me know if I may assist further.
    Brandon H.NinjaTrader Customer Service

    Comment


      #3
      Originally posted by nventimiglia View Post
      in this example Isee reference to using the Close array, but It is not clear which data this is referring to : the current time frame or the custom one.
      Welcome to the forums!

      The Close series (usually) refers to close prices on the primary bar series.
      (EDIT: But not always, it's actually subtle ... understanding BarsInProgress
      is key -- see my closing below.)

      The example you found is a good one.
      What you probably missed was the plural 's' form, aka, the Closes series.

      Understanding the singular vs plural form, ie, Close vs Closes, is very critical.

      To access the data series added by the AddDataSeries, you must use the
      plural form, like this,

      Closes[1][0] <-- 1st AddDataSeries
      Closes[2][0] <-- 2nd AddDataSeries


      The '1' or '2' is the BarsInProgress index.

      By definition, when using BarsInProgress index value of '0', this always
      means the primary bar series.

      Thus, this equivalence (usually) holds true,

      Closes[0][0] == Close[0] <-- primary bars

      [EDIT: I say 'usually' because Close[0] is actually shorthand for the
      current BarsInProgress context, that is,

      Closes[BarsInProgress][0] == Close[0]

      It's very important to read the help pages cited by Brandon.]

      Carefully re-read the examples you discovered, take great care to
      notice how the plural 's' forms are being used to reference the data
      from the additional data series. With that example in mind, now
      read my closing below ...

      -=o=-

      These are very advanced topics.
      It helps to think in terms of a 'BarsInProgress context'.

      That is, OnBarUpdate always runs in a 'BarsInProgress context', which
      means that all singular series, such as High/Low/Open/Close/etc etc,
      have been set to shorthand references to the plural series of the same
      name for the current BarsInProgress value.

      After you understand that OnBarUpdate is called when a bar closes on
      the primary series (which is BIP=0), you need to quickly grasp that OBU
      is also called when a bar closes on each of the secondary data series
      added by AddDataSeries. Yep, OBU is doing extra duty -- the only
      way you know which bar series this OBU is referencing is by looking
      at BarsInProgress, which is a critical concept, because it also defines the
      'BarsInProgress context' ... that is,

      In every call to OnBarUpdate, Close[n] is a shorthand way of saying
      Closes[BarsInProgress][n]. So, just before NT calls your OBU,
      it sets up the BarsInProgress context, and all the singular data series
      names are set to the current BIP value.

      That is,
      Close[n] is really Closes[BarsInProgress][n]
      High[n] is really Highs[BarsInProgress][n]
      Open[n] is really Opens[BarsInProgress][n]
      etc etc

      That's why the plural 's' form is so important, it allows access to any of
      the secondary data series (aka, those data series added via calls to
      AddDataSeries) regardless of the current BarsInProgress context.

      Using Close[0] is really just a convenient shorthand.



      Make sense?
      Last edited by bltdavid; 12-21-2022, 07:38 PM.

      Comment


        #4
        Ok, So this helps. Can I get a code review on this simple moving average script locked to the daily timeframe?

        The expected result is a simple moving average being drawn on all timeframes. The actual result is the SMA renders on the daily time frame and up (weekly works as well). Hourly time frames for instance render nothing.

        Code:
        namespace NinjaTrader.NinjaScript.Indicators
        {
            public class _DailySMA : Indicator
            {
                [Range(1, int.MaxValue), NinjaScriptProperty]
                [Display(ResourceType = typeof(Custom.Resource), Name = "Period", GroupName = "NinjaScriptParameters", Order = 0)]
                public int Period { get; set; }
        
                protected override void OnStateChange()
                {
                    if (State == State.SetDefaults)
                    {
                        Description                                    = @"_DailySMA";
                        Name                                        = "_DailySMA";
                        Calculate                                    = Calculate.OnBarClose;
                        IsOverlay                                    = true;
                        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;
                        Period = 20;
                    }
                    else if (State == State.Configure)
                    {
                        AddDataSeries(Data.BarsPeriodType.Day, 1);
                        AddPlot(Brushes.CornflowerBlue, NinjaTrader.Custom.Resource.NinjaScriptIndicatorNameSMA);
                    }
                }
        
                protected override void OnBarUpdate()
                {
                    Value[0] = SMA(Closes[1][0], Period)[0];
                }
            }
        }​

        Comment


          #5
          Try this,
          Value[0] = SMA(Closes[1], Period)[0];

          Comment


            #6
            There are other ways to do what you want.

            Try studying this sample.
            Last edited by bltdavid; 12-22-2022, 01:22 AM.

            Comment


              #7
              Hello nentimiglia,

              Thanks for your note.

              bltdavid is correct. To have the SMA calculated from the Close of the added Daily series, you could use Value[0] = SMA(Closes[1], Period)[0]; in your script.

              When we pass an index of 1 into Closes[] when using SMA(Closes[1], Period)[0];​, we are accessing the Close price of the first added data series in the script. In this case, the Daily series.

              Please let me know if you have further questions about this topic.
              Brandon H.NinjaTrader Customer Service

              Comment


                #8
                Hi,
                I have a strategy where I have two AddDataSeries( 1 Tick and 1 minute), that is calling an indicator that has an AddDataSeries al well for 15 minutes; in both scrpts they are in State == State.Configure.

                I tried to run a backtest without success, on the script output I get the message:

                'MCPindicator' tried to load additional data. All data must first be loaded by the hosting NinjaScript in its configure state. Attempted to load MES 09-23 Globex: 15 Minute
                'MCPindicator' tried to load additional data. All data must first be loaded by the hosting NinjaScript in its configure state. Attempted to load MES 09-23 Globex: 1 Minute

                Is it possibe to have AddDataSeries in the Indicator using different data vs. those added in the calling Strategy?

                Thank you
                Martin

                Comment


                  #9
                  Hello Martin,

                  Thanks for your notes.

                  The strategy must have the same AddDataSeries() calls that the indicator has.

                  You would need to also add the 15-minute series to your script since the indicator you are referencing has an added 15-minute series.

                  From the AddDataSeries() help guide: "Should your script be the host for other scripts that are creating indicators and series dependent resources in State.DataLoaded, please make sure that the host is doing the same AddDataSeries() calls as those hosted scripts would. For further reference, please also review the 2nd example below and the 'Adding additional Bars Objects to NinjaScript' section in Multi-Time Frame & Instruments"

                  ​See this help guide page for more information about AddDataSeries(): https://ninjatrader.com/support/help...=adddataseries
                  Brandon H.NinjaTrader Customer Service

                  Comment

                  Latest Posts

                  Collapse

                  Topics Statistics Last Post
                  Started by judysamnt7, 03-13-2023, 09:11 AM
                  4 responses
                  59 views
                  0 likes
                  Last Post DynamicTest  
                  Started by ScottWalsh, Yesterday, 06:52 PM
                  4 responses
                  36 views
                  0 likes
                  Last Post ScottWalsh  
                  Started by olisav57, Yesterday, 07:39 PM
                  0 responses
                  7 views
                  0 likes
                  Last Post olisav57  
                  Started by trilliantrader, Yesterday, 03:01 PM
                  2 responses
                  22 views
                  0 likes
                  Last Post helpwanted  
                  Started by cre8able, Yesterday, 07:24 PM
                  0 responses
                  10 views
                  0 likes
                  Last Post cre8able  
                  Working...
                  X