TrendEnvelopes_v2Alert
Download scriptThis tool is designed to help traders identify and visualize market trends by creating a dynamic "envelope" around price action. Instead of just looking at a single moving average, it calculates a boundary zone that helps distinguish between bullish and bearish momentum.
Core Logic and Functionality
Trend Identification The script works by calculating a moving average as its foundation. It then creates an upper and lower boundary (the "envelopes") based on a percentage deviation from that average. By monitoring where the price closes relative to these boundaries, the tool determines the current market direction:
- Bullish Trend: Triggered when the price closes above the upper boundary.
- Bearish Trend: Triggered when the price closes below the lower boundary.
Dynamic Envelope Behavior The envelopes are not static; they react to the movement of the market. During a bullish trend, the script tracks the lowest point of the lower boundary to ensure it creates a continuous visual path. Conversely, during a bearish trend, it tracks the highest point of the upper boundary. This ensures that the "floor" or "ceiling" of the trend remains visually consistent and smooth as it moves with the price.
Visual Signals and Alerts The tool provides clear visual feedback on the chart:
- Trend Lines: It draws distinct lines representing the current trend's boundaries.
- Entry Signals: If configured, the tool can place specific arrow markers on the chart at the exact moment the market shifts from a bullish to a bearish state (or vice versa). These signals are calculated using the Average True Range (ATR) to ensure they are positioned logically relative to price volatility.
Notifications To keep traders informed without needing to watch the screen constantly, the script includes an automated alert system. When a trend shift is detected, the tool can:
- Trigger a pop-up alert message on your terminal.
- Play a specific sound file (defaulting to a news chime).
- Repeat these alerts a customizable number of times with a set delay.
- Optionally send an email notification directly to your registered account, providing a summary of the signal for the specific currency pair or asset.
Summary for the User
Essentially, this script acts as an automated "trend scanner." It filters out market noise by focusing on price breakouts from established averages. When the market breaks through these calculated envelopes, the tool identifies the new trend direction, draws the boundaries accordingly, and notifies you immediately so you can react to the change in momentum.
//+------------------------------------------------------------------+
//| TrendEnvelopes_v1.mq4 |
//| Copyright © 2006, TrendLaboratory Ltd. |
//| http://finance.groups.yahoo.com/group/TrendLaboratory |
//| E-mail: igorad2003@yahoo.co.uk |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, TrendLaboratory Ltd."
#property link "http://finance.groups.yahoo.com/group/TrendLaboratory"
//---- indicator settings
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 LightBlue
#property indicator_color2 Orange
#property indicator_width1 2
#property indicator_width2 2
#property indicator_color3 LightBlue
#property indicator_color4 Orange
#property indicator_width3 2
#property indicator_width4 2
//---- indicator parameters
extern int MA_Period = 34;
int MA_Shift = 0;
int MA_Method = 3;
int Applied_Price = 0;
double Deviation =0.2;
int UseSignal = 0;
extern int PlayCount = 3;
extern string wavName = "news.wav";
extern int Pause = 10;
extern bool SendMessage=false;
//---- indicator buffers
double UpBuffer[];
double DnBuffer[];
double UpSignal[];
double DnSignal[];
double smax[];
double smin[];
double trend[];
bool UpTrendAlert=false, DownTrendAlert=false;
//----
int ExtCountedBars=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
int draw_begin;
string short_name;
//---- drawing settings
IndicatorBuffers(7);
SetIndexStyle(0,DRAW_LINE);
SetIndexShift(0,MA_Shift);
SetIndexStyle(1,DRAW_LINE);
SetIndexShift(1,MA_Shift);
SetIndexStyle(2,DRAW_ARROW);
SetIndexShift(2,MA_Shift);
SetIndexArrow(2,233);
SetIndexStyle(3,DRAW_ARROW);
SetIndexShift(3,MA_Shift);
SetIndexArrow(3,234);
IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
if(MA_Period<14) MA_Period=14;
draw_begin=MA_Period-1;
//---- indicator short name
IndicatorShortName("Env("+MA_Period+")");
SetIndexLabel(0,"UpTrendEnv");
SetIndexLabel(1,"DnTrendEnv");
SetIndexLabel(2,"UpSignal");
SetIndexLabel(3,"DnSignal");
SetIndexDrawBegin(0,draw_begin);
SetIndexDrawBegin(1,draw_begin);
SetIndexDrawBegin(2,draw_begin);
SetIndexDrawBegin(3,draw_begin);
//---- indicator buffers mapping
SetIndexBuffer(0,UpBuffer);
SetIndexBuffer(1,DnBuffer);
SetIndexBuffer(2,UpSignal);
SetIndexBuffer(3,DnSignal);
SetIndexBuffer(4,smax);
SetIndexBuffer(5,smin);
SetIndexBuffer(6,trend);
if(Deviation<0.1) Deviation=0.1;
if(Deviation>100.0) Deviation=100.0;
//---- initialization done
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int limit;
if(Bars<=MA_Period) return(0);
ExtCountedBars=IndicatorCounted();
//---- check for possible errors
if (ExtCountedBars<0) return(-1);
//---- last counted bar will be recounted
if (ExtCountedBars>0) ExtCountedBars--;
limit=Bars-ExtCountedBars;
//---- EnvelopesM counted in the buffers
for(int i=limit; i>=0; i--)
{
smax[i] = (1+Deviation/100)*iMA(NULL,0,MA_Period,0,MA_Method,Applied_Price,i);
smin[i] = (1-Deviation/100)*iMA(NULL,0,MA_Period,0,MA_Method,Applied_Price,i);
trend[i]=trend[i+1];
if (Close[i]>smax[i+1]) trend[i]=1;
if (Close[i]<smin[i+1]) trend[i]=-1;
if(trend[i]>0)
{
if (smin[i]<smin[i+1]) smin[i]=smin[i+1];
UpBuffer[i]=smin[i];
if (UseSignal>0)
if (trend[i+1]<0) UpSignal[i] = Low[i]-0.5*iATR(NULL,0,MA_Period,i);
DnBuffer[i]=EMPTY_VALUE;
if (trend[1]!=trend[2] && !UpTrendAlert)
{
ps(1);
UpTrendAlert=true; DownTrendAlert=false;
}
}
else
{
if(smax[i]>smax[i+1]) smax[i]=smax[i+1];
DnBuffer[i]=smax[i];
if (UseSignal>0)
if (trend[i+1]>0) DnSignal[i] = High[i]+0.5*iATR(NULL,0,MA_Period,i);
UpBuffer[i]=EMPTY_VALUE;
if (trend[1]!=trend[2] && !DownTrendAlert)
{
ps(-1);
UpTrendAlert=false; DownTrendAlert=true;
}
}
}
//---- done
return(0);
}
int ps(int trnd)
{
string Message=" "+Symbol()+": No Signal";
if (trnd<0) Message = " "+Symbol()+": Signal for SELL";
if (trnd>0) Message = " "+Symbol()+": Signal for BUY";
Alert(Message);
for (int i=0;i<=PlayCount;i++)
{
Sleep(Pause*1000);
PlaySound(wavName);
}
if (SendMessage)
{
SendMail ("Signal from Indicator",TimeToStr(CurTime())+Message);
}
}
//+------------------------------------------------------------------+
Comments