Author: 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
ZZ_FF_v4
//+------------------------------------------------------------------+
//|                                                 ZZ_FF_v4.mq4   |
//|                                                 George Tischenko |
//|                    Zig-Zag & Fractal Filter                      |
//+------------------------------------------------------------------+
/*
Ðàñ÷åò öåíîâûõ ýêñòðåìóìîâ ïðîèçâîäèòñÿ ñ ïîìîùüþ ôóíêöèé iHighest / iLowest
Ôèëüòðàöèÿ ïîëó÷åííûõ çíà÷åíèé ïðîèçâîäèòñÿ ñ ïîìîùüþ ôðàêòàëüíîãî ôèëüòðà
äîáàâëåíà âèçóàëèçàöèÿ ôðàêòàëîâ, îïðåäåëåííûõ ïî àëãîðèòìó äàííîãî èíäèêàòîðà
*/
#property copyright "George Tischenko"

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 DodgerBlue
#property indicator_color2 DodgerBlue

extern int ExtPeriod=10;  //êîëè÷åñòâî áàðîâ äëÿ ðàñ÷åòà ýêñòðåìóìîâ
extern int MinAmp=10;     //ìèíèìàëüíîå ðàññòîÿíèå öåíû ìåæäó ñîñåäíèìè ïèêîì è âïàäèíîé (èíà÷å íå ðåãèñòðèðóåòñÿ)

int TimeFirstExtBar,lastUPbar,lastDNbar,TimeOpen; //âðåìÿ îòêðûòèÿ òåêóùåãî áàðà;
double MP,lastUP,lastDN;
double UP[],DN[];
bool downloadhistory=false;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   TimeFirstExtBar=0;
   TimeOpen=0;
   MP=MinAmp*Point;
   lastUP=0; lastDN=0;
//---- indicators
   IndicatorDigits(Digits);
   IndicatorBuffers(6);

   SetIndexBuffer(0,UP);
   SetIndexStyle(0,DRAW_ZIGZAG,STYLE_SOLID,3);

   SetIndexBuffer(1,DN);
   SetIndexStyle(1,DRAW_ZIGZAG);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int BarsForRecalculation,i;

   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+ExtPeriod;

   BarsForRecalculation=limit;
   if(limit>2)
     {
      if(downloadhistory) //èñòîðèÿ çàãðóæåíà
        {
         ArrayInitialize(UP,EMPTY_VALUE);
         ArrayInitialize(DN,EMPTY_VALUE);
        }
      else downloadhistory=true;
     }
   if(BarsForRecalculation>0) TimeOpen=Time[limit]; //ïðîâåðèì ýòó ñòðîêó ïðè îòêðûòèè ÌÒ-4 ñ ïåðåðûâîì
/*
â ñâÿçè ñ òåì, ÷òî ôðàêòàëîì ïî îïðåäåëåíèþ ÿâëÿåòñÿ öåíîâîé ýêñòðåìóì îòíîñèòåëüíî 2 áàðîâ âïðàâî
(îñòàëüíîå ñì. ôóíêöèþ Fractal) - ñîîòâåòñòâåííî ôðàêòàë íà 3 áàðå ìîæåò ñ÷èòàòüñÿ ñôîðìèðîâàííûì 
òîëüêî ïðè îòêðûòèè íóëåâîãî òåêóùåãî áàðà: [3]-2-1-0 Ïîýòîìó ðàñ÷åò öèêëà âûïîëíÿåòñÿ òîëüêî ïðè 
îòêðûòèè íîâîãî áàðà. Âíóòðè áàðà ïðè ïîñòóïëåíèè íîâûõ òèêîâ ðàñ÷åò íå ïðîèçâîäèòñÿ.
*/
   if(TimeOpen<Time[0])
     {
      //======== îñíîâíîé öèêë
      while(BarsForRecalculation>1)
        {
         i=BarsForRecalculation+1; lastUP=0; lastDN=0; lastUPbar=i; lastDNbar=i;
         int LET=LastEType(); //ïîèñê ïîñëåäíåãî ýêñòðåìóìà

         //---- ðàññìîòðèì öåíîâûå ýêñòðåìóìû çà ðàñ÷åòíûé ïåðèîä:       
         double H=High[iHighest(NULL,0,MODE_HIGH,ExtPeriod,i)];
         double L=Low[iLowest(NULL,0,MODE_LOW,ExtPeriod,i)];

         //---- ðàññìîòðèì, èìåþòñÿ ëè íà áàðå [i] ôðàêòàëû ìèíèìàëüíîé èëè ìàêñèìàëüíîé öåí: 
         double Fup=Fractal(1,i); //MODE_UPPER 
         double Fdn=Fractal(2,i); //MODE_LOWER

         //---- ïðîàíàëèçèðóåì ñèòóàöèþ è ðàññìîòðèì âîçìîæíîñòü ðåãèñòðàöèè íîâûõ ýêñòðåìóìîâ: 

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

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

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

            case -2 : //ïðåäïîëîæèòåëüíî ñíà÷àëà ñôîðìèðîâàëñÿ HIGH ïîòîì LOW (ìåäâåæèé áàð)
              {
               switch(LET)
                 {
                  case 1 : //ïðåäûäóùèé ýêñòðåìóì - ïèê
                    {
                     if(NormalizeDouble(Fup-Fdn-MP,Digits)>0)
                       {
                        DN[i]=Fdn;
                        if(NormalizeDouble(Fup-lastUP,Digits)>0 && iTime(NULL,0,lastUPbar)>TimeFirstExtBar)
                          {UP[lastUPbar]=EMPTY_VALUE; UP[i]=Fup;}
                       }
                     else
                       {
                        if(NormalizeDouble(lastUP-Fdn-MP,Digits)>0) DN[i]=Fdn;
                        else
                          {
                           if(NormalizeDouble(Fup-lastUP,Digits)>0) {UP[lastUPbar]=EMPTY_VALUE; UP[i]=Fup;}
                          }
                       }
                     break;
                    }
                  case -1 : //ïðåäûäóùèé ýêñòðåìóì - âïàäèíà
                    {
                     if(NormalizeDouble(Fup-Fdn-MP,Digits)>0)
                       {
                        if(NormalizeDouble(Fup-lastDN-MP,Digits)>0) {UP[i]=Fup; DN[i]=Fdn;}
                        else
                          {
                           if(NormalizeDouble(lastDN-Fdn,Digits)>0) {DN[lastDNbar]=EMPTY_VALUE; DN[i]=Fdn;}
                          }
                       }
                     else
                       {
                        if(NormalizeDouble(Fup-lastDN-MP,Digits)>0) UP[i]=Fup;
                        else
                          {
                           if(NormalizeDouble(Fdn-lastDN,Digits)>0) {DN[lastDNbar]=EMPTY_VALUE; DN[i]=Fdn;}
                          }
                       }
                    }
                 } //switch LET
              }// case -2 
           }
         //----  
         BarsForRecalculation--;
        }
      //========
      TimeOpen=Time[0];
     }
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| ôóíêöèÿ îïðåäåëåíèÿ ôðàêòàëîâ                                    |
//+------------------------------------------------------------------+  
double Fractal(int mode,int i)
  {
//----
   bool fr=true;
   int a,b,count;
   double res;

   switch(mode)
     {

      case 1 : //ïîèñê âåðõíèõ ôðàêòàëîâ
         //ñïðàâà îò ôðàêòàëà äîëæíî áûòü 2 áàðà ñ áîëåå íèçêèìè ìàêñèìóìàìè
         //ñëåâà îò ôðàêòàëà ïîæåò áûòü ãðóïïà áàðîâ, êîòîðóþ çàâåðøàò 2 áàðà ñ áîëåå íèçêèìè ìàêñèìóìàìè 
         //ìàêñèìóì ëþáîãî áàðà èç ãðóïïû íå äîëæåí ïðåâûñèòü ìàêñèìóì ôðàêòàëüíîãî áàðà    
        {
         for(b=i-1;b>i-3;b--)
           {
            if(High[i]<=High[b]) {fr=false; break;}
           }
         a=i+1;
         while(count<2)
           {
            if(High[i]<High[a]) {fr=false; break;}
            else
              {
               if(High[i]>High[a]) count++;
               else count=0;
              }
            a++;
           }
         if(fr==true) res=High[i];
         break;
        }

      case 2 : //ïîèñê íèæíèõ ôðàêòàëîâ
         //ñïðàâà îò ôðàêòàëà äîëæíî áûòü 2 áàðà ñ áîëåå âûñîêèìè ìèíèìóìàìè
         //ñëåâà îò ôðàêòàëà ìîæåò áûòü ãðóïïà áàðîâ, êîòîðóþ çàâåðøàò 2 áàðà ñ áîëåå âûñîêèìè ìèíèìóìàìè 
         //ìèíèìóì ëþáîãî áàðà èç ãðóïïû íå äîëæåí áûòü íèæå ìèíèìóìà ôðàêòàëüíîãî áàðà 
        {
         for(b=i-1;b>i-3;b--)
           {
            if(Low[i]>=Low[b]) {fr=false; break;}
           }
         a=i+1;
         while(count<2)
           {
            if(Low[i]>Low[a]) {fr=false; break;}
            else
              {
               if(Low[i]<Low[a]) count++;
               else count=0;
              }
            a++;
           }
         if(fr==true) res=Low[i];
        }
     }
//----
   return(res);
  }
//+------------------------------------------------------------------+
//| ôóíêöèÿ îïðåäåëåíèÿ ïîñëåäíåãî ýêñòðåìóìà                        |
//+------------------------------------------------------------------+  
int LastEType()
  {
//----
   int m,n,res;
   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) res=1;
   else
     {
      if(lastUPbar>lastDNbar) res=-1;
      else //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) res=1;       //áàçîâûé îòñ÷åò - ïèê
         else if(m>n) res=-1; //áàçîâûé îòñ÷åò - âïàäèíà
        }
     }
//----    
   return(res); //åñëè res==0 - çíà÷èò ýòî íà÷àëî îòñ÷åòà èëè â ñàìîì íà÷àëå çàôèêñèðîâàí âíåøíèé áàð ñ 2 ýêñòðåìóìàìè
  }
//+------------------------------------------------------------------+
//| ôóíêöèÿ àíàëèçà òåêóùåé ñèòóàöèè                                 |
//+------------------------------------------------------------------+ 
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)                                   //íà ðàñ÷åòíîì áàðå ïîòåíöèàëüíûé ïèê è ïîòåíöèàëüíàÿ âïàäèíà 
     {
      switch(GetOrderFormationBarHighLow(i))
        {//ïðåäïîëîæèòåëüíî ñíà÷àëà ñôîðìèðîâàëñÿ LOW ïîòîì HIGH (áû÷èé áàð)
         case -1 : return(2); break;
         //ïðåäïîëîæèòåëüíî ñíà÷àëà ñôîðìèðîâàëñÿ HIGH ïîòîì LOW (ìåäâåæèé áàð)
         case 1 : return(-2);
        }
     }
//----  
   return(0);                                             //íà ðàñ÷åòíîì áàðå ïóñòî...
  }
//+------------------------------------------------------------------+
//| ôóíêöèÿ âîçâðàùàåò ïîðÿäîê ôîðìèðîâàíèÿ High Low äëÿ áàðà        |
//|  1: ñíà÷àëà High, çàòåì Low                                      |
//| -1: ñíà÷àëà Low, çàòåì High                                      |
//|  0: High = Low                                                   |
//+------------------------------------------------------------------+ 
int GetOrderFormationBarHighLow(int Bar)
  {
//---- Äëÿ íà÷àëà âñòðîèì ïðîñòåéøóþ ëîãèêó ïî Open / Close
   int res=0;
   if(High[Bar]==Low[Bar]) return(res);
   if(Close[Bar]>Open[Bar]) res=-1;
   if(Close[Bar]<Open[Bar]) res=1;

   if(res==0) // Êîãäà Close = Open
     {
      double a1=High[Bar]-Close[Bar];
      double a2=Close[Bar]-Low[Bar];
      if(a1>a2) res=-1;
      if(a1<a2) res=1;
      if(res==0) res=1; // Êîãäà è ýòî ðàâíî  - áóäåì òàê ñ÷èòàòü! è áàñòà! - íàòÿæêà!
     }
//----
   return(res);
  }
//+------------------------------------------------------------------+

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---