yet another iMAonArray question

 

I thought I solved this a while ago, but while troubleshooting my code I thought it might be a good idea to validate all my assumptions, and iMAOnArray is one function for which the documentation is outright confusing.

Say i have built an array tmp[1000], which gets filled left to right, i.e:

[1,2,3,4,5,0,0,0,...,0]

if i wanted to calculate the 3-element average at the fifth element (i=5), i'd use

iMAOnArray(tmp,0,3,0,MODE_EMA,1000-i)

And i would expect this to return the EMA of (3+4+5).

Am i using this correctly? If not, what is the correct way to use this function in this scenario?

 
don't forget Array[0] is the first element
 
gatornuke:

I thought I solved this a while ago, but while troubleshooting my code I thought it might be a good idea to validate all my assumptions, and iMAOnArray is one function for which the documentation is outright confusing.

Say i have built an array tmp[1000], which gets filled left to right, i.e:

[1,2,3,4,5,0,0,0,...,0]

if i wanted to calculate the 3-element average at the fifth element (i=5), i'd use

And i would expect this to return the EMA of (3+4+5).

Am i using this correctly? If not, what is the correct way to use this function in this scenario?

which way is your iterator, i, going? from left to right, or right to left? bec. iMAOnArray() considers elements from left to right, by default.

if i=5, then 1000-i, then that is 995th element, not 5th. try and do some prints as below:


int Period=3;
double result;
for(int i=ArraySize(tmp)-1;i>=Period;i--){ <------------- which way your iterator going?

result=iMAOnArray(tmp,0,Period,0,MODE_EMA,1000-i);

if(i==5){Print(" source = ", tmp[i]," avg = ",result);break;}
}
 
 

So i=5 would refer to the 995th element from right to left, which would correspond to the 5th element from left to right, correct?

Either way, my iterator goes from left to right, i=1 refers to the first array element. I did 1000-i because it was my understanding that iMAOnArray reads the array backwards. Again, the documentation makes this very confusing, and i got to this point after some trial and error, but i'm still not 100% sure this is right.

 
Seems to me that i=5 refers to a variable, however declaration of elements of lets say array=[5] seems to me that you could not use 5 because 5 is the sixth element with {0} being the first.
So the five elements would be {0,1,2,3,4} this is 5 elements, so array[5] = {0,1,2,3,4}
If your trying to select actually element number 5, then you need to select -1

That's how I understand this anyhow, but hey I'm NOOB

Am I wrong ?

Hope this helps
 
gatornuke:

So i=5 would refer to the 995th element from right to left, which would correspond to the 5th element from left to right, correct?

Either way, my iterator goes from left to right, i=1 refers to the first array element. I did 1000-i because it was my understanding that iMAOnArray reads the array backwards. Again, the documentation makes this very confusing, and i got to this point after some trial and error, but i'm still not 100% sure this is right.

pertaining documentation: it may be confusing however for this case, i can't help avoiding the fact that it is spelt out in an almost blatant and outright manner whether right-left or vice-versa, even going further to propose the alternative for the opposite case:

double iMAOnArray( double array[], int total, int period, int ma_shift, int ma_method, int shift)

Calculation of the Moving Average on data stored in a numeric array. Unlike iMA(...), the iMAOnArray function does not take data by symbol name, timeframe, the applied price.

The price data must be previously prepared. -----> this refers to your tmp[] array

The indicator is calculated from left to right. ------> this refers to the direction of averaging your tmp[] elements which takes precedence, left to right.

To access to the array elements as to a series array (i.e., from right to left), one has to use the ArraySetAsSeries function. ----> this is the alternative if you want the other direction of averaging


as you can deduce from this, a lot depends on how your tmp[] is arranged in prior, for eg. is it from most recent to most latest, etc, etc, and which direction you iterate its i iterator. Just hypothetically speaking at this point, from your original piece:

Say i have built an array tmp[1000], which gets filled left to right, i.e:

[1,2,3,4,5,0,0,0,...,0]

if i wanted to calculate the 3-element average at the fifth element (i=5), i'd use

And i would expect this to return the EMA of (3+4+5).

iMAOnArray(tmp,0,3,0,MODE_EMA,1000-i)

Wrong result: case: i=5 --->1000-5=995, returns 3-element average, from 995th element to 997th, hence 0+0+0.

Right result: case will be i=998--->1000-998=2. returns 3-element average, from 2nd element to 4th element, hence (3+4+5) as you expected.

Test the hypothesis by printing out some results on the screen to be verified manually/mentally. Unless you have other ideas, please do share.

 

ok, so i have an array tmpset[] that is populated with opening prices for the last 26 candles (tmpset[0] -> tmpset[25] = Open[25] -> Open[0]). Indices 26+ of tmpset[] are then populated with future values. I did this debugging check:

      double tempav=0;
      double tempcount=0;
      Print (DoubleToStr(tmpset[22],5)+" "+DoubleToStr(tmpset[23],5)+" "+DoubleToStr(tmpset[24],5)+" "+DoubleToStr(tmpset[25],5)+" "+DoubleToStr(tmpset[26],5)+" "+DoubleToStr(tmpset[27],5)+" "+DoubleToStr(tmpset[28],5)+" "+DoubleToStr(tmpset[29],5)+" "+DoubleToStr(tmpset[30],5));
      Print(DoubleToStr(iMAOnArray(tmpset,0,3,0,MODE_SMA,1000-i),5));
      for (int j = i-2;j<=i;j++){
      tempcount++;
      tempav=tempav+tmpset[j];
      }
      Print(DoubleToStr(tempav/tempcount,5));

and found out that for i=25, iMAOnArray(tmpset,0,3,0,MODE_SMA,1000-i) gives me the 3-element moving average of i=22-24. So it was shifted by one. In order to get the correct values, one must use iMAOnArray(tmpset,0,3,0,MODE_SMA,999-i). I again confirmed this.

diostar, this is small potatoes compared to what you said, though. The problem is that even though this function is "spelt out in an almost blatant and outright manner," it's totally wrong. As you and I initially understood it, the function supposedly averages from left to right, and the array index is also interpreted from left to right. In reality, it does the complete opposite, indexing from right to left, and counting from right to left.

 
gatornuke:

ok, so i have an array tmpset[] that is populated with opening prices for the last 26 candles (tmpset[0] -> tmpset[25] = Open[25] -> Open[0]). Indices 26+ of tmpset[] are then populated with future values. I did this debugging check:

and found out that for i=25, iMAOnArray(tmpset,0,3,0,MODE_SMA,1000-i) gives me the 3-element moving average of i=22-24. So it was shifted by one. In order to get the correct values, one must use iMAOnArray(tmpset,0,3,0,MODE_SMA,999-i). I again confirmed this.

diostar, this is small potatoes compared to what you said, though. The problem is that even though this function is "spelt out in an almost blatant and outright manner," it's totally wrong. As you and I initially understood it, the function supposedly averages from left to right, and the array index is also interpreted from left to right. In reality, it does the complete opposite, indexing from right to left, and counting from right to left.

1) i=25 ---> 1000-25=985. (not 25).

2) At index 985: iMAonArray() takes the 3-element average from index 983, 984, 985. LEFT TO RIGHT ---SMALLEST INDEX TO LARGEST INDEX.

Your right to left, is the equivalent of the documentation left to right, from smallest index to largest, which is standard array indexing, quite frankly.