Author: Copyright � 2007, MetaQuotes Software Corp.
Zigzag2_R

This script is designed to identify and visualize significant price fluctuations on a trading chart, specifically highlighting the "peaks" (high points) and "valleys" (low points) of market movement. It automates the detection of these structural turns to help traders see the underlying trend of price action more clearly.

Core Logic Overview

The script functions by scanning through historical price data and filtering out minor "noise" to isolate only the most significant turning points. It works through three primary logical phases:

1. Filtering and Significance Mapping The tool first analyzes every candle on the chart to determine if it contains a significant high or low point. To do this, it uses three main criteria:

  • Depth: It looks back over a specific number of candles to find the highest and lowest prices in that window.
  • Deviation: It ensures that the price move is large enough to be considered meaningful; if a price change is too small, the script ignores it.
  • Backstep: It checks nearby candles to ensure that a point is truly a unique turning point rather than a repeated price level.

This phase creates a "map" of potential highs and lows, discarding any minor fluctuations that don't meet the user-defined strength requirements.

2. State Tracking (The ZigZag Movement) Once the map of significant points is created, the script begins to "connect the dots." It keeps track of what it is currently looking for: either a new peak or a new valley. This prevents the lines from moving erratically and ensures the visual flow follows the direction of the market.

3. Dynamic Correction (The "Cutting" Logic) One of the most important features of this script is its ability to "correct" itself in real-time. Because markets are dynamic, a new high or low might form that surpasses a previously identified point.

  • If the script identifies a new peak that is higher than the one it just marked, it will automatically remove (or "cut") the previous mark and place the new one at the current highest point.
  • This ensures that the final visual representation always reflects the absolute most extreme high or low reached during a specific trend move.

Visual Behavior

The script uses a specialized drawing method that connects these points with continuous lines. By focusing on "Peaks" and "Lows," it transforms a cluttered price chart into a simplified path of major price swings, making it easier to identify when a trend is changing or when the market is entering a period of consolidation.

Miscellaneous
Implements a curve of type %1
13 Views
0 Downloads
0 Favorites
Zigzag2_R
//+------------------------------------------------------------------+
//|                                                   Zigzag2_R_.mq4 |
//|                 Copyright © 2005-2007, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
/* Â ñòàíäàðòíîì èíäèêàòîðå http://codebase.mql4.com/ru/238 äëÿ      |
ðèñîâàíèÿ èñïîëüçîâàëñÿ ñòèëü DRAW_SECTION. Ýòîò ñòèëü ïîçâîëÿåò     |
ðèñîâàòü îòðåçêàìè òîëüêî ìåæäó òî÷êàìè, íàõîäÿùèìèìñÿ íà ðàçíûõ     |
áàðàõ. Ñòèëü îòðèñîâêè DRAW_ZIGZAG ïîçâîëÿåò ñíÿòü ýòî îãðàíè÷åíèå,  |
äëÿ ýòîãî èñïîëüçóþòñÿ äâà áóôåðà âìåñòî îäíîãî. Äëÿ èëëþñòðàöèè     |
ýòîãî ñòèëÿ è áûë íàïèñàí Zigzag2_R_.mq4.                            |
 êîä äîáàâëåíà îáðàáîòêà âíåøíåãî  áàðà (outside bar), êîãäà  High  |
òåêóùåãî áàðà âûøå ïðåäûäóùèõ, à Low òåêóùåãî áàðà íèæå ïðåäûäóùèõ.  |
Êîä òàêæå äåìîíñòðèðóåò, ÷òî öâåò îïðåäåëÿåòñÿ öâåòîì ïåðâîãî èç     |
äâóõ áóôåðîâ.                                                        |
#property indicator_chart_window                                     |
#property indicator_buffers 2                                        |
#property indicator_color1 Blue                                      |
#property indicator_color2 Red                                       |
Äëÿ âûçîâà ýòîãî èíäèêàòîðà èç äðóãèõ ïðîãðàìì íà mql4 òåïåðü        |
íåîáõîäèìî èñïîëüçîâàòü äâå êîíñòðóêöèè:                             |
iCustom(NULL, 0, "Zigzag2_R_", 12, 5, 3, 0, index) - ïè÷êè           |
iCustom(NULL, 0, "Zigzag2_R_", 12, 5, 3, 0, index) - äîíûøêè         |
Áëîê îáðàáîòêè âíåøíåãî áàðà äàí êàê ïðèìåð. Âû ìîæåòå èñïîëüçîâàòü  |
ñâîé àëãîðèòì äëÿ òàêîé ñèòóàöèè.                                    |
//+------------------------------------------------------------------+
*/
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"
//----
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Red
//---- indicator parameters
extern int ExtDepth = 12;
extern int ExtDeviation = 5;
extern int ExtBackstep = 3;
//---- indicator buffers
double ZigzagPeakBuffer[];
double ZigzagLawnBuffer[];
double HighMapBuffer[];
double LowMapBuffer[];
int level = 3; // recounting's depth 
bool downloadhistory = false;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   IndicatorBuffers(4);
//---- drawing settings
   SetIndexStyle(0, DRAW_ZIGZAG);
   SetIndexStyle(1, DRAW_ZIGZAG);
//---- indicator buffers mapping
   SetIndexBuffer(0, ZigzagPeakBuffer);
   SetIndexBuffer(1, ZigzagLawnBuffer);
   SetIndexLabel(0, "ZigzafPeak");
   SetIndexLabel(1, "ZigzafLawn");
//----
   SetIndexBuffer(2, HighMapBuffer);
   SetIndexBuffer(3, LowMapBuffer);
//----
   SetIndexEmptyValue(0, 0.0);
   SetIndexEmptyValue(1, 0.0);
//---- indicator short name
   IndicatorShortName("ZigZag(" + ExtDepth + "," + ExtDeviation + "," + 
                      ExtBackstep + ")");
//---- 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;
// history was downloaded
   if(counted_bars == 0 && downloadhistory) 
     {
       ArrayInitialize(ZigzagPeakBuffer, 0.0);
       ArrayInitialize(ZigzagLawnBuffer, 0.0);
       ArrayInitialize(HighMapBuffer, 0.0);
       ArrayInitialize(LowMapBuffer, 0.0);
     }
//----
   if(counted_bars == 0) 
     {
       limit = Bars - ExtDepth;
       downloadhistory = true;
     }
//----
   if(counted_bars > 0) 
     {
       //----
       while(counterZ < 3 && i < 100)
         {
           res = (ZigzagPeakBuffer[i] + ZigzagLawnBuffer[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--)  
         {
           ZigzagPeakBuffer[i] = 0.0;  
           ZigzagLawnBuffer[i] = 0.0;  
           LowMapBuffer[i] = 0.0;
           HighMapBuffer[i] = 0.0;
         }
     } 
//----
   for(shift = limit; shift >= 0; shift--)
     {
       val = Low[iLowest(NULL, 0, MODE_LOW, ExtDepth, shift)];
       //----
       if(val == lastlow) 
           val = 0.0;
       else 
         { 
           lastlow = val; 
           //----
           if((Low[shift] - val) > (ExtDeviation*Point)) 
               val = 0.0;
           else
             {
               //----
               for(back = 1; back <= ExtBackstep; back++)
                 {
                   res = LowMapBuffer[shift+back];
                   //----
                   if((res != 0) && (res > val)) 
                       LowMapBuffer[shift+back] = 0.0; 
                 }
             }
         } 
       //----
       if(Low[shift] == val) 
           LowMapBuffer[shift] = val; 
       else 
           LowMapBuffer[shift] = 0.0;
       //--- high
       val = High[iHighest(NULL, 0, MODE_HIGH, ExtDepth, shift)];
       //----
       if(val == lasthigh) 
           val = 0.0;
       else 
         {
           lasthigh = val;
           //----
           if((val - High[shift]) > (ExtDeviation*Point)) 
               val = 0.0;
           else
             {
               //----
               for(back = 1; back <= ExtBackstep; back++)
                 {
                   res = HighMapBuffer[shift+back];
                   //----
                   if((res != 0) && (res < val)) 
                       HighMapBuffer[shift+back] = 0.0; 
                 } 
             }
         }
       //----
       if(High[shift] == val) 
           HighMapBuffer[shift] = val; 
       else 
           HighMapBuffer[shift] = 0.0;
     }
// 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)
         {
           // look for peak or lawn 
           case 0: if(lastlow == 0 && lasthigh == 0)
                     {
                       if(HighMapBuffer[shift] != 0)
                         {
                           lasthigh = High[shift];
                           lasthighpos = shift;
                           whatlookfor = -1;
                           ZigzagPeakBuffer[shift] = lasthigh;
                           res = 1;
                         }
                       if(LowMapBuffer[shift] != 0)
                         {
                           lastlow = Low[shift];
                           lastlowpos = shift;
                           whatlookfor = 1;
                           ZigzagLawnBuffer[shift] = lastlow;
                           res = 1;
                         }
                     }
                   break;  
           // look for peak
           case 1: if(LowMapBuffer[shift] != 0.0 && LowMapBuffer[shift] < lastlow &&
                      HighMapBuffer[shift] == 0.0)
                     {
                       ZigzagLawnBuffer[lastlowpos] = 0.0;
                       lastlowpos = shift;
                       lastlow = LowMapBuffer[shift];
                       ZigzagLawnBuffer[shift] = lastlow;
                       res = 1;
                     }
                   if(HighMapBuffer[shift] != 0.0 && LowMapBuffer[shift] == 0.0)
                     {
                       lasthigh = HighMapBuffer[shift];
                       lasthighpos = shift;
                       ZigzagPeakBuffer[shift] = lasthigh;
                       whatlookfor = -1;
                       res = 1;
                     }   
                   break;               
           // look for lawn
           case -1:  if(HighMapBuffer[shift] != 0.0 && 
                        HighMapBuffer[shift] > lasthigh && 
                        LowMapBuffer[shift] == 0.0)
                       {
                         ZigzagPeakBuffer[lasthighpos] = 0.0;
                         lasthighpos = shift;
                         lasthigh = HighMapBuffer[shift];
                         ZigzagPeakBuffer[shift] = lasthigh;
                       }
                     if(LowMapBuffer[shift] != 0.0 && HighMapBuffer[shift] == 0.0)
                       {
                         lastlow = LowMapBuffer[shift];
                         lastlowpos = shift;
                         ZigzagLawnBuffer[shift] = lastlow;
                         whatlookfor = 1;
                       }   
                     break;               
           default: return; 
         }
     }
//----
   return(0);
  }
//+------------------------------------------------------------------+

Comments