//+------------------------------------------------------------------+
//| Web:                                                 Q(Sig0).mq4 |
//|                                                              MNS |
//|                                                mns777.ru@mail.ru |
//+------------------------------------------------------------------+
#property copyright "MNS"
#property link      "Web:" 
//---- Определение индикаторов
#property indicator_chart_window
#property indicator_buffers 8
//---- Цвета
     
#property indicator_color7 Gold
#property indicator_color8 Gold
//---- толщина индикаторных линий
#property indicator_width7 2
#property indicator_width8 2

//---- Параметры
//----Q1
extern int PeriodCCI = 14 ;
extern int PriceCCI = 5;
extern int BuyLevel = -100 ;
extern int SellLevel = 100 ;
//----Q2
extern int ExtDepth=12;
extern int ExtDeviation=5;
extern int ExtBackstep=3;



extern double NormalizeAccuracy = 0.0000;


//---- Буферы
double Q1[];
double Q2[];
double Q3[];
double Q4[];
double Q5[];
double Q6[];
double CrossUp[];
double CrossDown[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
  //---- Установка параметров прорисовки
  //     Q
  SetIndexStyle( 0, DRAW_NONE );
  SetIndexStyle( 1, DRAW_NONE );
  SetIndexStyle( 2, DRAW_NONE );
  SetIndexStyle( 3, DRAW_NONE );
  SetIndexStyle( 4, DRAW_NONE );
  SetIndexStyle( 5, DRAW_NONE );
  
  //     Сигналы
  SetIndexStyle( 6, DRAW_ARROW, EMPTY );
  SetIndexArrow( 6, 241 );
  SetIndexStyle( 7, DRAW_ARROW, EMPTY );
  SetIndexArrow( 7, 242 );
  //---- Задание буферов
  SetIndexBuffer( 0, Q1    );
  SetIndexBuffer( 1, Q2    );
  SetIndexBuffer( 2, Q3    );
  SetIndexBuffer( 3, Q4    );
  SetIndexBuffer( 4, Q5    );
  SetIndexBuffer( 5, Q6    );
  SetIndexBuffer( 6, CrossUp   );
  SetIndexBuffer( 7, CrossDown );
  
  IndicatorDigits( MarketInfo( Symbol(), MODE_DIGITS ) );
  
  //---- Название и метки
  IndicatorShortName( "Q(Sig0)" );
  SetIndexLabel( 0, NULL  );
  SetIndexLabel( 1, NULL );
  SetIndexLabel( 2, NULL   );
  SetIndexLabel( 3, NULL  );
  SetIndexLabel( 4, NULL   );
  SetIndexLabel( 5, NULL  );
  SetIndexLabel( 6, NULL  );
  SetIndexLabel( 7, NULL  );
  
  return ( 0 );
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
{
  static bool bBuy  = False;
  static bool bSell = False;
    
  bool   bConditionUp;
  bool   bConditionDown;
  double Range;
  double AvgRange;
  int    iLimit;
  int    i;
  int    counter;
  int    counted_bars = IndicatorCounted();
  
  
  //---- check for possible errors
  if ( counted_bars < 0 ) 
    return ( -1 );
  
  //---- last counted bar will be recounted
  if ( counted_bars > 0 ) counted_bars--;
  
  iLimit = Bars - counted_bars;
  
  for ( i = 0; i <= iLimit; i++ ) {
    Q1[i] = iCCI(NULL,0,PeriodCCI,PriceCCI,i);
    Q2[i] = iCustom(NULL,0,"ZigZag",ExtDepth, ExtDeviation,ExtBackstep,0,i);
    Q3[i] = 0;
    Q4[i] = 0;
    Q5[i] = 0;
    Q6[i] = 0;
  } 
  
  for ( i = 1; i <= iLimit; i++ ) {
    AvgRange = 0;
    for ( counter = i; counter <= i + 9; counter++ ) {
      AvgRange += MathAbs( High[ counter ] - Low[ counter ] );
    }
    Range = AvgRange/10;
    
    /*if ( i == 0 ) {
      bConditionUp   = ( FastMA[i  ] > SlowMA[i  ] ) &&
                       ( FastMA[i+1] < SlowMA[i+1] ); // пересечение вверх 
      bConditionDown = ( FastMA[i  ] < SlowMA[i  ] ) &&
                       ( FastMA[i+1] > SlowMA[i+1] ); // пересечение вниз
    }
    else {*/
      bConditionUp   = (Q1[i] > BuyLevel )&&  
                       (Q1[i+1] < BuyLevel )&& 
                       (Close[i] > High[i+1] ) &&
                       ( Q2[i+1] != 0 )&&                     
                              
                                                  
                                                                
                       ( NormalizeDouble(Q1[i]-Q1[i+1],4)>=NormalizeAccuracy);
                       
      bConditionDown =  (Q1[i] < SellLevel )&&  
                       (Q1[i+1] > SellLevel )&&
                       (Close[i] < Low[i+1] ) &&
                       ( Q2[i+1] != 0 )&&
                           
                         
                       
                       
                       
                       ( NormalizeDouble(Q1[i+1]-Q1[i],4)>=NormalizeAccuracy);
    //} 
    
    
                       
                       
    
      if ( bConditionUp )
    CrossUp[i] = Low[i] - Range * 0.5;
    else if ( bConditionDown )
    CrossDown[i] = High[i] + Range * 0.5;
    
    if ( !bBuy && bConditionUp ) {
      // Флаги
      bBuy  = True;  // установка флага покупки
      bSell = False; // сброс флага продажи
      
     
       
      
    }
    else if ( !bSell && bConditionDown ) {
      // Флаги
      bSell = True;  // установка флага продажи
      bBuy  = False; // сброс флага покупки
      
     
       
    } 
  } 
 return ( 0 );
}