MA_Crossover_Alert3-34_v1

Download script
Author: Copyright � 2005, Jason Robinson (jnrtrading)
MA_Crossover_Alert3-34_v1

This script is designed for the MetaTrader trading platform to help traders identify specific momentum shifts by monitoring the relationship between two different moving averages. It automates the detection of "crossovers," which occur when a faster-moving average intersects a slower-moving one, signaling a potential change in market direction.

Core Logic and Functionality

1. Moving Average Customization The tool allows users to define two distinct moving averages: a "Fast" average (which reacts quickly to price changes) and a "Slow" average (which follows the long-term trend). It provides significant flexibility by allowing you to choose:

  • Calculation Methods: You can select from various standard mathematical models, including Simple, Exponential, Smoothed, Linear Weighted, and Least Squares Moving Averages.
  • Price Sources: Rather than just looking at closing prices, the tool can calculate averages based on the high, low, open, or weighted averages of a candle's price range.

2. Crossover Detection The script constantly scans the history of the chart to find moments where the Fast Moving Average crosses over the Slow Moving Average.

  • Bullish Signal (Cross Up): When the Fast average moves from below to above the Slow average, the script identifies a potential upward trend and places a visual marker on the chart.
  • Bearish Signal (Cross Down): When the Fast average moves from above to below the Slow average, the script identifies a potential downward trend and places a corresponding visual marker.

3. Visual Indicators To make these crossovers easy to see—especially when zoomed out or obscured by heavy price action—the script plots specific symbols (arrows) directly on your chart. These markers are positioned dynamically based on the current price range, ensuring they remain visible regardless of the asset's volatility.

4. Real-Time Notifications Beyond just visual markings, the script acts as an active monitoring system. It is programmed to trigger alerts based on these crossovers:

  • Audio Alerts: It can produce a sound notification immediately when a crossover occurs.
  • Email Notifications: If enabled, it can send a detailed email containing the specific price (Ask/Bid), the time of the occurrence, and the specific currency pair or asset being traded.

5. Smart Filtering The logic includes internal "flags" and global variables to help manage how alerts are delivered. It attempts to ensure that signals are processed correctly for the current timeframe and symbol, providing a structured way to monitor multiple charts simultaneously without constant manual oversight.

Price Data Components
Series array that contains open time of each bar
Indicators Used
Moving average indicator
Miscellaneous
Implements a curve of type %1It issuies visual alerts to the screenIt sends emails
12 Views
0 Downloads
0 Favorites
MA_Crossover_Alert3-34_v1
/*-----------------------------+
|			       |
| 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_color2 Red

extern bool SoundON=true;
extern bool EmailON=false;

extern int FastMA_Mode = 3; //0=sma, 1=ema, 2=smma, 3=lwma, 4=lsma
extern int FastMA_Period =   3;
extern int FastPriceMode = 6;//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 = 3; //0=sma, 1=ema, 2=smma, 3=lwma, 4=lsma
extern int SlowMA_Period =   34;
extern int SlowPriceMode = 6;//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;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0, DRAW_ARROW, EMPTY, 3);
   SetIndexArrow(0, 233);
   SetIndexBuffer(0, CrossUp);
   SetIndexStyle(1, DRAW_ARROW, EMPTY, 3);
   SetIndexArrow(1, 234);
   SetIndexBuffer(1, CrossDown);
   GlobalVariableSet("AlertTime"+Symbol()+Period(),CurTime());
   GlobalVariableSet("SignalType"+Symbol()+Period(),OP_SELLSTOP);
//   GlobalVariableSet("LastAlert"+Symbol()+Period(),0);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- 
   GlobalVariableDel("AlertTime"+Symbol()+Period());
   GlobalVariableDel("SignalType"+Symbol()+Period());
//   GlobalVariableDel("LastAlert"+Symbol()+Period());

//----
   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);
}


//+------------------------------------------------------------------+
//| 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;
       
      if (FastMA_Mode == 4)
      {
         fastMAnow = LSMA(FastMA_Period, FastPriceMode, i);
         fastMAprevious = LSMA(FastMA_Period, FastPriceMode,  i+1);
         
      }
      else
      {
         fastMAnow = iMA(NULL, 0, FastMA_Period, 0, FastMA_Mode, FastPriceMode, i);
         fastMAprevious = iMA(NULL, 0, FastMA_Period, 0, FastMA_Mode, FastPriceMode, i+1);
      }

      if (SlowMA_Mode == 4)
      {
         slowMAnow = LSMA( SlowMA_Period, SlowPriceMode, i);
         slowMAprevious = LSMA( SlowMA_Period, SlowPriceMode, i+1);
      }
      else
      {
         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; }
         CrossUp[i] = Low[i] - Range*0.75;
      }
      else if ((fastMAnow < slowMAnow) && (fastMAprevious > slowMAprevious))
      {
         if (i == 1 && flagval2==0) { flagval2=1; flagval1=0; }
         CrossDown[i] = High[i] + Range*0.75;
      }
   }
   
   if (flagval1==1 && CurTime() > GlobalVariableGet("AlertTime"+Symbol()+Period()) && GlobalVariableGet("SignalType"+Symbol()+Period())!=OP_BUY)
   {
//      if (GlobalVariableGet("LastAlert"+Symbol()+Period()) < 0.5)
//      {
      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());
//      }
      tmp = CurTime() + (Period()-MathMod(Minute(),Period()))*60;
      GlobalVariableSet("AlertTime"+Symbol()+Period(),tmp);
      GlobalVariableSet("SignalType"+Symbol()+Period(),OP_SELL);
//      GlobalVariableSet("LastAlert"+Symbol()+Period(),1);
   }
   
   if (flagval2==1 && CurTime() > GlobalVariableGet("AlertTime"+Symbol()+Period()) && GlobalVariableGet("SignalType"+Symbol()+Period())!=OP_SELL) {
//      if (GlobalVariableGet("LastAlert"+Symbol()+Period()) > -0.5)
//      {
      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());
//      }
      tmp = CurTime() + (Period()-MathMod(Minute(),Period()))*60;
      GlobalVariableSet("AlertTime"+Symbol()+Period(),tmp);
      GlobalVariableSet("SignalType"+Symbol()+Period(),OP_BUY);
//      GlobalVariableSet("LastAlert"+Symbol()+Period(),-1);
   }

   return(0);
}

Comments