Add Series<T> To specific BarsInProgress

Hi there, I am building a strategy that considers 15-minute bars and 240-minute bars. I am calculating a market bias on both time frames. The intention is to capture what is happening on a larger timeframe (240-minute) and consider that in the decision-making timeframe (15-minute). My 15-minute bias works just fine. Every 15 minutes, I get a new entry in my data series, so Bias15[0] will shuffle to Bias15[1], and at no point do I have any 0 values

My challenge is with my Bias240. The intention of my Bias240 series is to update every 240 minutes a new bias value. However, if I’m looking at my 15-minute chart, then a new Bias240 Data series entry populates every 15 minutes, not 240 minutes, and I ended up with a number of 0 values in my series. So I really only get a non-0 value every 16 bars.

I know there’s a thing I can do with CurrentBar (current bar of the chart you’re looking) and then CurrentBars[2] (returns current bar of a Data Series of a specified time frame). How do I get the same effect from a Series? If not, then I guess I’ll just make an array and manually store these values.

Any help would be greatly appreciated, thank you!!

Nathan.

what have you done with AddDataSeries to get the 240 minute bar data set?

how is your strat code referencing the bar set for 15 min vs 240 min?

1 Like

Hi there Strong-Thermal-Emiss,
Thank you for your reply. If you need any addional information please let know. Otherwise, I’ve pasted a trimmed down version of my code below with what I think is the information you’re requesting. I appreciate your help.

Nathan.
namespace NinjaTrader.NinjaScript.Strategies
{
public class Lab93M : Strategy
{
#region Constants & Variables
// Constants
…

    private Series<double> totalBias;
    private Series<double> Bias240min;
    private Series<double> Bias15min;

    ...
    #endregion

    protected override void OnStateChange()
    {
        if (State == State.SetDefaults)
        {
            ...

            AddPlots();
        }

        else if (State == State.Configure)
        {
            AddDataSeries(BarsPeriodType.Minute, Timeframe240min);      // BarsInProgress index = 1, 4-hour
            AddDataSeries(BarsPeriodType.Minute, Timeframe15min);       // BarsInProgress index = 2, 15-minute
        }

        else if (State == State.DataLoaded)
        {
            Bias240min  = new Series<double>(this, MaximumBarsLookBack.Infinite);
            Bias15min   = new Series<double>(this, MaximumBarsLookBack.Infinite);
            totalBias   = new Series<double>(this, MaximumBarsLookBack.Infinite);
        }
    }
}

protected override void OnBarUpdate()
    {
        // **********************************************************************************************
        //                                          4-Hour
        // **********************************************************************************************
        #region 4-hour Timeframe (HTF)
        if (BarsInProgress == 1 && CurrentBars[1] > 7)
        {
            Bias240min[0] = CalculateBias(tf240min);
        }
        #endregion

        // **********************************************************************************************
        //                                          15-Min
        // **********************************************************************************************
        #region 15-minute Timeframe (MTF)
        if (BarsInProgress == 2 && CurrentBars[2] > 2)
        {
            Bias15min[0] = CalculateBias(tf15min);
        }

        totalBias[0] = Bias15min[0] + Bias240min[0];
    }

}

In State.DataLoaded where you’re defining your Series, you need to define them in such a way that they line up with the appropriate data series. The way you have them, they are all lined up with the primary series (ie; price bars).

BarsArray[0] is price bars.
BarsArray[1] is your 240 min series
BarsArray[2] is your 15 min series

Therefore, if you want your Bias240min series to line up with your 240 min data series, you’ll need to define it as follows:

Bias240min = new Series(SMA(BarsArray[1],1),MaximumBarsLookBack.Infinite);
Bias15min = new Series(SMA(BarsArray[2],1),MaximumBarsLookBack.Infinite);

This will make the two series line up with their corresponding data series.

Hope this helps.

1 Like

fc77,
This is awesome. So instead of “this” (which I don’t fully understand what “this” means), you’re creating a simple moving average of the last 1 bars for the respective data series. Makes sense and it’s a super elegant solution (which I like).

Can you point me to any resources that would help me to understand what “this” is and why I can just replace it with a SMA? I hover over “Series” and it says it’s a “NinjascriptBase.” I click on that, and it takes me further into the weeds to some stuff that I just don’t understand. Screenshot below (hopefully). I’m not asking for a full tutorial on this, but if I’m to search for things to better understand this, could you tell me what to search for? It seems like these are the nuts and bolts of the functions I’m calling when writing a Ninjascript, and it would benefit me if I understood them maybe a level or two deeper. Thanks again for your help with this.

edit: so I know that I can just search for C# what is “this.” I’ve done that before, but it only returns stuff like… well… this:
" The this keyword is a reference to the current instance of the class.

In your example, this is used to reference the current instance of the class Complex and it removes the ambiguity between int real in the signature of the constructor vs. the public int real; in the class definition."

I just don’t understand that. My ask is more “hey, have you ever come across a YouTube video or some resource where someone really puts it into terms that are easy to grasp.” Again: thank you.

Nathan.

When you write “this” in this context, you are referring it to the instance of the class, which is the strategy or indicator itself. Passing this to a series like new Series<double>(this) links the data series so it gets updated in sync with its bar updates. https://ninjatrader.com/support/helpguides/nt8/NT%20HelpGuide%20English.html?seriest.htm

In this example, I use a series based on the point of control that I passed to an SMA. point-of-control-sma/PointOfControlMovingAverage.cs at main · WaleeTheRobot/point-of-control-sma · GitHub

1 Like

“this” is a reference to the specific instance of the class - here the indicator or strategy is the class as you can see from the declaration line. ex:

public class MyBeautifulIndicator : Indicator

Let’s say you have two charts. One with 3 days of data and one with 10 days of data loaded. You add the same indicator on both charts. Now you have two instances of the same indicator (class) running on your platform. Let’s say the indicator makes a call to Draw.TextFixed() to place a text label on the chart window based on some calculations. Since you have different number of days on the two charts, results may be different. Draw.TextFixed() will need to know which chart to place the appropriate text on. By passing “this” from the indicator instance to Draw.TextFixed(), you’re giving it a reference (think of it as an address) where to place its text. The two indicator instances will pass “this” to Draw.TextFixed() to tell it where to draw the corresponding text.

In the context of declaring the new Series, again “this” refers to the current indicator instance. The Series declaration by default will use the primary bar series from “this” (ie; Bars or BarsArray[0]). If you have additional data series defined in your indicator and want a new Series aligned with those other data series, then you’ll have to instantiate the Series using the appropriate BarsArray[N].

Where to learn: NinjaScript is built on C#. There are NT specific syntax that you can read about in NT’s documentation as I’m sure you already know. The rest is standard C# stuff. I would say the best way to learn would be to probably read a primer on C# or object oriented programming (OOP) and learn about how classes are built, instantiated and used.

Going back to the Series example, in my previous reply I jumped straight to the final answer. You don’t have to use the SMA when you declare the new Series. You could also do something like this.

Bias240min = new Series(BarsArray[1], MaximumBarsLookBack.Infinite);

I believe this works too. But if you enable compile time warnings (right click in NS Editor > Show Warnings), I believe the above syntax will generate a warning. I like all my scripts to compile clean and without warnings. I asked NT scripting support about this warning and they suggested the syntax with the SMA that I posted previously. With either syntax, you’re declaring a new Series that aligns with the specific data series. The one with SMA compiles clean (without warnings), but I believe both will work. This is why I suggested the syntax with SMA. I heavily use the syntax with SMA in all my script so I know it works.

Hope this helps and it wasn’t more than what you wanted to see LOL.

Good luck.