AlexSTAL_ZigZagProfExtra

Author: Aleksandr Chugunov & George Tischenko
Price Data Components
Series array that contains open time of each bar
Miscellaneous
Implements a curve of type %1
0 Views
0 Downloads
0 Favorites
AlexSTAL_ZigZagProfExtra
//+------------------------------------------------------------------+
//|                                     AlexSTAL_ZigZagProfExtra.mq4 |
//|                                                   AlexSTAL & PPC |
//|                      Professional Zig-Zag                        |
//+------------------------------------------------------------------+
#property copyright "Aleksandr Chugunov & George Tischenko"

#include <AlexSTAL_OutsideBar.mqh>

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 Red

// Êîëè÷åñòâî áàðîâ äëÿ ðàñ÷åòà ýêñòðåìóìîâ
// íå ìîæåò áûòü ìåíüøå 2
extern int ExtPeriod = 12;
// Ìèíèìàëüíîå ðàññòîÿíèå öåíû ìåæäó ñîñåäíèìè ïèêîì è âïàäèíîé (èíà÷å íå ðåãèñòðèðóåòñÿ)
extern int MinAmplitude = 10;
// Ìèíèìàëüíîå äâèæåíèå öåíû â ïóíêòàõ íà íóëåâîì áàðå äëÿ ïåðåðàñ÷åòà èíäèêàòîðà
extern int MinMotion = 0;
// Èñïîëüçîâàòü áîëåå òî÷íûé àëãîðèòì âû÷èñëåíèÿ ïîðÿäêà ôîðìèðîâàíèÿ High/Low áàðà
extern bool UseSmallerTFforEB = true;
// Ñêîëüêî áàðîâ íåîáõîäèìî ïðîâåðÿòü íà êîððåêòíîñòü óæå ïðîñ÷èòàííîé èñòîðèè
// 0 - âñþ èñòîðèþ
extern int ExtraCheckedBarsCount = 0;

// Áóôåðû èíäèêàòîðà
double UP[], DN[];

// Áóôåð äëÿ êýøèðîâàíèÿ âíåøíåãî áàðà
double OB[];

// =Extra= Â äàííûõ áóôåðàõ áóäåì ñîõðàíÿòü High/Low äëÿ êàæäîãî áàðà
double barH[], barL[];

// Âðåìÿ îòêðûòèÿ ïîñëåäíåãî îáñ÷èòàííîãî áàðà
datetime LastBarTime;
// Çàùèòà îò äîêà÷êè èñòîðèè
int LastBarsCount, LastBarNum;
// Äëÿ îïòèìèçàöèè ðàñ÷åòîâ
double LastBarLastHigh, LastBarLastLow;
// Âðåìÿ ïåðâîãî ýêñòðåìóìà (íåîáõîäèìî äëÿ àëãîðèòìà âíåøíåãî áàðà)
datetime TimeFirstExtBar;

// Ñòàòè÷åñêèå ïåðåìåííûå äëÿ óñêîðåíèÿ ðàñ÷åòîâ
double MP, MM;

// Âñïîìîãàòåëüíàÿ ïåðåìåííàÿ
bool DownloadHistory;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
   if (ExtPeriod < 2)
      ExtPeriod = 2;
   
   if (MinAmplitude < 0)
      MinAmplitude = 0;
   MP = NormalizeDouble(MinAmplitude * Point, Digits);
   
   if (MinMotion < 1)
      MinMotion = 1;
   MM = NormalizeDouble(MinMotion * Point, Digits);
   
   if (ExtraCheckedBarsCount < 0)   // =Extra=
      ExtraCheckedBarsCount = 0;
   
   //---- indicators
   IndicatorDigits(Digits);
   IndicatorBuffers(5);

   SetIndexBuffer(0, UP);
   SetIndexStyle(0, DRAW_ZIGZAG);
   SetIndexBuffer(1, DN);
   SetIndexStyle(1, DRAW_ZIGZAG);
   
   SetIndexBuffer(2, OB);
   SetIndexBuffer(3, barH);   // =Extra=
   SetIndexBuffer(4, barL);   // =Extra=
   
   LastBarsCount = 0;
   DownloadHistory = true;
   
   //----
   return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
{
   //----
   return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   // Áëîê ïîëíîé èíèöèàëèçàöèè ïðè ïîäêà÷êå èñòîðèè
   // ----------------------------------------------
   int counted_bars = IndicatorCounted(), i;
   
   // Ïðîâåðèì è îáíóëèì ïðè íåîáõîäèìîñòè èíäèêàòîðíûå áóôåðû
   if ( counted_bars != 0 )
      for (i = (Bars-counted_bars-2); i >= 0; i--)
        {
         if (UP[i] != EMPTY_VALUE)
            UP[i] = EMPTY_VALUE;
         if (DN[i] != EMPTY_VALUE)
            DN[i] = EMPTY_VALUE;
         if (OB[i] != EMPTY_VALUE)
            OB[i] = EMPTY_VALUE;
        }
   
   // Áåð忏íîãî... êàê ãîâîðèòñÿ ñàìè çíàåòå ÷òî
   // Ïðè ïîèñêå áàãà MT4 äîáàâèë...
   if (LastBarsCount == 0)
      LastBarsCount = Bars;
   if (Bars < LastBarsCount)
      DownloadHistory = true;
   LastBarsCount = Bars;
   
   // IndicatorCounted() ìîæåò îáíóëèòñÿ ïðè âîññòàíîâëåíèè ñâÿçè
   if ( counted_bars == 0 )
      DownloadHistory = true;
   
   // Çàùèòà îò äîêà÷êè ïðîïóùåííîé èñòîðèè âíóòðü ðàñ÷åòà
   if ( (counted_bars != 0) && (LastBarNum != 0) )
      if ( (Bars - iBarShift(NULL, 0, LastBarTime, true)) != LastBarNum )
         DownloadHistory = true;
   
   // Ïîëíàÿ èíèöèàëèçàöèÿ
   if (DownloadHistory)
     {
      ArrayInitialize(UP, EMPTY_VALUE);
      ArrayInitialize(DN, EMPTY_VALUE);
      ArrayInitialize(OB, EMPTY_VALUE);
      ArrayInitialize(barH, EMPTY_VALUE);   // =Extra=
      ArrayInitialize(barL, EMPTY_VALUE);   // =Extra=
      TimeFirstExtBar = 0;
      counted_bars = 0;
      LastBarTime = 0;
      LastBarNum = 0;
      DownloadHistory = false;
     }
   
   // Áëîê îïðåäåëåíèÿ ôîðìèðîâàíèÿ íîâîãî áàðà (ïåðâûé äîøåäøèé òèê)
   bool NewBar = false;
   if (LastBarTime != Time[0])
     {
      NewBar = true;
      LastBarTime = Time[0];
      LastBarNum = Bars;
      // íîâûé áàð - îáíóëèì ïåðåìåííûå äëÿ îïòèìèçàöèè ðàñ÷åòîâ
      LastBarLastHigh = High[0];
      LastBarLastLow = Low[0];
     }

   // Âû÷èñëèì íåîáõîäèìîå êîëè÷åñòâî áàðîâ äëÿ ïåðåñ÷åòà
   int BarsForRecalculation;
   if ( counted_bars != 0 )
     {
      BarsForRecalculation = Bars - counted_bars - 1;
      // Áëîê îïòèìèçàöèè ðàñ÷åòîâ
      if (!NewBar)
        {
         if ( (NormalizeDouble(High[0]-LastBarLastHigh, Digits) >= MM) || (NormalizeDouble(LastBarLastLow-Low[0], Digits) >= MM) )
           {
            LastBarLastHigh = High[0];
            LastBarLastLow = Low[0];
           } else {
            // Íà äàííîì òèêå ðàñ÷åò ïðîèçâîäèòü íå áóäåì, òàê êàê öåíà èçìåíÿëàñü âíóòðè
            // íóëåâîãî áàðà èëè æå å¸ èçìåíåíèÿ íå áûëè áîëüøå ìèíèìàëüíîãî ïîðîãà,
            // çàäàííîãî â ïåðåìåííîé MinMotion
            return(0);
           }
        }
     } else {
      BarsForRecalculation = Bars - ExtPeriod;
     }
   
   // =Extra=
   // Çàïîëíèì ìàññèâû íîâûìè çíà÷åíèÿìè ñ àíàëèçîì ñòàðûõ
   int FoundDifference = -1;
   int tmpCB = Bars - 1;
   if ( ExtraCheckedBarsCount > 0)
      tmpCB = MathMin(tmpCB, ExtraCheckedBarsCount);
   for (i = tmpCB; i >= (Bars - counted_bars); i--)
     {
      if (barH[i] != High[i])
        {
         FoundDifference = MathMax(FoundDifference, i);
         barH[i] = High[i];
        }
      
      if (barL[i] != Low[i])
        {
         FoundDifference = MathMax(FoundDifference, i);
         barL[i] = Low[i];
        }
     }

   // Äëÿ áàðîâ, ïîäñ÷èòàííûõ íà äàííîì òèêå ïðîñòî çàïîëíÿåì ìàññèâû
   for (i = (Bars - counted_bars - 1); i >= 0; i--)
     {
      barH[i] = High[i];
      barL[i] = Low[i];
     }
   
   // Áûëè íàéäåíû ïåðåðàñ÷åòû â ðàñ÷èòàííîì ïåðèîäå
   if ( FoundDifference != -1 )
     {
      for (i = FoundDifference; i >= 0; i--)
        {
         UP[i] = EMPTY_VALUE;
         DN[i] = EMPTY_VALUE;
         OB[i] = EMPTY_VALUE;
        }
      BarsForRecalculation = FoundDifference;
     }
   // =Extra= end
   
   //======================================================
   //======== îñíîâíîé öèêë ===============================
   //======================================================
   int LET;
   double H, L, Fup, Fdn;
   int lastUPbar, lastDNbar;
   double lastUP, lastDN;
   int m, n; // Äëÿ ïîèñêà ïîñëåäíåãî ýêñòðåìóìà
   for (i = BarsForRecalculation; i >= 0; i--)
     {
      // Ïîèñê ïîñëåäíåãî ýêñòðåìóìà
      // ---------------------------
      lastUP = 0;
      lastDN = 0;
      lastUPbar = i;
      lastDNbar = i;
      LET = 0; 
      m = 0; n = 0;
      while ( UP[lastUPbar] == EMPTY_VALUE )
        {
         if ( lastUPbar > (Bars-ExtPeriod) )
            break;
         lastUPbar++;
        }
      lastUP = UP[lastUPbar]; //âîçìîæíî íàøëè ïîñëåäíèé ïèê
      while ( DN[lastDNbar] == EMPTY_VALUE)
        {
         if ( lastDNbar > (Bars-ExtPeriod) )
            break;
         lastDNbar++;
        } 
      lastDN = DN[lastDNbar]; //âîçìîæíî íàøëè ïîñëåäíþþ âïàäèíó
   
      if ( lastUPbar < lastDNbar)
         LET = 1;
      if ( lastUPbar > lastDNbar)
         LET = -1;
      if ( lastUPbar == lastDNbar)
        {
         //lastUPbar==lastDNbar íàäî óçíàòü, êàêîé îäèíî÷íûé ýêñòðåìóì áûë ïîñëåäíèì:
         m = lastUPbar;
         n = m;
         while ( m == n )
           {
            m++; n++;
            while ( UP[m] == EMPTY_VALUE )
              {
               if ( m > (Bars-ExtPeriod) )
                  break;
               m++;
              } //âîçìîæíî íàøëè ïîñëåäíèé ïèê
            while ( DN[n] == EMPTY_VALUE )
              {
               if ( n > (Bars-ExtPeriod) )
                  break;
               n++;
              } //âîçìîæíî íàøëè ïîñëåäíþþ âïàäèíó
            if ( MathMax(m, n) > (Bars-ExtPeriod) )
               break;
           }
         if (m < n)
            LET = 1;       //áàçîâûé îòñ÷åò - ïèê
         else
            if (m > n)
               LET = -1; //áàçîâûé îòñ÷åò - âïàäèíà
        }
      // åñëè LET==0 - çíà÷èò ýòî íà÷àëî îòñ÷åòà èëè â ñàìîì íà÷àëå çàôèêñèðîâàí âíåøíèé áàð ñ 2 ýêñòðåìóìàìè
      // Êîíåö ïîèñêà ïîñëåäíåãî ýêñòðåìóìà
      // ----------------------------------

      //---- ðàññìîòðèì öåíîâûå ýêñòðåìóìû çà ðàñ÷åòíûé ïåðèîä:       
      H = High[iHighest(NULL, 0, MODE_HIGH, ExtPeriod, i)];
      L = Low[iLowest(NULL, 0, MODE_LOW, ExtPeriod, i)];
      Fup = High[i];
      Fdn = Low[i];
      
      //---- ïðîàíàëèçèðóåì ñèòóàöèþ è ðàññìîòðèì âîçìîæíîñòü ðåãèñòðàöèè íîâûõ ýêñòðåìóìîâ: 
      switch(Comb(i,H,L,Fup,Fdn))
        {
         //---- íà ðàñ÷åòíîì áàðå ïîòåíöèàëüíûé ïèê (Comb)      
         case 1 :
            switch(LET)
              {
               case 1 :
                  //ïðåäûäóùèé ýêñòðåìóì òîæå ïèê, âûáèðàåì áîëüøèé:
                  if ( lastUP < Fup )
                    {
                     UP[lastUPbar] = EMPTY_VALUE;
                     UP[i] = Fup;
                    }
                  break;
               case -1 :
                  if ( (Fup-lastDN) > MP ) //ïðåäûäóùèé ýêñòðåìóì - âïàäèíà
                     UP[i] = Fup;
                  break; 
               default :
                  UP[i] = Fup;
                  TimeFirstExtBar = iTime(NULL, 0, i); //0 - çíà÷èò ýòî íà÷àëî ðàñ÷åòà 
                  break; 
              }
            break;

         //---- íà ðàñ÷åòíîì áàðå ïîòåíöèàëüíàÿ âïàäèíà  (Comb)          
         case -1 :
            switch(LET)
              {
               case 1 :
                  if ( (lastUP-Fdn) > MP ) //ïðåäûäóùèé ýêñòðåìóì - ïèê
                     DN[i] = Fdn;
                  break; 
               case -1 :
                  //ïðåäûäóùèé ýêñòðåìóì òîæå âïàäèíà, âûáèðàåì ìåíüøóþ:
                  if ( lastDN > Fdn )
                    {
                     DN[lastDNbar] = EMPTY_VALUE;
                     DN[i] = Fdn;
                    }
                  break;
               default :
                  DN[i] = Fdn;
                  TimeFirstExtBar = iTime(NULL, 0, i); //0 - çíà÷èò ýòî íà÷àëî ðàñ÷åòà 
                  break;
              }
            break;

         //---- íà ðàñ÷åòíîì áàðå ïîòåíöèàëüíûé ïèê è ïîòåíöèàëüíàÿ âïàäèíà (Comb)        
         case 2 : //ïðåäïîëîæèòåëüíî ñíà÷àëà ñôîðìèðîâàëñÿ LOW ïîòîì HIGH (áû÷èé áàð)
            switch(LET)
              {
               case 1 : //ïðåäûäóùèé ýêñòðåìóì - ïèê
                  if ( (Fup-Fdn) > MP )
                    {
                     if ( (lastUP-Fdn) > MP )
                       {
                        UP[i] = Fup;
                        DN[i] = Fdn;
                       } else {
                        if ( lastUP < Fup )
                          {
                           UP[lastUPbar] = EMPTY_VALUE;
                           UP[i] = Fup;
                          }
                       }
                    } else {
                     if ( (lastUP-Fdn) > MP )
                        DN[i] = Fdn;
                     else {
                        if ( lastUP < Fup )
                          {
                           UP[lastUPbar] = EMPTY_VALUE;
                           UP[i] = Fup;
                          }
                       }
                    }
                  break;
               case -1 : //ïðåäûäóùèé ýêñòðåìóì - âïàäèíà
                  if ( (Fup-Fdn) > MP )
                    {
                     UP[i] = Fup;
                     if ( (Fdn < lastDN) && (iTime(NULL, 0, lastDNbar) > TimeFirstExtBar) )
                       {
                        DN[lastDNbar] = EMPTY_VALUE;
                        DN[i] = Fdn;
                       }
                    } else {
                     if ( (Fup-lastDN) > MP )
                        UP[i] = Fup;
                     else {
                        if ( lastDN > Fdn )
                          {
                           DN[lastDNbar] = EMPTY_VALUE;
                           DN[i] = Fdn;
                          }
                       }
                    }
                  break;
               default: break;
              } //switch LET
            break;

         //---- íà ðàñ÷åòíîì áàðå ïîòåíöèàëüíûé ïèê è ïîòåíöèàëüíàÿ âïàäèíà (Comb)        
         case -2 : //ïðåäïîëîæèòåëüíî ñíà÷àëà ñôîðìèðîâàëñÿ HIGH ïîòîì LOW (ìåäâåæèé áàð)
            switch(LET)
              {
               case 1 : //ïðåäûäóùèé ýêñòðåìóì - ïèê
                  if ( (Fup-Fdn) > MP )
                    {
                     DN[i] = Fdn;
                     if ( (lastUP < Fup) && (iTime(NULL, 0, lastUPbar) > TimeFirstExtBar) )
                       {
                        UP[lastUPbar] = EMPTY_VALUE;
                        UP[i] = Fup;
                       }
                    } else {
                     if ( (lastUP-Fdn) > MP)
                        DN[i] = Fdn;
                     else {
                        if ( lastUP < Fup )
                          {
                           UP[lastUPbar] = EMPTY_VALUE;
                           UP[i] = Fup;
                          }
                       }
                    }
                  break;
               case -1 : //ïðåäûäóùèé ýêñòðåìóì - âïàäèíà
                  if ( (Fup-Fdn) > MP )
                    {
                     if ( (Fup-lastDN) > MP )
                       {
                        UP[i] = Fup;
                        DN[i] = Fdn;
                       } else {
                        if (lastDN > Fdn)
                          {
                           DN[lastDNbar] = EMPTY_VALUE;
                           DN[i] = Fdn;
                          }
                       }
                    } else {
                     if ( (Fup-lastDN) > MP )
                        UP[i] = Fup;
                     else {
                        if ( lastDN > Fdn)
                          {
                           DN[lastDNbar] = EMPTY_VALUE;
                           DN[i] = Fdn;
                          }
                       }
                    }
                  break;
               default: break;
              } //switch LET
            break;
         
         default: break;
        } // switch (ãëàâíûé)
     } // for (ãëàâíûé)
   //----
   return(0);
}
//+------------------------------------------------------------------+
//| ôóíêöèÿ àíàëèçà òåêóùåé ñèòóàöèè                                 |
//+------------------------------------------------------------------+ 
int Comb(int i, double H, double L, double Fup, double Fdn)
{
   //----
   if (Fup==H && (Fdn==0 || (Fdn>0 && Fdn>L))) return(1);  //íà ðàñ÷åòíîì áàðå ïîòåíöèàëüíûé ïèê
   if (Fdn==L && (Fup==0 || (Fup>0 && Fup<H))) return(-1); //íà ðàñ÷åòíîì áàðå ïîòåíöèàëüíàÿ âïàäèíà
   if (Fdn==L && Fup==H)                                   //íà ðàñ÷åòíîì áàðå ïîòåíöèàëüíûé ïèê è ïîòåíöèàëüíàÿ âïàäèíà 
     {
      // Ïîïûòêà íàéòè êåøèðîâàííûå äàííûå â áóôåðå OB[]
      int OrderFormationHL = OB[i];
      if (OrderFormationHL == EMPTY_VALUE)
        {
         OrderFormationHL = GetOrderFormationBarHighLow(Symbol(), Period(), i, UseSmallerTFforEB);
         OB[i] = OrderFormationHL;
        }
      switch(OrderFormationHL)
        {
         case -1:       //ïðåäïîëîæèòåëüíî ñíà÷àëà ñôîðìèðîâàëñÿ LOW ïîòîì HIGH (áû÷èé áàð)
            return(2);
            break;
         case 1:        //ïðåäïîëîæèòåëüíî ñíà÷àëà ñôîðìèðîâàëñÿ HIGH ïîòîì LOW (ìåäâåæèé áàð)
            return(-2); 
            break;
        }
     }
   //----  
   return(0);           //íà ðàñ÷åòíîì áàðå ïóñòî...
}

Comments