//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2012, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""

#property indicator_separate_window
#property indicator_buffers 4

#property indicator_color1 White  //Red
#property indicator_color2 Magenta  //Blue
#property indicator_color3 DarkGray  //DimGray
#property indicator_color4 DarkGray  //DimGray
#property indicator_width1  2
#property indicator_width2  1
#property indicator_style3 2
#property indicator_style4 2

extern string  TimeFrame    = "Current time frame";
extern int Processed        = 2000;
extern int Control_Period   = 14;
extern int WprPeriod        = 14;
extern int Signal_Period    = 5;
extern int Signal_Method    = MODE_SMA;
extern int BB_Up_Period     = 12;
extern double BB_Up_Deviation  = 2.0;
extern int BB_Dn_Period     = 12;
extern double BB_Dn_Deviation  = 2.0;


double values[];
double signal[];
double band_up[];
double band_dn[];

string indicatorFileName;
bool   returnBars;
int    timeFrame;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init() 
  {
   SetIndexStyle(0,DRAW_LINE); SetIndexBuffer(0,values);
   SetIndexStyle(1,DRAW_LINE); SetIndexBuffer(1,signal);
   SetIndexStyle(2,DRAW_LINE); SetIndexBuffer(2,band_up);
   SetIndexStyle(3,DRAW_LINE); SetIndexBuffer(3,band_dn);
   indicatorFileName = WindowExpertName();
   returnBars        = TimeFrame == "returnBars";     if(returnBars)     return(0);
   timeFrame         = stringToTimeFrame(TimeFrame);
   IndicatorShortName(timeFrameToString(timeFrame)+WindowExpertName());
   return (0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int deinit() 
  {
   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) { values[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]);
         values[i]  = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue",Processed,Control_Period,Signal_Period,Signal_Method,
                              BB_Up_Period,BB_Up_Deviation,BB_Dn_Period,BB_Dn_Deviation,0,y);
         signal[i]  = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue",Processed,Control_Period,Signal_Period,Signal_Method,
                              BB_Up_Period,BB_Up_Deviation,BB_Dn_Period,BB_Dn_Deviation,1,y);
         band_up[i] = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue",Processed,Control_Period,Signal_Period,Signal_Method,
                              BB_Up_Period,BB_Up_Deviation,BB_Dn_Period,BB_Dn_Deviation,2,y);
         band_dn[i] = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue",Processed,Control_Period,Signal_Period,Signal_Method,
                              BB_Up_Period,BB_Up_Deviation,BB_Dn_Period,BB_Dn_Deviation,3,y);

        }
      return(0);
     }
   datetime bar_time;
   int idx,counter,offset,bar_shft,bar_cont;
   double price_high,price_close,price_low,trigger_high,trigger_low;
   double sum_up,sum_dn,complex_up,complex_dn;
   if(limit>Processed) limit=Processed;

   for(idx=limit; idx>=0; idx--) 
     {
      counter=0;
      complex_up=0; complex_dn=0;
      trigger_high=-999999; trigger_low=999999;

      while(counter<Control_Period) 
        {
         sum_up=0; sum_dn=0;

         offset=idx+counter;
         bar_time = iTime(Symbol(), 0, offset);
         bar_shft = iBarShift(Symbol(), 0, bar_time, FALSE);
         bar_cont = bar_shft - Period(); if(bar_cont < 0) bar_cont = 0;

         for(int jdx=bar_shft; jdx>=bar_cont; jdx--) 
           {
            price_high  = iHigh(Symbol(), 0, jdx);
            price_close = iClose(Symbol(), 0, jdx);
            price_low   = iLow(Symbol(), 0, jdx);
            if(price_high > trigger_high) {trigger_high = price_high; sum_up += price_close;}
            if(price_low  < trigger_low ) {trigger_low  = price_low;  sum_dn += price_close;}
           }

         counter++;
         complex_up+=sum_up; complex_dn+=sum_dn;
        }
      if(complex_dn!=0.0 && complex_up!=0.0)
         values[idx]=((complex_dn/complex_up-complex_up/complex_dn)+(iWPR(NULL,0,WprPeriod,idx)+50)/10) ;
     }

   for(idx=limit; idx>=0; idx--) 
     {
      signal[idx]  = iMAOnArray(values, 0, Signal_Period, 0, Signal_Method, idx);
      band_up[idx] = iBandsOnArray(values, 0, BB_Up_Period, BB_Up_Deviation, 0, MODE_UPPER, idx);
      band_dn[idx] = iBandsOnArray(values, 0, BB_Dn_Period, BB_Dn_Deviation, 0, MODE_LOWER, idx);
     }

   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 timeFrameToString(int tf)
  {
   for(int i=ArraySize(iTfTable)-1; i>=0; i--)
      if(tf==iTfTable[i]) return(sTfTable[i]);
   return("");
  }
//
//
//
//
//

string stringUpperCase(string str)
  {
   string   s=str;

   for(int length=StringLen(str)-1; length>=0; length--)
     {
      int tchar=StringGetChar(s,length);
      if((tchar>96 && tchar<123) || (tchar>223 && tchar<256))
         s=StringSetChar(s,length,tchar-32);
      else if(tchar>-33 && tchar<0)
         s=StringSetChar(s,length,tchar+224);
     }
   return(s);
  }
//+------------------------------------------------------------------+
