!!ZigZagTriad

Download script
Author: Copyright � 2005, MetaQuotes Software Corp.
!!ZigZagTriad

This script functions as a visual trading tool designed to identify and highlight significant price turning points on a chart. Instead of showing every minor fluctuation in price, it filters out "noise" to reveal the major structural highs and lows of the market.

Core Functionality

The logic operates by scanning historical price data to find local peaks (highs) and troughs (lows). It uses three primary settings to determine how these points are identified:

  • Depth: This determines how far back the script looks to find a high or low point. A larger depth means it will only mark very prominent swings, while a smaller depth captures more frequent movements.
  • Deviation: This acts as a filter to ensure that a price movement is significant enough to be considered a "turn." It prevents the script from marking tiny, insignificant wobbles in the price.
  • Backstep: This ensures there is a minimum distance between identified points, preventing multiple marks from appearing too close together.

How the Logic Processes Data

The script processes the market data in three distinct phases:

  1. Initial Identification: The tool first scans the price history to find potential high and low values based on the Depth and Deviation settings. It stores these potential candidates while checking against the Backstep requirement.
  2. Refinement (The "ZigZag" Logic): This is a critical step where the script compares identified points against one another. If it finds a new high that is higher than a previously recorded high, or a new low that is lower than a previous low, it "corrects" the chart by removing the older, less significant mark. This ensures that the resulting lines connect the most extreme points of each trend.
  3. Visual Mapping: Finally, the script organizes these confirmed peaks and troughs into clear visual markers. Depending on your settings, it can display these as a connected line (the classic ZigZag look) or as specific arrow indicators at the exact moments where the price reversed direction.

Practical Use

By stripping away the minor movements of the market, this tool allows a trader to see the "skeleton" of the price action. It helps in identifying trend reversals, measuring the strength of current price swings, and establishing support and resistance levels by highlighting the most significant structural boundaries of the market history.

Miscellaneous
Implements a curve of type %1
20 Views
2 Downloads
0 Favorites
!!ZigZagTriad
//+------------------------------------------------------------------+
//|                                        Custom Moving Average.mq4 |
//|                      Copyright © 2005, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Blue
#property indicator_color2 Red
#property indicator_color3 Gray
//---- indicator parameters
extern int  ExtDepth=12;
extern int  ExtDeviation=5;
extern int  ExtBackstep=3;
extern bool ShowZigZag=False;
//---- indicator buffers
double ExtMapBuffer[];
double ExtMapBuffer2[];
double ExtMapBufferU[];
double ExtMapBufferD[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
   IndicatorBuffers(4);
   SetIndexBuffer(0,ExtMapBufferU); SetIndexStyle(0,DRAW_ARROW); SetIndexArrow(0,159);
   SetIndexBuffer(1,ExtMapBufferD); SetIndexStyle(1,DRAW_ARROW); SetIndexArrow(1,159);
   SetIndexBuffer(2,ExtMapBuffer);
   if(ShowZigZag)
         SetIndexStyle(2,DRAW_SECTION);
   else  SetIndexStyle(2,DRAW_NONE);
   SetIndexBuffer(3,ExtMapBuffer2);
   SetIndexEmptyValue(0,0.0);
   SetIndexEmptyValue(1,0.0);
   SetIndexEmptyValue(2,0.0);
   
   IndicatorShortName("ZigZag("+ExtDepth+","+ExtDeviation+","+ExtBackstep+")");
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   int    shift, back,lasthighpos,lastlowpos;
   double val,res;
   double curlow,curhigh,lasthigh,lastlow;

   for(shift=Bars-ExtDepth; shift>=0; shift--)
     {
      ExtMapBufferU[shift]=0;
      ExtMapBufferD[shift]=0;
      val=Low[Lowest(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=ExtMapBuffer[shift+back];
               if((res!=0)&&(res>val)) ExtMapBuffer[shift+back]=0.0; 
              }
           }
        } 
      ExtMapBuffer[shift]=val;
      //--- high
      val=High[Highest(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=ExtMapBuffer2[shift+back];
               if((res!=0)&&(res<val)) ExtMapBuffer2[shift+back]=0.0; 
              } 
           }
        }
      ExtMapBuffer2[shift]=val;
     }

   // final cutting 
   lasthigh=-1; lasthighpos=-1;
   lastlow=-1;  lastlowpos=-1;

   for(shift=Bars-ExtDepth; shift>=0; shift--)
     {
      curlow=ExtMapBuffer[shift];
      curhigh=ExtMapBuffer2[shift];
      if((curlow==0)&&(curhigh==0)) continue;
      //---
      if(curhigh!=0)
        {
         if(lasthigh>0) 
           {
            if(lasthigh<curhigh) ExtMapBuffer2[lasthighpos]=0;
            else ExtMapBuffer2[shift]=0;
           }
         //---
         if(lasthigh<curhigh || lasthigh<0)
           {
            lasthigh=curhigh;
            lasthighpos=shift;
           }
         lastlow=-1;
        }
      //----
      if(curlow!=0)
        {
         if(lastlow>0)
           {
            if(lastlow>curlow) ExtMapBuffer[lastlowpos]=0;
            else ExtMapBuffer[shift]=0;
           }
         //---
         if((curlow<lastlow)||(lastlow<0))
           {
            lastlow=curlow;
            lastlowpos=shift;
           } 
         lasthigh=-1;
        }
     }
  
   double prevPeak=0;
   for(shift=Bars-1; shift>=0; shift--)
   {
      if(shift>=Bars-ExtDepth)
      {
         ExtMapBuffer[shift] =0.0;
         ExtMapBufferU[shift]=0.0;
         ExtMapBufferD[shift]=0.0;
      }            
      else
      {
         res=ExtMapBuffer2[shift];
         if(res!=0.0) ExtMapBuffer[shift] =res;
      }
      res=ExtMapBuffer[shift];
      ExtMapBufferU[shift]=ExtMapBufferU[shift+1];
      ExtMapBufferD[shift]=ExtMapBufferD[shift+1];
      if(res!=0.0) 
      {
        if(res>prevPeak && prevPeak!=0) ExtMapBufferU[shift]=res;
        if(res<prevPeak && prevPeak!=0) ExtMapBufferD[shift]=res;
        prevPeak = res;
      }                   
  }
}

Comments