Indicador funciona no mt5 da XP, mas não no mt5 da Modal. Não sei como corrigir o problema.

 

Olá pessoal,

sou novo na programação do mql5, então não conheço muita coisa. geralmente eu procuro um indicador parecido com o que preciso e vou modificando até chegar no que quero. 

Peguei um indicador que calcula a média móvel dos volumes de alta e de baixa separados (https://www.mql5.com/pt/code/20381) e modifiquei para que fosse plotada a diferença entre essas médias em forma de histograma.

Deu certo na corretora XP, eu escolho o período e o método de cálculo (simples, exponencial ...) e é gerado o histograma. Porém, quando eu coloco esse indicador no mt5 da modal, ele funciona apenas o método de cálculo simples e ainda deixa bem lento o mt5, lentidão essa não presente na xp com o indicador colocado. Quando excluo o indicador do gráfico, mt5 da modal volta a ficar rápido.

Alguém pode me ajudar a identificar o problema, ou melhorar esse código ?

Obrigado,

Segue o código: 

//+------------------------------------------------------------------+
//|                                                 Split_Vol_MA.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                                 https://mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://mql5.com"
#property version   "1.00"
#property description "Split Moving Average of Volume"
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots   1
//--- plot UP
#property indicator_label1  "Hist"
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  clrBlue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
//--- plot DN
//#property indicator_label2  "Down"
//#property indicator_type2   DRAW_LINE
//#property indicator_color2  clrRed
//#property indicator_style2  STYLE_SOLID
//#property indicator_width2  1
//--- input parameters
input uint           InpPeriod   =  14;         // Period
input ENUM_MA_METHOD InpMethod   =  MODE_SMA;   // Method
//--- indicator buffers
double         BufferUP[];
double         BufferDN[];
double         BufferMaUp[];
double         BufferMaDn[];
double         BufferHist[];
//--- global variables
int            period_ma;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- set global variables
   period_ma=int(InpPeriod<1 ? 1 : InpPeriod);
//--- indicator buffers mapping
   SetIndexBuffer(0,BufferHist,INDICATOR_DATA);
   SetIndexBuffer(1,BufferUP,INDICATOR_CALCULATIONS);
   SetIndexBuffer(2,BufferDN,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,BufferMaUp,INDICATOR_CALCULATIONS);
   SetIndexBuffer(4,BufferMaDn,INDICATOR_CALCULATIONS);
   
//--- setting indicator parameters
   IndicatorSetString(INDICATOR_SHORTNAME,"SplitVolMA("+(string)period_ma+")");
   IndicatorSetInteger(INDICATOR_DIGITS,Digits());
//--- setting buffer arrays as timeseries
   ArraySetAsSeries(BufferUP,true);
   ArraySetAsSeries(BufferDN,true);
   ArraySetAsSeries(BufferMaUp,true);
   ArraySetAsSeries(BufferMaDn,true);
   ArraySetAsSeries(BufferHist,true);
//---
   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[])
  {
//--- Проверка на минимальное колиество баров для расчёта
   if(rates_total<period_ma) return 0;
//--- Установка массивов буферов как таймсерий
   ArraySetAsSeries(close,true);
   ArraySetAsSeries(volume,true);
   
//--- Проверка и расчёт количества просчитываемых баров
   int limit=rates_total-prev_calculated;
   if(limit>1)
     {
      limit=rates_total-2;
      ArrayInitialize(BufferUP,EMPTY_VALUE);
      ArrayInitialize(BufferDN,EMPTY_VALUE);
      ArrayInitialize(BufferHist,EMPTY_VALUE);
      ArrayInitialize(BufferMaUp,0);
      ArrayInitialize(BufferMaDn,0);
     }
//--- Подготовка данных
   for(int i=limit; i>=0 && !IsStopped(); i--)
     {
      BufferMaUp[i]=0;
      BufferMaDn[i]=0;
      if(close[i]>close[i+1])
         BufferMaUp[i]=(double)volume[i];
      else
         BufferMaDn[i]=(double)volume[i];
     }
//--- Расчёт индикатора
   for(int i=limit; i>=0 && !IsStopped(); i--)
     {
      BufferUP[i]=MAOnArray(BufferMaUp,0,period_ma,0,InpMethod,i);
      BufferDN[i]=MAOnArray(BufferMaDn,0,period_ma,0,InpMethod,i);
      BufferHist[i]=BufferUP[i]-BufferDN[i];
     }
     

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| iMAOnArray() https://www.mql5.com/ru/articles/81                 |
//+------------------------------------------------------------------+
double MAOnArray(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);
  }
//+------------------------------------------------------------------+
Split_MA
Split_MA
  • www.mql5.com
O indicador exibe numa janela separada dois componentes da média móvel para um determinado período - altista e baixista. Tem três parâmetros ajustáveis:
Razão: