Welcome to NexusFi: the best trading community on the planet, with over 150,000 members Sign Up Now for Free
Genuine reviews from real traders, not fake reviews from stealth vendors
Quality education from leading professional traders
We are a friendly, helpful, and positive community
We do not tolerate rude behavior, trolling, or vendors advertising in posts
We are here to help, just let us know what you need
You'll need to register in order to view the content of the threads and start contributing to our community. It's free for basic access, or support us by becoming an Elite Member -- see if you qualify for a discount below.
-- Big Mike, Site Administrator
(If you already have an account, login at the top of the page)
Thanks very much for the reply. I still don't quite get it though... Just to clarify, I am setting this up inside a strategy, not inside an Indicator (I don't know if that makes a difference)
Say that I have 10 instruments, and that I want to maintain a ranked list based on their current SMA. Should I somehow specify:
//Inside variables:
private SMA sma1;
int numInstruments = 10;
int smaPeriod = 10;
...
//Inside OnStartup() -> I know this won't work, I just wasn't sure how else to communicate what I was thinking...
for(int i = 0; i < numInstruments; i++);
sma1[i] = SMA(i,smaPeriod);
...
Thanks very much for the reply. I still don't quite get it though... Just to clarify, I am setting this up inside a strategy, not inside an Indicator (I don't know if that makes a difference)
Say that I have 10 instruments, and that I want to maintain a ranked list based on their current SMA. Should I somehow specify:
//Inside variables:
private SMA sma1;
int numInstruments = 10;
int smaPeriod = 10;
...
//Inside OnStartup() -> I know this won't work, I just wasn't sure how else to communicate what I was thinking...
for(int i = 0; i < numInstruments; i++);
sma1[i] = SMA(i,smaPeriod);
...
private SMA sma1;
private SMA sma2;
private SMA sma3;
...
sma1 = SMA(Closes[0],smaPeriod);
sma2 = SMA(Closes[1],smaPeriod);
sma3 = SMA(Closes[2],smaPeriod);
If you want to use an indicator in a strategy, it is best to add an instance of the indicator to the strategy via the Add() method.
If you want to use your strategy with 10 different instruments, you would first add the 10 instruments in the Initialize() section of the strategy. Bar Index 0 denotes the primary bars, and bar indices 1 to 10 would denote the 10 added bar series (index follows the order in which they have been added).
Within the Initialize() section you can then add indicators to your strategy, also via Add(). This is required if you wish that the indicators are plotted, otherwise you can call indicators directly in OnBarUpdate().
Just so that I'm clear, what if I only need the indicator for calculations, but don't care about plotting it?
> If I want to apply this indicator to each of the 10 instruments, should I have to add a separate instance of the indicator for each of the instruments?
Initialize()
{
Add(....all instruments...);
for(int i = 1; i <= numberOfAddedInstruments; i++)
{
Add(SMA(Closes[i],smaPeriod));
}
> Or, can I somehow add one instance of the indicator and then point that to various DataSeries later in the strategy?
Sorry if I'm not describing it quite clearly (Although, I would imagine that if I could just figure out a way to describe it, I probably wouldn't have any issue programming it...)
Thanks a million for helping with this, I'm very much lost in the dark right now
Just so that I'm clear, what if I only need the indicator for calculations, but don't care about plotting it?
You can call it directly from within OnBarUpdate() as SMA(Closes[i], period).
kbeary33
> If I want to apply this indicator to each of the 10 instruments, should I have to add a separate instance of the indicator for each of the instruments?
That is what I would try to do.
kbeary33
> Or, can I somehow add one instance of the indicator and then point that to various DataSeries later in the strategy?
for(int i = 0; i <= numInstruments; i++)
{
Add(ATR(BarsArray[i],ATRPeriod));
Add(ROC(BarsArray[i],RankingPeriod1));
}
init = true;
... But NinjaTrader then throws an error saying that you can't use "Add()" outside of the initialize function
I am actually working with a fairly large list of instruments (300+), so obviously I don't want to type a line manually for each of the indicators that I want to add. Is there some other way than what I've tried to do in the code above to iterate through the list of instruments and add their corresponding indicator?
Also, from a memory usage standpoint: If I'm running an optimization run, and NinjaTrader creates a new instance of each indicator for each set of parameters, will Ninja ever release that memory, or no? Right now, the memory usage gradually explodes (using all 12GB of RAM), and the only way to fix it is to close NT and restart.
I understand that the best way to handle this on a single instrument strategy is to create a unique instance of the indicator, and just reference that instance, but how can you hard code that to iterate automatically? Is there a way in C# to use a dynamic string when declaring variables? Not sure how to explain, but I'm thinking something along the lines of:
for (int i = 0; i < numberInstruments; i++)
{
private SMA sma[i] = SMA(BarsArray[i], smaPeriod);
}
Thanks very much, this seemed to work. I had thought that because the ATR calc needed all of the high/low/close/open, it would have to be passed the BarsArray item. Passing Closes returned the same value though, so apparently that's ok
One last thing - Will adding the indicators to the strategy serve the same purpose as declaring a unique named instance of the indicator?
ie
Add(ATR(Closes[1],ATRPeriod)) --> same performance as: private ATR myATR1 = ATR(Closes[1],ATRPeriod)
Thanks very much, this seemed to work. I had thought that because the ATR calc needed all of the high/low/close/open, it would have to be passed the BarsArray item. Passing Closes returned the same value though, so apparently that's ok
If you look at the code of the ATR indicator, it does not use Input[0] anywhere. If it did, the output values would depend on the type of data passed. Therefore ATR(Closes[1], ATRPeriod) is the same as ATR(Highs[1], ATRPeriod). I would prefer to write ATR(Inputs[1], ATRPeriod) as this covers the general case.
kbeary33
One last thing - Will adding the indicators to the strategy serve the same purpose as declaring a unique named instance of the indicator?
ie
Add(ATR(Closes[1],ATRPeriod)) --> same performance as: private ATR myATR1 = ATR(Closes[1],ATRPeriod)
The main purpose of addingan indicator via the ADD() method is to have them directly plotted by the strategy. If this is not required, the code below is a simpler solution:
An Array can store any type, including DataSeries objects. As an example, let's create an array to hold more than one DataSeries. The rank (number of elements) of the array does not need to be hard coded. It can be user selected or programmatically controlled, and the setting of the object references can be done in a For loop.
Declare the array. At this point the rank (number of elements) is not yet defined and the array is empty.
private DataSeries [] multiSeries;
//declare an array that will contain object references to DataSeries objects.
In the Initialize() method:
//specify the number of elements in the array, which is the integer called rank
multiSeries[]=new DataSeries[rank];
//the array now contains the number rank of object references that need to be set to instances of objects
for (int count = 0; count<rank; count++)
multiSeries[count]=new DataSeries(this);
Remember, an array is a ZERO BASED collection. So, for example, if an array contains 5 items, the subscripts of the items will be 0 through 4, not 1 through 5. Hence the start and end points of the For loop.
Each of these objects is accessed like any other DataSeries, but don't forget the first subscript that tells you which one is being accessed.
That's it, we're almost done for today. Have a nice day!
But before I return to my undisclosed location, here is an example of how to use this technique, based on the Freedom of Movement Indicator in the April 2014 issue of TASC. By eliminating dependencies on external classes, the performance of the indicator has been improved. (I have other, more ambitious uses in mind for this technique, since for this particular indicator it is not really worth the trouble.)
"If we don't loosen up some money, this sucker is going down." -GW Bush, 2008
“Lack of proof that something is true does not prove that it is not true - when you want to believe.” -Humpty Dumpty, 2014
“The greatest shortcoming of the human race is our inability to understand the exponential function.” Prof. Albert Bartlett