Author: Copyright � 2007, MetaQuotes Software Corp.
ZigZag_R

This script is an optimized version of the popular Zigzag technical indicator. It is designed to identify significant price swings (peaks and valleys) on a trading chart while ensuring the software runs efficiently without slowing down your platform.

Core Functionality

The primary purpose of this tool is to filter out minor market "noise" and highlight the broader trend by connecting major highs and lows. Unlike standard versions that might struggle with heavy processing during backtesting, this script uses an intelligent recalculation logic to keep the performance smooth.

How the Logic Works

  • Smart Processing: When you first load the chart, the script analyzes the entire available history to establish the initial trend. For every new price tick that arrives afterward, it doesn't need to re-calculate everything from the beginning. Instead, it identifies the most recent major turning points and only updates the necessary sections of the data.
  • Recalculation Depth: The script features a specific setting that determines how far back into history it should look to update its calculations. This prevents the "heavy" processing common in older versions, allowing for faster testing and real-time updates.
  • Data Filtering: The logic incorporates three main parameters to define what constitutes a "significant" move:
    • Depth: Determines how many bars (candles) are looked at to find a high or low point.
    • Deviation: Acts as a minimum threshold; the price must move by at least this amount for the script to recognize a new turn.
    • Backstep: Ensures that the points identified are distinct and not overlapping, preventing the creation of "floating" points on shorter timeframes.
  • Dynamic Adjustment: As new data arrives, the script constantly checks if the current price has surpassed a previous peak or valley. If it has, the script "moves" the point to the newest extreme, effectively redrawing the Zigzag line to reflect the most current market structure.

Summary for Users

This tool is designed for traders who want a clean, accurate visual of market trends without sacrificing computer performance. It automatically cleans up historical data and focuses on providing a clear path of significant price movements, making it ideal for identifying support/resistance levels and trend reversals.

Miscellaneous
Implements a curve of type %1
10 Views
0 Downloads
0 Favorites
ZigZag_R
//+------------------------------------------------------------------+
//|                                                    Zigzag_R_.mq4 |
//|                 Copyright © 2005-2007, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
/* Ýòîò âàðèàíò Zigzag'à ÿâëÿåòñÿ ïðîñòîé îïòèìèçàöèåé ñòàðîãî       |
âàðèàíòà, ê êîòîðîìó ïðèâûêëè ñîòíè òûñÿ÷ ïîëüçîâàòåëåé Metatrader   |
åùå ñ âåðñèè ÌÒ3 (ÿçûê MQL2).                                        |
Èñïîëüçîâàíèå èíäèêàòîðà áåç îïòèìèçàöèè äåëàëî ñëîæíûì è äîëãèì     |
òåñòèðîâàíèå ñîâåòíèêîâ, èñïîëüçóþùèõ çíà÷åíèÿ ïîëüçîâàòåëüñêîãî     |
èíäèêàòîðà Zigzag. Îïòèìèçèðîâàííûé âàðèàíò ðåøàåò äàííóþ ïðîáëåìó.  | 
 ïåðâûé ðàç, ïðè ïåðâîì çàïóñêå èíäèêàòîð ïðîñ÷èòûâàåò âñþ èñòîðèþ. | 
Ïðè ïîñëåäóþùèõ âûçîâàõ ïðè ïðèõîäå íîâûõ òèêîâ â ðåàëüíîì âðåìåíè   |
èëè ïðè èñïîëüçîâàíèè â òåñòåðå íàõîäèòñÿ òðåòèé ýêñòðåìóì îò        |
òåêóùåãî âðåìåíè âãëóáü èñòîðèè è ïåðåñ÷åò íà÷èíàåòñÿ ñ íåãî. Åñëè   |
Âû õîòèòå íà÷èíàòü ïåðåñ÷åò ñî âòîðîãî ýêñòðåìóìà, ïîìåíÿéòå         |
çíà÷åíèå ïåðåìåííîé level, êîòîðàÿ îïðåäåëÿåò ãëóáèíó ïåðåñ÷åòà:     |
int level = 3; // recounting's depth                                 |
Âñå íàçâàíèÿ âíåøíèõ ïåðåìåííûõ ñîõðàíåíû èç ñîîáðàæåíèé             |
ïðååìñòâåííîñòè. Êðîìå òîãî, óáðàíû ýêñòðåìóìû, âèñÿùèå â âîçäóõå,   |
êîòîðûå îáðàçîâûâàëèñü íà ìèíóòíûõ òàéì-ôðåéìàõ.                     |
//+------------------------------------------------------------------+
*/
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"
//----
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
//---- indicator parameters
extern int ExtDepth = 12;
extern int ExtDeviation = 5;
extern int ExtBackstep =3;
//---- indicator buffers
double ZigzagBuffer[];
double HighMapBuffer[];
double LowMapBuffer[];
// recounting's depth 
int level = 3; 
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(" + 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(ZigzagBuffer, 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 = 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 = 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;
                          ZigzagBuffer[shift] = lasthigh;
                          res = 1;
                        }
                      if(LowMapBuffer[shift] != 0)
                        {
                          lastlow = Low[shift];
                          lastlowpos = shift;
                          whatlookfor = 1;
                          ZigzagBuffer[shift] = lastlow;
                          res = 1;
                        }
                     }
                    break;  
           // look for peak
           case 1: 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;               
           // look for lawn
           case -1:  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