convert mql4 to mql5

 
Hi, everyone,

I wanted to convert the following MQL4 Indicator to MQ5. Unfortunately, the compiler spits the error message: ARRAY OUT OF RANGE. The error message refers to the following line in the OnCalc(): " if(close[i]> close[i+1])  ". I do not quite understand the program logic of MQL4, which is why I can not interpret the error. However, I suspect that I somehow have to work with the ArraySetassSeries () function.


MQ5 Approach:

#property indicator_separate_window

#property indicator_buffers 3
#property indicator_plots   2
//---Number of Trades
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrViolet
#property indicator_width1  3
#property indicator_label1  "ForceIndex"

//---std deviation pos
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrYellow
#property indicator_width2  1
#property indicator_label2  "std dev"

extern int Period1=14; 
extern int MaPeriod = 10;
extern ENUM_MA_METHOD MaMode = MODE_EMA;
 

double Line[],Line2[];
double Temp[];


int OnInit()
{
 
   //IndicatorDigits(_Digits);
   //IndicatorSetInteger(INDICATOR_DIGITS,)
   
   SetIndexBuffer(0,Line,INDICATOR_DATA);
   SetIndexBuffer(1,Line2,INDICATOR_DATA);
   SetIndexBuffer(2,Temp,INDICATOR_CALCULATIONS);
   
   
return(INIT_SUCCEEDED);
}


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(time,true);
//ArraySetAsSeries(close,true);
//ArraySetAsSeries(tick_volume,true);

     int i,start;
//--- check for bars count
   if(rates_total<=Period1+MaPeriod)
      return(0);
//---
   start=Period1-1;
   if(start+1<prev_calculated)
      start=prev_calculated-2;
   else
     {
      for(i=0; i<start; i++)
        {
         Line[i]=0.0;
         Line2[i]=0.0;
         Temp[i]=0.0;
        }
     }
  
  
  
 
   for (i=start; i<rates_total && !IsStopped(); i++)
   {
      Temp[i]=0;
      if(close[i]> close[i+1]) // close[i+1] is out of range. 
      {
        Temp[i]=  tick_volume[i] * (close[i]- close[i+1]);
      }
  
     if(close[i]< close[i-1]) 
     {
       Temp[i]=  -1* tick_volume[i] * (close[i+1]- close[i]);
     }
      Line[i]=iMAOnArrayMQL4(Temp,0,Period1,0,MODE_SMA,i)*Period1;
  } 
  for (i=start; i<rates_total && !IsStopped(); i++) Line2[i] = iMAOnArrayMQL4(Line,0,MaPeriod,0,MaMode,i);

 return(rates_total);
}


int IndicatorCountedMQL4(int prev_calculated)
  {
   if(prev_calculated>0) return(prev_calculated-1);
   if(prev_calculated==0) return(0);
   return(0);
  }
  
  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);
  }


The original mq4 Version:

#property copyright "Copyright ?2018, Gehtsoft USA LLC"
#property link      "http://fxcodebase.com"
#property version "1.0"

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1  clrRed
#property indicator_color2  clrYellow

 
extern int Period1=14; 
extern int MaPeriod = 10;
extern ENUM_MA_METHOD MaMode = MODE_EMA;
 

double Line[],Line2[];
double Temp[];


int init()
{
 
   IndicatorDigits(_Digits);
   IndicatorBuffers(3);
   SetIndexBuffer(0,Line); SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(1,Line2);SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(2,Temp);
   IndicatorShortName("Time Segmented Volume");
return(0);
}

int deinit()
{

 return(0);
}

int start()
{
 
   int counted_bars=IndicatorCounted();
      if(counted_bars<0) return(-1);
      if(counted_bars>0) counted_bars--;
           int limit=MathMin(Bars-counted_bars,Bars-1);
  
   for (int i=limit; i>=0; i--)
   {
      Temp[i]=0;
      if(Close[i]> Close[i+1]) 
      {
        Temp[i]=  Volume[i] * (Close[i]- Close[i+1]);
      }
    Print("i: ",i," Close: ",Close[i]);
     if(Close[i]< Close[i+1]) 
     {
       Temp[i]=  -1* Volume[i] * (Close[i+1]- Close[i]);
     }
      Line[i]=iMAOnArray(Temp,0,Period1,0,MODE_SMA,i)*Period1;
  } 
  for (i=limit; i>=0; i--) Line2[i] = iMAOnArray(Line,0,MaPeriod,0,MaMode,i);

 return(0);
}


I would appreciate your Help :)
Files:
 
   for (int i=limit; i>=0; i--)
      if(close[i]> close[i+1]) // close[i+1] is out of range. 

In MT4, buffers and the predefined arrays are all ordered AsSeries. There is a difference between the arrays passed to OnCalculate (e.g. low[]) and the MT4 predefined variables (e.g. Low[].) The passed arrays have no default direction, just like MT5.

To determine the indexing direction of time[], open[], high[], low[], close[], tick_volume[], volume[] and spread[], call ArrayGetAsSeries(). In order not to depend on default values, you should unconditionally call the ArraySetAsSeries() function for those arrays, which are expected to work with.predefined variables (e.g. Low[].) The passed arrays have no default direction, just like MT5.
          Event Handling Functions - Functions - Language Basics - MQL4 Reference

Reason: