passing arrays by reference to a function

Questions about MultiCharts and user contributed studies.
janus
Posts: 835
Joined: 25 May 2009
Has thanked: 63 times
Been thanked: 104 times

passing arrays by reference to a function

Postby janus » 02 May 2010

Can someone please confirm the following is correct?

I'm passing a numeric array to a function, which is defined as NumericArrayRef so I can modify certain elements while in the function. It appears I can also reference any element in the array in the past using something like: array[3][2], which means the 3rd element 2 bars ago. I can set any element in the array as long as it's only the most recent one. For example array[3] = 0; will work but array[3][2] = 0; will not (gives a compiler error). This is with the function complied as type simple, not series (to avoid the function being called forcibly on each bar, which is not what I want as it would cause problems if it did).

In other words, defining an array in a function as by reference also causes it to be treated as type series. Is this all fine? I hope so.

User avatar
Bruce DeVault
Posts: 438
Joined: 19 Jan 2010
Location: Washington DC
Been thanked: 2 times
Contact:

Postby Bruce DeVault » 02 May 2010

It is true that you can use one more series of square brackets than there are dimensions, and that this will index into the past for the element specified up to that point.

You can read from such past elements though even if you don't pass it by reference - the advantage to passing it by reference is that you can write to the current element, and that it saves memory and time to not make a copy.

It also doesn't matter whether the function itself is series or simple in this case.

bowlesj3
Posts: 2180
Joined: 21 Jul 2007
Has thanked: 227 times
Been thanked: 429 times

Postby bowlesj3 » 02 May 2010

What I discovered about series functions is that if you have a work variable defined only in that function it will store that work field such that you can go back in time with the square brackets. The RSI function relies on this.

Related to this, I have a process where I loop to determine what the price will be if an RSI value hits a certain level by the end of the bar. To do this I create a price variable to store a copy of the close which the RSI uses in my studies. It is called BarsEndPrice10Sec. I have a loop that changes this price and feeds it into the standard RSI function until the resulting RSI reaches this target (my entry point actually). That way I can know what my entry point will be in actual price. What is tricky about it is at the very bottom of the study when BarStatus=2 occurs I have to reset that copy of the closing price to the actual closing price. If I do not do this what I mentioned in the first paragraph above will kick in and thse work fields in the series RSI function will get all screwed up when they are stored for the square brackets historic reference and the RSI will no longer calculate properly. Here is the final statement in my study to fix it so the RSI work fields are stored correctly in the series function process.

if BarStatus = 2 then
begin
BarsEndPrice10Sec = Close;
BarsEndRSI10Sec = RSI(BarsEndPrice10Sec,14);
end;

It is a good thing to know because it can take a while before one realizes they have to do the reset on BarStatus=2

janus
Posts: 835
Joined: 25 May 2009
Has thanked: 63 times
Been thanked: 104 times

Postby janus » 04 May 2010

What I discovered about series functions is that if you have a work variable defined only in that function it will store that work field such that you can go back in time with the square brackets. The RSI function relies on this.
Yes, that's the purpose of a series function. I don't think there's any other purpose of making a function of type series as distinct from simple. However, I stay away from using series functions - it's a very bad programming feature IMHO. I might call the same function more than once in a study based on certain conditions. If the function is a series type, it would be called forcibly several times per bar (once for each time it's declared) regardless of the conditional tests I apply. So, to maintain my programming sanity I always use simple functions. If I need to access historical values of local variables in a function, I declare them in the main study and define the corresponding input variable in the function as a series type (eg, NumericSeries). By doing this it no longer is a local variable but I see no problem with this. If I have a lot of these variables, I store them in an array instead. That way I can pass a batch of variables in one go. It also makes it easy to share them with other functions, which I do very often.

I'm sure series functions have their place for some but I rather avoid them like the plague.

bowlesj3
Posts: 2180
Joined: 21 Jul 2007
Has thanked: 227 times
Been thanked: 429 times

Postby bowlesj3 » 04 May 2010

I don't think I have ever run across a series function until EL. Dynamic (holding their values until the next call) yes. Am I correct in assuming it is an invention of the C language? I guess Dynamic functions could contain working arrays so maybe I have actually. I have never had any use for one or at least never thought to use one.

User avatar
Bruce DeVault
Posts: 438
Joined: 19 Jan 2010
Location: Washington DC
Been thanked: 2 times
Contact:

Postby Bruce DeVault » 05 May 2010

Series functions are unique to languages designed for time series analysis. EasyLanguage was one of the first to really make the idea popular, especially for finance. It's a shortcut, in that for instance if you have an exponential moving average (which requires every bar to be seen by the algorithm so you can calculate its value at a later bar), you can reference it like "if x then y = xaverage(...)" without getting the wrong value. For those who have a background in non-EL programming, this can be counterintuitive, but for those who just want to program strategies, this is a huge time saver, in that they're not familiar with how the functions work technically - they just know they can use a statement like the one above and they get the right answer.

bowlesj3
Posts: 2180
Joined: 21 Jul 2007
Has thanked: 227 times
Been thanked: 429 times

Postby bowlesj3 » 05 May 2010

Yes I think the idea is okay. Before I had my experience described above I had read that they are actually faster and my impression was this is because they store roll around tables for you automatically (ones where the programmer tests for off the end and resets the subscript/index to the other end). I have assumed that the MaxBarsBack tables are as such anyway. So my assumption is that when you mark your function as series you are saying "store the work tables for repeat use in a standard roll around processing format". Anything that saves me work as a trader (former higher level programmer only low level programer when a student) is fine with me. If it is a bit slower even I don't care.


Return to “MultiCharts”