//------------------------------------------------------------------
#property copyright "www,forex-station.com"
#property link      "www,forex-station.com"
//------------------------------------------------------------------
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1  clrLimeGreen
#property indicator_color2  clrPaleVioletRed
#property indicator_width1  2
#property indicator_width2  2
#property indicator_minimum 0
#property indicator_maximum 1
#property strict

//
//
//
//
//

extern ENUM_TIMEFRAMES    TimeFrame  = PERIOD_CURRENT; // Time frame
extern int                CCIPeriod  = 50;             // CCI period
extern ENUM_APPLIED_PRICE CCIPrice   = PRICE_TYPICAL;  // Price

double cci[],cciU[],cciD[],prices[],trend[],count[];
string IndicatorFileName;
#define _mtfCall(_buff,_ind) iCustom(NULL,TimeFrame,IndicatorFileName,PERIOD_CURRENT,CCIPeriod,CCIPrice,_buff,_ind)

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

int init()
{
   IndicatorBuffers(6);
      SetIndexBuffer(0,cciU); SetIndexStyle(0,DRAW_HISTOGRAM);
      SetIndexBuffer(1,cciD); SetIndexStyle(1,DRAW_HISTOGRAM);
      SetIndexBuffer(2,cci);
      SetIndexBuffer(3,prices);
      SetIndexBuffer(4,trend);
      SetIndexBuffer(5,count);
         IndicatorFileName = WindowExpertName();
         TimeFrame = MathMax(TimeFrame,_Period);   
   IndicatorShortName(timeFrameToString(TimeFrame)+" CCI ("+(string)CCIPeriod+")");
   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); count[0] = limit;
         if (TimeFrame != Period())
         {
            limit = (int)MathMax(limit,MathMin(Bars-1,_mtfCall(5,0)*TimeFrame/_Period));
            for(int i=limit; i>=0 && !_StopFlag; i--)
            {
               int y = iBarShift(NULL,TimeFrame,Time[i]);
               trend[i] = _mtfCall(4,y);
               cciD[i]  = (trend[i] == -1) ? 1 : EMPTY_VALUE;
               cciU[i]  = (trend[i] ==  1) ? 1 : EMPTY_VALUE;
            }
            return(0);
         }            

   //
   //
   //
   //
   //

   for(int i=limit,k; i>=0; i--)
   {
      prices[i] = iMA(NULL,0,1,0,MODE_SMA,CCIPrice,i);
      double avg = 0; for(k=0; k<CCIPeriod && (i+k)<Bars; k++) avg +=         prices[i+k];      avg /= (CCIPeriod);
      double dev = 0; for(k=0; k<CCIPeriod && (i+k)<Bars; k++) dev += MathAbs(prices[i+k]-avg); dev /= (CCIPeriod);
            cci[i]   = (dev!=0) ? (prices[i]-avg)/(0.015*dev) : 0;
            trend[i] = (cci[i]>0) ? 1 : (cci[i]<0) ? -1 : (i<Bars-1) ? trend[i+1] : 0;
            cciD[i]  = (trend[i] == -1) ? 1 : EMPTY_VALUE;
            cciU[i]  = (trend[i] ==  1) ? 1 : EMPTY_VALUE;
   }
   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("");
}