ZigZag_with_Chanel_Rays+onelegY

Author: Copyright � 2008, Dolsergon & MetaQuotes Software Corp.
ZigZag_with_Chanel_Rays+onelegY

This script is a technical analysis tool designed to identify significant price movements and structural trends on a trading chart. It primarily automates the detection of "peaks" and "valleys" in price action, making it easier for a user to visualize the overall direction of the market without being distracted by minor price fluctuations.

Core Logic Overview

The script operates through three primary layers of logic:

1. Noise Filtering and Peak Identification Instead of drawing a line at every single price change, the script uses a set of mathematical filters (Depth, Deviation, and Backstep). These settings allow it to ignore "market noise"—the small, insignificant ups and downs that happen throughout a trading session. It looks for significant turns in the market by identifying where the price has moved enough to be considered a meaningful high or low point.

2. Structural Mapping (The Zigzag) Once the script filters out the noise, it maps out the structural "skeleton" of the price movement:

  • Highs: It identifies the highest points reached during an upward move.
  • Lows: It identifies the lowest points reached during a downward move.
  • Sequence: The logic ensures that these points are connected in a logical sequence (a high followed by a low, or vice versa), creating a continuous "Zigzag" path that reveals the trend's history.

3. Dynamic Channeling and Visual Aids Beyond just drawing the Zigzag line, the script performs an additional calculation to help identify support and resistance areas:

  • Automatic Referencing: Every time a new significant high or low is identified, the script "looks back" into the recent price history.
  • Channel Projection: It attempts to find previous significant price levels to create visual reference points (dotted lines). These act as markers to show where the price has reacted in the past, helping traders see potential zones where the market might stall or reverse.

How it Works for the User

In simple terms, the script cleans up the chart. It looks at a messy series of price bars and says: "Ignore these tiny movements; here are the actual major turning points." It then draws a clear path connecting those points and places visual markers on the chart to indicate historical price levels, providing a clearer picture of the market's "footprint" over time.

Miscellaneous
Implements a curve of type %1
14 Views
0 Downloads
0 Favorites
ZigZag_with_Chanel_Rays+onelegY
//+------------------------------------------------------------------+
//|                                           Zigzag_ws_Chanel_R.mq4 |
//|          Copyright © 2008, Dolsergon & MetaQuotes Software Corp. |
//|                                      http://tradecoder.narod.ru/ |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
//mod2008fxtsd +onelegyellow
#property copyright "Copyright © 2008, Dolsergon & MetaQuotes Software Corp."
#property link      "http://tradecoder.narod.ru/; http://www.metaquotes.net/"

#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 Red
#property indicator_width1 2
#property indicator_color2 Pink
#property indicator_color3 Pink
#property indicator_color4 Gold
//---- indicator parameters
extern int ExtDepth=12;
extern int ExtDeviation=5;
extern int ExtBackstep=3;
//---- indicator buffers
double ZigzagBuffer[];
double HighMapBuffer[];
double LowMapBuffer[];
double BufChanelHigh[];
double BufChanelLow[];
double LastLegBuffer[];

int level=3; // recounting's depth 
bool downloadhistory=false;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   IndicatorBuffers(6);
//---- drawing settings
   SetIndexStyle(0,DRAW_SECTION);
   SetIndexBuffer(0,ZigzagBuffer);
   SetIndexEmptyValue(0,0.0);
   
   SetIndexStyle(1, DRAW_SECTION);
   SetIndexBuffer(1,BufChanelHigh);
   SetIndexEmptyValue(1,0.0);
   
   SetIndexStyle(2, DRAW_SECTION);
   SetIndexBuffer(2,BufChanelLow);
   SetIndexEmptyValue(2,0.0);

   SetIndexStyle(3,DRAW_SECTION);
   SetIndexBuffer(3,LastLegBuffer);
   SetIndexEmptyValue(3,0.0);


   SetIndexBuffer(4,HighMapBuffer);
   SetIndexBuffer(5,LowMapBuffer);

   IndicatorShortName("ZigZag_ws_Chanel_Rll("+ExtDepth+","+ExtDeviation+","+ExtBackstep+")");

	ObjectCreate("ZZCR1", OBJ_TREND, 0, Time[0], Close[0], Time[10], Close[10]);
	ObjectSet("ZZCR1", OBJPROP_COLOR, Aqua);
	ObjectSet("ZZCR1", OBJPROP_WIDTH, 2);
	ObjectSet("ZZCR1", OBJPROP_STYLE, STYLE_DOT);
	ObjectSet("ZZCR1", OBJPROP_BACK, false);
	ObjectSet("ZZCR1", OBJPROP_RAY, true);
	
	ObjectCreate("ZZCR2", OBJ_TREND, 0, Time[0], Close[0], Time[10], Close[10]);
	ObjectSet("ZZCR2", OBJPROP_COLOR, Khaki);
	ObjectSet("ZZCR2", OBJPROP_WIDTH, 2);
	ObjectSet("ZZCR2", OBJPROP_STYLE, STYLE_DOT);
	ObjectSet("ZZCR2", OBJPROP_BACK, false);
	ObjectSet("ZZCR2", OBJPROP_RAY, true);
	
   return(0);
  }
  
  
  
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   int i,p, counted_bars = IndicatorCounted();
   int limit,counterZ,whatlookfor;
   int shift,back,lasthighpos,lastlowpos;
   double val,res;
   double curlow,curhigh,lasthigh,lastlow;

   if (counted_bars==0 && downloadhistory) // history was downloaded
     {
      ArrayInitialize(ZigzagBuffer,0.0);
      ArrayInitialize(BufChanelHigh,0.0);
      ArrayInitialize(BufChanelLow,0.0);
      ArrayInitialize(LastLegBuffer,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<level && 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;
 
         LastLegBuffer[i]=0.0;  
         
         BufChanelHigh[i]=0.0;
         BufChanelLow[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)
        {
         case 0: // look for peak or lawn 
            if (lastlow==0 && lasthigh==0)
              {
               if (HighMapBuffer[shift]!=0)
                 {
                  lasthigh=High[shift];
                  lasthighpos=shift;
                  whatlookfor=-1;
                  SetHighZZ(shift, lasthigh);
                  res=1;
                 }
               if (LowMapBuffer[shift]!=0)
                 {
                  lastlow=Low[shift];
                  lastlowpos=shift;
                  whatlookfor=1;
                  SetLowZZ(shift, lastlow);
                  res=1;
                 }
              }
             break;  
         case 1: // look for peak
            if (LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<lastlow && HighMapBuffer[shift]==0.0)
              {
               SetLowZZ(lastlowpos, 0.0);
               lastlowpos=shift;
               lastlow=LowMapBuffer[shift];
               SetLowZZ(shift, lastlow);
               res=1;
              }
            if (HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)
              {
               lasthigh=HighMapBuffer[shift];
               lasthighpos=shift;
               SetHighZZ(shift, lasthigh);
               whatlookfor=-1;
               res=1;
              }   
            break;               
         case -1: // look for lawn
            if (HighMapBuffer[shift]!=0.0 && HighMapBuffer[shift]>lasthigh && LowMapBuffer[shift]==0.0)
              {
               SetHighZZ(lasthighpos, 0.0);
               lasthighpos=shift;
               lasthigh=HighMapBuffer[shift];
               SetHighZZ(shift, lasthigh);
              }
            if (LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)
              {
               lastlow=LowMapBuffer[shift];
               lastlowpos=shift;
               SetLowZZ(shift, lastlow);
               whatlookfor=1;
              }   
            break;               
         default: return; 
        }
     }


   for (p=0,i=0;i<Bars && p<2;i++)
   {
      if (ZigzagBuffer[i] != 0)
      {
         LastLegBuffer[i] = ZigzagBuffer[i]; p++;
      }
   }



   return(0);
  }


//=================================================================================================
void SetLowZZ(int pShift, double pValue) 
{
	ZigzagBuffer[pShift]=pValue;
	BufChanelLow[pShift]=pValue;
	
	// Âåðõíèé ëó÷èê ---------------------------------------------
	for (int b1=0; b1<200; b1++) 
	{
		if (BufChanelHigh[b1] > 0) break;
		
	}
	for (int b2=b1+1; b2<400; b2++) 
	{
		if (BufChanelHigh[b2] > 0) break;
	}
	ObjectSet("ZZCR1", OBJPROP_TIME1, Time[b2]);
	ObjectSet("ZZCR1", OBJPROP_PRICE1, High[b2]);
	ObjectSet("ZZCR1", OBJPROP_TIME2, Time[b1]);
	ObjectSet("ZZCR1", OBJPROP_PRICE2, High[b1]);
}
//=================================================================================================
void SetHighZZ(int pShift, double pValue) 
{
	ZigzagBuffer[pShift]=pValue;
	BufChanelHigh[pShift]=pValue;
	
	// Íèæíèé ëó÷èê ---------------------------------------------
	for (int b1=0; b1<200; b1++) 
	{
		if (BufChanelLow[b1] > 0) break;
		
	}
	for (int b2=b1+1; b2<400; b2++) 
	{
		if (BufChanelLow[b2] > 0) break;
	}
	ObjectSet("ZZCR2", OBJPROP_TIME1, Time[b2]);
	ObjectSet("ZZCR2", OBJPROP_PRICE1, Low[b2]);
	ObjectSet("ZZCR2", OBJPROP_TIME2, Time[b1]);
	ObjectSet("ZZCR2", OBJPROP_PRICE2, Low[b1]);
}




Comments