[i] ZigZag_Pointer_alert_only at turning points

Download script
Author: dr_richard_gaines
[i] ZigZag_Pointer_alert_only at turning points

This tool is designed to filter out the "noise" of a volatile financial market to identify the primary structural peaks and valleys (highs and lows) in price action. By highlighting these key turning points, it allows you to see the underlying trend more clearly.

Core Logic and Filtering

The script functions by scanning historical price data based on three user-defined settings: Depth, Deviation, and Backstep.

  1. Identification of Extremes: The tool constantly looks for significant highs and lows within a specific window of time (the Depth). It ignores minor fluctuations that do not meet a minimum size requirement (the Deviation), ensuring that only meaningful price moves are captured.
  2. Backstep Validation: To ensure the "peaks" and "valleys" identified are actually the most extreme points in a specific area, the tool uses a "backstep" mechanism. This prevents multiple dots from appearing in a tight cluster, favoring the true highest or lowest point of a move.
  3. Dynamic Refinement: The script performs a secondary pass over the data to refine these points. If a new, more significant high or low is discovered that contradicts a previous one (for example, finding a higher peak than a previously marked one in the same sequence), it "re-cuts" the old point and updates the chart to reflect the more accurate extreme.

Trend Monitoring and Alerts

The final layer of logic focuses on tracking the progression of these identified points over time. The tool monitors the positions of the two most recent structural peaks and valleys:

  • Directional Tracking: It remembers where the last two major turning points occurred. If the relationship between these points shifts—indicating that the price is moving from an upward trend into a downward trend, or vice versa—the script recognizes this as a potential change in market direction.
  • Automated Notifications: When the logic detects this significant shift in trend structure (a "possible change in direction"), it triggers an alert. This provides a real-time notification that the market's momentum may be shifting, allowing for quicker reactions to new market behavior.

In summary, this script acts as a structural filter that cleans up messy price charts, identifies the most important turning points, and notifies you immediately when the primary trend structure changes.

Miscellaneous
Implements a curve of type %1It issuies visual alerts to the screen
13 Views
0 Downloads
0 Favorites
[i] ZigZag_Pointer_alert_only at turning points
//+------------------------------------------------------------------+
//|                                               ZigZag Pointer.mq4 |
//|                                    zigzag modified by Dr. Gaines |
//|                                      dr_richard_gaines@yahoo.com |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "dr_richard_gaines"
#property link      "http://www.metaquotes.net/"

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 White
#property indicator_width1 3
#property indicator_color2 Black
#property indicator_width2 3 
//---- indicator parameters
extern int ExtDepth=100;
extern int ExtDeviation=75;
extern int ExtBackstep=15;
//---- indicator buffers
double ExtMapBuffer[];
double ExtMapBuffer2[];
int OldLastZigZag, OldPreviousZigZag;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   IndicatorBuffers(2);
//---- drawing settings
   SetIndexStyle(0,DRAW_ARROW);
   SetIndexArrow(0, 171);
   SetIndexStyle(1,DRAW_ARROW);
   SetIndexArrow(1, 171);  
//---- indicator buffers mapping
   SetIndexBuffer(0,ExtMapBuffer);
   SetIndexBuffer(1,ExtMapBuffer2);
   SetIndexEmptyValue(0,0.0);
   
//---- indicator short name
   IndicatorShortName("ZigZag("+ExtDepth+","+ExtDeviation+","+ExtBackstep+")");
//---- initialization done
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   int    shift, back,lasthighpos,lastlowpos;
   double val,res;
   double curlow,curhigh,lasthigh,lastlow;

   for(shift=Bars-ExtDepth; shift>=0; shift--)
     {
      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;
        }
     }
  
   for(shift=Bars-1; shift>=0; shift--)
     {
      if(shift>=Bars-ExtDepth) ExtMapBuffer[shift]=0.0;
      else
        {
         res=ExtMapBuffer2[shift];
         if(res!=0.0) ExtMapBuffer2[shift]=res;
        }
  	int i=0;
  	int LastZigZag, PreviousZigZag;
   
   int h=0;
   while ( ExtMapBuffer[h]==0 && ExtMapBuffer2[h]==0) {
   	h++;
   }
   
   LastZigZag=h;
   
   h++;
   while(ExtMapBuffer[h]==0 && ExtMapBuffer2[h]==0) {
   	h++;
   }
   
   PreviousZigZag=h;
   
   if (OldLastZigZag!=LastZigZag || OldPreviousZigZag!=PreviousZigZag) {
   	if ((OldLastZigZag>LastZigZag)&& (OldPreviousZigZag>PreviousZigZag)) Alert("Possible change in direction... (M",Period()," ",Symbol(),")");
    	OldLastZigZag=LastZigZag;
   	OldPreviousZigZag=PreviousZigZag;
   	//ObjectDelete("Fibo");
   	//ObjectCreate("Fibo", OBJ_FIBO, 0, Time[PreviousZigZag], ExtMapBuffer[LastZigZag], Time[LastZigZag], ExtMapBuffer[PreviousZigZag]);
  }
   if (OldLastZigZag!=LastZigZag || OldPreviousZigZag!=PreviousZigZag) {
   	if((OldLastZigZag<LastZigZag)&& (OldPreviousZigZag<PreviousZigZag)) Alert("Possible change in direction... (M",Period()," ",Symbol(),")");
   	OldLastZigZag=LastZigZag;
   	OldPreviousZigZag=PreviousZigZag;
   	//ObjectDelete("Fibo");
   	//ObjectCreate("Fibo", OBJ_FIBO, 0, Time[PreviousZigZag], ExtMapBuffer[LastZigZag], Time[LastZigZag], ExtMapBuffer[PreviousZigZag]);
   }
     }
  }
  
  //end//

Comments