i_MF_Fractal_ZZ_3in1

Download script
Author: Copyright � 2008, BiViSi Corp.
i_MF_Fractal_ZZ_3in1

This script is designed to analyze market trends by identifying significant price turning points across three different timeframes simultaneously. It essentially acts as a multi-layered "ZigZag" indicator, helping traders visualize the underlying structure of the market from broad (long-term) perspectives down to more granular (short-term) movements.

Core Logic and Functionality

1. Multi-Timeframe Analysis The script operates on three distinct timeframes at once: Large, Middle, and Small. By calculating these concurrently, it allows you to see how short-term price fluctuations relate to larger historical trends. For example, it can show you a small "zigzag" move while simultaneously tracking the larger trend of the day or week.

2. Automated Timeframe Alignment To ensure the data is consistent and mathematically sound, the script includes automatic checks:

  • It verifies that your current chart timeframe is compatible with the three chosen settings.
  • If the timeframes provided are not perfect multiples of your current chart (e.g., trying to use a 10-minute interval on a 5-minute chart), it automatically adjusts them to the nearest valid multiple.
  • It enforces a logical hierarchy, ensuring that "Small" is smaller than "Middle," and "Middle" is smaller than "Large."

3. Fractal Point Identification The script uses a "Fractal" logic to find significant peaks (highs) and valleys (lows). Instead of just marking every high price, it looks for specific patterns where a price point is higher or lower than the bars surrounding it.

  • It scans back through history to identify these turning points.
  • It focuses on "significant" points to avoid cluttering your chart with minor price noise.

4. ZigZag Filtering and Smoothing Once the script identifies potential peaks and valleys, it applies a filtering process to clean up the data:

  • Redundancy Removal: If the script finds two consecutive peaks in the same direction, it keeps only the most significant one (the highest or lowest) and ignores the other.
  • Visual Clarity: This ensures that the resulting "ZigZag" lines are smooth and represent true structural changes in price rather than jittery movements.

5. Performance Optimization The logic is built to be efficient. It uses "Force" triggers, meaning it only performs heavy calculations when a new candle is fully formed or when a specific timeframe period has actually elapsed. This prevents the script from slowing down your trading platform by constantly recalculating data that hasn't changed yet.

Summary for the User

In plain terms, this tool looks at the market through three different "magnifying glasses" at the same time. It finds the most important highs and lows on each of those scales and connects them with lines. This allows you to see the "big picture" trend while still being aware of smaller price shifts occurring in real-time.

Miscellaneous
Implements a curve of type %1
108 Views
0 Downloads
0 Favorites
i_MF_Fractal_ZZ_3in1
//-----------------------------------------------------------------------
// MF_Fractal_ZZ_3in1.mq4
// Èíäèêàòîð ôîðìèðóåò íà ðàáî÷åì òàéìôðåéìå ïîñëåäîâàòåëüíîñòü óçëîâ
// çèãçàãà, âû÷èñëåííûõ íà ñýìóëèðîâàííûõ òðåõ ñòàðøèõ.
// Ðàáîòàåò íà âñåõ è ñî âñåìè, â ò.÷. è íåñòàíäàðòíûìè ÒÔ
// Îãðàíè÷åíèÿ:
// - ñòàðøèå ÒÔ äîëæíû áûòü êðàòíû ðàáî÷åìó, åñëè íåò, òî çíà÷åíèÿ
//   óñòàíàâëèâàþòñÿ ïðèíóäèòåëüíî. 
// - ðàáî÷èé ÒÔ <= ñàìîìó ìåëêîìó èç ñòàðøèõ
// - TFSmall < TFMidle && TFMidle < TFLarge
// - TFLarge <=43200 (ìåñÿö) 
//-----------------------------------------------------------------------

#property copyright "Copyright © 2008, BiViSi Corp."
#property link      "riderfin@bk.ru"
#property link      "ICQ 499949112"

#property indicator_chart_window    
#property indicator_buffers 3
//---- ñòèëü  èíäèêàòîðíîé ëèíèè
#property indicator_color1 Blue 
#property indicator_color2 Red
#property indicator_color3 Yellow        
#property indicator_style1 0
#property indicator_style2 0
#property indicator_style3 0
#property indicator_width1 5
#property indicator_width2 3
#property indicator_width3 1
//---- ÂÕÎÄÍÛÅ ÏÀÐÀÌÅÒÐÛ ÈÍÄÈÊÀÒÎÐÀ 
extern int VolExt=50; // âû÷èñëåíèå "VolExt+1" ïîñëåäíèõ îïîðíûõ òî÷åê
extern int TFLarge=1440;
extern int TFMidle=240;
extern int TFSmall=60;
//---- Variables 
double Large[],Midle[],Small[];  // îïîðíûå òî÷êè (áóôåðû èíäèêàòîðà)
datetime PrevTimePer[4];         // âðåìåíà ïîñëåäíåãî ðàñ÷åòà ïî êàæäîìó ÒÔ
datetime PrevTimeCalc=0; 
double P60,CP60;
int CurPeriod, ErrorTF=0, NumberExt, Per,  largelast=0, midlelast=0, smalllast=0;
//-----------------------------------------------------------------------
int init() 
{
   // èíèöèàëèçàöèÿ 
   IndicatorBuffers(3); // ñòðîêà "íà ïåðñïåêòèâó" :)
   SetIndexBuffer(0,Large); SetIndexStyle(0,DRAW_SECTION);
   SetIndexEmptyValue(0,0.0);
   SetIndexBuffer(1,Midle); SetIndexStyle(1,DRAW_SECTION);
   SetIndexEmptyValue(1,0.0); 
   SetIndexBuffer(2,Small); SetIndexStyle(2,DRAW_SECTION);
   SetIndexEmptyValue(2,0.0);
   ArrayInitialize(PrevTimePer,0);
   CurPeriod=Period(); CP60=CurPeriod*60;
   // Îãðàíè÷åíèÿ:
   // êîíòðîëü ÒÔ è ââåäåííûõ ïàðàìåòðîâ
   if (MathCeil(TFSmall/CurPeriod) != TFSmall/CurPeriod) 
      TFSmall=MathCeil(TFSmall/CurPeriod)*CurPeriod;
   if (MathCeil(TFMidle/CurPeriod) != TFMidle/CurPeriod)
      TFMidle=MathCeil(TFMidle/CurPeriod)*CurPeriod;
   if (MathCeil(TFLarge/CurPeriod) != TFLarge/CurPeriod)
       TFLarge=MathCeil(TFLarge/CurPeriod)*CurPeriod;
   if (CurPeriod > TFSmall) 
      {Alert ("Ïåðèîä ãðàôèêà äîëæåí áûòü ìåíüøå èëè ðàâåí ", TFSmall," ìèí.");
       ErrorTF=1;return;}
   if (TFSmall >= TFMidle || TFMidle >= TFLarge || TFLarge>43200)
      {Alert ("Íåêîððåêòíûé âûáîð òàéìôðåéìîâ äëÿ ðàñ÷åòà!!!"); ErrorTF=1;return;}
   return;              
}
//--------------------------------------------------------------------
int start()
{
   if ( ErrorTF==1 ) return; // íåêîððåêòíûé òàéìôðåéì   
   FractalCalc(); 
   return;
}
//======================================================================
// Ïîèñê 5-òè áàðíûõ ôðàêòàëîâ è âû÷èñëåíèå óçëîâ çèãçàãà 
// íà ýìóëÿöèè ñòàðøèõ ÒÔ, óäàëåíèå ëèøíèõ è îòîáðàæåíèå íà òåêóùåì ÒÔ
//======================================================================
void FractalCalc ()
{   
   // Force  ¹1 - âû÷ òîëüêî íà ïîëíîñòüþ ñôîðìèðîâàâøåìñÿ áàðå ðàáî÷åãî ÒÔ
   if (PrevTimeCalc == Time[0]) return; else PrevTimeCalc=Time[0];
   int y, x, k, i, j, extr=0; 
   // âðåìÿ ïîñëåäíåãî áàðà òåê ÒÔ, çàêðûâàþùåãî áàð ¹1-5 ñòàðøåãî ÒÔ
   int t1, t2, t3, t4, t5;                     
   // íîìåð ïîñëåäíåãî áàðà òåê ÒÔ, çàêðûâàþùåãî áàð ¹1-5 ñòàðøåãî ÒÔ
   int limit1, limit2, limit3, limit4, limit5; 
   // íîìåðà áàðîâ òåê ÒÔ ñ ïèêàìè è äîíûøêàìè ñîîòâ áàðàì 1-5 ñòàðøåãî ÒÔ
   int up1,up2,up3,up4,up5,dn1,dn2,dn3,dn4,dn5;
      
   for (y=1; y<=3; y++) // öèêë ïî ðàññ÷èòûâàåìûì ÒÔ
      {
      if (y==1) Per=TFLarge; if (y==2) Per=TFMidle; if (y==3) Per=TFSmall;
      P60=Per*60;
      // Force ¹2 - Âû÷èñëÿåì èçëîìû òîëüêî ñ ôîðìèðîâàíèåì áàðà ñòàðøåãî ÒÔ
      if (PrevTimePer[y] !=0)
         { 
         if (Per<43200 && (Time[0] - PrevTimePer[y])<P60 )continue;
         if (Per==43200 && Month()==TimeMonth(PrevTimePer[y]))continue;
         }
      // Îáðàáîòêà ïðîïóñêà áàðîâ
      // Åñëè ïðÿìîëèíåéíî PrevTimePer[y]=Time[0], òî â ñëó÷àå ïðîïóñêà áàðîâ
      // íà ðàáî÷åì ÒÔ ïðîèçîéäåò ñäâèã âñåé öåïî÷êè ðàñ÷åòà íà âåëè÷èíó ïðîïóñêà
      PrevTimePer[y]=MathCeil(Time[0]/Per/60)*P60; 
      
      NumberExt=0;  extr=0;
      k=Per/CurPeriod;
      // îãðàíè÷åíèå öèêëà - â çàâèñèìîñòè îò òîãî êàêîé ÒÔ îáñ÷èòûâàåì
      // è îò ïîñëåäíåãî íàéäåííîãî ôðàêòàëà
      i=MathCeil(Bars/k)-5;
      // Force #3 - îáñ÷èòûâàåì, íà÷èíàÿ ñ ïîñëåäíåãî èçëîìà
      if(y==1 && largelast !=0) i=largelast+k;
      if(y==2 && midlelast !=0) i=midlelast+k;
      if(y==3 && smalllast !=0) i=smalllast+k;
      for (x=1; x<=i; x++) 
         {
         // íàõîäèì ïèêè è äîíûøêè
         // âðåìÿ íà÷àëà ïîñëåäíåãî áàðà òåê ÒÔ, çàêðûâàþùåãî áàð ¹1 ñòàðøåãî ÒÔ
         if (PrevTimePer[y] !=0) t1=PrevTimePer[y]-x*P60+(k-1)*CP60;
         else t1=MathCeil(Time[0]/Per/60)*P60-x*P60+(k-1)*CP60;
         t2=t1-P60; t3=t2-P60; t4=t3-P60; t5=t4-P60;
         limit1=iBarShift(NULL,0,t1, false); limit2=iBarShift(NULL,0,t2, false);
         limit3=iBarShift(NULL,0,t3, false); limit4=iBarShift(NULL,0,t4, false);
         limit5=iBarShift(NULL,0,t5, false);         
         up1=iHighest(NULL,0,MODE_HIGH,k,limit1); up2=iHighest(NULL,0,MODE_HIGH,k,limit2);
         up3=iHighest(NULL,0,MODE_HIGH,k,limit3); up4=iHighest(NULL,0,MODE_HIGH,k,limit4);
         up5=iHighest(NULL,0,MODE_HIGH,k,limit5);
         dn1=iLowest(NULL,0,MODE_LOW,k,limit1); dn2=iLowest(NULL,0,MODE_LOW,k,limit2);
         dn3=iLowest(NULL,0,MODE_LOW,k,limit3); dn4=iLowest(NULL,0,MODE_LOW,k,limit4);
         dn5=iLowest(NULL,0,MODE_LOW,k,limit5);

         // èùåì îïîðíûå òî÷êè
         if(High[up3]>High[up2] && High[up3]>High[up1] && High[up3]>=High[up4] && High[up3]>=High[up5])
            {
            if (y==1){Large[up3]=High[up3];largelast=up3;}
            if (y==2){Midle[up3]=High[up3];midlelast=up3;}
            if (y==3){Small[up3]=High[up3];smalllast=up3;}
            NumberExt++;  extr++;
            }
         if(Low[dn3]<Low[dn2] && Low[dn3]<Low[dn1] && Low[dn3]<=Low[dn4] && Low[dn3]<=Low[dn5])
            {
            if (y==1){Large[dn3]=Low[dn3];largelast=dn3;}
            if (y==2){Midle[dn3]=Low[dn3];midlelast=dn3;}
            if (y==3){Small[dn3]=Low[dn3];smalllast=dn3;}
            NumberExt++; extr++;
            }
         if (NumberExt>VolExt) break;   
         } 
      }

// Óäàëåíèå ëèøíèõ ýêñòðåìóìîâ äëÿ ôîðìèðîâàíèÿ ïðàâèëüíîãî çèãçàãà
// èç 2-õ è áîëåå ïîäðÿä èäóùèõ ïèêîâ\äîíûøêîâ âûáèðàþòñÿ ìàêñèìàëüíûé\ìèíèìàëüíûé,
// à ïðè ðàâåíñòâå -  ñ íàèìåíüøèì íîìåðîì áàðà.... ëèøíèå îáíóëÿþòñÿ

   if (extr==0) return;
   for (y=1; y<=3; y++)
      {
      if (y==1) j=ArraySize(Large);if (y==2)j=ArraySize(Midle);
      if (y==3)j=ArraySize(Small);      
      int min=0, max=0, extmin=0, extmax=0;
      NumberExt=0;      
      for (x=1;x<=j;x++)
         {
         if (y==1)
            {
            if (Large[x] == 0.0 ) continue;
            if (Large[x] == High[x])
               {
               NumberExt++; extmax++; extmin=0;
               if (extmax==2)
                  {
                  if (Large[max]>=Large[x])Large[x]=0.0;
                  else {Large[max]=0.0;max=x;}
                  extmax--;  
                  }
               else max=x;
               }
            if (Large[x] == Low[x])
               {
               NumberExt++; extmax=0; extmin++;
               if (extmin==2)
                  {
                  if (Large[min]<=Large[x])Large[x]=0.0;
                  else {Large[min]=0.0;min=x;}
                  extmin--;  
                  }
               else min=x;
               }
            }         
         if (y==2)
            {
            if (Midle[x] == 0.0 ) continue;
            if (Midle[x] == High[x])
               {
               NumberExt++; extmax++; extmin=0;
               if (extmax==2)
                  {
                  if (Midle[max]>=Midle[x])Midle[x]=0.0;
                  else {Midle[max]=0.0;max=x;}
                  extmax--;  
                  // ìîæíî è ïîïðîùå, êàê âûøå, íî.... óáèðàåì ðàñõîæäåíèÿ
                  /*
                  if (Midle[max]>Midle[x])Midle[x]=0.0; 
                  if (Midle[max]==Midle[x])
                     {
                     if (Large[x] == High[x]) {Midle[max]=0.0;max=x;}
                     else Midle[x]=0.0; 
                     }
                  if (Midle[max]<Midle[x]){Midle[max]=0.0;max=x;}
                  */
                  }
               else max=x;
               }
            if (Midle[x] == Low[x])
               {
               NumberExt++; extmax=0; extmin++;
               if (extmin==2)
                  {
                  if (Midle[min]<=Midle[x])Midle[x]=0.0;
                  else {Midle[min]=0.0;min=x;}
                  extmin--;  
                  // ìîæíî è ïîïðîùå, êàê âûøå, íî.... óáèðàåì ðàñõîæäåíèÿ
                  /*
                  if (Midle[min]<Midle[x])Midle[x]=0.0; 
                  if (Midle[min]==Midle[x])
                     {
                     if (Large[x] == Low[x]) {Midle[min]=0.0;min=x;}
                     else Midle[x]=0.0; 
                     }
                  if (Midle[min]>Midle[x]){Midle[min]=0.0;min=x;}
                  */
                  }
               else min=x;
               }
            }         
         if (y==3)
            {
            if (Small[x] == 0.0 ) continue;
            if (Small[x] == High[x])
               {
               NumberExt++; extmax++; extmin=0;
               if (extmax==2)
                  {
                  if (Small[max]>=Small[x])Small[x]=0.0;
                  else {Small[max]=0.0;max=x;}
                  extmax--;  
                  // ìîæíî è ïîïðîùå, êàê âûøå, íî.... óáèðàåì ðàñõîæäåíèÿ
                  /*
                  if (Small[max]>Small[x])Small[x]=0.0; 
                  if (Small[max]==Small[x])
                     {
                     if (Midle[x] == High[x]) {Small[max]=0.0;max=x;}
                     else Small[x]=0.0; 
                     }
                  if (Small[max]<Small[x]){Small[max]=0.0;max=x;}
                  */
                  }
               else max=x;
               }
            if (Small[x] == Low[x])
               {
               NumberExt++; extmax=0; extmin++;
               if (extmin==2)
                  {
                  if (Small[min]<=Small[x])Small[x]=0.0;
                  else {Small[min]=0.0;min=x;}
                  extmin--;  
                  // ìîæíî è ïîïðîùå, êàê âûøå, íî.... óáèðàåì ðàñõîæäåíèÿ
                  /*
                  if (Small[min]<Small[x])Small[x]=0.0; 
                  if (Small[min]==Small[x])
                     {
                     if (Midle[x] == Low[x]) {Small[min]=0.0;min=x;}
                     else Small[x]=0.0; 
                     }
                  if (Small[min]>Small[x]){Small[min]=0.0;max=x;}
                  */
                  }
               else min=x;
               }
            }         
         if (NumberExt>VolExt+5) break;
         }
      }         

}
//--------------------------------------------------------------------

Comments