2MA CrossoverWithPrice_002
Download scriptThis script is designed for traders who use Moving Averages to identify trends and entry points. Its primary purpose is to automatically detect and highlight the exact moment two moving averages cross each other on a price chart.
Core Functionality
The tool monitors two independent moving averages simultaneously. When these two lines intersect, it signifies a potential shift in market momentum—moving from an upward trend to a downward one, or vice versa. To make this information easy to digest, the script places visual markers (arrows) on the chart at the point of crossover.
Key Features
- Customizable Moving Averages: Users can choose between several different types of moving averages (such as Simple, Exponential, Smoothed, or Linear Weighted). You can also define specific periods for both averages to suit different trading styles.
- Flexible Data Sources: The logic allows the script to calculate values based on various price points, including the Close, Open, High, Low, or even a weighted average of these figures (Median, Typical, or Weighted).
- Visual Indicators: Instead of just drawing lines, the script places distinct arrows on the chart. You can choose from several different arrow styles (such as thick, thin, hollow, or diagonal) to ensure they are clearly visible against your background.
- Dynamic Positioning: The arrows are automatically placed at a respectful distance above or below the price candles based on the current market volatility. This prevents the markers from overlapping with the price bars.
Notification System
To ensure traders don't have to watch the charts constantly, the script includes an integrated alert system:
- Pop-up Alerts: A visual and audible notification will trigger immediately when a crossover occurs.
- Email Notifications: If enabled, the script can send an email directly to your connected account providing the same information.
- Contextual Info: Every alert is prefixed with the current currency pair and timeframe (e.g., "EURUSD (H1)"), so you know exactly where the signal occurred at a glance.
Technical Logic Summary
The script constantly scans the most recent price data. It compares the position of Moving Average 1 against Moving Average 2 across three consecutive time points: the previous bar, the current bar, and the following bar. If it detects that the averages have swapped positions (e.g., one was below and is now above), it triggers the visual arrow and sends the corresponding alert.
//+------------------------------------------------------------------+
//| 2MA Crossover.mq4 modified from |
//| EMA-Crossover_Signal.mq4 |
//| Copyright © 2005-07, Jason Robinson (jnrtrading) |
//| http://www.jnrtading.co.uk |
//+------------------------------------------------------------------+
/*
+------------------------------------------------------------------+
| Allows you to enter two ema 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 emas |
| from the chart. (emas are initially set at 5 and 6) |
+------------------------------------------------------------------+
*/
#property copyright "Copyright © 2005-07, Jason Robinson (jnrtrading)"
#property link "http://www.jnrtrading.co.uk"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 DodgerBlue
#property indicator_width1 3
#property indicator_color2 Magenta
#property indicator_width2 3
extern string note1 = "First Moving Average";
extern int MA1 = 3;
extern string note2 = "0=sma, 1=ema, 2=smma, 3=lwma";
extern int MA1Mode = 1; //0=sma, 1=ema, 2=smma, 3=lwma
extern string note2b = " 0=close, 1=open, 2=high, 3=low,";
extern string note2c = " 4=median(high+low)/2,";
extern string note2d = " 5=typical(high+low+close)/3,";
extern string note2e = " 6=weighted(high+low+close+close)/4";
extern int MA1Price = 1;//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 string note3 = "--------------------------------------------";
extern string note4 = "Second Moving Average";
extern int MA2 = 7;
extern string note5 = "0=sma, 1=ema, 2=smma, 3=lwma";
extern int MA2Mode = 1; //0=sma, 1=ema, 2=smma, 3=lwma
extern string note5b = " 0=close, 1=open, 2=high, 3=low,";
extern string note5c = " 4=median(high+low)/2,";
extern string note5d = " 5=typical(high+low+close)/3,";
extern string note5e = " 6=weighted(high+low+close+close)/4";
extern int MA2Price = 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 string note6 = "--------------------------------------------";
extern string note7 = "Arrow Type";
extern string note8 = "0=Thick, 1=Thin, 2=Hollow, 3=Round";
extern string note9 = "4=Fractal, 5=Diagonal Thin";
extern string note10 = "6=Diagonal Thick, 7=Diagonal Hollow";
extern string note11 = "8=Thumb, 9=Finger";
extern int ArrowType=2;
extern string note12 = "--------------------------------------------";
extern string note13 = "turn on Alert = true; turn off = false";
extern bool AlertOn = true;
extern string note14 = "--------------------------------------------";
extern string note15 = "send Email Alert = true; turn off = false";
extern bool SendAnEmail=false;
double CrossUp[];
double CrossDown[];
string AlertPrefix, MA1short_name, MA2short_name;
string GetTimeFrameStr() {
switch(Period())
{
case 1 : string TimeFrameStr="M1"; break;
case 5 : TimeFrameStr="M5"; break;
case 15 : TimeFrameStr="M15"; break;
case 30 : TimeFrameStr="M30"; break;
case 60 : TimeFrameStr="H1"; break;
case 240 : TimeFrameStr="H4"; break;
case 1440 : TimeFrameStr="D1"; break;
case 10080 : TimeFrameStr="W1"; break;
case 43200 : TimeFrameStr="MN1"; break;
default : TimeFrameStr=Period();
}
return (TimeFrameStr);
}
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
if (ArrowType == 0) {
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0, 233);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1, 234);
}
else if (ArrowType == 1) {
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0, 225);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1, 226);
}
else if (ArrowType == 2) {
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0, 241);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1, 242);
}
else if (ArrowType == 3) {
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0, 221);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1, 222);
}
else if (ArrowType == 4) {
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0, 217);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1, 218);
}
else if (ArrowType == 5) {
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0, 228);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1, 230);
}
else if (ArrowType == 6) {
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0, 236);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1, 238);
}
else if (ArrowType == 7) {
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0, 246);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1, 248);
}
else if (ArrowType == 8) {
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0, 67);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1, 68);
}
else if (ArrowType == 9) {
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0, 71);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1, 72);
}
SetIndexBuffer(0, CrossUp);
SetIndexBuffer(1, CrossDown);
//---- indicator short name
switch(MA1Mode)
{
case 1 : MA1short_name="EMA"; break;
case 2 : MA1short_name="SMMA"; break;
case 3 : MA1short_name="LWMA"; break;
default :
MA1Mode=0;
MA1short_name="SMA";
}
switch(MA2Mode)
{
case 1 : MA2short_name="EMA"; break;
case 2 : MA2short_name="SMMA"; break;
case 3 : MA2short_name="LWMA"; break;
default :
MA2Mode=0;
MA2short_name="SMA";
}
AlertPrefix=Symbol()+" ("+GetTimeFrameStr()+"): ";
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
bool NewBar()
{
static datetime lastbar;
datetime curbar = Time[0];
if(lastbar!=curbar)
{
lastbar=curbar;
return (true);
}
else
{
return(false);
}
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start() {
int limit, i, counter;
double MA1now, MA2now, MA1previous, MA2previous, MA1after, MA2after;
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;
MA1now = iMA(NULL, 0, MA1, 0, MA1Mode, MA1Price, i);
MA1previous = iMA(NULL, 0, MA1, 0, MA1Mode, MA1Price, i+1);
MA1after = iMA(NULL, 0, MA1, 0, MA1Mode, MA1Price, i-1);
MA2now = iMA(NULL, 0, MA2, 0, MA2Mode, MA2Price, i);
MA2previous = iMA(NULL, 0, MA2, 0, MA2Mode, MA2Price, i+1);
MA2after = iMA(NULL, 0, MA2, 0, MA2Mode, MA2Price, i-1);
if ((MA1now > MA2now) && (MA1previous < MA2previous) && (MA1after > MA2after)) {
CrossUp[i] = Low[i] - Range*1.5;
if (AlertOn && NewBar()) {
Alert(AlertPrefix+MA1short_name+" ("+MA1+") "+"crosses UP " + MA2short_name+" ("+MA2+")");
}
if (SendAnEmail && NewBar()) {
SendMail(AlertPrefix,MA1short_name+" ("+MA1+") "+"crosses UP " + MA2short_name+" ("+MA2+")");
}
}
else if ((MA1now < MA2now) && (MA1previous > MA2previous) && (MA1after < MA2after)) {
CrossDown[i] = High[i] + Range*1.5;
if (AlertOn && NewBar()) {
Alert(AlertPrefix+MA1short_name+" ("+MA1+") "+"crosses DOWN " + MA2short_name+" ("+MA2+")");
}
if (SendAnEmail && NewBar()) {
SendMail(AlertPrefix,MA1short_name+" ("+MA1+") "+"crosses DOWN " + MA2short_name+" ("+MA2+")");
}
}
}
return(0);
}
Comments