Author: Copyright � 2008-2009, GreenDog
_iGDR_ZZ

This tool is designed to help traders visualize and identify market trends by dynamically drawing colored lines that follow the price action. Instead of simply showing raw data, it attempts to "map" the structure of the market by connecting significant highs and lows while providing visual cues for trend reversals.

Core Logic Overview

The script operates by identifying key turning points in the market—specifically the peaks (highs) and valleys (lows). Its primary goal is to distinguish between bullish and bearish movements and connect these movements with smooth transitions.

1. Dynamic Trend Identification

The script continuously monitors the price movement to determine the current market direction:

  • Bullish Movement: When the price breaks above established previous highs, the logic identifies this as a potential upward trend.
  • Bearish Movement: When the price drops below established previous lows, the logic identifies this as a potential downward trend.

2. Structural Mapping (The "ZigZag" Effect)

Rather than just marking points, the script draws connecting lines between these peaks and valleys:

  • Trend Lines: It creates continuous visual paths. When a new high or low is confirmed, the script calculates the trajectory from the previous point to the current one.
  • Color Coding: The script uses different colors (Gold, Dark Green, and Red) to provide immediate visual feedback on the nature of the trend and the specific types of price points being hit.

3. Volatility Adjustment

A key feature of this logic is its ability to account for market volatility. It calculates a "High-Low" range based on historical data. This ensures that the lines and trend identifications aren't just reacting to minor price flickers; instead, they are scaled based on the actual range of price movement over a specific period.

4. Automatic Trend Reversal

The script includes logic to handle "trend exhaustion." If the price moves significantly away from the most recent peak or valley without creating a new one, the script is programmed to look for the next most logical structural point to anchor the trend line. This helps in identifying when a current move may be losing steam and preparing for a potential shift in direction.

Summary of Visual Output

  • Lines: Provide a continuous visual flow of the price "path," making it easier to see the sequence of highs and lows.
  • Arrows/Markers: Highlight specific structural breaks where the trend has officially shifted or a new significant peak/valley has been reached.
  • Dynamic Adaptation: The indicator automatically adjusts its sensitivity based on your settings, ensuring that the lines remain relevant whether the market is moving slowly or experiencing high volatility.
Price Data Components
Series array that contains the highest prices of each barSeries array that contains the lowest prices of each bar
Miscellaneous
Implements a curve of type %1
7 Views
0 Downloads
0 Favorites
_iGDR_ZZ
// Indicators Pack - Green Digger Reseach
//+------------------------------------------------------------------+
//|                                            [IP-GDR] ZigZag color |
//|                          Copyright © 2008-2009, GreenDog, Russia |
//|                                                    krot@inbox.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008-2009, GreenDog"
#property link      "krot@inbox.ru"

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Gold
#property indicator_color2 DarkGreen
#property indicator_color3 Red
#property indicator_width1 1
#property indicator_width2 2
#property indicator_width3 2

extern double extHL = 4.8; // êîýô äëÿ ñðåäíåãî HL, îïðåäåëÿþùåãî ïóòü â ïóíêòàõ, ïðè êîòîðîì âåðøèíà ñ÷èòàåòñÿ óñòàíîâëåííîé
extern int extFlat = 48;   // êîëè÷åñòâî áàðîâ ôëåòà, êîãäà âåðøèíà ðèñóåòñÿ ïðèíóäèòåëüíî
extern int sBars = 480;    // show bars

double aUP[],aDW[],aMA[];

double lastHL,aLv[3];
bool Go = true, first = true;
int trend,lastLow,lastHigh;

int init(){
   IndicatorBuffers(3);
   SetIndexBuffer(0,aMA);
   SetIndexBuffer(1,aUP);
   SetIndexBuffer(2,aDW);
   SetIndexStyle(0,DRAW_ARROW); SetIndexArrow(0,250);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexStyle(2,DRAW_LINE);
   SetIndexEmptyValue(0,EMPTY_VALUE);
   SetIndexEmptyValue(1,EMPTY_VALUE);
   SetIndexEmptyValue(2,EMPTY_VALUE);
   IndicatorDigits(Digits+1);

   if (sBars!=0 && sBars<2) { Go=false; return(-1); }
   if (sBars==0) sBars=10000;
   return(0);
}

int deinit(){
   Comment("");
}

int start(){
   int lastBars,count;
   
   if (!Go) { Comment("Íåêîððåêòíûå ïàðàìåòðû èíäèêàòîðà!"); return(-1); }
   if (Bars<sBars+extFlat) { Comment("Íåäîñòàòî÷íî áàðîâ íà ãðàôèêå!"); return(0); }  
   else Comment("");
//   if (Bars==lastBars) return(0); // åñëè ìåäëåííûé, ñ÷èòàåì òîêà â íà÷àëå áàðà
   if (Bars-lastBars<=1){
      if (Bars-lastBars==1){ lastHigh++; lastLow++; calcHL(); }
      count=Bars-lastBars;
   }
   else { 
      ArrayInitialize(aMA,EMPTY_VALUE); ArrayInitialize(aUP,EMPTY_VALUE); ArrayInitialize(aDW,EMPTY_VALUE); first=true;
   }
   lastBars=Bars;
   
   if (first){ // ïðè ïåðâîì çàïóñêå îïðåäåëÿåì ñðåäíåå õë
      calcHL();
      // îïðåäåëÿåì ïåðâóþ òî÷êó
      double min=iLowest(NULL,0,MODE_LOW,extFlat,sBars);
      double max=iHighest(NULL,0,MODE_HIGH,extFlat,sBars);
      if (max<min){ // åñëè ïîñëåäíÿÿ âåðøèíà high
         lastLow=min; pushHigh(max); count=max;
      }
      else { // åñëè ïîñëåäíÿÿ âåðøèíà low
         lastHigh=max; pushLow(min); count=min;
      }
      first=false;
   }

   // îñíîâíîé öèêë
   for(int i=count;i>=0;i--){
      if (trend==OP_BUY){ // ëó÷ ââåðõ
         if (High[i]>aLv[1]) pushHigh(i); // åñëè îáíîâëåíèå õàé
         else if (Low[i]<aLv[2] || Low[i]<aLv[0]) pushLow(i); // çàäåëè óðîâíè îòñòàþùåãî èëè ïðåäûäóùåãî ëîó
         else if (lastHigh-i>extFlat) pushLow(iLowest(NULL,0,MODE_LOW,extFlat,i)); // íå ïîðà ëè ñìåíèòü òðåíä
      }
      else { // ëó÷ âíèç
         if (Low[i]<aLv[1]) pushLow(i); // åñëè îáíîâëåíèå low
         else if (High[i]>aLv[2] || High[i]>aLv[0]) pushHigh(i); // çàäåëè óðîâíè îòñòàþùåãî èëè ïðåäûäóùåãî õàé
         else if (lastLow-i>extFlat) pushHigh(iHighest(NULL,0,MODE_HIGH,extFlat,i)); // íå ïîðà ëè ñìåíèòü òðåíä
      }
   }
   
   return(0);
}

void calcHL(){
   double HL=0; 
   for(int i=Bars;i>=0;i--) { HL=HL+High[i]-Low[i]; if (i==sBars) lastHL=HL; }
   lastHL=NormalizeDouble(extHL*(MathSqrt(HL/Bars*(HL-lastHL)/sBars)),Digits);
//      lastHL=NormalizeDouble(extHL*(HL/Bars+(HL-lastHL)/sBars)/2,Digits);
//      lastHL=NormalizeDouble(extHL*HL/Bars,Digits);
   return(0);
}

void pushHigh(int sh){
   lastHigh=sh; trend=OP_BUY; aMA[sh]=High[sh];
   aLv[0]=Low[lastLow]; aLv[1]=High[lastHigh]; aLv[2]=aLv[1]-lastHL;
   int count=lastLow-lastHigh; // ïðîðèñîâêà è çàïîëíåíèå áóôåðîâ
   for(int i=0;i<=count;i++) aUP[lastLow-i]=Low[lastLow]+i*(High[sh]-Low[lastLow])/count;
   return(0);
}

void pushLow(int sh){
   lastLow=sh; trend=OP_SELL; aMA[sh]=Low[sh];
   aLv[0]=High[lastHigh]; aLv[1]=Low[lastLow]; aLv[2]=aLv[1]+lastHL;
   int count=lastHigh-lastLow; // ïðîðèñîâêà è çàïîëíåíèå áóôåðîâ
   for(int i=0;i<=count;i++) aDW[lastHigh-i]=High[lastHigh]-i*(High[lastHigh]-Low[sh])/count;
   return(0);
}


Comments