#property link      "www.forex-tsd.com"      
#property copyright "www.forex-tsd.com" 

#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1  Red
#property indicator_color2  RoyalBlue
#property indicator_color3  Red
#property indicator_color4  RoyalBlue
#property indicator_width1  1
#property indicator_width2  1
#property indicator_width3  2
#property indicator_width4  2

//
//
//
//
//

extern string TimeFrame     = "Current time frame";
extern int    MaPeriod      = 21;
extern int    MaMetod       = 3;
extern int    Step          = 0;
extern bool   BetterFormula = false;

//
//
//
//
//

double Buffer1[];
double Buffer2[];
double Buffer3[];
double Buffer4[];
double trend[];
string indicatorFileName;
bool   returnBars;
int    timeFrame;

//+------------------------------------------------------------------+
//|                                                                  |
//|------------------------------------------------------------------|
//
//
//
//
//

int init()
{
   IndicatorBuffers(5);
   SetIndexBuffer(0,Buffer1); SetIndexStyle(0,DRAW_HISTOGRAM);
   SetIndexBuffer(1,Buffer2); SetIndexStyle(1,DRAW_HISTOGRAM);
   SetIndexBuffer(2,Buffer3); SetIndexStyle(2,DRAW_HISTOGRAM);
   SetIndexBuffer(3,Buffer4); SetIndexStyle(3,DRAW_HISTOGRAM);
   SetIndexBuffer(4,trend); 
   
   //
   //
   //
   //
   //
       
   indicatorFileName = WindowExpertName();
   returnBars        = TimeFrame == "returnBars";     if (returnBars)     return(0);
   timeFrame         = stringToTimeFrame(TimeFrame);
          
   //
   //
   //
   //
   //
   
   return(0);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int start()
{
   int counted_bars=IndicatorCounted();
      if(counted_bars<0) return(-1);
      if(counted_bars>0) counted_bars--;
         int limit=MathMin(Bars-counted_bars,Bars-1);
         if (returnBars) { Buffer1[0] = limit+1; return(0); }
         if (timeFrame!=Period())
         {
            limit = MathMax(limit,MathMin(Bars-1,iCustom(NULL,timeFrame,indicatorFileName,"returnBars",0,0)*timeFrame/Period()));
            for (int i=limit; i>=0; i--)
            {
               int y = iBarShift(NULL,timeFrame,Time[i]);               
                  Buffer1[i] = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue",MaPeriod,MaMetod,Step,BetterFormula,0,y);
                  Buffer2[i] = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue",MaPeriod,MaMetod,Step,BetterFormula,1,y);
                  Buffer3[i] = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue",MaPeriod,MaMetod,Step,BetterFormula,2,y);
                  Buffer4[i] = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue",MaPeriod,MaMetod,Step,BetterFormula,3,y);
            }
            return(0);
         }
      
   //
   //
   //
   //
   //
       
   double pointModifier = MathPow(10,Digits%2);
   for (int pos=limit; pos >= 0; pos--)
   {  
      double maOpen  = iMA(NULL,0,MaPeriod,0,MaMetod,PRICE_OPEN ,pos);
      double maClose = iMA(NULL,0,MaPeriod,0,MaMetod,PRICE_CLOSE,pos);
      double maLow   = iMA(NULL,0,MaPeriod,0,MaMetod,PRICE_LOW  ,pos);
      double maHigh  = iMA(NULL,0,MaPeriod,0,MaMetod,PRICE_HIGH ,pos);
   
      //
      //
      //
      //
      //
        
         if (BetterFormula) {
               if (maHigh!=maLow)
                     double haClose = (maOpen+maClose)/2+(((maClose-maOpen)/(maHigh-maLow))*MathAbs((maClose-maOpen)/2));
               else  haClose = (maOpen+maClose)/2; }
         else        haClose = (maOpen+maHigh+maLow+maClose)/4;
                     double haOpen   = (Buffer3[pos+1]+Buffer4[pos+1])/2;
                     double haHigh   = MathMax(maHigh, MathMax(haOpen,haClose));
                     double haLow    = MathMin(maLow,  MathMin(haOpen,haClose));

         if (haOpen<haClose) { Buffer1[pos]=haLow;  Buffer2[pos]=haHigh; } 
         else                { Buffer1[pos]=haHigh; Buffer2[pos]=haLow;  } 
                               Buffer3[pos]=haOpen;
                               Buffer4[pos]=haClose;
      
      //
      //
      //
      //
      //

      if (Step>0)
      {
         if(MathAbs(Buffer1[pos]-Buffer1[pos+1]) < Step*pointModifier*Point) Buffer1[pos]=Buffer1[pos+1];
         if(MathAbs(Buffer2[pos]-Buffer2[pos+1]) < Step*pointModifier*Point) Buffer2[pos]=Buffer2[pos+1];
         if(MathAbs(Buffer3[pos]-Buffer3[pos+1]) < Step*pointModifier*Point) Buffer3[pos]=Buffer3[pos+1];
         if(MathAbs(Buffer4[pos]-Buffer4[pos+1]) < Step*pointModifier*Point) Buffer4[pos]=Buffer4[pos+1];
      }
      trend[pos] = trend[pos+1];
         if (Buffer3[pos] < Buffer4[pos]) trend[pos] =  1;
         if (Buffer3[pos] > Buffer4[pos]) trend[pos] = -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};

//
//
//
//
//

int stringToTimeFrame(string tfs)
{
   tfs = stringUpperCase(tfs);
   for (int i=ArraySize(iTfTable)-1; i>=0; i--)
         if (tfs==sTfTable[i] || tfs==""+iTfTable[i]) return(MathMax(iTfTable[i],Period()));
                                                      return(Period());
}

//
//
//
//
//

string stringUpperCase(string str)
{
   string   s = str;

   for (int length=StringLen(str)-1; length>=0; length--)
   {
      int char = StringGetChar(s, length);
         if((char > 96 && char < 123) || (char > 223 && char < 256))
                     s = StringSetChar(s, length, char - 32);
         else if(char > -33 && char < 0)
                     s = StringSetChar(s, length, char + 224);
   }
   return(s);
}