Indicator shows wrong values

 
Hi, I have rewritten an indicator from MQL4 to MQL5, but it is not displayed correctly. When I reload it, it shows different values than before.
//+------------------------------------------------------------------+
//|                                                         Test.mq5 |
//|                                        Copyright 2019, Arthur S. |
//|                    https://www.mql5.com/en/users/michael12345678 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, Arthur S."
#property link      "https://www.mql5.com/en/users/michael12345678"
#property version   "1.00"

#property indicator_chart_window
#property indicator_buffers 6
#property indicator_plots 4

#property indicator_label1 "1" //"Blue Line"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2

#property indicator_label2 "2" //"Red Line"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_style2 STYLE_SOLID
#property indicator_width2 2

#property indicator_label2 "3" //"Red Line"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_style2 STYLE_SOLID
#property indicator_width2 2

#property indicator_label1 "4" //"Blue Line"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2

input int num40 = 40;
double appliedprice = 0.0;
double num = 0.0;
double ind2[];
double ind3[];
double ind0[];
double ind1[];
int result;

double MovingAverageBuffer1[];
double MovingAverageBuffer2[];

int MovingAverage1;
int MovingAverage2;

int j2;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   SetIndexBuffer(0,ind0,INDICATOR_DATA);
   SetIndexBuffer(1,ind1,INDICATOR_DATA);
   SetIndexBuffer(2,ind2,INDICATOR_DATA);
   SetIndexBuffer(3,ind3,INDICATOR_DATA);
   SetIndexBuffer(4,MovingAverageBuffer1,INDICATOR_CALCULATIONS);
   SetIndexBuffer(5,MovingAverageBuffer2,INDICATOR_CALCULATIONS);
   
   MovingAverage1=iMA(_Symbol,_Period,MathFloor(num40/2),0,MODE_LWMA,PRICE_CLOSE);
   if(MovingAverage1==INVALID_HANDLE)
   {
      Print("The iMA object was not created: Error ",GetLastError());
      return INIT_FAILED;
   }
   
   MovingAverage2=iMA(_Symbol,_Period,num40,0,MODE_LWMA,PRICE_CLOSE);
   if(MovingAverage2==INVALID_HANDLE)
   {
      Print("The iMA object was not created: Error ",GetLastError());
      return INIT_FAILED;
   }
   
   result=num40+MathFloor(MathSqrt(num40));
   
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
//   ArraySetAsSeries(MovingAverageBuffer1,true);
//   ArraySetAsSeries(MovingAverageBuffer2,true);
   
   int copied1=CopyBuffer(MovingAverage1,0,0,rates_total,MovingAverageBuffer1);
   int copied2=CopyBuffer(MovingAverage2,0,0,rates_total,MovingAverageBuffer2);
   
   int currentbarscounted = prev_calculated-1;
   if (currentbarscounted < 1) {
      for (int i = 1; i <= result; i++) ind2[Bars(_Symbol,_Period) - i] = 0;
      for (int i2 = 1; i2 <= num40; i2++) ind3[Bars(_Symbol,_Period) - i2] = 0;
   }
   if (currentbarscounted > 0) currentbarscounted--;
   int startpoint = Bars(_Symbol,_Period) - 2; //currentbarscounted;
//   for (int j = 0; j < startpoint; j++) ind3[j] = 2.0 * iMAMQL4(NULL, 0, MathFloor(num40 / 2), 0, MODE_LWMA, PRICE_CLOSE, j) - iMAMQL4(NULL, 0, num40, 0, MODE_LWMA, PRICE_CLOSE, j);
   for (int j = 0; j < startpoint; j++) ind3[j] = 2.0 * MovingAverageBuffer1[j] - MovingAverageBuffer2[j];
   for (int j2 = 0; j2 < startpoint; j2++) ind2[j2] = iMAOnArrayMQL4(ind3, 0, MathFloor(MathSqrt(num40)), 0, MODE_LWMA, j2 + num);
   for (int k = j2; k >= 0; k--) {
      if (ind3[k] > ind2[k]) {
         ind0[k] = high[k];
         ind1[k] = low[k];
      } else {
         if (ind3[k] < ind2[k]) {
            ind1[k] = high[k];
            ind0[k] = low[k];
         }
      }
   }
   
   return(rates_total);
}
//+------------------------------------------------------------------+
double iMAMQL4(string symbol,
               int tf,
               int period,
               int ma_shift,
               int method,
               int price,
               int shift)
  {
   ENUM_TIMEFRAMES timeframe=TFMigrate(tf);
   ENUM_MA_METHOD ma_method=MethodMigrate(method);
   ENUM_APPLIED_PRICE applied_price=PriceMigrate(price);
   int handle=iMA(symbol,timeframe,period,ma_shift,
                  ma_method,applied_price);
   if(handle<0)
     {
      Print("The iMA object is not created: Error",GetLastError());
      return(-1);
     }
   else
      return(CopyBufferMQL4(handle,0,shift));
  }
  double iMAOnArrayMQL4(double &array[],
                      int total,
                      int period,
                      int ma_shift,
                      int ma_method,
                      int shift)
  {
   double buf[],arr[];
   if(total==0) total=ArraySize(array);
   if(total>0 && total<=period) return(0);
   if(shift>total-period-ma_shift) return(0);
   switch(ma_method)
     {
      case MODE_SMA :
        {
         total=ArrayCopy(arr,array,0,shift+ma_shift,period);
         if(ArrayResize(buf,total)<0) return(0);
         double sum=0;
         int    i,pos=total-1;
         for(i=1;i<period;i++,pos--)
            sum+=arr[pos];
         while(pos>=0)
           {
            sum+=arr[pos];
            buf[pos]=sum/period;
            sum-=arr[pos+period-1];
            pos--;
           }
         return(buf[0]);
        }
      case MODE_EMA :
        {
         if(ArrayResize(buf,total)<0) return(0);
         double pr=2.0/(period+1);
         int    pos=total-2;
         while(pos>=0)
           {
            if(pos==total-2) buf[pos+1]=array[pos+1];
            buf[pos]=array[pos]*pr+buf[pos+1]*(1-pr);
            pos--;
           }
         return(buf[shift+ma_shift]);
        }
      case MODE_SMMA :
        {
         if(ArrayResize(buf,total)<0) return(0);
         double sum=0;
         int    i,k,pos;
         pos=total-period;
         while(pos>=0)
           {
            if(pos==total-period)
              {
               for(i=0,k=pos;i<period;i++,k++)
                 {
                  sum+=array[k];
                  buf[k]=0;
                 }
              }
            else sum=buf[pos+1]*(period-1)+array[pos];
            buf[pos]=sum/period;
            pos--;
           }
         return(buf[shift+ma_shift]);
        }
      case MODE_LWMA :
        {
         if(ArrayResize(buf,total)<0) return(0);
         double sum=0.0,lsum=0.0;
         double price;
         int    i,weight=0,pos=total-1;
         for(i=1;i<=period;i++,pos--)
           {
            price=array[pos];
            sum+=price*i;
            lsum+=price;
            weight+=i;
           }
         pos++;
         i=pos+period;
         while(pos>=0)
           {
            buf[pos]=sum/weight;
            if(pos==0) break;
            pos--;
            i--;
            price=array[pos];
            sum=sum-lsum+price*period;
            lsum-=array[i];
            lsum+=price;
           }
         return(buf[shift+ma_shift]);
        }
      default: return(0);
     }
   return(0);
  }
  ENUM_MA_METHOD MethodMigrate(int method)
  {
   switch(method)
     {
      case 0: return(MODE_SMA);
      case 1: return(MODE_EMA);
      case 2: return(MODE_SMMA);
      case 3: return(MODE_LWMA);
      default: return(MODE_SMA);
     }
  }
  ENUM_APPLIED_PRICE PriceMigrate(int price)
  {
   switch(price)
     {
      case 1: return(PRICE_CLOSE);
      case 2: return(PRICE_OPEN);
      case 3: return(PRICE_HIGH);
      case 4: return(PRICE_LOW);
      case 5: return(PRICE_MEDIAN);
      case 6: return(PRICE_TYPICAL);
      case 7: return(PRICE_WEIGHTED);
      default: return(PRICE_CLOSE);
     }
  }
  double CopyBufferMQL4(int handle,int index,int shift)
  {
   double buf[];
   switch(index)
     {
      case 0: if(CopyBuffer(handle,0,shift,1,buf)>0)
         return(buf[0]); break;
      case 1: if(CopyBuffer(handle,1,shift,1,buf)>0)
         return(buf[0]); break;
      case 2: if(CopyBuffer(handle,2,shift,1,buf)>0)
         return(buf[0]); break;
      case 3: if(CopyBuffer(handle,3,shift,1,buf)>0)
         return(buf[0]); break;
      case 4: if(CopyBuffer(handle,4,shift,1,buf)>0)
         return(buf[0]); break;
      default: break;
     }
   return(EMPTY_VALUE);
  }
  ENUM_TIMEFRAMES TFMigrate(int tf)
  {
   switch(tf)
     {
      case 0: return(PERIOD_CURRENT);
      case 1: return(PERIOD_M1);
      case 5: return(PERIOD_M5);
      case 15: return(PERIOD_M15);
      case 30: return(PERIOD_M30);
      case 60: return(PERIOD_H1);
      case 240: return(PERIOD_H4);
      case 1440: return(PERIOD_D1);
      case 10080: return(PERIOD_W1);
      case 43200: return(PERIOD_MN1);
      
      case 2: return(PERIOD_M2);
      case 3: return(PERIOD_M3);
      case 4: return(PERIOD_M4);      
      case 6: return(PERIOD_M6);
      case 10: return(PERIOD_M10);
      case 12: return(PERIOD_M12);
      case 16385: return(PERIOD_H1);
      case 16386: return(PERIOD_H2);
      case 16387: return(PERIOD_H3);
      case 16388: return(PERIOD_H4);
      case 16390: return(PERIOD_H6);
      case 16392: return(PERIOD_H8);
      case 16396: return(PERIOD_H12);
      case 16408: return(PERIOD_D1);
      case 32769: return(PERIOD_W1);
      case 49153: return(PERIOD_MN1);      
      default: return(PERIOD_CURRENT);
     }
  }
 

I don't know why, but the "iMAOnArrayMQL4" doesn't seem to be working properly.

Use "MovingAverages.mqh" instead.

#property indicator_chart_window
#property indicator_buffers 6
#property indicator_plots 4
#include <MovingAverages.mqh>

#property indicator_label1 "1" //"Blue Line"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2

#property indicator_label2 "2" //"Red Line"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_style2 STYLE_SOLID
#property indicator_width2 2

#property indicator_label3 "3" //"Red Line"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrRed
#property indicator_style3 STYLE_SOLID
#property indicator_width3 2

#property indicator_label4 "4" //"Blue Line"
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrBlue
#property indicator_style4 STYLE_SOLID
#property indicator_width4 2

input int num40 = 40;
//double appliedprice = 0.0;
int num = 0;

int OnInit()

//result = num40 + MathFloor(MathSqrt(num40));
for (int i = 1; i <= MathFloor(MathSqrt(num40)); i++)
   num += i;

int OnCalculate

int copied1 = CopyBuffer(MovingAverage1, 0, 0, rates_total, MovingAverageBuffer1);
int copied2 = CopyBuffer(MovingAverage2, 0, 0, rates_total, MovingAverageBuffer2);

/*int currentbarscounted = prev_calculated - 1;
if (currentbarscounted < 1)
{
   for (int i = 1; i <= result; i++) ind2[Bars(_Symbol, _Period) - i] = 0;
   for (int i2 = 1; i2 <= num40; i2++) ind3[Bars(_Symbol, _Period) - i2] = 0;
}
if (currentbarscounted > 0) currentbarscounted--;
int startpoint = Bars(_Symbol, _Period) - 2; //currentbarscounted;*/

//   for (int j = 0; j < startpoint; j++) ind3[j] = 2.0 * iMAMQL4(NULL, 0, MathFloor(num40 / 2), 0, MODE_LWMA, PRICE_CLOSE, j) - iMAMQL4(NULL, 0, num40, 0, MODE_LWMA, PRICE_CLOSE, j);
   
   int startpoint;
   
   if (prev_calculated == 0)
        startpoint = num40;
   else
        startpoint = prev_calculated - 1;
        
   for (int j = startpoint; j < rates_total; j++) 
        ind3[j] = 2.0 * MovingAverageBuffer1[j] - MovingAverageBuffer2[j];
        
   LinearWeightedMAOnBuffer(rates_total, prev_calculated, num40, (int)MathFloor(MathSqrt(num40)), ind3, ind2, num);
        
   //for (int j2 = startpoint; j2 < rates_total; j2++) 
        //ind2[j2] = iMAOnArrayMQ4(ind3, 0, MathFloor(MathSqrt(num40)), 0, MODE_LWMA, j2);
        
   for (int k = startpoint; k < rates_total; k++)
   {
      if (ind3[k] > ind2[k])
      {
         ind0[k] = high[k];
         ind1[k] = low[k];
      }
      else
      {
         if (ind3[k] < ind2[k])
         {
            ind1[k] = high[k];
            ind0[k] = low[k];
         }
      }
   }
 
Transferring Indicators from MQL4 to MQL5
Transferring Indicators from MQL4 to MQL5
  • www.mql5.com
Hello dear readers! In today's article I'm going to represent you an algorithm of transferring simple price calculations from MQL4 to MQL5. With a glance to the difference between MQL5 and MQL4 I added the library of functions mql4_2_mql5.mqh ; we will learn how to use it after reading this article. 1. Preparing an Indicator for Transferring...
 
Nagisa Unada:

I don't know why, but the "iMAOnArrayMQL4" doesn't seem to be working properly.

Use "MovingAverages.mqh" instead.

int OnInit()

int OnCalculate

Many, many thanks!!! You have really helped me a lot.

 
Carl Schreiber:

Maybe these articles help you:

https://www.mql5.com/de/articles/66
https://www.mql5.com/de/articles/81

Thanks, but I already know the article.

Reason: