
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_color1  clrLime
#property indicator_width1  2
#property indicator_color2  clrLime
#property indicator_color3  clrRed
#property indicator_width3  2
#property indicator_color4  clrRed
#property indicator_width4  2
#property indicator_color5  clrWhite
#property indicator_width5  2

extern ENUM_TIMEFRAMES  TimeFrame       = PERIOD_CURRENT; // Time frame
input int               period          = 2; // Close of a bar how many periods back
input bool              updateeverytick = false;
input bool              alert           = true;
input bool              Interpolate     = true;              // Interpolate in mtf mode

double diff[],huu[],hdd[],hud[],hdu[],valh[],count[];

int timeoffirstbar, limitdown=1;
string indicatorFileName;
#define _mtfCall(_buff,_ind) iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,period,updateeverytick,alert,_buff,_ind)

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+

int init()
  {
    
//---- indicator line
   IndicatorBuffers(7);
   SetIndexBuffer(0,huu, INDICATOR_DATA); SetIndexStyle(0,DRAW_HISTOGRAM);
   SetIndexBuffer(1,hud, INDICATOR_DATA); SetIndexStyle(1,DRAW_HISTOGRAM);
   SetIndexBuffer(2,hdd, INDICATOR_DATA); SetIndexStyle(2,DRAW_HISTOGRAM);
   SetIndexBuffer(3,hdu, INDICATOR_DATA); SetIndexStyle(3,DRAW_HISTOGRAM);
   SetIndexBuffer(4,diff,INDICATOR_DATA); SetIndexStyle(4,DRAW_LINE);
   SetIndexBuffer(5,valh);
   SetIndexBuffer(6,count);
  
   timeoffirstbar=Time[1];
   if (updateeverytick) limitdown=0;  
   
   indicatorFileName = WindowExpertName();
   TimeFrame         = fmax(TimeFrame,_Period);
      
   IndicatorShortName(timeFrameToString(TimeFrame)+" histogram tool");
   return(0);
  }

//----


 
//+------------------------------------------------------------------+
//| MTF Supertrend                                                   |
//+------------------------------------------------------------------+

int start()
{

   int counted_bars=IndicatorCounted();
      if(counted_bars<0) return(-1);
      if(counted_bars>0) counted_bars--;
         int limit = fmin(Bars-counted_bars,Bars-1); count[0] = limit;
         
         //
         //
         //
         
         if (TimeFrame != Period())
         {
            limit = (int)MathMax(limit,MathMin(Bars-1,_mtfCall(6,0)*TimeFrame/_Period));
            for(int i=limit; i>=0 && !_StopFlag; i--)
            {
               int y = iBarShift(NULL,TimeFrame,Time[i]);
                  huu[i]  = _mtfCall(0,y);
                  hud[i]  = _mtfCall(1,y);
                  hdd[i]  = _mtfCall(2,y);
                  hdu[i]  = _mtfCall(3,y);
                  diff[i] = _mtfCall(4,y);
              
                  //
                  //
                  //
                     
                  if (!Interpolate || (i>0 && y==iBarShift(NULL,TimeFrame,Time[i-1]))) continue;
                    #define _interpolate(buff) buff[i+k] = buff[i]+(buff[i+n]-buff[i])*k/n
                    int n,k; datetime btime = iTime(NULL,TimeFrame,y);
                       for(n = 1; (i+n)<Bars && Time[i+n] >= btime; n++) continue;	
                       for(k = 1; k<n && (i+n)<Bars && (i+k)<Bars; k++) 
                       {
                          _interpolate(diff); 
                          huu[i+k] = (huu[i]!= 0.0) ? _interpolate(diff) : 0.0; 
  	                       hud[i+k] = (hud[i]!= 0.0) ? _interpolate(diff) : 0.0; 
  	                       hdd[i+k] = (hdd[i]!= 0.0) ? _interpolate(diff) : 0.0; 
  	                       hdu[i+k] = (hdu[i]!= 0.0) ? _interpolate(diff) : 0.0; 
                       }                 
         }
   return(0);
   }  
   
   //
   //
   //
   
   for(i=limit;i>=limitdown;i--)
   {
    diff[i]=Close[i]-Close[i+period]; 
    valh[i] = (i<Bars-1) ? (diff[i]>0) ? (diff[i]>diff[i+1]) ? 0 : 1 : (diff[i]<diff[i+1]) ? 2 : 3 : 0;     
    huu[i] = (valh[i] == 0) ? diff[i] : 0.0;
    hud[i] = (valh[i] == 1) ? diff[i] : 0.0;
    hdd[i] = (valh[i] == 2) ? diff[i] : 0.0;
    hdu[i] = (valh[i] == 3) ? diff[i] : 0.0;   
   }   
   
   // alert, if it hasn't been called already for the closed bar, and if the differential is sufficiently large:
   if ((alert) && (Time[1]!=timeoffirstbar) && (diff[1] > MathAbs(diff[2])+MathAbs(diff[3]))) 
      {
      Alert("histogram tool: Price differential is large and positive!"); 
      timeoffirstbar=Time[1];
      }      
   if ((alert) && (Time[1]!=timeoffirstbar) && (-diff[1] > MathAbs(diff[2])+MathAbs(diff[3]))) 
      {
      Alert("histogram tool: Price differential is large and negative!");
      timeoffirstbar=Time[1];
      }    
   
   return(0);
  }
//+------------------------------------------------------------------+

//
//
//

string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"};
int    iTfTable[] = {1,5,15,30,60,240,1440,10080,43200};

string timeFrameToString(int tf)
{
   for (int i=ArraySize(iTfTable)-1; i>=0; i--) 
         if (tf==iTfTable[i]) return(sTfTable[i]);
                              return("");
}



