GannZigZag_001

Download script
Author:
GannZigZag_001

This script is designed to function as a visual charting tool that identifies and maps significant price trends and structural pivot points on a trading platform. It essentially "simplifies" the market noise by identifying core momentum shifts, allowing users to see the primary direction of the price action more clearly.

Core Logic Overview

The indicator works by scanning historical price data to identify extreme highs and lows (peaks and valleys). Instead of simply marking every small movement, it uses a specific logic to determine when a trend has officially changed or stabilized.

1. Trend Tracking and Detection The script continuously monitors the high and low points of each candle. It keeps track of two primary states: an upward trend and a downward trend. To decide when one trend ends and another begins, it uses a "counter" system (defined by the GSv_range parameter). This ensures that the indicator doesn't react to minor, insignificant price fluctuations but waits for a sustained movement before confirming a new structural point.

2. Identifying Pivot Points (Extremums) The logic looks for specific conditions where the price reaches a new high or a new low:

  • Highs: It records new maximums as they occur.
  • Lows: It records new minimums as they occur.
  • Balance: When the counter for highs and lows reaches a certain threshold, the script recognizes this as a "balance" point or a significant turn in market structure.

3. Dynamic Switching Logic The script contains sophisticated "if-then" rules to handle different market behaviors:

  • Simultaneous Extremums: If a single candle manages to hit both a new high and a new low simultaneously (common in highly volatile moments), the script checks the price completion (bullish vs. bearish) to decide which direction the trend line should follow.
  • Single Extremum Shifts: If the market only hits a new high without meeting the full counter requirements, the script will update the current high/low markers but remain cautious about officially switching the trend direction until confirmed by further price action.

4. Visual Representation Once the logic determines a significant peak or valley has been reached based on the user's range settings, it "draws" a line or section on the chart. It effectively connects these structural points, creating a zigzag-like path that highlights the backbone of the market movement.

Summary for the User

In plain terms, this tool acts like an automated trend-mapper. You provide it with a sensitivity range, and it handles the heavy lifting of scanning thousands of candles to find the "true" peaks and valleys. It filters out the "jitter" of the market to show you a clean progression of price movement, helping you visualize where the market has shifted from one major level to another.

Miscellaneous
Implements a curve of type %1Uses files from the file systemIt issuies visual alerts to the screenIt writes information to file
6 Views
0 Downloads
0 Favorites
GannZigZag_001
//+------------------------------------------------------------------+
//|                                                   GannZIGZAG.mq4 |
//|                      Copyright © 2005, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 DeepSkyBlue
#property indicator_color2 Black
//---- input parameters
extern int GSv_range=2;
//---- buffers
double GSv_sl[];
double GSv_m[];
//----
bool draw_up=0,draw_dn=0,initfl=0;
int  fPoint_i,sPoint_i,s_up,s_dn,drawf,lb,idFile;
double h,l;
bool cur_h=0,cur_l=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0,DRAW_SECTION,STYLE_DOT);
   //SetIndexStyle(1,DRAW_SECTION);
   SetIndexBuffer(0,GSv_sl);
   //SetIndexBuffer(1,GSv_m);
   SetIndexEmptyValue(0,0.0);
   //SetIndexEmptyValue(1,0.0);
   FileDelete("Gann.txt");
   idFile=FileOpen("Gann.txt",FILE_READ|FILE_WRITE,"  ");
//----
   return(0);
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int counted_bars=IndicatorCounted();
   int cb,limit,i;
//---- 
   if( GSv_range<1 )
   {
      Alert("Indicator is calculating /n values for GSv_range not less than 1!!!");
      return(-1);
   }
   if( counted_bars<0 )
   {
      return(-1);
   }
   else
   {
      if( Bars-1-counted_bars<=0 )
      {
         limit=0;
      }
      else
      {
         limit=Bars-1-counted_bars;
      }
   }
   //ïåðâîíà÷àëüíàÿ èíèöèàëèçàöèÿ
   if( initfl!=1 )
   {
      myInit();
   }
   //FileWrite(idFile,"  0. Áàðîâ íà ãðàôèêå "+Bars);
   //öèêë ïî áàðàì
   for( cb=limit;cb>=0;cb--)
   {
      if( cb==0 ) FileWrite(idFile,"---- current bar index "+cb+" "+(Bars-1-cb)+" time "+TimeToStr(Time[cb])+" bars on the chart "+Bars);
      //åñëè íà ïðåäûäóùåì áàðå áûë îòðèñîâàí ýêñòðåìóì
      if( GSv_sl[cb+1]>0 && lb!=Bars-1-cb )
      {
         if( draw_up!=0 )
         {
            s_dn=0;
            if( cb==0 ) FileWrite(idFile,"  1. Maximum was drawing, counter for minimums was zeroing");
         }
         else
         {
            if( draw_dn!=0 )
            {
               s_up=0;
               if( cb==0 ) FileWrite(idFile,"  2. Minimum was drawing, counter for maximums was zeroing");
            }
         }
      }
      if( lb!=Bars-1-cb )
      {
         cur_h=0;
         cur_l=0;
         if( cb==0 ) FileWrite(idFile,"  2.1 new bar, flag for maximum/minimum was zeroing");
      }
      if( cb>Bars-2-drawf || (High[cb]<=High[cb+1] && Low[cb]>=Low[cb+1]) )
      {
         if( cb==0 ) FileWrite(idFile,"  3. Either 'inner' bar, or up to the first extremum");
         continue;
      }
      if( draw_up!=0 )
      {
         if( cb==0 ) FileWrite(idFile,"  4. Indicator is in uptrend");
         //åñëè ëèíèÿ íàïðàâëåíà ââåðõ
         if( High[cb]>h )
         {
            //åñëè äîñòèãíóò íîâûé ìàêñèìóì
            h=High[cb];
            cur_h=1;
            if( cb==0 ) FileWrite(idFile,"  5. New maximum was reached = "+h+" cur_h "+cur_h);
         }
         if( Low[cb]<l )
         {
            //åñëè äîñòèãíóò íîâûé ìèíèìóì
            l=Low[cb];
            if( cb==0 ) FileWrite(idFile,"  6. New minimum was reached = "+l);
            //åñëè ýòî íå òîò æå ñàìûé áàð
            if( lb!=Bars-1-cb || cur_l!=1 ) s_dn++;
            cur_l=1;
            if( cb==0 ) FileWrite(idFile,"  7. New bar, counter for minimums was increased "+s_dn+" cur_l "+cur_l);
         }
         //åñëè ñ÷åò÷èêè ðàâíû
         if( s_up==s_dn )
         {
            if( cb==0 ) FileWrite(idFile,"  8. counters are equal");
            //åñëè ïîñëåäíèé áàð îäíîâðåìåííî íîâûé ìàêñèìóì è ìèíèìóì
            if( cur_h==cur_l && cur_l==1 )
            {
               if( cb==0 ) FileWrite(idFile,"  9. There are 2 extremums");
               //åñëè ñâå÷à ìåäâåæüÿ
               if( Close[cb]<=Open[cb] )
               {
                  draw_up=0;
                  draw_dn=1;
                  fPoint_i=sPoint_i;
                  sPoint_i=Bars-1-cb;
                  GSv_sl[cb]=l;
                  for( i=cb+1;i<Bars-1-fPoint_i;i++ )
                  {
                     GSv_sl[i]=0;
                  }
                  if( cb==0 ) FileWrite(idFile,"  10.Bearish candle, line up = "+draw_up+", line down,"+draw_dn+" fPoint_i = "+fPoint_i+" sPoint_i "+sPoint_i+" indicator = "+GSv_sl[cb]);
               }
               else
               {
                  //åñëè ñâå÷à áû÷üÿ
                  sPoint_i=Bars-1-cb;
                  GSv_sl[cb]=h;
                  for( i=cb+1;i<Bars-1-fPoint_i;i++ )
                  {
                     GSv_sl[i]=0;
                  }
                  if( cb==0 ) FileWrite(idFile,"  11. Bullish candle, line up = "+draw_up+", line down,"+draw_dn+" fPoint_i = "+fPoint_i+" sPoint_i "+sPoint_i+" indicator = "+GSv_sl[cb]);
               }
            }
            else
            {
               //åñëè ïîñëåäíèé áàð òîëüêî íîâûé ìàêñèìóì
               if( cur_h==1 )
               {
                  sPoint_i=Bars-1-cb;
                  GSv_sl[cb]=h;
                  l=Low[cb];
                  for( i=cb+1;i<Bars-1-fPoint_i;i++ )
                  {
                     GSv_sl[i]=0;
                  }
                  if( cb==0 ) FileWrite(idFile,"  12. Maximum only, indicator = "+GSv_sl[cb]+" sPoint_i "+sPoint_i+" l "+l);
               }
               else
               {
                  if( cur_l==1 )
                  {
                     //åñëè ïîñëåäíèé áàð òîëüêî íîâûé ìèíèìóì
                     draw_up=0;
                     draw_dn=1;
                     fPoint_i=sPoint_i;
                     sPoint_i=Bars-1-cb;
                     GSv_sl[cb]=l;
                     h=High[cb];
                     for( i=cb+1;i<Bars-1-fPoint_i;i++ )
                     {
                        GSv_sl[i]=0;
                     }
                     if( cb==0 ) FileWrite(idFile,"  13. Minimum only, indicator = "+GSv_sl[cb]+" fPoint_i "+fPoint_i+" sPoint_i "+sPoint_i+" draw_up "+draw_up+" draw_dn "+draw_dn+" h "+h);
                  }
               }
            }
         }
         else
         {
            //èíà÷å åñëè ñìåíû íàïðàâëåíèÿ íåò ÿâíî (ñ÷åò÷èê Dn ñâå÷åé íå ðàâåí GSv_range)
            if( cb==0 ) FileWrite(idFile,"  14. counters are not equal");
            //åñëè äîñòèãíóò íîâûé ìàêñèìóì
            if( cur_h==1 )
            {
               sPoint_i=Bars-1-cb;
               GSv_sl[cb]=h;
               for( i=cb+1;i<Bars-1-fPoint_i;i++ )
               {
                  GSv_sl[i]=0;
               }
               l=Low[cb];
               if( cb==0 ) FileWrite(idFile,"  15. New maximum, indicator "+GSv_sl[cb]+" sPoint_i "+sPoint_i+" l "+l);
            }
         }
      }
      else
      {
         //åñëè ëèíèÿ íàïðàâëåíà âíèç
         if( cb==0 ) FileWrite(idFile,"  16. Indicator is on downtrend");
         if( High[cb]>h )
         {
            //åñëè äîñòèãíóò íîâûé ìàêñèìóì
            h=High[cb];
            if( cb==0 ) FileWrite(idFile,"  17. New maximum was riched "+h);
            if( lb!=Bars-1-cb || cur_h!=1 ) s_up++;
            cur_h=1;
            //åñëè ýòî íå òîò æå ñàìûé áàð
            if( cb==0 ) FileWrite(idFile,"  18. New bar, counter for maximums was increased "+s_up+" cur_h "+cur_h+" h "+h);
         }
         if( Low[cb]<l )
         {
            //åñëè äîñòèãíóò íîâûé ìèíèìóì
            l=Low[cb];
            cur_l=1;
            if( cb==0 ) FileWrite(idFile,"  19. New minimum was riched "+l+" cur_l "+cur_l);
         }
         //åñëè ñ÷åò÷èêè ðàâíû 
         if( s_up==s_dn )
         {
            if( cb==0 ) FileWrite(idFile,"  20. counters are equal");
            //åñëè ïîñëåäíèé áàð îäíîâðåìåííî íîâûé ìàêñèìóì è ìèíèìóì
            if( cur_h==cur_l && cur_l==1 )
            {
               if( cb==0 ) FileWrite(idFile,"  21. There are 2 extremums");
               //åñëè ñâå÷à ìåäâåæüÿ
               if( Close[cb]<=Open[cb] )
               {
                  sPoint_i=Bars-1-cb;
                  GSv_sl[cb]=l;
                  for( i=cb+1;i<Bars-1-fPoint_i;i++ )
                  {
                     GSv_sl[i]=0;
                  }
                  if( cb==0 ) FileWrite(idFile,"  22. Bearish candle, indicator "+GSv_sl[cb]+" sPoint_i "+sPoint_i);
               }
               else
               {
                  //åñëè ñâå÷à áû÷üÿ
                  draw_up=1;
                  draw_dn=0;
                  fPoint_i=sPoint_i;
                  sPoint_i=Bars-1-cb;
                  GSv_sl[cb]=h;
                  for( i=cb+1;i<Bars-1-fPoint_i;i++ )
                  {
                     GSv_sl[i]=0;
                  }
                  if( cb==0 ) FileWrite(idFile,"  23. Bullish candle, indicator "+GSv_sl[cb]+" draw_up "+draw_up+" draw_dn "+draw_dn+" sPoint_i "+sPoint_i+" fPoint_i "+fPoint_i);
               }
            }
            else
            {
               //åñëè ïîñëåäíèé áàð òîëüêî íîâûé ìàêñèìóì
               if( cur_h==1 )
               {
                  draw_up=1;
                  draw_dn=0;
                  fPoint_i=sPoint_i;
                  sPoint_i=Bars-1-cb;
                  GSv_sl[cb]=h;
                  l=Low[cb];
                  for( i=cb+1;i<Bars-1-fPoint_i;i++ )
                  {
                     GSv_sl[i]=0;
                  }
                  if( cb==0 ) FileWrite(idFile,"  24. Maximum only, indicator "+GSv_sl[cb]+" draw_up "+draw_up+" draw_dn "+draw_dn+" sPoint_i "+sPoint_i+" fPoint_i "+fPoint_i+" l "+l);
               }
               else
               {
                  if( cur_l==1 )
                  {
                     //åñëè ïîñëåäíèé áàð òîëüêî íîâûé ìèíèìóì
                     sPoint_i=Bars-1-cb;
                     GSv_sl[cb]=l;
                     h=High[cb];
                     for( i=cb+1;i<Bars-1-fPoint_i;i++ )
                     {
                        GSv_sl[i]=0;
                     }
                     if( cb==0 ) FileWrite(idFile,"  25. Minimum only, indicator "+GSv_sl[cb]+" sPoint_i "+sPoint_i+" h "+h);
                  }
               }
            }
         }
         else
         {
            //èíà÷å åñëè ñìåíû íàïðàâëåíèÿ íåò ÿâíî (ñ÷åò÷èê Up ñâå÷åé íå ðàâåí GSv_range)
            if( cb==0 ) FileWrite(idFile,"  26. Counters are not equal");
            //åñëè äîñòèãíóò íîâûé ìèíèìóì
            if( cur_l==1 )
            {
               sPoint_i=Bars-1-cb;
               GSv_sl[cb]=l;
               for( i=cb+1;i<Bars-1-fPoint_i;i++ )
               {
                  GSv_sl[i]=0;
               }
               h=High[cb];
               if( cb==0 ) FileWrite(idFile,"  27. New minimum was riched, indicator "+GSv_sl[cb]+" sPoint_i "+sPoint_i+" h "+h);
            }
         }
      }
      if( lb!=Bars-1-cb ) lb=Bars-1-cb;
   }

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

//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- 
   FileClose(idFile);
//----
   return(0);
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
// Ôóíêöèÿ íà÷àëüíîé èíèöèàëèçàöèè èíäèêàòîðà                        |
//+------------------------------------------------------------------+
void myInit()
  {
//---- 
   int cb;
   fPoint_i=0;
   h=High[Bars-1];
   l=Low[Bars-1];
   for( cb=Bars-2;cb>=0;cb--)
   {
      if( High[cb]>High[cb+1] || Low[cb]<Low[cb+1] )
      {
         if( High[cb]>h && High[cb]>High[cb+1] )
         {
            s_up++;
         }
         if( Low[cb]<l && Low[cb]<Low[cb+1] )
         {
            s_dn++;
         }
      }
      else
      {
         continue;
      }
      if( s_up==s_dn && s_up==GSv_range )
      {
         h=High[cb];
         l=Low[cb];
         sPoint_i=Bars-1-cb;
         if( Close[cb]>=Open[cb] )
         {
            s_dn=0;
            GSv_sl[Bars-1]=Low[Bars-1];
            GSv_sl[cb]=High[cb];
            draw_up=1;
            break;
         }
         else
         {
            s_up=0;
            GSv_sl[Bars-1]=High[Bars-1];
            GSv_sl[cb]=Low[cb];
            draw_dn=1;
            break;
         }
      }
      else
      {
         h=High[cb];
         l=Low[cb];
         sPoint_i=Bars-1-cb;
         if( s_up==GSv_range )
         {
            s_dn=0;
            GSv_sl[Bars-1]=Low[Bars-1];
            GSv_sl[cb]=High[cb];
            draw_up=1;
            break;
         }
         else
         {
            if( s_dn==GSv_range )
            {
               s_up=0;
               GSv_sl[Bars-1]=High[Bars-1];
               GSv_sl[cb]=Low[cb];
               draw_dn=1;
               break;
            }
         }
      }
   }
   initfl=1;
   drawf=sPoint_i;
//----
   return(0);
  }
//+------------------------------------------------------------------+

Comments