Author: Copyright � 2005, MetaQuotes Software Corp.
Z-Z1_email

This script functions as a specialized technical analysis tool designed to identify and map significant structural turning points in price movement. It essentially "cleans" the market noise to reveal the underlying path of price action by identifying major peaks and valleys.

Core Logic Overview

The primary objective of this logic is to track the extremes of price—specifically the highest highs and lowest lows over a defined period. Rather than showing every small fluctuation, it focuses on significant "swings." It does this by scanning historical data and establishing whether a current price point represents a meaningful change in direction compared to previous trends.

How the System Processes Data

The logic operates through three distinct phases:

1. Identifying Potential Turning Points The script first examines the price history to find local highs and lows. It uses specific depth and deviation settings to filter out minor "wiggles" in the market. If a price movement is too small or doesn't meet the required intensity, the script ignores it. If it does meet the criteria, the script marks these points as potential structural anchors.

2. Refining and Filtering the Path Once potential peaks and valleys are identified, the logic performs a "cleanup" phase. It ensures that the price path makes logical sense by comparing new points to previous ones. For example:

  • If a new high is detected that is higher than the previous one, it validates that peak.
  • If a new low is detected that is lower than the previous one, it updates the structure.
  • If a point contradicts the established trend (such as a smaller peak appearing where a larger one should be), the script "cuts" or removes the invalid data to maintain a clear, continuous zigzag path.

3. Signal Generation and Notifications After the structural path is cleaned and finalized, the script analyzes the relationship between the most recent two confirmed turning points. It calculates the direction of movement:

  • Upward Movement: If the price moves from a low point to a higher peak, it identifies an upward trend.
  • Downward Movement: If the price moves from a high point to a lower valley, it identifies a downward trend.

User Alerts

The final stage of the logic is the communication layer. When a new confirmed turning point is established, the script checks the direction of the move. Depending on your settings, it can trigger real-time alerts or send emails to notify you immediately of a "Buy" or "Sell" signal based on the direction of that latest structural shift.

Miscellaneous
Implements a curve of type %1It issuies visual alerts to the screenIt sends emails
8 Views
0 Downloads
0 Favorites
Z-Z1_email
//+------------------------------------------------------------------+
//|                                       Z1.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 1
#property indicator_color1 Blue
//---- indicator parameters
extern int ExtDepth=36;
extern int ExtDeviation=5;
extern int ExtBackstep=3;
extern int barn=1500;
extern int from=0;
extern bool  Alert_On    = true;
extern bool SendAnEmail=false;

//---- indicator buffers
double ExtMapBuffer[];
double ExtMapBuffer2[];

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

   for(shift=barn-ExtDepth; shift>from; 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=barn-ExtDepth; shift>from; 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=barn-1; shift>from; shift--){
      if(shift>=barn-ExtDepth) ExtMapBuffer[shift]=0.0;
      else{
         res=ExtMapBuffer2[shift];
         if(res!=0.0) ExtMapBuffer[shift]=res;
         }
      }
   int last_found[2],f = 0; 
   for(shift=from+1; f<2 && shift<barn; shift++){
      if(ExtMapBuffer[shift]!=0){
         last_found[f] = shift;
         f++;
         }
      }
   if(f>0){
      if(last_time != Time[last_found[0]]){
         last_time = Time[last_found[0]];
         double dir = ExtMapBuffer[last_found[0]]-ExtMapBuffer[last_found[1]];
      if(Alert_On)
      {
         if(dir>0){
            Alert("Found SELL signal Z-Z1["+Period()+"] at "+Symbol()+",bar = "+last_found[0]);
            if (SendAnEmail) SendMail("Found SELL signal Z-Z1["+Period()+"]", "Found SELL signal Z-Z1["+Period()+"] at "+Symbol()+",bar = "+last_found[0]);
            }
         else if(dir<0){
            Alert("Found BUY signal Z-Z1["+Period()+"] at "+Symbol()+",bar = "+last_found[0]);
            if (SendAnEmail) SendMail("Found BUY signal Z-Z1["+Period()+"]", "Found BUY signal Z-Z1["+Period()+"] at "+Symbol()+",bar = "+last_found[0]);
            }
         else if(f==1){
            Alert("Found signal Z-Z1["+Period()+"] at "+Symbol()+",bar = "+last_found[0]);
            if (SendAnEmail) SendMail("Found signal Z-Z1["+Period()+"]", "Found signal Z-Z1["+Period()+"] at "+Symbol()+",bar = "+last_found[0]);
            }
       } 
         }
      }
}

Comments