Series Basics with NinjaScript
We’ve put together a series of posts to help you in your journey to learn how to program from scratch, or edit existing NinjaTrader indicators and strategies. All of our posts are geared toward the non-programmer, so even though we will present a lot of information, for all of you more technical people out there, we will not go into all the technicalities of C#, NinjaTrader, or NinjaScript. It’s also important to note that even though we show you how to do something in NinjaTrader, that is by no way the only way to do it. We will present what has worked best for us and what will be most easily understood by someone learning how to program. Finally, for the more advance users, we are going to leave things out and over simplify certain parts because we are focused on learning what we need to so we can get started on our NinjaScript journey.
In the next tutorial we will begin developing an Improved SMA Crossover indicator, but before we do, we need to review an extremely important concept, one that we will continue to build on in the future, which is Series<T>. This data type comes in handy when we want to reference the value of variables X BarsAgo.
NinjaScript Series <Type> Basics
It is important to understand the basics of Series<Type> because unlike what we’ve seen previously, Series<Type> could mean a double, bool, int, or more. The definition of Series<T> is:
- A Series<T> is a special generic type of data structure that can be constructed with any chosen data type and holds a series of values equal to the same number of elements as bars in a chart. If you have 200 bars loaded in your chart with a moving average plotted, the moving average itself holds a Series<double> object with 200 historical values of data, one for each bar. Series<double> objects can be used as input data for all indicator methods. The Series<T> class implements the ISeries<T> interface.
- While it is rare to create and use variables of straight object, it can be helpful in generic type casting for databases, reflection, serialization, event sending, or tagging. More commonly, in the scope of NinjaTrader, having a Series of type object is useful to hold custom class objects in NinjaTrader’s supported Series<object> type. With this, you may have a synchronized list of a class; synced to a specific BarsAgo for synchronization and commonality between NinjaTrader’s given series (i.e., Close[BarsAgo], etc).
As with most of our Tutorials, we believe the best way to learn Series<Type> is through examples, but first, if you haven’t already, please review the concepts presented in Part 6 as Series<Type> is dependent upon the concepts presented there.
In this example we will create a variable that holds a value of 1 if the trend is up, -1 if the trend is down, and 0 if there is no trend (we will define trend as if the bar closes up or down). We will also define a Series<Type> variable as true if there are two trending bars in a row (false otherwise). Additionally, we define a custom class and explore how a Series can hold any object.
The first thing we want to do in our example is relevant to the custom class generic Series<>, whereby we create a simple class that holds moving average information. Specifically, we will hold the value of three different types of moving averages.
The second thing we want to do in our example is declare our Series<Type>.
You will notice that the above looks similar to declaring a double, or bool (private double iTrend; private bool iUp, iDown; private Series maValues;), but when we declared a Series<Type>, we placed the double and bool inside of <>. By placing double / bool inside of <>, we are telling NinjaTrader we want to create a Seriesype> object that contains double / bool values. The first part is similar to what we have seen in prior tutorials, but that is only the first step is initializing our Series<Type> variable. Our new variables will be able to reference BarsAgo, but by default they are only capable of storing 256 data points. What that really means is if you need to reference a data point greater than 256 BarsAgo, so say 300 BarsAgo (e.g. iTrend), you will need to do one of two things:
- In your indicator settings, change MaximumBarsLookBack to MaximumBarsLookBack.Infinite, which will allow you to reference as far back in time as you want OR
- Preferred: In the next step of initializing our Series<Type>, we can set the individual Series<Type> to have a MaximumBarsLookBack of MaximumBarsLookBack.Infinite
Before we go any further, the reason we prefer the second method to the first is because in the first scenario, all Series<Type> variables will have a MaximumBarsLookBack.Infinite, which takes up more resources. So, if we know which Series<Type> variables need to reference values greater than 256 BarsAgo, we can use fewer resources by only setting that / those variables to MaximumBarsLookBack.Infinite. Let’s take a look at the different scenarios for getting our variables ready for use (we will perform the following in State.DataLoaded) Note: You will only use one of these three options, NOT all three:
The full example of how to get our four variables ready for use is as follows:
Great! Now it’s time to see how we assign values to our Series<Type> variables. In the following example we will assign a 1 to up bars, -1 to down bars, and 0 to bars that don’t meet either criteria. Additionally, we will have to instantiate our maValues Series for each bar, since it is a class. This is done using the new keyword. Once our Series is instantiated for this bar, we can use it to store data.
Now that we are defining iTrend based on our definition of “trend,” it’s time to determine if we have had 2 consecutive “trends” in a row:
We have almost completed the basics with Series<Type>, but we will show one last example of how to reference the Series<> variables, which is based on the same concept as referencing the Series. We will reference Series by using Variable[BarsAgo]:
It’s As Simple As That
We presented the basics of Series<Type> in this tutorial and will continue to build upon our understanding in future tutorials. Now it’s time to begin working on our Improved SMA Cross indicator, so checkout Part 8 – AddPlot and Plot Variables.