ZIGZAG-FRACTALS

Download script
Author: Copyright � 2007, MetaQuotes Software Corp.
ZIGZAG-FRACTALS

This script is designed to identify and visualize significant turning points in price action by combining two different types of technical analysis: Fractals and the ZigZag logic. Its primary purpose is to filter out minor market "noise" and highlight the major peaks (highs) and valleys (lows) that define the overall trend of a chart.

Core Logic Overview

The script operates through a three-step process to determine where the most important price points occur:

1. Data Filtering (Fractal Identification) The tool first scans the market data to find "Fractals." In technical analysis, a fractal is a specific price point that is higher or lower than the bars surrounding it. The script identifies these potential turning points but adds a layer of verification to ensure that if multiple fractals appear in close proximity, only the most significant one (the highest high or the lowest low) is kept.

2. Trend Tracking Once the potential turning points are identified, the script determines the current direction of the market. It maintains a memory of whether it is currently searching for a new "peak" (to identify a move upward) or a new "valley" (to identify a move downward). By knowing the current trend, the script can distinguish between a meaningful price reversal and a minor fluctuation.

3. Final Refinement (ZigZag Smoothing) The final stage is where the actual lines are drawn on your chart. The script performs a "cleanup" of the data:

  • If it finds a new peak that is higher than the previous peak while moving in an upward trend, it replaces the old point with the new, higher one.
  • Conversely, if it finds a lower valley while moving in a downward trend, it updates the position to that new low.
  • This creates a continuous, jagged line that connects only the most extreme price points, effectively "skipping" the small zig-zags that occur during normal market consolidation.

User Experience

For a trader, this means the visual output provides a clear, simplified map of the market's structure. Instead of seeing every minor price tick, the gold line on your chart represents the "skeleton" of the price movement—clearly showing where major support and resistance levels have formed and helping to visualize the momentum of the current trend.

Indicators Used
Fractals
Miscellaneous
Implements a curve of type %1
19 Views
0 Downloads
0 Favorites
ZIGZAG-FRACTALS
//+------------------------------------------------------------------+
//|                                              Zigzag-fractals.mq4 |
//|                 Copyright © 2005-2007, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Gold

//---- indicator parameters



//---- indicator buffers
double ZigzagBuffer[];

double HighMapBuffer[];
double LowMapBuffer[];

int level=3; // recounting's depth 
bool downloadhistory=false;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   IndicatorBuffers(3);
//---- drawing settings
   SetIndexStyle(0,DRAW_SECTION);
//---- indicator buffers mapping
   SetIndexBuffer(0,ZigzagBuffer);
 
    SetIndexBuffer(1,HighMapBuffer);
   SetIndexBuffer(2,LowMapBuffer);
   SetIndexEmptyValue(0,0.0);



//---- indicator short name
   IndicatorShortName("ZigZag-fractal");
//---- initialization done
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   int i, counted_bars = IndicatorCounted();
   int limit,counterZ,whatlookfor;
   int shift,back,lasthighpos,lastlowpos;
   double val,res;
   double curlow,curhigh,lasthigh,lastlow;

   if (counted_bars==0 && downloadhistory) // history was downloaded
     {
      ArrayInitialize(ZigzagBuffer,0.0);
  
      ArrayInitialize(HighMapBuffer,0.0);
      ArrayInitialize(LowMapBuffer,0.0);
     }
   if (counted_bars==0) 
     {
      limit=Bars-12;
      downloadhistory=true;
     }
   if (counted_bars>0) 
     {
      while (counterZ<3 && i<100)
        {
         res=ZigzagBuffer[i];
         if (res!=0) counterZ++;
         i++;
        }
      i--;
      limit=i;
      if (LowMapBuffer[i]!=0) 
        {
         curlow=LowMapBuffer[i];
         whatlookfor=1;
        }
      else
        {
         curhigh=HighMapBuffer[i];
         whatlookfor=-1;
        }
      for (i=limit-1;i>=0;i--)  
        {
         ZigzagBuffer[i]=0.0;  
         LowMapBuffer[i]=0.0;
         HighMapBuffer[i]=0.0;
        }
     }
      
   for(shift=limit; shift>=0; shift--)
     {
      val=iFractals(NULL, 0, MODE_LOWER, shift);//Low[iLowest(NULL,0,MODE_LOW,12,shift)];
      if(val==lastlow) val=0.0;
      else 
        { 
         lastlow=val; 
         if((Low[shift]-val)>(1*Point)) val=0.0;
         else
           {
            for(back=1; back<=1; back++)
              {
               res=LowMapBuffer[shift+back];
               if((res!=0)&&(res>val)) LowMapBuffer[shift+back]=0.0; 
              }
           }
        } 
      LowMapBuffer[shift]=val;
      
         
       
      //--- high
      val=iFractals(NULL, 0, MODE_UPPER, shift);//High[iHighest(NULL,0,MODE_HIGH,12,shift)];//iFractals(NULL, 0, MODE_UPPER, 3);

      if(val==lasthigh) val=0.0;
      else 
        {
         lasthigh=val;
         if((val-High[shift])>(1*Point)) val=0.0;
         else
           {
            for(back=1; back<=1; back++)
              {
               res=HighMapBuffer[shift+back];
               if((res!=0)&&(res<val)) HighMapBuffer[shift+back]=0.0; 
              } 
           }
        }
      HighMapBuffer[shift]=val;
     
         
     
     }

   // final cutting 
   if (whatlookfor==0)
     {
      lastlow=0;
      lasthigh=0;  
     }
   else
     {
      lastlow=curlow;
      lasthigh=curhigh;
     }
   for (shift=limit;shift>=0;shift--)
     {
      res=0.0;
      switch(whatlookfor)
        {
         case 0: // look for peak or lawn 
            if (lastlow==0 && lasthigh==0)
              {
               if (HighMapBuffer[shift]!=0)
                 {
                  lasthigh=High[shift];
                  lasthighpos=shift;
                  whatlookfor=-1;
                  ZigzagBuffer[shift]=lasthigh;
                
                  res=1;
                 }
               if (LowMapBuffer[shift]!=0)
                 {
                  lastlow=Low[shift];
                  lastlowpos=shift;
                  whatlookfor=1;
                  ZigzagBuffer[shift]=lastlow;
             
                  res=1;
                 }
              }
             break;  
         case 1: // look for peak
            if (LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<lastlow && HighMapBuffer[shift]==0.0)
              {
               ZigzagBuffer[lastlowpos]=0.0;
               lastlowpos=shift;
               lastlow=LowMapBuffer[shift];
               ZigzagBuffer[shift]=lastlow;
             
               res=1;
              }
            if (HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)
              {
               lasthigh=HighMapBuffer[shift];
               lasthighpos=shift;
               ZigzagBuffer[shift]=lasthigh;
              
               whatlookfor=-1;
               res=1;
              }   
            break;               
         case -1: // look for lawn
            if (HighMapBuffer[shift]!=0.0 && HighMapBuffer[shift]>lasthigh && LowMapBuffer[shift]==0.0)
              {
               ZigzagBuffer[lasthighpos]=0.0;
               lasthighpos=shift;
               lasthigh=HighMapBuffer[shift];
               ZigzagBuffer[shift]=lasthigh;
              
              }
            if (LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)
              {
               lastlow=LowMapBuffer[shift];
               lastlowpos=shift;
               ZigzagBuffer[shift]=lastlow;
              
               whatlookfor=1;
              }   
            break;               
         default: return; 
        }
     }

   return(0);
  }
//+------------------------------------------------------------------+

Comments