//+------------------------------------------------------------------+
//|                                                    Zee Zee i.mq4 |
//|                                Copyright © 2007, Carlos J. Rivas |
//|                                                 carlos@vealo.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, Carlos J. Rivas"
#property link      "carlos@vealo.com"
#property description "modif. by Mobidik && Tankk"
//------
#property indicator_separate_window
#property indicator_buffers 5
//------
#property indicator_color1  clrLavender
#property indicator_color2  clrRed
#property indicator_color3  clrBlue
#property indicator_color4  clrGold
#property indicator_color5  clrMagenta
//------
#property indicator_width1  2
#property indicator_width2  3
#property indicator_width3  3
//------
#property indicator_style4  STYLE_DASH
#property indicator_style5  STYLE_DASH
//------
#property indicator_levelcolor clrGreen
#property indicator_levelstyle STYLE_DOT
//---- input parameters
extern int  CCIPeriod           = 15;
extern int  SmoothPeriod        = 1;
extern ENUM_MA_METHOD Mode      = MODE_SMA;
extern ENUM_APPLIED_PRICE Price = PRICE_OPEN;  //CLOSE;
extern int  SigCCI              = 15;
extern ENUM_MA_METHOD ModeS1    = MODE_LWMA;
extern int  SigSig              = 21;
extern ENUM_MA_METHOD ModeS2    = MODE_LWMA;
extern int  AlertLevel          = 200;
extern bool AlertMessageLevel   = true; 
extern bool AlertSoundLevel     = false;
extern bool AlertMessagePic     = true; 
extern bool AlertSoundPic       = false;
extern int  SignalBar           = 1;

datetime TimeBarP;
datetime TimeBarL;
//---- buffers
double CCIBuffer[], CCIBufferHi[], CCIBufferLow[];
double SIGCCI[], SIGSIG[];  int mns;
double RelBuffer[], DevBuffer[], MovBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   CCIPeriod = fmax(CCIPeriod,2);   
   SmoothPeriod = fmax(SmoothPeriod,1);   
   if (CCIPeriod==SmoothPeriod) SmoothPeriod+=1;
   mns = (CCIPeriod>SmoothPeriod) ? 1 : -1;
//---- 3 additional buffers are used for counting.
   IndicatorBuffers(8);   IndicatorDigits(1);
   SetIndexBuffer(0,CCIBuffer);     SetIndexStyle(0,DRAW_LINE);  SetIndexEmptyValue(0,0.0); 
   SetIndexBuffer(1,CCIBufferHi);   SetIndexStyle(1,DRAW_LINE);  SetIndexEmptyValue(1,0.0); 
   SetIndexBuffer(2,CCIBufferLow);  SetIndexStyle(2,DRAW_LINE);  SetIndexEmptyValue(2,0.0); 
   SetIndexBuffer(3,SIGCCI);        SetIndexStyle(3,DRAW_LINE);  SetIndexEmptyValue(3,0.0); 
   SetIndexBuffer(4,SIGSIG);        SetIndexStyle(4,DRAW_LINE);  SetIndexEmptyValue(4,0.0); 
   SetIndexBuffer(5,RelBuffer);     SetIndexStyle(5,DRAW_NONE);  
   SetIndexBuffer(6,DevBuffer);     SetIndexStyle(6,DRAW_NONE);  
   SetIndexBuffer(7,MovBuffer);     SetIndexStyle(7,DRAW_NONE);  
//---
   SetLevelValue(0,0); 
   SetLevelValue(1,AlertLevel); 
   SetLevelValue(2,-AlertLevel);
//---- name for DataWindow and indicator subwindow label
   string IndikName="Zee Zee ["+(string)CCIPeriod+"->"+(string)SmoothPeriod+"->"+(string)SigCCI+"->"+(string)SigSig+"]";
   IndicatorShortName(IndikName);
   SetIndexLabel(0,"Zee Zee ["+(string)CCIPeriod+"->"+(string)SmoothPeriod+"]");
   SetIndexLabel(1,"CCI High  +200");
   SetIndexLabel(2,"CCI Low   -200");
   SetIndexLabel(3,"Signal for CCI ["+(string)SigCCI+"]");
   SetIndexLabel(4,"Signal for Signal ["+(string)SigSig+"]");
//----
   //SetIndexDrawBegin(0,CCIPeriod);
//----
   return(0);
  }
//**************************************************************************//
//***              Custom indicator deinitialization function              ***
//**************************************************************************//
int deinit()  { Comment("");  return(0); }
//+------------------------------------------------------------------+
//| Commodity Channel Index                                          |
//+------------------------------------------------------------------+
int start()
{
   int    i,k,CountedBars=IndicatorCounted();
   double price,sum,mul;
   if(Bars<=CCIPeriod) return(0);
//---- initial zero
   if (CountedBars<1)
     {
      for (i=1; i<=CCIPeriod; i++) {
        CCIBuffer[Bars-i]=0.0;
        DevBuffer[Bars-i]=0.0;
        MovBuffer[Bars-i]=0.0; }
     }
//---- last counted bar will be recounted
   int limit=Bars-CountedBars;
   if(CountedBars>0) limit++;
//---- moving average
   for(i=0; i<limit; i++)  MovBuffer[i]=iMA(NULL,0,CCIPeriod,0,Mode,Price,i);
//---- standard deviations
   i=Bars-CCIPeriod+1;
   if(CountedBars>CCIPeriod-1) i=Bars-CountedBars-1;
   mul=0.010/CCIPeriod;
   while(i>=0)
     {
      sum=0.0;
      k=i+CCIPeriod-1;
      while(k>=i)
       {
         price=iMA(NULL,0,SmoothPeriod,0,Mode,Price,k);
         sum+=MathAbs(price-MovBuffer[i]);
         k--;
       }
      DevBuffer[i]=sum*mul;
      i--;
     }
   i=Bars-CCIPeriod+1;
   if(CountedBars>CCIPeriod-1) i=Bars-CountedBars-1;
   while(i>=0)
     {
      price=iMA(NULL,0,SmoothPeriod,0,Mode,Price,i);
      RelBuffer[i]=price-MovBuffer[i];
      i--;
     }
//---- cci counting
   i=Bars-CCIPeriod+1;
   if(CountedBars>CCIPeriod) i=Bars-CountedBars-1;
   while(i>=0)
     {
      if(DevBuffer[i]==0.0) CCIBuffer[i]=0.0;
      else CCIBuffer[i]=RelBuffer[i]/DevBuffer[i]*mns;
      
      if (CCIBuffer[i] >= 200) {
        CCIBufferHi[i]=CCIBuffer[i];
        //CCIBuffer[i]=0.0;
      } 

      if (CCIBuffer[i] <= -200) {
        CCIBufferLow[i]=CCIBuffer[i];
        //CCIBuffer[i]=0.0;
      } 
      i--;
     }
//+------------------------------------------------------------------+

   for (i=limit; i>=0; i--) { if (SigCCI>1) SIGCCI[i] = iMAOnArray(CCIBuffer,Bars,SigCCI,0,ModeS1,i);   else SIGCCI[i]=0; }
   
   for (i=limit; i>=0; i--) { if (SigSig>1) SIGSIG[i] = iMAOnArray(SIGCCI,Bars,SigSig,0,ModeS2,i);   else SIGSIG[i]=0; }
//+------------------------------------------------------------------+
    
    if(AlertMessagePic || AlertSoundPic) 
     {
       if(TimeBarP!=Time[0] && CCIBuffer[2+SignalBar]>-200 && CCIBuffer[1+SignalBar]<-200 && CCIBuffer[SignalBar]<-200)
        {
          TimeBarP=Time[0];
          if(AlertMessagePic) Alert(WindowExpertName()+" - "+_Symbol+"  "+PeriodString()+" - пик Min");
          if(AlertSoundPic)   PlaySound("alert2.wav");
        }
       if(TimeBarP!=Time[0] && CCIBuffer[2+SignalBar]<200 && CCIBuffer[1+SignalBar]>200 && CCIBuffer[SignalBar]>200)
        {
          TimeBarP=Time[0];
          if(AlertMessagePic) Alert(WindowExpertName()+" - "+_Symbol+"  "+PeriodString()+" - пик Max");
          if(AlertSoundPic)   PlaySound("alert2.wav");
        }
     } 
     
    if(AlertMessageLevel || AlertSoundLevel) 
     {
       if(TimeBarL!=Time[0] && CCIBuffer[1+SignalBar]>-AlertLevel && CCIBuffer[SignalBar]<-AlertLevel)
        {
          TimeBarL=Time[0];
          if(AlertMessageLevel) Alert(WindowExpertName()+" - "+_Symbol+"  "+PeriodString()+" - пробит уровень: -"+AlertLevel);
          if(AlertSoundLevel)   PlaySound("alert2.wav");
        }
       if(TimeBarL!=Time[0] && CCIBuffer[1+SignalBar]<AlertLevel && CCIBuffer[SignalBar]>AlertLevel)
        {
          TimeBarL=Time[0];
          if(AlertMessageLevel) Alert(WindowExpertName()+" - "+_Symbol+"  "+PeriodString()+" - пробит уровень: +"+AlertLevel);
          if(AlertSoundLevel)   PlaySound("alert2.wav");
        }
     } 
//+------------------------------------------------------------------+
return(0);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string PeriodString()
{
    switch (_Period) 
     {
        case PERIOD_M1:  return("M1");
        case PERIOD_M5:  return("M5");
        case PERIOD_M15: return("M15");
        case PERIOD_M30: return("M30");
        case PERIOD_H1:  return("H1");
        case PERIOD_H4:  return("H4");
        case PERIOD_D1:  return("D1");
        case PERIOD_W1:  return("W1");
        case PERIOD_MN1: return("MN1");
     }    
   return("M" + string(_Period));
}
//-------------------------------------------------------------------+