iMAOnArray question

 

Dear All,

It's my first post here, however, I have been using MT4 and MQL for two years now. I have come across something that I don't understand regarding iMAOnArray. In particular following is the indicator. It is Elder's Market Thermometer. T[] holds the greater of the high or low daily extensions. MT is an average of this. The issue is in calculating MT. For simplicity I look at simple moving average of two periods. I calculate this explicitly as well as using iMAOnArray. The interesting thing is that for the very second Bar in the Chart, both the explicit (manual) and iMAOnArray result are the same. However as of the third Bar, iMAOnArray goes beserk and publishes a MAX_LONG (i.e. 2 billion and something). These results are published by the Print statement at the bottom.

Obviously I must be doing something wrong. Can anyone point out what?

Thank you for your help,

CC

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 DarkGray
#property indicator_color2 Red

extern int LookBack=2;

double T[];
double MT[];

bool PrintOnce = true;

int init() {
//Alert(Bars);
IndicatorDigits(6);

SetIndexStyle(0,DRAW_HISTOGRAM);
SetIndexBuffer(0,T);
SetIndexLabel(0,"Temperature");

SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(1,MT);
SetIndexLabel(1,"EMA Temp");
SetIndexEmptyValue(1,0.0);

return(0);
}

int deinit() {

return(0);
}


int start() {
int i;
if (Bars<=LookBack) return(0);

int counted_bars=IndicatorCounted();

if (counted_bars<1) {
T[Bars-1] = 0.0;
MT[Bars-1] = 0.0;
for (i = 2; i<=LookBack-1; i++) {

if (High[Bars-i]<=High[Bars-i+1] && Low[Bars-i]>=Low[Bars-i+1])
T[Bars-i] = 0;
else if(High[Bars-i]-High[Bars-i+1] >= Low[Bars-i+1] - Low[Bars-i]) {
T[Bars-i] = High[Bars-i]-High[Bars-i+1];
} else {
T[Bars-i] = Low[Bars-i+1] - Low[Bars-i];
}

MT[Bars-i] = 0.0;
}
}

int st = Bars-LookBack;
if (counted_bars>=LookBack) {
st = Bars-counted_bars+1;
if(PrintOnce) {
Print("Now in Live Loop");
PrintOnce = false;
}
}

for (i = st; i>=0; i--) {
if (High[i]<=High[i+1] && Low[i]>=Low[i+1])
T[i] = 0;
else if(High[i]-High[i+1] >= Low[i+1] - Low[i]) {
T[i] = High[i]-High[i+1];
} else {
T[i] = Low[i+1] - Low[i];
}

double tt = 0.0;
for (int j = i+LookBack-1; j>=i; j--) {
tt+=T[j];
}
MT[i] = tt/LookBack;
if (i==Bars-2 || i==Bars-3) Print(DoubleToStr(MT[i],6));

MT[i]=iMAOnArray(T, 0, LookBack, 0, MODE_SMA, i);
if (i==Bars-2 || i==Bars-3) Print(DoubleToStr(MT[i],6));
}


return(0);
}

 

Please use this to post code . . . it makes it easier to read.

 
  1. Use SRC
  2. st = Bars-counted_bars+1;
    Initial run counted_bars is zero so you are going from Bars+1 down to zero instead of Bars-1
  3. or (i = 2; i<=LookBack-1; i++) {
    
    if (High[Bars-i]<=High[Bars-i+1] && Low[Bars-i]>=Low[Bars-i+1])
    T[Bars-i] = 0;
    else if(High[Bars-i]-High[Bars-i+1] >= Low[Bars-i+1] - Low[Bars-i]) {
    This is completely unreadable. You have TWO limit conditions, The look back for T which is one and the look back for MT which is LookBack. Separate and simplify
    #define DRAWBEGIN 1
    SetIndexDrawBegin(0, DRAWBEGIN);
    SetIndexDrawBegin(1, LookBack);
    :
    int start() {
        int Tbars=IndicatorCounted(), MTbars = Tbars;
        if (MTbars < LookBack)  mtBars  = LookBack;
        if (Tbars < DRAWBEGIN){ tBars   = DRAWBEGIN;
            T[Bars-1] = 0.0;
        }
        for( int i = Bars - 1 - Tbars; i >= 0; i--){
            if (High[i]<=High[i+1] && Low[i]>=Low[i+1])     T[i] = 0;
            else if(High[i]-High[i+1] >= Low[i+1] - Low[i]) T[i] = High[i]-High[i+1];
            else                                            T[i] = Low[i+1] - Low[i];
        }
        for( i = Bars - 1 - MTbars; i >= 0; i--){
            double tt = 0.0;
            for (int j = i+LookBack-1; j>=i; j--)   tt+=T[j];
            MT[i] = tt/LookBack;
    
            if (i==Bars-2 || i==Bars-3) Print(DoubleToStr(MT[i],6));
    
            MT[i]=iMAOnArray(T, 0, LookBack, 0, MODE_SMA, i);
            if (i==Bars-2 || i==Bars-3) Print(DoubleToStr(MT[i],6));
        }
    }

 

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 DarkGray
#property indicator_color2 Red

int LookBack=2;

double T[];
double MT[];

bool PrintOnce = true;

int init() {
   IndicatorDigits(6);

   SetIndexStyle(0,DRAW_HISTOGRAM);
   SetIndexBuffer(0,T);
   SetIndexLabel(0,"Temperature");

   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(1,MT);
   SetIndexLabel(1,"EMA Temp");
   SetIndexEmptyValue(1,0.0);

   return(0);
}

int deinit() {
   return(0);
} 


int start() {
    int i;
    if (Bars<=LookBack) return(0);   // error check

    int counted_bars=IndicatorCounted();

    // Perform calculations on first pass of indicator
    if (counted_bars<1) {
           T[Bars-1] = 0.0;   // Initialize Temperature to 0.0 on the first Bar
           MT[Bars-1] = 0.0;  // Initialize MA(Temperature) to 0.0 on the first Bar
          
           for (i = 2; i<=LookBack-1; i++) {
                // Bars 2 and onwards work out Elder's market temperature:
                // MAX(Hi[i]-Hi[i+1],Lo[i+1]-Lo[i]), in effect taking the 
                // bigger of the up or down run.

                if (High[Bars-i]<=High[Bars-i+1] && Low[Bars-i]>=Low[Bars-i+1]) 
                      T[Bars-i] = 0;
                else if(High[Bars-i]-High[Bars-i+1] >= Low[Bars-i+1] - Low[Bars-i]) {
                      T[Bars-i] = High[Bars-i]-High[Bars-i+1];
                } else {
                      T[Bars-i] = Low[Bars-i+1] - Low[Bars-i];
                }

                // The MA(Temperature) has its first 1..LookBack01 values set to 0.0
                MT[Bars-i] = 0.0;              }
     }

     // Figure out the start of the indicator loop.  
     // On the first pass it is at the index where the previous loop
     // left off.  All other passes are set at the second to last bar.
     int st = Bars-LookBack;        
     if (counted_bars>=LookBack) st = Bars-counted_bars+1;

     for (i = st; i>=0; i--) {
            // Same temperature calculation as above.
            if (High[i]<=High[i+1] && Low[i]>=Low[i+1]) 
                T[i] = 0;
            else if(High[i]-High[i+1] >= Low[i+1] - Low[i]) {
                T[i] = High[i]-High[i+1];
            } else {
                T[i] = Low[i+1] - Low[i];
            }

            // Manual simple moving average calculation.  This calculation produces the RIGHT answers.
            double tt = 0.0;
            for (int j = i+LookBack-1; j>=i; j--) {
                  tt+=T[j]; 
            }
            MT[i] = tt/LookBack; 
            // On Bars 2 and 3 print out the manual results to compare to the iMAOnArray result.
            if (i==Bars-2 || i==Bars-3) Print(DoubleToStr(MT[i],6));

            // Work out the SMA using the built in function.
            MT[i]=iMAOnArray(T, 0, LookBack, 0, MODE_SMA, i);
            if (i==Bars-2 || i==Bars-3) Print(DoubleToStr(MT[i],6));
 
            // QUESTION:
            // Here is the interesting question: both SMA methods above produce the same result for Bar 2
            // on Bar 3, the manual calculation as expected produces the (T[Bar-3] + T[Bar-2]) / 2,
            // However iMAOnArray produces 2147483647
            // ANYBODY KNOW WHY?
     }


    return(0);
}

Apologies for the previous copy paste. Here is the code again in the format requested, as well as with more detaile comments. MY question is in capitals at end. Effectively the manual calculation produces the right answers, however, the iMAOnArray function produces wrong answers from the 3rd Bar onwards (this is for the LookBack = 2, for bigger LookBacks it iMAOnArray will bomb on bar LookBack + 1).

Any ideas why?

Thank you very much for your feedback,

CC

 

Dear WHRoeder,

Your code certainly does work.

With regards to your first point on st. st is set to Bars - counted_bars + 1 only once conted_bars > 0, i.e. (as I understand it ) on the second pass.

I am obviously making a mistake somewhere, however, it is not obvious where, any pointers would help me understand my mistake.

Thank you again,

CC

 
It's still wrong. Always: Bars - 1 - counted_bars