iMAOnArray issue.

 

been looking for a solution to this.. having troubles.



a very simple EA that initialize an array with values.. and prints the results of iMAOnArray.



//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{

double testArray[10];
for(int i=1;i<=10;i++) {
testArray[i-1] = i;
}

Print("Total Zero: " + iMAOnArray(testArray, 0, 3, 0, MODE_SMA, 0));
Print("Total Three: " + iMAOnArray(testArray, 3, 3, 0, MODE_SMA, 0));

}



The problem is undeterministic (programmers nightmare)



Print("Total=Zero: " + iMAOnArray(testArray, 0, 3, 0, MODE_SMA, 0)); //prints Total=Zero: 9
Print("Total=Three: " + iMAOnArray(testArray, 3, 3, 0, MODE_SMA, 0)); //prints Total=Three: 9



which is fine.. BUT.... simply reverse the calls...



Print("Total=Three: " + iMAOnArray(testArray, 3, 3, 0, MODE_SMA, 0)); //prints Total=Three: 2

Print("Total=Zero: " + iMAOnArray(testArray, 0, 3, 0, MODE_SMA, 0)); //prints Total=Zero: 2


If I had hair I would pull it out. Why does this perform like this? Obviously, some 'state' is being remembered.. just not sure what it is. Could anyone explain? Thanks

 

iMAOnArray() operates on a "series" array.

Use ArraySetAsSeries() to prepare your array.

 
phy:

iMAOnArray() operates on a "series" array.

Use ArraySetAsSeries() to prepare your array.

I understand how ArraySetAsSeries works. That is not my question.



Why does this return one set of values when I run the EA (Note: the 'total' parameter is the only difference)


state 1:

Print("State 1 (zero total): " + iMAOnArray(testArray, 0, 3, 0, MODE_SMA, 0));
Print("State 1 (three total): " + iMAOnArray(testArray, 3, 3, 0, MODE_SMA, 0));



But then, lets just reverse the order that these statements are called... (Note: the statement with total 3 is called first and 0 is called second)


state 2:

Print("State 2: " + iMAOnArray(testArray, 3, 3, 0, MODE_SMA, 0));

Print("State 2: " + iMAOnArray(testArray, 0, 3, 0, MODE_SMA, 0));




The problem is state 1 and state 2 return different results!



state1 prints out for example:

State 1 (zero total): 9

State 1 (three total): 9



state2 prints out for example

State 2 (zero total): 2

State 2 (three total): 2



state 1 SHOULD read:

State 1 (zero total): 9

State 1 (three total): 2


state 2 SHOULD read:

State 2 (three total): 2

State 2 (zero total): 9



please let me know why this happens. thanks!

 

You have found something buggy. My mistake...

Here is where you report such things:

http://www.metaquotes.net

 

See description of the iMAOnArray():

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. The indicator is calculated from 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.

Parameters:

array[] - Array with data.
total -

The number of items to be counted. 0 means whole array.

period - Averaging period for calculation.
ma_shift - MA shift
ma_method - MA method. It can be any of the Moving Average method enumeration value.
shift - Index of the value taken from the indicator buffer (shift relative to the current bar the given amount of periods ago).

You specify zero value for second parameter of iMAOnArray() and that mean whole array for calculating. In this case both calls is equal. Are you agree?

 

Something odd happens when a value other than 0 is used for the "total" parameter.

I have no idea how to properly use the "total" parameter, but here is my test script.

The output of the IMAOnArray with 0 "total" seems broken when it is output after using iMAOnArray with non-zero "total". --- Why is output D not "2.0000"

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----

    double testArray[10];
    ArraySetAsSeries(testArray, true);
    string out;
    int i;
    
    
    ////////////////////////////////////////////////////////////
    //Write Array 
    
    for(i = 0 ;i < 10;i++) {
        testArray[i] = i+1;
    }      

    // use default total parameter first
    Print("Print A: "  + iMAOnArray(testArray, 0, 3, 0, MODE_SMA, 0));
    Print("Print B: "  + iMAOnArray(testArray, 3, 3, 0, MODE_SMA, 0));

    out="";    
    for( i = 0 ;i < 10;i++) {
        out = out + "  ";
        out = out + testArray[i];
    }     
    Print(out);

    ////////////////////////////////////////////////////////////
    //Rewrite Array 
    
    for( i = 0 ;i < 10;i++) {
        testArray[i] = i+1;
    } 

    // Use total Parameter first..
    Print("Print C: "  + iMAOnArray(testArray, 3, 3, 0, MODE_SMA, 0));
    Print("Print D: "  + iMAOnArray(testArray, 0, 3, 0, MODE_SMA, 0));

    out = "";
    for( i = 0 ;i < 10;i++) {
        out = out + "  ";
        out = out + testArray[i];
    } 
    Print(out);
    
    
    

//----
   return(0);
}
//+------------------------------------------------------------------+

/*
Output:

2008.08.13 03:03:00    xxxxxx EURUSD,M5: removed
2008.08.13 03:03:00    xxxxxx EURUSD,M5: uninit reason 0
2008.08.13 03:03:00    xxxxxx EURUSD,M5:   1.00000000  2.00000000  3.00000000  4.00000000  5.00000000  6.00000000  7.00000000  8.00000000  9.00000000  10.00000000
2008.08.13 03:03:00    xxxxxx EURUSD,M5: Print D: 9.00000000
2008.08.13 03:03:00    xxxxxx EURUSD,M5: Print C: 9.00000000
2008.08.13 03:03:00    xxxxxx EURUSD,M5:   1.00000000  2.00000000  3.00000000  4.00000000  5.00000000  6.00000000  7.00000000  8.00000000  9.00000000  10.00000000
2008.08.13 03:03:00    xxxxxx EURUSD,M5: Print B: 2.00000000
2008.08.13 03:03:00    xxxxxx EURUSD,M5: Print A: 2.00000000
2008.08.13 03:03:00    xxxxxx EURUSD,M5: loaded successfully
2008.08.13 03:02:47    Compiling 'xxxxxx'
 

1. For common array function iMAOnArray() calculates from left to right.



2. For price series function iMAOnArray() calculates from right to left. See ArraySetAsSeries().



3. What means the operator for price series?

iMAOnArray(testArray, 3, 3, 0, MODE_SMA, 0))



Current now iMAOnArray() recalculates only in array was changed. Because this block works not properly:

    // Use total Parameter first..
    Print("Print C: "  + iMAOnArray(testArray, 3, 3, 0, MODE_SMA, 0));
    Print("Print D: "  + iMAOnArray(testArray, 0, 3, 0, MODE_SMA, 0));



If array will be modified the iMAOnArray() returns correct value.

    // Use total Parameter first..
    Print("Print C: "  + iMAOnArray(testArray, 3, 3, 0, MODE_SMA, 0));
    array[9] = 10;  // array is "changed" 
    //  now MAOnArray() should be calculated again
    Print("Print D: "  + iMAOnArray(testArray, 0, 3, 0, MODE_SMA, 0));
There are no plans to change such behavior of function iMAOnArray(). Use it as is.
 

Well, OK...

I didn't expect the C operation to change the results of D.

 
phy:

Well, OK...

I didn't expect the C operation to change the results of D.

Rosh:

1. For common array function iMAOnArray() calculates from left to right.



2. For price series function iMAOnArray() calculates from right to left. See ArraySetAsSeries().



3. What means the operator for price series?



Current now iMAOnArray() recalculates only in array was changed. Because this block works not properly:



If array will be modified the iMAOnArray() returns correct value.

There are no plans to change such behavior of function iMAOnArray(). Use it as is.


How does one make this work properly?



Right now, I have one array plotting "backwards". The numbers are correct but the order is wrong. I have tried every combination of ArraySetAsSeries() to no avail. This is frustrating. I have been programming since 1977 and haven't been stumped like this for a long time. I know it has to be SIMPLE!!




This is in a SCRIPT:


double ma[5000];
double av[5000];
 
double ExtMapBuffer1[5000];
double ExtMapBuffer2[5000];
double ExtMapBuffer3[5000];
double ExtMapBuffer4[5000];
 
    
 
if(NumPass > limit2 ) { iMax = limit2 ; } else { iMax = NumPass - 1 ; } 
 
   for(int i2 = iMax; i2 >= 0; i2--)
    {
       x = x+1;
 
 
        ExtMapBuffer2[i2] = ExtMapBuffer2[i2+1]+x;
    }
    
 
 
 
   for(i=0; i<iMax; i++)
   {
      ExtMapBuffer3[i]=iMAOnArray(ExtMapBuffer2,iMax,MovingAveragePeriod,0,MovingAverageType,i);
      if (Use2ndMA == true) {
      ExtMapBuffer4[i]=iMAOnArray(ExtMapBuffer2,iMax,MovingAveragePeriod2,0,MovingAverageType2,i);
      }
   }


Just so you know I can use iMAOnArray:



 
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 LightSeaGreen
#property indicator_color2 OrangeRed
 
extern int MAperiod = 5;
extern int MAtype   = 1;
 
//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
 
double XX;
 
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   IndicatorShortName("A/D_with_Avg");
//---- indicators
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,ExtMapBuffer1);
    SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(1,ExtMapBuffer2);  
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Accumulation/Distribution                                        |
//+------------------------------------------------------------------+
int start()
  {
  
  
   int limit,i,counted_bars=IndicatorCounted();
//----
   limit=Bars-counted_bars-1;
   
   i = limit;
   
   while(i>=0)
     {
      double high =High[i];
      double low  =Low[i];
      double open =Open[i];
      double close=Close[i];
      ExtMapBuffer1[i]=(close-low)-(high-close);
      if(ExtMapBuffer1[i]!=0)
        {
         double diff=high-low;
         if(0==diff)
            ExtMapBuffer1[i]=0;
         else
           {
            ExtMapBuffer1[i]/=diff;
            ExtMapBuffer1[i]*=Volume[i];
           }
        }
      if(i<Bars-1) ExtMapBuffer1[i]+= NormalizeDouble( ExtMapBuffer1[i+1], Digits ) ;
      i--;
     }
     
     
  for(i = limit ; i >= 0; i--) 
  { 
   XX               = iMAOnArray(ExtMapBuffer1,Bars,MAperiod,0,MAtype,i); 
   ExtMapBuffer2[i] = NormalizeDouble(XX, Digits ) ;  
  }     
     
     
//----
   return(0);
  }


Is it because of the arrays instead of INDEX buffers that I am having problems?

 
TheRumpledOne:


How does one make this work properly?



Right now, I have one array plotting "backwards". The numbers are correct but the order is wrong. I have tried every combination of ArraySetAsSeries() to no avail. This is frustrating. I have been programming since 1977 and haven't been stumped like this for a long time. I know it has to be SIMPLE!!




This is in a SCRIPT:




Just so you know I can use iMAOnArray:





Is it because of the arrays instead of INDEX buffers that I am having problems?



I may have "fixed" the problem by adding these statements:



int start()
{
 
ArraySetAsSeries(ExtMapBuffer2, true);
ArraySetAsSeries(ExtMapBuffer3, true);
ArraySetAsSeries(ExtMapBuffer4, true);


Only problem is now, the moving averages don't seem to "get up to speed" fast enough.


Using a 2 period average should mean it only takes 2 bars to get up to speed but it's taking longer.

 

Index Buffer arrays are series arrays by default. They will be intialized with the SetIndexBuffer() function.

Other arrays are not, and have to be set as "series", for use with any of the iXXXOnArray() functions.

.

If using iMAOnArray, the array must be a "series" array.

I would say DO NOT use the "total" paramter, I never have, and don't have problems. Leave it zero. This thread is about "buggy" results when "total" is not zero.

.

You don't have to use the default ExtMapBuffer1-8 names, by the way.

Reason: