// ---------------------------------------------------------------------------
//  Çèãçàã ïî ýêñòðåìóìàì êàê ó Ë.Âèëüÿìñà.
//
//  Âåðñèÿ 2.0: Ââåäåíà îïòèìèçàöèÿ ïîñëåäîâàòåëüíîñòåé ýêñòðåìóìîâ.
//
//  Âåðñèÿ 3.0: Ââåä¸í ðåæèì "áûñòðîé" ðàáîòû ïî ñôîðìèðîâàâøèìñÿ áàðàì.
//              Ââåäåíà ïîäñâåòêà òð¸õ óðîâíåé ýêñòðåìóìîâ - êàê â êíèãå
//              Ëàððè Âèëüÿìñà.
// ---------------------------------------------------------------------------
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_color1  SkyBlue
#property indicator_color2  SkyBlue
#property indicator_color3  Lime
#property indicator_color4  Blue
#property indicator_color5  Red
#property indicator_width1  2
#property indicator_width2  2
// Êîäû ñòðåëîê.
#define ARROW_CODE_L1 0x9F
#define ARROW_CODE_L2 0x77
#define ARROW_CODE_L3 0x6C
// Ïàðàìåòðû èíäèêàòîðà.
extern int  ZZ_LINE_LEVEL = 2;    // Óðîâåíü ïðî÷åð÷èâàåìûõ ëèíèé.
extern bool FAST_MODE     = true; // Ðåæèì ðàáîòû ïî ñôîðìèðîâàâøèìñÿ áàðàì.
                                  // Áóôåðû èíäèêàòîðà.
double buf_zz1[],buf_zz2[],buf_l1[],buf_l2[],buf_l3[];
int    maximum[],minimum[];
// Ïðåäåë óðîâíÿ, äî êîòîðîãî èùåì ýêñòðåìóìû.
int   max_level;
// Èíèöèàëèçàöèÿ.
int init()
  {
   IndicatorShortName(StringConcatenate(
                      "AZZX - LARRYZZ v3.0 (",ZZ_LINE_LEVEL,", ",FAST_MODE,")"));
   SetIndexBuffer(0,buf_zz1);
   SetIndexBuffer(1,buf_zz2);
   SetIndexBuffer(2,buf_l1);
   SetIndexBuffer(3,buf_l2);
   SetIndexBuffer(4,buf_l3);
   SetIndexStyle(0,DRAW_ZIGZAG);
   SetIndexStyle(1,DRAW_ZIGZAG);
   SetIndexStyle(2,DRAW_ARROW);
   SetIndexStyle(3,DRAW_ARROW);
   SetIndexStyle(4,DRAW_ARROW);
   SetIndexArrow(2,ARROW_CODE_L1);
   SetIndexArrow(3,ARROW_CODE_L2);
   SetIndexArrow(4,ARROW_CODE_L3);
   SetIndexEmptyValue(0,0);
   SetIndexEmptyValue(1,0);
   SetIndexEmptyValue(2,0);
   ArrayResize(maximum,Bars);
   ArrayResize(minimum,Bars);
   if(ZZ_LINE_LEVEL>3)
     {
      max_level=ZZ_LINE_LEVEL;
        } else {
      max_level=3;
     }
   return(0);
  }
// Ãëàâíûé öèêë.
int start()
  {
   int i,j;
// Ïîääåðæêà áûñòðîãî ðåæèìà ðàáîòû.
   if((FAST_MODE==true) && (Bars-IndicatorCounted()==1)) return(0);
   int counted_bars=IndicatorCounted();
   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
   int limit=Bars-counted_bars;
   if(counted_bars==0) limit--=1+1;
   ArrayResize(maximum,limit);
   ArrayResize(minimum,limit);
// Ïîèñê ýêñòðåìóìîâ.
   ArrayInitialize(maximum,0);
   ArrayInitialize(minimum,0);
   for(i=1; i<=max_level; i++) pass(i,limit);
// Ïîñòðîåíèå èíäèêàòîðîâ.
   ArrayInitialize(buf_zz1,0);
   ArrayInitialize(buf_zz2,0);
   ArrayInitialize(buf_l1,0);
   ArrayInitialize(buf_l2,0);
   ArrayInitialize(buf_l3,0);
   for(i=limit-1; i>=0; i--)
     {
      if(maximum[i]>=ZZ_LINE_LEVEL)
        {
         for(j=i+1; j<limit; j++)
           {
            buf_zz1[i]=High[i];
            if(minimum[j]>=ZZ_LINE_LEVEL)
              {
               // Íîðìàëüíàÿ ñèòóàöèÿ.
               break;
                 } else if((maximum[i]>=ZZ_LINE_LEVEL) && (buf_zz1[i]>0)) {
               // Îñòàíåòñÿ òîëüêî îäèí...
               if(High[i]>High[j])
                 {
                  buf_zz1[j]=0;
                    } else {
                  buf_zz1[i]=0;
                 }
              }
           }
        }
      if(minimum[i]>=ZZ_LINE_LEVEL)
        {
         for(j=i+1; j<limit; j++)
           {
            buf_zz2[i]=Low[i];
            if(maximum[j]>=ZZ_LINE_LEVEL)
              {
               // Íîðìàëüíàÿ ñèòóàöèÿ.
               break;
                 } else if((minimum[i]>=ZZ_LINE_LEVEL) && (buf_zz2[i]>0)) {
               // Îñòàíåòñÿ òîëüêî îäèí...
               if(Low[i]<Low[j])
                 {
                  buf_zz2[j]=0;
                    } else {
                  buf_zz2[i]=0;
                 }
              }
           }
        }
      if(maximum[i] == 1) buf_l1[i] = High[i];
      if(minimum[i] == 1) buf_l1[i] = Low [i];
      if(maximum[i] == 2) buf_l2[i] = High[i];
      if(minimum[i] == 2) buf_l2[i] = Low [i];
      if(maximum[i] >= 3) buf_l3[i] = High[i];
      if(minimum[i] >= 3) buf_l3[i] = Low [i];
     }
   return(0);
  }
// Ïðîõîä ïî óðîâíþ.
// Âîçâðàùàåò true, åñëè áûëè íàéäåíû ýêñòðåìóìû çàäàííîãî óðîâíÿ.
bool pass(int level,int lim)
  {
   return(pass_maximum(level,lim) || pass_minimum(level,lim));
  }
// Ïîèñê ìåíüøåãî èëè ðàâíîãî ìàêñèìóìà ñëåâà.
//  ñëó÷àå íåóäà÷è âîçâðàùàåò çàâåäîìî áîëüøîå ÷èñëî.
double find_left_maximum(int bar,int lim)
  {
   int i,level=maximum[bar];
   for(i=bar+1; i<lim; i++)
     {
      if(maximum[i]>=level)
        {
         return(High[i]);
        }
     }
// Äîøëè äî êîíöà èñòîðèè.
   return(High[bar]+1);
  }
// Ïîèñê ìåíüøåãî èëè ðàâíîãî ìàêñèìóìà ñïðàâà.
//  ñëó÷àå íåóäà÷è âîçâðàùàåò çàâåäîìî áîëüøîå ÷èñëî.
double find_right_maximum(int bar)
  {
   int i,level=maximum[bar];
   for(i=bar-1; i>=0; i--)
     {
      if(maximum[i]>=level)
        {
         return(High[i]);
        }
     }
// Äîøëè äî íà÷àëà èñòîðèè.
   return(High[bar]+1);
  }
// Ïðîõîä ïî ìàêñèìóìàì äëÿ óðîâíÿ.
// Âîçâðàùàåò true, åñëè áûëè íàéäåíû ìàêñèìóìû.
bool pass_maximum(int level,int lim)
  {
   int i,limit=lim-2,prev=level-1,result=false;
   for(i=1; i<limit; i++)
     {
      if(maximum[i]==prev)
        {
         double l = find_left_maximum(i,limit);
         double r = find_right_maximum(i);
         if((l<=High[i] && r<High[i]) || (l<High[i] && r<=High[i]))
           {
            maximum[i] = level;
            result     = true;
           }
        }
     }
   return(result);
  }
// Ïîèñê ìåíüøåãî èëè ðàâíîãî ìèíèìóìà ñëåâà.
//  ñëó÷àå íåóäà÷è âîçâðàùàåò çàâåäîìî ìåíüøåå ÷èñëî.
double find_left_minimum(int bar,int lim)
  {
   int i,level=minimum[bar];
   for(i=bar+1; i<lim; i++)
     {
      if(minimum[i]>=level)
        {
         return(Low[i]);
        }
     }
// Äîøëè äî êîíöà èñòîðèè.
   return(Low[bar]-1);
  }
// Ïîèñê ìåíüøåãî èëè ðàâíîãî ìèíèìóìà ñïðàâà.
//  ñëó÷àå íåóäà÷è âîçâðàùàåò çàâåäîìî ìåíüøåå ÷èñëî.
double find_right_minimum(int bar)
  {
   int i,level=minimum[bar];
   for(i=bar-1; i>=0; i--)
     {
      if(minimum[i]>=level)
        {
         return(Low[i]);
        }
     }
// Äîøëè äî íà÷àëà èñòîðèè.
   return(Low[bar]-1);
  }
// Ïðîõîä ïî ìèíèìóìàì äëÿ óðîâíÿ.
// Âîçâðàùàåò true, åñëè áûëè íàéäåíû ìèíèìóìû.
bool pass_minimum(int level,int lim)
  {
   int i,limit=lim-2,prev=level-1,result=false;
   for(i=1; i<limit; i++)
     {
      if(minimum[i]==prev)
        {
         double l = find_left_minimum(i,lim);
         double r = find_right_minimum(i);
         if((l>=Low[i] && r>Low[i]) || (l>Low[i] && r>=Low[i]))
           {
            minimum[i] = level;
            result     = true;
           }
        }
     }
   return(result);
  }
//+------------------------------------------------------------------+
             
            
            
            
            
Comments