
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 Lime
#property indicator_width1  2
#property indicator_color2 Red
#property indicator_width2  2
#property indicator_color3 White
#property indicator_width3  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[], up[], dn[],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(4);
   SetIndexStyle(0,DRAW_HISTOGRAM);
   SetIndexBuffer(0,up);
   SetIndexStyle(1,DRAW_HISTOGRAM);
   SetIndexBuffer(1,dn);
   SetIndexStyle(2,DRAW_LINE);
   SetIndexBuffer(2,diff);
   SetIndexBuffer(3,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(3,0)*TimeFrame/_Period));
            for(int i=limit; i>=0 && !_StopFlag; i--)
            {
               int y = iBarShift(NULL,TimeFrame,Time[i]);
                  up[i]   = _mtfCall(0,y);
                  dn[i]   = _mtfCall(1,y);
                  diff[i] = _mtfCall(2,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); 
                          up[i+k] = (up[i]!= 0.0) ? _interpolate(diff) : 0.0; 
  	                       dn[i+k] = (dn[i]!= 0.0) ? _interpolate(diff) : 0.0; 
                       }                 
         }
   return(0);
   }  
   
   //
   //
   //
   
   for(i=limit;i>=limitdown;i--)
   {
    diff[i]=Close[i]-Close[i+period];       
    if (diff[i]>0.0) {up[i]=diff[i]; dn[i]=0.0;};
    if (diff[i]<0.0) {dn[i]=diff[i]; up[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("");
}



