Final Draft ArrZZx2_alerts

Download script
Author:
Final Draft ArrZZx2_alerts

This script is designed as a sophisticated technical analysis tool for trading platforms. Its primary purpose is to identify market trends, pinpoint specific price fluctuations, and provide visual signals (arrows) to help traders determine potential entry or exit points based on price momentum and structural shifts.

The logic functions through a multi-layered processing system that cleans the "noise" of the market before generating final signals:

1. Data Smoothing and Base Calculations

The script begins by analyzing raw price data (such as Open, Close, High, or Low prices). Instead of looking at every tiny fluctuation, it applies a weighted smoothing process. This creates a stable foundation that represents the general "flow" of the market. By using different weightings, the tool can prioritize certain types of price information to create a smoother, more reliable baseline for the subsequent steps.

2. Signal Filtering (The Moving Average Layer)

Once the base price is established, the script applies an additional layer of calculation to identify peaks and valleys. It looks for significant high and low points within specific windows of time. This step helps the tool distinguish between minor market "wiggles" and actual structural changes in direction. It essentially filters out the distractions of everyday volatility to find where the market is genuinely turning.

3. Structural Trend Identification

The script then performs a deeper analysis of these peaks and valleys to identify the overarching trend. It categorizes price action into structural movements:

  • Long-term Trends: Identifying major shifts in market direction.
  • Short-term Dynamics: Monitoring smaller fluctuations that occur within the larger trend.

By comparing current price points against previous historical peaks and troughs, the script determines if the market is currently in an uptrend, a downtrend, or a transitional phase.

4. Signal Generation and Alerting

The final logic layer translates all these calculations into actionable visual cues on the chart:

  • Directional Arrows: When the script detects a confirmed structural shift, it places "Up" or "Down" arrows to notify the user of a trend change.
  • Refined Markers: It creates specific markers to highlight potential price limits or areas where momentum is shifting significantly.
  • Automated Notifications: The script includes an integrated alert system. When the logic confirms a trend change, it can trigger a visual pop-up on the screen, play an audio sound, or (optionally) send an email notification to ensure the trader sees the signal immediately.

Summary of User Experience

For the end user, this means you don't have to manually interpret dozens of different price movements. The script performs the heavy lifting by smoothing out the market noise, identifying the significant structural "turning points," and then placing clear arrows on your chart to tell you when the trend has officially shifted.

Indicators Used
Moving average indicator
Miscellaneous
Implements a curve of type %1It issuies visual alerts to the screenIt sends emailsIt plays sound alerts
9 Views
0 Downloads
0 Favorites
Final Draft ArrZZx2_alerts
//+------------+-----------------------------------------------------+
//| v.22.04.07 |                                         ArrZZx2.mq4 |
//+------------+                                                     |
//|------------|              Bookkeeper, 2007, yuzefovich@gmail.com |
//+------------+-----------------------------------------------------+
#property copyright ""
#property link      "http://www.forexter.land.ru/indicators.htm"
//----
#property indicator_chart_window
#property indicator_buffers 8
#property indicator_color1  White
#property indicator_width1 1
#property indicator_color2  Lime
#property indicator_color3  Blue
#property indicator_color4  Blue
#property indicator_color5  Aqua
#property indicator_width5 1
#property indicator_color6  Violet
#property indicator_width6 1
#property indicator_color7  Aqua
#property indicator_width7 1
#property indicator_color8  Violet
#property indicator_width8 1
//--------------------------------------------------------------------
extern int    SR              = 3;  // =3..4
extern int    SRZZ            = 5; // =4..12..20..12
extern int    MainRZZ         = 12;//20; // =12..20..54..20
extern int    FP              = 21;
extern int    SMF             = 3;  // =1..5
extern bool   DrawZZ          = false;
extern string exaprice        = "Price modes";
extern string exprice         = "0=close,1=open,2=high,3=low";
extern string exprice2        = "4=(h+l)/2,5=(h+l+c)/3,6=(H+L+2*C)/4";        
extern int    PriceConst      = 0; 
extern bool   alertsOn        = true;
extern bool   alertsOnCurrent = true;
extern bool   alertsMessage   = true;
extern bool   alertsSound     = true;
extern bool   alertsEmail     = false;
//extern string Prefix="ArrZZx2"; 
//--------------------------------------------------------------------
double        Lmt[];
double        LZZ[];
double        SA[];
double        SM[];
double        Up[];
double        Dn[];
double        pUp[];
double        pDn[];
//---------------------------------------------------------------------
int LTF[6]={0,0,0,0,0,0},STF[5]={0,0,0,0,0}; 
int MaxBar, nSBZZ, nLBZZ, SBZZ, LBZZ;
bool First=true;
int prevBars=0;
//---------------------------------------------------------------------
void MainCalculation(int Pos) {
if((Bars-Pos)>(SR+1)) SACalc(Pos); else SA[Pos]=0; 
if((Bars-Pos)>(FP+SR+2)) SMCalc(Pos); else SM[Pos]=0; return; }
//---------------------------------------------------------------------
void SACalc(int Pos) { int sw, i, w, ww, Shift; double sum; 
switch(PriceConst) {
case  0: 
  SA[Pos]=iMA(NULL,0,SR+1,0,MODE_LWMA,PRICE_CLOSE,Pos);
  break;
case  1: 
  SA[Pos]=iMA(NULL,0,SR+1,0,MODE_LWMA,PRICE_OPEN,Pos);
  break;
/*case  2: 
  SA[Pos]=iMA(NULL,0,SR+1,0,MODE_LWMA,PRICE_HIGH,Pos);
  break;
case  3: 
  SA[Pos]=iMA(NULL,0,SR+1,0,MODE_LWMA,PRICE_LOW,Pos);
  break;*/
case  4: 
  SA[Pos]=iMA(NULL,0,SR+1,0,MODE_LWMA,PRICE_MEDIAN,Pos);
  break;
case  5: 
  SA[Pos]=iMA(NULL,0,SR+1,0,MODE_LWMA,PRICE_TYPICAL,Pos);
  break;
case  6: 
  SA[Pos]=iMA(NULL,0,SR+1,0,MODE_LWMA,PRICE_WEIGHTED,Pos);
  break;
default: 
  SA[Pos]=iMA(NULL,0,SR+1,0,MODE_LWMA,PRICE_OPEN,Pos);
  break; }
for(Shift=Pos+SR+2;Shift>Pos;Shift--) { sum=0.0; sw=0; i=0; w=Shift+SR;
ww=Shift-SR; if(ww<Pos) ww=Pos;
while(w>=Shift) {i++; sum=sum+i*SnakePrice(w); sw=sw+i; w--; }
while(w>=ww) { i--; sum=sum+i*SnakePrice(w); sw=sw+i; w--; }
SA[Shift]=sum/sw; } return; }
//----
double SnakePrice(int Shift) {
switch(PriceConst) {
   case  0: return(Close[Shift]);
   case  1: return(Open[Shift]);
   /*case  2: return(High[Shift]);
   case  3: return(Low[Shift]);*/
   case  4: return((High[Shift]+Low[Shift])/2);
   case  5: return((Close[Shift]+High[Shift]+Low[Shift])/3);
   case  6: return((2*Close[Shift]+High[Shift]+Low[Shift])/4);
   default: return(Open[Shift]); } }
//---------------------------------------------------------------------
void SMCalc(int i) { double t, b;
for(int Shift=i+SR+2;Shift>=i;Shift--) {
t=SA[ArrayMaximum(SA,FP,Shift)]; b=SA[ArrayMinimum(SA,FP,Shift)];
SM[Shift]=(2*(2+SMF)*SA[Shift]-(t+b))/2/(1+SMF); } return; }
//---------------------------------------------------------------------
void LZZCalc(int Pos) { 
int i,RBar,LBar,ZZ,NZZ,NZig,NZag; 
i=Pos-1; NZig=0; NZag=0;
while(i<MaxBar && ZZ==0) { i++; LZZ[i]=0; RBar=i-MainRZZ; 
if(RBar<Pos) RBar=Pos; LBar=i+MainRZZ;
if(i==ArrayMinimum(SM,LBar-RBar+1,RBar)) { ZZ=-1; NZig=i; }
if(i==ArrayMaximum(SM,LBar-RBar+1,RBar)) { ZZ=1;NZag=i; } }
if(ZZ==0) return; NZZ=0;
if(i>Pos) { if(SM[i]>SM[Pos]) { if(ZZ==1) {
if(i>=Pos+MainRZZ && NZZ<5) { NZZ++; LTF[NZZ]=i; } NZag=i; 
LZZ[i]=SM[i]; } }
else { if(ZZ==-1) { if(i>=Pos+MainRZZ && NZZ<5) { NZZ++; LTF[NZZ]=i; }
NZig=i; LZZ[i]=SM[i]; } } }
while(i<LBZZ || NZZ<5) {  LZZ[i]=0; RBar=i-MainRZZ; 
if(RBar<Pos) RBar=Pos; LBar=i+MainRZZ;
if(i==ArrayMinimum(SM,LBar-RBar+1,RBar)) {
if(ZZ==-1 && SM[i]<SM[NZig]) { 
if(i>=Pos+MainRZZ && NZZ<5) LTF[NZZ]=i; LZZ[NZig]=0; LZZ[i]=SM[i]; 
NZig=i; }
if(ZZ==1) { if(i>=Pos+MainRZZ && NZZ<5) { NZZ++; LTF[NZZ]=i; } 
LZZ[i]=SM[i]; ZZ=-1; NZig=i; } }
if(i==ArrayMaximum(SM,LBar-RBar+1,RBar)) {
if(ZZ==1 && SM[i]>SM[NZag]) { 
if(i>=Pos+MainRZZ && NZZ<5) LTF[NZZ]=i; LZZ[NZag]=0; LZZ[i]=SM[i]; 
NZag=i; }
if(ZZ==-1) { if(i>=Pos+MainRZZ && NZZ<5) { NZZ++; LTF[NZZ]=i; } 
LZZ[i]=SM[i]; ZZ=1; NZag=i; } } i++; if(i>MaxBar) return; } 
nLBZZ=Bars-LTF[5]; LZZ[Pos]=SM[Pos]; return; }
//----
void SZZCalc(int Pos) { 
int i,RBar,LBar,ZZ,NZZ,NZig,NZag; 
i=Pos-1; NZig=0; NZag=0;
while(i<=LBZZ && ZZ==0) { i++; pDn[i]=0; pUp[i]=0; Dn[i]=0; Up[i]=0; 
Lmt[i]=0; RBar=i-SRZZ; if(RBar<Pos) RBar=Pos; LBar=i+SRZZ;
if(i==ArrayMinimum(SM,LBar-RBar+1,RBar)) { ZZ=-1; NZig=i; }
if(i==ArrayMaximum(SM,LBar-RBar+1,RBar)) { ZZ=1; NZag=i; } }
if(ZZ==0) return; NZZ=0;
if(i>Pos) { if(SM[i]>SM[Pos]) { if(ZZ==1) {
if(i>=Pos+SRZZ && NZZ<4) { NZZ++; STF[NZZ]=i; } NZag=i; 
Dn[i-1]=Open[i-1]; } }
else { if(ZZ==-1) { if(i>=Pos+SRZZ && NZZ<4) { NZZ++; STF[NZZ]=i; }
NZig=i; Up[i-1]=Open[i-1]; } } }
while(i<=LBZZ || NZZ<4) { pDn[i]=0; pUp[i]=0; Dn[i]=0; Up[i]=0; 
Lmt[i]=0; RBar=i-SRZZ; if(RBar<Pos) RBar=Pos; LBar=i+SRZZ;
if(i==ArrayMinimum(SM,LBar-RBar+1,RBar)) {
if(ZZ==-1 && SM[i]<SM[NZig]) { 
if(i>=Pos+SRZZ && NZZ<4) STF[NZZ]=i; Up[NZig-1]=0; Up[i-1]=Open[i-1]; 
NZig=i; } if(ZZ==1) { if(i>=Pos+SRZZ && NZZ<4) { NZZ++; STF[NZZ]=i; } 
Up[i-1]=Open[i-1]; ZZ=-1; NZig=i;  } }
if(i==ArrayMaximum(SM,LBar-RBar+1,RBar)) {
if(ZZ==1 && SM[i]>SM[NZag]) { 
if(i>=Pos+SRZZ && NZZ<4) STF[NZZ]=i; Dn[NZag-1]=0; Dn[i-1]=Open[i-1]; 
NZag=i; } if(ZZ==-1) { if(i>=Pos+SRZZ && NZZ<4) { NZZ++; STF[NZZ]=i; } 
Dn[i-1]=Open[i-1]; ZZ=1; NZag=i; } } i++; if(i>LBZZ) return; } 
nSBZZ=Bars-STF[4]; return; }
//---------------------------------------------------------------------
void ArrCalc() { int i,j,k,n,z=0; double p, b;
i=LBZZ; while(LZZ[i]==0) i--; j=i; p=LZZ[i]; i--; while(LZZ[i]==0) i--; 
if(LZZ[i]>p) z=1; if(LZZ[i]>0 && LZZ[i]<p) z=-1; p=LZZ[j]; i=j-1;  
while(i>0) { if(LZZ[i]>p) { z=-1; p=LZZ[i]; }
if(LZZ[i]>0 && LZZ[i]<p) { z=1;  p=LZZ[i]; }
if(z>0 && Dn[i]>0) { Lmt[i]=Open[i]; Dn[i]=0; }
if(z<0 && Up[i]>0) { Lmt[i]=Open[i]; Up[i]=0; }
if(z>0 && Up[i]>0) { if(i>1) { j=i-1; k=j-SRZZ+1; if(k<0) k=0; 
n=j; while(n>=k && Dn[n]==0) { pUp[n]=Up[i]; pDn[n]=0; n--; } } 
if(i==1) pUp[0]=Up[i]; } 
if(z<0 && Dn[i]>0) { if(i>1) { j=i-1; k=j-SRZZ+1; if(k<0) k=0; 
n=j; while(n>=k && Up[n]==0) { pDn[n]=Dn[i]; pUp[n]=0; n--; } } 
if(i==1) pDn[0]=Dn[i]; } 
i--; } return; }


int init()
{ 
IndicatorBuffers(8);
SetIndexBuffer(0,Lmt);
SetIndexStyle(0,DRAW_ARROW,EMPTY,2); 
SetIndexArrow(0,110);
SetIndexEmptyValue(0,0.0);
SetIndexBuffer(1,LZZ);

if(DrawZZ)
{
SetIndexStyle(1,DRAW_SECTION,EMPTY,4);
SetIndexEmptyValue(1,0.0); }
else SetIndexStyle(1,DRAW_NONE);

SetIndexBuffer(2,SA);
SetIndexStyle(2,DRAW_NONE);
SetIndexBuffer(3,SM);
SetIndexStyle(3,DRAW_NONE);
SetIndexBuffer(4,Up);
SetIndexStyle(4,DRAW_ARROW,EMPTY,1);//Green up arrow
SetIndexArrow(4,110);
SetIndexEmptyValue(4,0.0);
SetIndexLabel(4,"trend UP");
SetIndexBuffer(5,Dn);
SetIndexStyle(5,DRAW_ARROW,EMPTY,1);//Red down arrow
SetIndexArrow(5,110);
SetIndexEmptyValue(5,0.0);
SetIndexLabel(5,"trend DOWN");
SetIndexBuffer(6,pUp);
SetIndexStyle(6,DRAW_ARROW,EMPTY,1);//Green up markers
SetIndexArrow(6,110);
SetIndexEmptyValue(6,0.0);
SetIndexBuffer(7,pDn);
SetIndexStyle(7,DRAW_ARROW,EMPTY,1);//Red down markers
SetIndexArrow(7,110);
SetIndexEmptyValue(7,0.0);
return(0);
}

//---------------------------------------------------------------------
void deinit()
{ 
return; 
}
//---------------------------------------------------------------------

int start() { 

int counted_bars=IndicatorCounted(); 
int limit,i,j,n;
if(counted_bars<0) return(-1); 
if(counted_bars>0) counted_bars--;

if(First==true) { 
if(SR<2) SR=2;
if(Bars<=2*(MainRZZ+FP+SR+2))
return(-1); 

if(SRZZ<=SR) SRZZ=SR+1; MaxBar=Bars-(MainRZZ+FP+SR+2);
LBZZ=MaxBar; SBZZ=LBZZ; prevBars=Bars; First=false; }

limit=Bars-counted_bars;for(i=limit;i>=0;i--) { MainCalculation(i); }

if(prevBars!=Bars) { SBZZ=Bars-nSBZZ; 
LBZZ=Bars-nLBZZ; prevBars=Bars; } 
SZZCalc(0); LZZCalc(0); ArrCalc(); 
//---------------------------------------------------------------------

   if (alertsOn)
   {
      if (alertsOnCurrent)
         int whichBar = 0;
      else   whichBar = 1;
      if (Up[whichBar] > 0) doAlert(" trend changeed to UP");
      if (Dn[whichBar] > 0) doAlert(" trend changeed ro DOWN");
   }   
   return(0);
}

//+------------------------------------------------------------------+
//
//
//
//
//

void doAlert(string doWhat)
{
   static string   previousAlert="nothing";
   static datetime previousTime;
   string message;
   
      if (previousAlert != doWhat || previousTime != Time[0]) {
          previousAlert  = doWhat;
          previousTime   = Time[0];

          //
          //
          //
          //
          //

          message =  StringConcatenate(Symbol()," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," ArrZZx2 ",doWhat);
             if (alertsMessage) Alert(message);
             if (alertsEmail)   SendMail(StringConcatenate(Symbol()," ArrZZx2"),message);
             if (alertsSound)   PlaySound("alert2.wav");
      }
}


Comments