//+------------------------------------------------------------------+
//|                                  master-heiken-ashi-smoothed.mq4 |
//|                        Copyright 2021, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+



#property indicator_separate_window
#property indicator_maximum 4.5
#property indicator_minimum 0.5
#property indicator_buffers 8
#property indicator_color1 Red
#property indicator_color2 Lime //current,0

#property indicator_color3 Red
#property indicator_color4 Lime //+1

#property indicator_color5 Red
#property indicator_color6 Lime  //+2

#property indicator_color7 Red
#property indicator_color8 Lime  //+3

//---- parameters
 int MaMetod =2;
 int MaPeriod=6;
 int MaMetod2 =3;
 int MaPeriod2=2;

//what is drawn
double bear_zero_buffer[];
double bull_zero_buffer[];
double bear_one_buffer[];
double bull_one_buffer[];
double bear_two_buffer[];
double bull_two_buffer[];
double bear_three_buffer[];
double bull_three_buffer[];

//extra buffers
//the second digit specifies the timeframe
double B10[];
double B20[];
double B30[];
double B40[];
double B50[];
double B60[];
double B70[];
double B80[];

double B11[];
double B21[];
double B31[];
double B41[];
double B51[];
double B61[];
double B71[];
double B81[];


double B12[];
double B22[];
double B32[];
double B42[];
double B52[];
double B62[];
double B72[];
double B82[];


double B13[];
double B23[];
double B33[];
double B43[];
double B53[];
double B63[];
double B73[];
double B83[];

int period_one;
int period_two;
int period_three;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
  
  SetLevelValue(1,1);
  SetLevelValue(2,2);
  SetLevelValue(3,3);
  SetLevelValue(4,4);
   SetIndexLabel(0,"zero_bear");
   SetIndexLabel(1,"zero_bull");
   SetIndexLabel(2,"one_bear");
   SetIndexLabel(3,"one_bull");
   SetIndexLabel(4,"two_bear");
   SetIndexLabel(5,"two_bull");
   SetIndexLabel(6,"three_bear");
   SetIndexLabel(7,"three_bull");
   
   SetIndexStyle(0,DRAW_ARROW);
   SetIndexArrow(0,167);
   SetIndexStyle(1,DRAW_ARROW);
   SetIndexArrow(1,167);
   SetIndexStyle(2,DRAW_ARROW);
   SetIndexArrow(2,167);
   SetIndexStyle(3,DRAW_ARROW);
   SetIndexArrow(3,167);
   SetIndexStyle(4,DRAW_ARROW);
   SetIndexArrow(4,167);
   SetIndexStyle(5,DRAW_ARROW);
   SetIndexArrow(5,167);
   SetIndexStyle(6,DRAW_ARROW);
   SetIndexArrow(6,167);
   SetIndexStyle(7,DRAW_ARROW);
   SetIndexArrow(7,167);
   
//--- indicator buffers mapping
     IndicatorBuffers(40);
     SetIndexBuffer(0,bear_zero_buffer);
     SetIndexBuffer(1,bull_zero_buffer);
     SetIndexBuffer(2,bear_one_buffer);   SetIndexLabel(2,NULL);
     SetIndexBuffer(3,bull_one_buffer);   SetIndexLabel(3,NULL);
     SetIndexBuffer(4,bear_two_buffer);   SetIndexLabel(4,NULL);
     SetIndexBuffer(5,bull_two_buffer);   SetIndexLabel(5,NULL);
     SetIndexBuffer(6,bear_three_buffer); SetIndexLabel(6,NULL);
     SetIndexBuffer(7,bull_three_buffer); SetIndexLabel(7,NULL);
     
     SetIndexBuffer(8,B10);
     SetIndexBuffer(9,B20);
     SetIndexBuffer(10,B30);
     SetIndexBuffer(11,B40);
     SetIndexBuffer(12,B50);
     SetIndexBuffer(13,B60);
     SetIndexBuffer(14,B70);
     SetIndexBuffer(15,B80);
     
     SetIndexBuffer(16,B11);
     SetIndexBuffer(17,B21);
     SetIndexBuffer(18,B31);
     SetIndexBuffer(19,B41);
     SetIndexBuffer(20,B51);
     SetIndexBuffer(21,B61);
     SetIndexBuffer(22,B71);
     SetIndexBuffer(23,B81);
     
     SetIndexBuffer(24,B12);
     SetIndexBuffer(25,B22);
     SetIndexBuffer(26,B32);
     SetIndexBuffer(27,B42);
     SetIndexBuffer(28,B52);
     SetIndexBuffer(29,B62);
     SetIndexBuffer(30,B72);
     SetIndexBuffer(31,B82);
     
     SetIndexBuffer(32,B13);
     SetIndexBuffer(33,B23);
     SetIndexBuffer(34,B33);
     SetIndexBuffer(35,B43);
     SetIndexBuffer(36,B53);
     SetIndexBuffer(37,B63);
     SetIndexBuffer(38,B73);
     SetIndexBuffer(39,B83);


    if(Period()==1)
    {
       period_one=5;
       period_two=15;
       period_three=30;
    }
    else if(Period()==5)
    {
       period_one=15;
       period_two=30;
       period_three=60;
    }
    else if(Period()==15)
    {
       period_one=30;
       period_two=60;
       period_three=240;
    }
    else if (Period()==30)
    {
    
       period_one=60;
       period_two=240;
       period_three=1440;
    }
    else if(Period()==60)
    {
    
       period_one=240;
       period_two=1440;
       period_three=10080;
    }
    else if(Period()==240)
    {
       period_one=1440;
       period_two=10080;
       period_three=43200;
    }
    else
      return (INIT_FAILED);
   IndicatorShortName(NULL);
    
   
//---
   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[])
  {
//---
   //the starting limit
   if(Bars<=10) return(0);
   int counted_bars=IndicatorCounted();
   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
   int limit=Bars-counted_bars;
   if(counted_bars==0) limit-=1+MathMax(1,MathMax(MaPeriod,MaPeriod2));
   
   //the higher time frame limits
   int limit_one=limit;
   int limit_two=limit;
   int limit_three=limit;
   
   //-------------------------------
   //make sure i got data
   static int waitcount=30;
   if(prev_calculated==0)
   {
      if(waitcount>0)
      {
       datetime t1=iTime(Symbol(),period_one,0);
       datetime t2=iTime(Symbol(),period_two,0);
       datetime t3=iTime(Symbol(),period_three,0);
       if(t1==0||t2==0||t3==0)
       {
        waitcount--;
        Print("WAITING FOR DATA");
        return (prev_calculated);
       
       }
       Print("DATA IS NOW AVAILABLE");
      
      }
      else
      {
        Print("CANT WAIT FOR DATA ANY LONGER");
      }      
   }
  //---------------------------------------------- 
   
   if(prev_calculated>0)
   {
      if(limit_one<int(period_one/Period()))
       limit_one=int(period_one/Period());
      
      if(limit_one>ArraySize(time))
       limit_one=ArraySize(time);
       
       //--------------------
   
   if(limit_two<int(period_two/Period()))
       limit_two=int(period_two/Period());
      
      if(limit_two>ArraySize(time))
       limit_two=ArraySize(time);
   
   
   if(limit_three<int(period_three/Period()))
       limit_one=int(period_three/Period());
      
      if(limit_three>ArraySize(time))
       limit_three=ArraySize(time);
   }
   
   //now the calculations for zero timeframe
   
   double maOpen,maClose,maLow,maHigh;
   double haOpen,haHigh,haLow,haClose;
   
   int pos=limit;
   
   while(pos>=0)
     {
      maOpen=iMA(NULL,0,MaPeriod,0,MaMetod,PRICE_OPEN,pos);
      maClose=iMA(NULL,0,MaPeriod,0,MaMetod,PRICE_CLOSE,pos);
      maLow=iMA(NULL,0,MaPeriod,0,MaMetod,PRICE_LOW,pos);
      maHigh=iMA(NULL,0,MaPeriod,0,MaMetod,PRICE_HIGH,pos);
      //----
      haOpen=(B50[pos+1]+B60[pos+1])/2;
      haClose=(maOpen+maHigh+maLow+maClose)/4;
      haHigh=MathMax(maHigh,MathMax(haOpen,haClose));
      haLow=MathMin(maLow,MathMin(haOpen,haClose));
      if(haOpen<haClose)
        {
         B70[pos]=haLow;
         B80[pos]=haHigh;
        }
      else
        {
         B70[pos]=haHigh;
         B80[pos]=haLow;
        }
      B50[pos]=haOpen;
      B60[pos]=haClose;
      pos--;
     }
   int i;
   for(i=0; i<limit; i++) B10[i]=iMAOnArray(B70,0,MaPeriod2,0,MaMetod2,i);
   for(i=0; i<limit; i++) B20[i]=iMAOnArray(B80,0,MaPeriod2,0,MaMetod2,i);
   for(i=0; i<limit; i++) B30[i]=iMAOnArray(B50,0,MaPeriod2,0,MaMetod2,i);
   for(i=0; i<limit; i++) B40[i]=iMAOnArray(B60,0,MaPeriod2,0,MaMetod2,i);
   for(i=0;i<limit;i++){if(B70[i]<B80[i]){bull_zero_buffer[i]=4; bear_zero_buffer[i]=0;}
                        else             {bull_zero_buffer[i]=0; bear_zero_buffer[i]=4;} }
   
   //now the calcualtions for timeframe one
   
   double maOpen1,maClose1,maLow1,maHigh1;
   double haOpen1,haHigh1,haLow1,haClose1;
   
   int pos1=limit_one;
   
   while(pos1>=0)
     {
     
     int mtf_one=iBarShift(Symbol(),period_one,time[pos1],false);
     
      maOpen1=iMA(NULL,period_one,MaPeriod,0,MaMetod,PRICE_OPEN,mtf_one);
      maClose1=iMA(NULL,period_one,MaPeriod,0,MaMetod,PRICE_CLOSE,mtf_one);
      maLow1=iMA(NULL,period_one,MaPeriod,0,MaMetod,PRICE_LOW,mtf_one);
      maHigh1=iMA(NULL,period_one,MaPeriod,0,MaMetod,PRICE_HIGH,mtf_one);
      //----
      haOpen1=(B51[pos1+1]+B61[pos1+1])/2;
      haClose1=(maOpen1+maHigh1+maLow1+maClose1)/4;
      haHigh1=MathMax(maHigh1,MathMax(haOpen1,haClose1));
      haLow1=MathMin(maLow1,MathMin(haOpen1,haClose1));
      if(haOpen1<haClose1)
        {
         B71[pos1]=haLow1;
         B81[pos1]=haHigh1;
        }
      else
        {
         B71[pos1]=haHigh1;
         B81[pos1]=haLow1;
        }
      B51[pos1]=haOpen1;
      B61[pos1]=haClose1;
      pos1--;
     }
   //int i;
   for(i=0; i<limit_one; i++) B11[i]=iMAOnArray(B71,0,MaPeriod2,0,MaMetod2,i);
   for(i=0; i<limit_one; i++) B21[i]=iMAOnArray(B81,0,MaPeriod2,0,MaMetod2,i);
   for(i=0; i<limit_one; i++) B31[i]=iMAOnArray(B51,0,MaPeriod2,0,MaMetod2,i);
   for(i=0; i<limit_one; i++) B41[i]=iMAOnArray(B61,0,MaPeriod2,0,MaMetod2,i);
   for(i=0;i<limit;i++){if(B71[i]<B81[i]){bull_one_buffer[i]=3; bear_one_buffer[i]=0;}
                        else             {bull_one_buffer[i]=0; bear_one_buffer[i]=3;} }
   
   //for calcualtion of time frame two
   
   double maOpen2,maClose2,maLow2,maHigh2;
   double haOpen2,haHigh2,haLow2,haClose2;
   
   int pos2=limit_two;
   
   while(pos2>=0)
     {
     
     int mtf_two=iBarShift(Symbol(),period_two,time[pos2],false);
     
      maOpen2=iMA(NULL,period_two,MaPeriod,0,MaMetod,PRICE_OPEN,mtf_two);
      maClose2=iMA(NULL,period_two,MaPeriod,0,MaMetod,PRICE_CLOSE,mtf_two);
      maLow2=iMA(NULL,period_two,MaPeriod,0,MaMetod,PRICE_LOW,mtf_two);
      maHigh2=iMA(NULL,period_two,MaPeriod,0,MaMetod,PRICE_HIGH,mtf_two);
      //----
      haOpen2=(B52[pos2+1]+B62[pos2+1])/2;
      haClose2=(maOpen2+maHigh2+maLow2+maClose2)/4;
      haHigh2=MathMax(maHigh2,MathMax(haOpen2,haClose2));
      haLow2=MathMin(maLow2,MathMin(haOpen2,haClose2));
      if(haOpen2<haClose2)
        {
         B72[pos2]=haLow2;
         B82[pos2]=haHigh2;
        }
      else
        {
         B72[pos2]=haHigh2;
         B82[pos2]=haLow2;
        }
      B52[pos2]=haOpen2;
      B62[pos2]=haClose2;
      pos2--;
     }
   //int i;
   for(i=0; i<limit_two; i++) B12[i]=iMAOnArray(B72,0,MaPeriod2,0,MaMetod2,i);
   for(i=0; i<limit_two; i++) B22[i]=iMAOnArray(B82,0,MaPeriod2,0,MaMetod2,i);
   for(i=0; i<limit_two; i++) B32[i]=iMAOnArray(B52,0,MaPeriod2,0,MaMetod2,i);
   for(i=0; i<limit_two; i++) B42[i]=iMAOnArray(B62,0,MaPeriod2,0,MaMetod2,i);
   for(i=0;i<limit;i++){if(B72[i]<B82[i]){bull_two_buffer[i]=2; bear_two_buffer[i]=0;}
                        else             {bull_two_buffer[i]=0; bear_two_buffer[i]=2;} }
   //----------------------------------------------------------------------------------------------
   
   
   double maOpen3,maClose3,maLow3,maHigh3;
   double haOpen3,haHigh3,haLow3,haClose3;
   
   int pos3=limit_three;
   
   while(pos3>=0)
     {
     
     int mtf_three=iBarShift(Symbol(),period_three,time[pos3],false);
     
      maOpen3=iMA(NULL,period_three,MaPeriod,0,MaMetod,PRICE_OPEN,mtf_three);
      maClose3=iMA(NULL,period_three,MaPeriod,0,MaMetod,PRICE_CLOSE,mtf_three);
      maLow3=iMA(NULL,period_three,MaPeriod,0,MaMetod,PRICE_LOW,mtf_three);
      maHigh3=iMA(NULL,period_three,MaPeriod,0,MaMetod,PRICE_HIGH,mtf_three);
      //----
      haOpen3=(B53[pos3+1]+B63[pos3+1])/2;
      haClose3=(maOpen3+maHigh3+maLow3+maClose3)/4;
      haHigh3=MathMax(maHigh3,MathMax(haOpen3,haClose3));
      haLow3=MathMin(maLow3,MathMin(haOpen3,haClose3));
      if(haOpen3<haClose3)
        {
         B73[pos3]=haLow3;
         B83[pos3]=haHigh3;
        }
      else
        {
         B73[pos3]=haHigh3;
         B83[pos3]=haLow3;
        }
      B53[pos3]=haOpen3;
      B63[pos3]=haClose3;
      pos3--;
     }
   //int i;
   for(i=0; i<limit_three; i++) B13[i]=iMAOnArray(B73,0,MaPeriod2,0,MaMetod2,i);
   for(i=0; i<limit_three; i++) B23[i]=iMAOnArray(B83,0,MaPeriod2,0,MaMetod2,i);
   for(i=0; i<limit_three; i++) B33[i]=iMAOnArray(B53,0,MaPeriod2,0,MaMetod2,i);
   for(i=0; i<limit_three; i++) B43[i]=iMAOnArray(B63,0,MaPeriod2,0,MaMetod2,i);
   for(i=0;i<limit;i++){if(B73[i]<B83[i]){bull_three_buffer[i]=1; bear_three_buffer[i]=0;}
                        else             {bull_three_buffer[i]=0; bear_three_buffer[i]=1;} }
   
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
