MQL4. Индикатор Heiken Ashi Smoothed+MA_In_Color+MA

 

Здравствуйте. Пишу индикатор состоящий из трех: Heiken Ashi Smoothed+MA_In_Color+MA. В тестере выдает ошибку на 204 строке array out of range in 'Fire.mq4' (204,28). Помогите найти ошибку.

#property indicator_chart_window
#property indicator_buffers 8
//--- plot Heiken1
#property indicator_color1  clrBlack
//--- plot Heiken2
#property indicator_color2  clrBlack
//--- plot Heiken3
#property indicator_color3  clrWhite
//--- plot Heiken4
#property indicator_color4  clrLime
//--- plot MA_In_Color1
#property indicator_color5  clrGoldenrod
//--- plot MA_In_Color2
#property indicator_color6  clrDarkSeaGreen
//--- plot MA_In_Color3
#property indicator_color7  clrOrangeRed
//--- plot MA8
#property indicator_color8  clrDimGray
//--- parameters Heiken Ashi Smoothed
extern int MaMetod =2;
extern int MaPeriod=6;
extern int MaMetod2 =3;
extern int MaPeriod2=2;
//--- parameters MA_In_Color_wAppliedPrice
extern int MAPeriod=12;
extern int MAType=3;
extern int MAAppliedPrice = 6;
//--- parameters MA
extern int      Period_MA =6;  
extern ENUM_MA_METHOD Method_MA =MODE_SMA;          // 0-3 
extern ENUM_APPLIED_PRICE Price_MA =PRICE_CLOSE;    // 0-6
extern int      Shift;                             //сдвиг по бару
//--- indicator buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
double ExtMapBuffer4[];
double         MA_In_Color1Buffer[];
double         MA_In_Color2Buffer[];
double         MA_In_Color3Buffer[];
double         MABuffer[];

int ExtCountedBars=0;

int    MAMode;
string strMAType;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   int    draw_begin;
   string short_name;
//--- indicator buffers mapping
   IndicatorBuffers(8);
   SetIndexBuffer(0,ExtMapBuffer1);
   SetIndexBuffer(1,ExtMapBuffer2);
   SetIndexBuffer(2,ExtMapBuffer3);
   SetIndexBuffer(3,ExtMapBuffer4);
   SetIndexDrawBegin(0,10);
   SetIndexDrawBegin(1,10);
   SetIndexDrawBegin(2,10);
   SetIndexDrawBegin(3,10);
//---- indicator buffers mapping
   SetIndexBuffer(0,ExtMapBuffer1);
   SetIndexBuffer(1,ExtMapBuffer2);
   SetIndexBuffer(2,ExtMapBuffer3);
   SetIndexBuffer(3,ExtMapBuffer4);
//----
   IndicatorBuffers(3);
   SetIndexBuffer(4,MA_In_Color1Buffer);
   SetIndexBuffer(5,MA_In_Color2Buffer);
   SetIndexBuffer(6,MA_In_Color3Buffer);
   SetIndexStyle(2,DRAW_LINE,STYLE_SOLID,2);
   SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,2);
   SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,2);
//----
   IndicatorBuffers(1);   
   SetIndexBuffer(7,MABuffer);  
   SetIndexStyle(0,DRAW_LINE);
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
   if(Period_MA<2) Period_MA=13;
   draw_begin=Period_MA-1;
//---- indicator short name
   switch(Method_MA)
     {
      case 1 : short_name="EMA(";  draw_begin=0; break;
      case 2 : short_name="SMMA("; break;
      case 3 : short_name="LWMA("; break;
      default :
         Method_MA=0;
         short_name="SMA(";
     }
   IndicatorShortName(short_name+Period_MA+")");
   SetIndexDrawBegin(0,draw_begin);
//---- indicator buffers mapping
   SetIndexBuffer(0,MABuffer);
//---- initialization done
  
  switch (MAType)
   {
      case 1: strMAType="EMA"; MAMode=MODE_EMA; break;
      case 2: strMAType="SMMA"; MAMode=MODE_SMMA; break;
      case 3: strMAType="LWMA"; MAMode=MODE_LWMA; break;
      case 4: strMAType="LSMA"; break;
      default: strMAType="SMA"; MAMode=MODE_SMA; break;
   }
   IndicatorShortName( strMAType+ " (" +MAPeriod + ") ");
//---- initialization done 
  
   return(0);
  }
//+------------------------------------------------------------------+
//| LSMA with PriceMode                                              |
//| PrMode  0=close, 1=open, 2=high, 3=low, 4=median(high+low)/2,    |
//| 5=typical(high+low+close)/3, 6=weighted(high+low+close+close)/4  |
//+------------------------------------------------------------------+

double LSMA(int Rperiod, int prMode, int shift)
{
   int i;
   double sum, pr;
   int length;
   double lengthvar;
   double tmp;
   double wt;

   length = Rperiod;
 
   sum = 0;
   for(i = length; i >= 1  ; i--)
   {
     lengthvar = length + 1;
     lengthvar /= 3;
     tmp = 0;
     switch (prMode)
     {
     case 0: pr = Close[length-i+shift];break;
     case 1: pr = Open[length-i+shift];break;
     case 2: pr = High[length-i+shift];break;
     case 3: pr = Low[length-i+shift];break;
     case 4: pr = (High[length-i+shift] + Low[length-i+shift])/2;break;
     case 5: pr = (High[length-i+shift] + Low[length-i+shift] + Close[length-i+shift])/3;break;
     case 6: pr = (High[length-i+shift] + Low[length-i+shift] + Close[length-i+shift] + Close[length-i+shift])/4;break;
     }
     tmp = ( i - lengthvar)*pr;
     sum+=tmp;
    }
    wt = sum*6/(length*(length+1));
    
    return(wt);
}  
//+------------------------------------------------------------------+
//| 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[])
  {
   double maOpen, maClose, maLow, maHigh;
   double haOpen, haHigh, haLow, haClose;
   double MA_Cur, MA_Prev;
   if(Bars<=10) return(0);
   ExtCountedBars=IndicatorCounted();
//---- check for possible errors
   if (ExtCountedBars<0) return(-1);
//---- last counted bar will be recounted
   if (ExtCountedBars>0) ExtCountedBars--;
   int pos=Bars-ExtCountedBars-1;
   while(pos>=0)
   {
      haOpen=(ExtMapBuffer3[pos+1]+ExtMapBuffer4[pos+1])/2; // Здесь ошибка array out of range in 'Fire.mq4' (204,28)
      haClose=(maOpen+maHigh+maLow+maClose)/4;
      haHigh=MathMax(maHigh, MathMax(haOpen, haClose));
      haLow=MathMin(maLow, MathMin(haOpen, haClose));
      if (haOpen<haClose)
        {
         ExtMapBuffer1[pos]=haLow;
         ExtMapBuffer2[pos]=haHigh;
        }
      else
        {
         ExtMapBuffer1[pos]=haHigh;
         ExtMapBuffer2[pos]=haLow;
        }
      ExtMapBuffer3[pos]=haOpen;
      ExtMapBuffer4[pos]=haClose;
      pos--;
     }
   int i;
     
   if (MAType == 4)
      {
        MA_Cur = LSMA(MAPeriod, MAAppliedPrice,i);
        MA_Prev = LSMA(MAPeriod, MAAppliedPrice,i+1);
      }
      else
      {
        MA_Cur = iMA(NULL,0,MAPeriod,0,MAMode, MAAppliedPrice,i);
        MA_Prev = iMA(NULL,0,MAPeriod,0,MAMode, MAAppliedPrice,i+1);
      }
 
         
//========== COLOR CODING ===========================================               
        
       MA_In_Color3Buffer[i] = MA_Cur; //red 
       MA_In_Color2Buffer[i] = MA_Cur; //green
       MA_In_Color1Buffer[i] = MA_Cur; //yellow
       
        if (MA_Prev > MA_Cur)
        {
        MA_In_Color2Buffer[i] = EMPTY_VALUE;
        
        }
       else if (MA_Prev < MA_Cur) 
        {
        MA_In_Color1Buffer[i] = EMPTY_VALUE; //-1 red/greem tight
        
        }
         else 
         {
         
         MA_In_Color1Buffer[i]=EMPTY_VALUE;//EMPTY_VALUE;
         MA_In_Color2Buffer[i]=EMPTY_VALUE;//EMPTY_VALUE;
         }
   
if(Bars<=Period_MA) return(0);
   ExtCountedBars=IndicatorCounted();
//---- check for possible errors
   if (ExtCountedBars<0) return(-1);
//---- last counted bar will be recounted
   if (ExtCountedBars>0) ExtCountedBars--;
//----
   switch(Method_MA)
     {
      case 0 : sma();  break;
      case 1 : ema();  break;
      case 2 : smma(); break;
      case 3 : lwma();
     }
       
   return(0);
  }
//+------------------------------------------------------------------+
//| Simple Moving Average                                            |
//+------------------------------------------------------------------+
void sma()
  {
   double sum=0;
   int    i,pos=Bars-ExtCountedBars-1;
//---- initial accumulation
   if(pos<Period_MA) pos=Period_MA;
   for(i=1;i<Period_MA;i++,pos--)
      sum+=Close[pos];
//---- main calculation loop
   while(pos>=0)
     {
      sum+=Close[pos];
      MABuffer[pos]=sum/Period_MA;
           sum-=Close[pos+Period_MA-1];
           pos--;
     }
//---- zero initial bars
   if(ExtCountedBars<1)
      for(i=1;i<Period_MA;i++) MABuffer[Bars-i]=0;
  }
//+------------------------------------------------------------------+
//| Exponential Moving Average                                       |
//+------------------------------------------------------------------+
void ema()
  {
   double pr=2.0/(Period_MA+1);
   int    pos=Bars-2;
   if(ExtCountedBars>2) pos=Bars-ExtCountedBars-1;
//---- main calculation loop
   while(pos>=0)
     {
      if(pos==Bars-2) MABuffer[pos+1]=Close[pos+1];
      MABuffer[pos]=Close[pos]*pr+MABuffer[pos+1]*(1-pr);
           pos--;
     }
  }
//+------------------------------------------------------------------+
//| Smoothed Moving Average                                          |
//+------------------------------------------------------------------+
void smma()
  {
   double sum=0;
   int    i,k,pos=Bars-ExtCountedBars+1;
//---- main calculation loop
   pos=Bars-Period_MA;
   if(pos>Bars-ExtCountedBars) pos=Bars-ExtCountedBars;
   while(pos>=0)
     {
      if(pos==Bars-Period_MA)
        {
         //---- initial accumulation
         for(i=0,k=pos;i<Period_MA;i++,k++)
           {
            sum+=Close[k];
            //---- zero initial bars
            MABuffer[k]=0;
           }
        }
      else sum=MABuffer[pos+1]*(Period_MA-1)+Close[pos];
      MABuffer[pos]=sum/Period_MA;
           pos--;
     }
  }
//+------------------------------------------------------------------+
//| Linear Weighted Moving Average                                   |
//+------------------------------------------------------------------+
void lwma()
  {
   double sum=0.0,lsum=0.0;
   double price;
   int    i,weight=0,pos=Bars-ExtCountedBars-1;
//---- initial accumulation
   if(pos<Period_MA) pos=Period_MA;
   for(i=1;i<=Period_MA;i++,pos--)
     {
      price=Close[pos];
      sum+=price*i;
      lsum+=price;
      weight+=i;
     }
//---- main calculation loop
   pos++;
   i=pos+Period_MA;
   while(pos>=0)
     {
      MABuffer[pos]=sum/weight;
      if(pos==0) break;
      pos--;
      i--;
      price=Close[pos];
      sum=sum-lsum+price*Period_MA;
      lsum-=Close[i];
      lsum+=price;
     }
//---- zero initial bars
   if(ExtCountedBars<1)
      for(i=1;i<Period_MA;i++) MABuffer[Bars-i]=0;
  }
//+------------------------------------------------------------------+

 


 
Anna_89:

Здравствуйте. Пишу индикатор состоящий из трех: Heiken Ashi Smoothed+MA_In_Color+MA. В тестере выдает ошибку на 204 строке array out of range in 'Fire.mq4' (204,28). Помогите найти ошибку.

 


Если исправить одну ошибку в строке 204, то полезет куча ошибок в других строках.

Надо полностью переделывать логику индикатора.

Вместо LSMA лучше использовать LRMA. результат тот же, но формула значительно проще.

 

Буквально вчера обсуждали подобную ошибку. Решение, соответственно, такое же: добавить проверку на допустимость индекса бара.