MA_Crossover_Email_Alert
Download scriptThis MetaTrader script is designed to act as a visual and audible signaling tool for traders who use Moving Average (MA) crossovers to identify market trends. Instead of requiring you to manually watch two moving lines constantly, the script automatically detects when they intersect and provides immediate feedback via on-screen markers, sound alerts, or emails.
Core Logic and Functionality
1. Dual Moving Average Tracking The script monitors two distinct moving averages simultaneously: a "Fast" average and a "Slow" average. Users can customize these based on different calculation methods (such as Simple, Exponential, Linear Weighted, or Least Squares) and choose which price data point the average should be based on (e.g., Close price, High, Low, or a combination of these).
2. The Crossover Detection The primary logic revolves around identifying the exact moment the "Fast" line crosses over the "Slow" line.
- Bullish Signal (Buy): When the Fast average moves from below the Slow average to above it, the script identifies a potential upward trend.
- Bearish Signal (Sell): When the Fast average moves from above the Slow average to below it, the script identifies a potential downward trend.
3. Dynamic Visual Markers To make these signals easy to see even on crowded charts, the script places specific icons at the crossover points:
- A Green arrow appears below the candle for bullish crossovers.
- A Red arrow appears above the candle for bearish crossovers. The script intelligently calculates the distance of these arrows from the price candles using a "Range" calculation, ensuring they are clearly visible and do not overlap with the bars.
4. Automated Notifications The script includes an integrated alert system to ensure you don't miss a trade:
- Sound Alerts: Provides an instant audio notification when a new crossover occurs.
- Email Alerts: Can be configured to send a direct message to your registered email, including the specific price (Ask/Bid), date, time, and the currency pair being traded.
5. User Customization The logic is built to be flexible. You can toggle the alerts on or off, change the mathematical smoothing of the averages, and define exactly how many periods back each average should look. This allows the tool to be adapted for different trading styles, from scalping (fast movements) to long-term trend following (slow movements).
/*-----------------------------+
| |
| Shared by www.Aptrafx.com |
| |
+------------------------------*/
//+------------------------------------------------------------------+
//| MA-Crossover_Alert.mq4 |
//| Copyright © 2005, Jason Robinson (jnrtrading) |
//| http://www.jnrtading.co.uk |
//| Modified by Robert Hill to add LSMA and alert or send email |
//| Added Global LastAlert to try to have alert only on new cross |
//| but does not seem to work. So indicator does alert every bar |
//+------------------------------------------------------------------+
/*
+------------------------------------------------------------------+
| Allows you to enter two ma periods and it will then show you at |
| Which point they crossed over. It is more usful on the shorter |
| periods that get obscured by the bars / candlesticks and when |
| the zoom level is out. Also allows you then to remove the mas |
| from the chart. (emas are initially set at 5 and 6) |
+------------------------------------------------------------------+
*/
#property copyright "Copyright © 2005, Jason Robinson (jnrtrading)"
#property link "http://www.jnrtrading.co.uk"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 LawnGreen
#property indicator_width1 2
#property indicator_color2 Red
#property indicator_width2 2
extern bool SoundON=true;
extern bool EmailON=false;
extern int FastMA_Mode = 1; //0=sma, 1=ema, 2=smma, 3=lwma, 4=lsma
extern int FastMA_Period = 5;
extern int FastPriceMode = 0;//0=close, 1=open, 2=high, 3=low, 4=median(high+low)/2, 5=typical(high+low+close)/3, 6=weighted(high+low+close+close)/4
extern int SlowMA_Mode = 1; //0=sma, 1=ema, 2=smma, 3=lwma, 4=lsma
extern int SlowMA_Period = 6;
extern int SlowPriceMode = 0;//0=close, 1=open, 2=high, 3=low, 4=median(high+low)/2, 5=typical(high+low+close)/3, 6=weighted(high+low+close+close)/4
double CrossUp[];
double CrossDown[];
int flagval1 = 0;
int flagval2 = 0;
//int weights[]; // Array uses by TMA
//double divisor; // Used by TMA
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
// IndicatorBuffers(3);
SetIndexStyle(0, DRAW_ARROW, EMPTY);
SetIndexArrow(0, 233);
SetIndexBuffer(0, CrossUp);
SetIndexStyle(1, DRAW_ARROW, EMPTY);
SetIndexArrow(1, 234);
SetIndexBuffer(1, CrossDown);
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| LSMA with PriceMode |
//| PrMode 0=close, 1=open, 2=high, 3=low, 4=median(high+low)/2, |
//| 5=typical(high+low+close)/3, 6=weighted(high+low+close+close)/4 |
//+------------------------------------------------------------------+
double LSMA(int Rperiod, int prMode, int shift)
{
int i;
double sum, pr;
int length;
double lengthvar;
double tmp;
double wt;
length = Rperiod;
sum = 0;
for(i = length; i >= 1 ; i--)
{
lengthvar = length + 1;
lengthvar /= 3;
tmp = 0;
switch (prMode)
{
case 0: pr = Close[length-i+shift];break;
case 1: pr = Open[length-i+shift];break;
case 2: pr = High[length-i+shift];break;
case 3: pr = Low[length-i+shift];break;
case 4: pr = (High[length-i+shift] + Low[length-i+shift])/2;break;
case 5: pr = (High[length-i+shift] + Low[length-i+shift] + Close[length-i+shift])/3;break;
case 6: pr = (High[length-i+shift] + Low[length-i+shift] + Close[length-i+shift] + Close[length-i+shift])/4;break;
}
tmp = ( i - lengthvar)*pr;
sum+=tmp;
}
wt = sum*6/(length*(length+1));
return(wt);
}
/*//====================================================================
// TMA coded as function from indicator code to save time on backtest
//====================================================================
double TMA(int Periods,int AppliedPrice,int shift)
{
int i,j;
double dPeriods = Periods;
int to=MathCeil(dPeriods/2.0);
//Calculate weigths
ArrayResize(weights,Periods);
for(i=0; i<to; i++)
{
weights[i] = i+1;
weights[Periods-1-i] = i+1;
}
divisor = 0.0;
for(j=0; j<Periods; j++)
divisor += weights[j];
double tma_val = 0.0;
for(j=0; j<Periods; j++)
{
double price = getPrice(AppliedPrice, Periods-j);
tma_val += price*weights[j];
}
return( tma_val/divisor);
}
//===================
// Used by TMA
//===================
double getPrice(int priceType, int index)
{
double price = 0.0;
switch(priceType)
{
case PRICE_OPEN : price = Open[index];
break;
case PRICE_HIGH : price = High[index];
break;
case PRICE_LOW : price = Low[index];
break;
case PRICE_MEDIAN : price = (High[index]+Low[index])/2.0;
break;
case PRICE_TYPICAL : price = (High[index]+Low[index]+Close[index])/3.0;
break;
case PRICE_WEIGHTED: price = (High[index]+Low[index]+2*Close[index])/4.0;
break;
case PRICE_CLOSE :
default : price = Close[index];
break;
}
return(price);
}
*/
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start() {
int limit, i, counter;
double tmp=0;
double fastMAnow, slowMAnow, fastMAprevious, slowMAprevious;
double Range, AvgRange;
int counted_bars=IndicatorCounted();
//---- check for possible errors
if(counted_bars<0) return(-1);
//---- last counted bar will be recounted
if(counted_bars>0) counted_bars--;
limit=Bars-counted_bars;
for(i = 0; i <= limit; i++) {
counter=i;
Range=0;
AvgRange=0;
for (counter=i ;counter<=i+9;counter++)
{
AvgRange=AvgRange+MathAbs(High[counter]-Low[counter]);
}
Range=AvgRange/10;
switch(FastMA_Mode)
{
case 4 :
{
fastMAnow = LSMA(FastMA_Period, FastPriceMode, i);
fastMAprevious = LSMA(FastMA_Period, FastPriceMode, i+1);
break;
}
case 5 :
{
fastMAnow = iCustom(Symbol(),0,"TMA",FastMA_Period,0,i);
fastMAprevious = iCustom(Symbol(),0,"TMA",FastMA_Period,0,i+1);
// fastMAnow = TMA(FastMA_Period, FastPriceMode, i);
// fastMAprevious = TMA(FastMA_Period, FastPriceMode, i+1);
break;
}
default :
{
fastMAnow = iMA(NULL, 0, FastMA_Period, 0, FastMA_Mode, FastPriceMode, i);
fastMAprevious = iMA(NULL, 0, FastMA_Period, 0, FastMA_Mode, FastPriceMode, i+1);
}
}
switch(SlowMA_Mode)
{
case 4 :
{
slowMAnow = LSMA( SlowMA_Period, SlowPriceMode, i);
slowMAprevious = LSMA( SlowMA_Period, SlowPriceMode, i+1);
}
case 5 :
{
slowMAnow = iCustom(Symbol(),0,"TMA",SlowMA_Period,0,i);
slowMAprevious = iCustom(Symbol(),0,"TMA",SlowMA_Period,0,i+1);
// slowMAnow = TMA(SlowMA_Period, SlowPriceMode, i);
// slowMAprevious = TMA(SlowMA_Period, SlowPriceMode, i+1);
break;
}
default :
{
slowMAnow = iMA(NULL, 0, SlowMA_Period, 0, SlowMA_Mode, SlowPriceMode, i);
slowMAprevious = iMA(NULL, 0, SlowMA_Period, 0, SlowMA_Mode, SlowPriceMode, i+1);
}
}
if ((fastMAnow > slowMAnow) && (fastMAprevious < slowMAprevious))
{
if (i == 1 && flagval1==0)
{
flagval1=1;
flagval2=0;
if (SoundON) Alert("BUY signal at Ask=",Ask,"\n Bid=",Bid,"\n Time=",TimeToStr(CurTime(),TIME_DATE)," ",TimeHour(CurTime()),":",TimeMinute(CurTime()),"\n Symbol=",Symbol()," Period=",Period());
if (EmailON) SendMail("BUY signal alert","BUY signal at Ask="+DoubleToStr(Ask,4)+", Bid="+DoubleToStr(Bid,4)+", Date="+TimeToStr(CurTime(),TIME_DATE)+" "+TimeHour(CurTime())+":"+TimeMinute(CurTime())+" Symbol="+Symbol()+" Period="+Period());
}
CrossUp[i] = Low[i] - Range*0.75;
}
else if ((fastMAnow < slowMAnow) && (fastMAprevious > slowMAprevious))
{
if (i == 1 && flagval2==0)
{
flagval2=1;
flagval1=0;
if (SoundON) Alert("SELL signal at Ask=",Ask,"\n Bid=",Bid,"\n Date=",TimeToStr(CurTime(),TIME_DATE)," ",TimeHour(CurTime()),":",TimeMinute(CurTime()),"\n Symbol=",Symbol()," Period=",Period());
if (EmailON) SendMail("SELL signal alert","SELL signal at Ask="+DoubleToStr(Ask,4)+", Bid="+DoubleToStr(Bid,4)+", Date="+TimeToStr(CurTime(),TIME_DATE)+" "+TimeHour(CurTime())+":"+TimeMinute(CurTime())+" Symbol="+Symbol()+" Period="+Period());
}
CrossDown[i] = High[i] + Range*0.75;
}
}
return(0);
}
Comments