//+----------------------------------------------------------------------------------+
//|                                         Heiken ashi - Suavizado MTF Separado.mq4 |
//|                                                                                  |
//+----------------------------------------------------------------------------------+
#property copyright "rodolfo.leonardo@gmail.com"
#property version       "1.20"
#property link          "https://www.mql5.com/pt/users/rodolfolm"
#property description   "Indicador Heiken ashi Suavizado  MTF"
#property strict


#property indicator_chart_window
#property indicator_buffers 6
#property indicator_color1  CLR_NONE
#property indicator_color2  CLR_NONE
#property indicator_color3  CLR_NONE
#property indicator_color4  CLR_NONE
#property indicator_width3  0
#property indicator_width4  0

//------- Parametros ------------------------------------------

extern ENUM_TIMEFRAMES    TFBar = PERIOD_CURRENT; 

//extern int TFBar       = 1440;           // TimeFrame
 bool bcgr       = false;           // BackGround
 int NumberOfBar = 2000;           // Número de barras
 color ColorUp   = DarkGreen;//Cor de compra
 color ColorDown = Maroon;//Cor de venda
 bool PaintBar0 = true;//Pinta Barra Atual
extern int HmaPeriod = 30;

//+------------------------------------------------------------------+
double bufferHc[];
double bufferHo[];
double bufferHh[];
double bufferHl[];
double buffersinal[];
double buffersinalp[];
double working[][8];
int    HalfPeriod;
int    HullPeriod;
double MaxDistup;
double MaxDistdwn;

#define _hrOpen  0
#define _haOpen  1
#define _hrClose 2
#define _haClose 3
#define _hrHigh  4
#define _haHigh  5
#define _hrLow   6
#define _haLow   7

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void init() {
   int i;
   int StartBar = 0;   // added by RaptorUK
   
   if(!PaintBar0) StartBar = 1;   // RaptorUK added by RaptorUK

   
  for (i=StartBar; i<NumberOfBar; i++) {  // RaptorUK modded from 0 to StartBar
    ObjectDelete("BodyTF"+TFBar+"Bar"+i);
    ObjectDelete("ShadowTFh"+TFBar+"Bar" + i);
    ObjectDelete("ShadowTFl"+TFBar+"Bar" + i);

  }
  for (i=StartBar; i<NumberOfBar; i++) {  // modded from 0 to StartBar
    ObjectCreate("BodyTF"+TFBar+"Bar"+i, OBJ_RECTANGLE, 0, 0,0, 0,0);
    ObjectCreate("ShadowTFh"+TFBar+"Bar"+i, OBJ_TREND, 0, 0,0, 0,0);
    ObjectCreate("ShadowTFl"+TFBar+"Bar"+i, OBJ_TREND, 0, 0,0, 0,0);

  }
  
     SetIndexBuffer(0,bufferHh); SetIndexStyle(0,DRAW_HISTOGRAM);
   SetIndexBuffer(1,bufferHl); SetIndexStyle(1,DRAW_HISTOGRAM);
   SetIndexBuffer(2,bufferHc); SetIndexStyle(2,DRAW_HISTOGRAM);
   SetIndexBuffer(3,bufferHo); SetIndexStyle(3,DRAW_HISTOGRAM);
   SetIndexBuffer(4,buffersinal); 
    SetIndexBuffer(5,buffersinalp); 
   //
   //
   //
   //
   //
      
   HmaPeriod  = MathMax(2,HmaPeriod);
   HalfPeriod = MathFloor(HmaPeriod/2.0);
   HullPeriod = MathFloor(MathSqrt(HmaPeriod));
   
 
}

//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
void deinit() {
 
   int StartBar = 0;   // added by RaptorUK
   
   if(!PaintBar0) StartBar = 1;   // added by RaptorUK


  for (int i=StartBar; i<NumberOfBar; i++) {  // RaptorUK modded from 0 to StartBar
    ObjectDelete("BodyTF"+TFBar+"Bar"+i);
    ObjectDelete("ShadowTFh"+TFBar+"Bar" + i);
    ObjectDelete("ShadowTFl"+TFBar+"Bar" + i);

  }
  Comment("");
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start() {

int counted_bars=IndicatorCounted();
   int i,r,limit;

bool OK_Period=false;   
  switch (TFBar)
  {    
    case 0:OK_Period=true;break;
    case 1:OK_Period=true;break;
    case 5:OK_Period=true;break;
    case 15:OK_Period=true;break;
    case 30:OK_Period=true;break;
    case 60:OK_Period=true;break;
    case 240:OK_Period=true;break;
    case 1440:OK_Period=true;break;
    case 10080:OK_Period=true;break;
    case 43200:OK_Period=true;break;
  }
  if (OK_Period==false)
     {
        Comment("TFBar != 1,5,15,30,60,240(H4), 1440(D1),10080(W1), 43200(MN) !");   

       return(0);
     }
  

  double   po, pc;       // Öåíû îòêðûòèÿ è çàêðûòèÿ ñòàðøèõ ñâå÷åê
  double   ph=0, pl=500; // Öåíû õàé è ëîó ñòàðøèõ ñâå÷åê
  datetime to, tc, ts;   // Âðåìÿ îòêðûòèÿ, çàêðûòèÿ è òåíåé ñòàðøèõ ñâå÷åê


    
  
   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
         limit = Bars-counted_bars;
         if (ArrayRange(working,0) != Bars) ArrayResize(working,Bars);



 int TF = TFBar;
 
   for(i=limit, r=Bars-i-1; i >= 0; i--,r++)
   {
    if(0 <= r && r < Bars && 0 <= i && i < Bars-1){
      working[r][_hrOpen]  = iMA(NULL,TF,HalfPeriod,0,MODE_LWMA,PRICE_OPEN,i)*2-iMA(NULL,TF,HmaPeriod,0,MODE_LWMA,PRICE_OPEN,i);
      working[r][_haOpen]  = iLwma(_hrOpen,HullPeriod,r);
      working[r][_hrClose] = iMA(NULL,TF,HalfPeriod,0,MODE_LWMA,PRICE_CLOSE,i)*2-iMA(NULL,TF,HmaPeriod,0,MODE_LWMA,PRICE_CLOSE,i);
      working[r][_haClose] = iLwma(_hrClose,HullPeriod,r);
      working[r][_hrHigh]  = iMA(NULL,TF,HalfPeriod,0,MODE_LWMA,PRICE_HIGH,i)*2-iMA(NULL,TF,HmaPeriod,0,MODE_LWMA,PRICE_HIGH,i);
      working[r][_haHigh]  = iLwma(_hrHigh,HullPeriod,r);
      working[r][_hrLow]   = iMA(NULL,TF,HalfPeriod,0,MODE_LWMA,PRICE_LOW,i)*2-iMA(NULL,TF,HmaPeriod,0,MODE_LWMA,PRICE_LOW,i);
      working[r][_haLow]   = iLwma(_hrLow,HullPeriod,r);
      
    
      
      double haOpen  = (bufferHo[i+1]+bufferHc[i+1])/2.0; 
      double haClose = (working[r][_haOpen]+working[r][_haClose]+working[r][_haHigh]+working[r][_haLow])/4.0;
      double haHigh  = MathMax(working[r][_haHigh],MathMax(haOpen,haClose));
      double haLow   = MathMin(working[r][_haLow] ,MathMin(haOpen,haClose));

      if (haOpen<haClose) 
         {
            bufferHl[i]=haLow;
            bufferHh[i]=haHigh;
            
             ph = haHigh; 
             pl = haLow; 
         } 
      else
         {
            bufferHh[i]=haLow;
            bufferHl[i]=haHigh;
            
             ph = haLow; 
             pl = haHigh; 
             
         }
         
      bufferHo[i]=haOpen;
      bufferHc[i]=haClose;
      
      po = haOpen;
      pc = haClose;
      
      to = iTime(Symbol(), TFBar, i);
      tc = iTime(Symbol(), TFBar, i) + TFBar*60;
      
    

        //-------------------------------
      ObjectSet("BodyTF"+TFBar+"Bar"+i, OBJPROP_TIME1, to);  //âðåìÿ îòêðûòèÿ
      ObjectSet("BodyTF"+TFBar+"Bar"+i, OBJPROP_PRICE1, ph); //öåíà îòêðûòèÿ
      ObjectSet("BodyTF"+TFBar+"Bar"+i, OBJPROP_TIME2, tc);  //âðåìÿ çàêðûòèÿ
      ObjectSet("BodyTF"+TFBar+"Bar"+i, OBJPROP_PRICE2, pl); //öåíà çàêðûòèÿ
      ObjectSet("BodyTF"+TFBar+"Bar"+i, OBJPROP_STYLE, STYLE_SOLID);
      ObjectSet("BodyTF"+TFBar+"Bar"+i, OBJPROP_WIDTH, 2);
      ObjectSet("BodyTF"+TFBar+"Bar"+i, OBJPROP_BACK, bcgr);
    //-------------------------------
   
 
    buffersinal[i] = 0;
  if (NormalizeDouble(Bid,Digits) > NormalizeDouble(ph,Digits) && !(NormalizeDouble(Bid,Digits) < NormalizeDouble(pl,Digits))) {
        
         buffersinal[i] = 1;
        }
    if (NormalizeDouble(Bid,Digits) < NormalizeDouble(pl,Digits) &&!(NormalizeDouble(Bid,Digits) > NormalizeDouble(ph,Digits))) {
     buffersinal[i] = -1;
    }
    
     buffersinalp[i]=0;
    if (NormalizeDouble(Bid,Digits) > NormalizeDouble(ph,Digits) && !(NormalizeDouble(Bid,Digits) < NormalizeDouble(pl,Digits))) {
        
         if(MaxDistup<NormalizeDouble(Bid-ph,3)) MaxDistup = NormalizeDouble(Bid-ph,3);
         MaxDistdwn=0;
          int percent =  0;
          if(MaxDistup>0)percent = NormalizeDouble(Bid-ph,3)*100/MaxDistup;
       
         buffersinalp[i] = percent;
        }
        
      if (NormalizeDouble(Bid,Digits) < NormalizeDouble(pl,Digits) &&!(NormalizeDouble(Bid,Digits) > NormalizeDouble(ph,Digits))) {
      //+ NormalizeDouble(pl - Bid,3)
       if(MaxDistdwn< NormalizeDouble(pl - Bid,3)) MaxDistdwn =  NormalizeDouble(pl - Bid,3); 
         MaxDistup=0;
       
         int percent =  0;
         if(MaxDistdwn>0)percent =  NormalizeDouble(pl - Bid,3)* 100/MaxDistdwn;
         
        buffersinalp[i] = percent;
       
       }
       //-------------------------------
       if (haOpen<haClose) {
       
          
          ObjectSet("BodyTF"+TFBar+"Bar"+i, OBJPROP_COLOR, ColorUp);
          ObjectSet("ShadowTFh"+TFBar+"Bar"+i, OBJPROP_COLOR, ColorUp);
          ObjectSet("ShadowTFl"+TFBar+"Bar"+i, OBJPROP_COLOR, ColorUp);
 
        }
        else {
        
          ObjectSet("BodyTF"+TFBar+"Bar"+i, OBJPROP_COLOR, ColorDown);
          ObjectSet("ShadowTFh"+TFBar+"Bar"+i, OBJPROP_COLOR, ColorDown);
          ObjectSet("ShadowTFl"+TFBar+"Bar"+i, OBJPROP_COLOR, ColorDown);

        
     
          }   
            
     
      }
   }
   
   //
   //
   //
   //
   
    

      
      
  
  return(0);
}
//+------------------------------------------------------------------+


double iLwma(int forBuffer, int period, int shift)
{
   double weight=0;
   double sum   =0;
   int    i,k;
   
   if (shift>=period)
   {
      for (i=0,k=period; i<period; i++,k--)
      {
            weight += k;
            sum    += working[shift-i][forBuffer]*k;
        }
        if (weight !=0)
                return(sum/weight);
        else    return(0.0);
    }
    else return(working[shift][forBuffer]);
}