MAxMAhilo_cross
Download scriptThis script is designed for MetaTrader 4 to help traders identify specific momentum shifts by monitoring the interaction between two different Moving Averages (MAs). Instead of just showing standard lines, it focuses on "crossover" events—the exact moments when one average moves from below another to above it (or vice versa).
Core Functionality
The tool tracks two distinct moving averages simultaneously. You can customize these based on your preferred calculation types (such as Simple, Exponential, Smoothed, or Linear Weighted) and the specific price points they follow (like Highs, Lows, or Close prices).
How it Works
-
Crossover Detection: The script constantly scans the chart to see if the first moving average has crossed over the "High" or "Low" boundaries of the second moving average.
- Bullish Signal (Cross Up): When the first moving average moves from below to above the second average's high point, the script identifies an upward momentum shift.
- Bearish Signal (Cross Down): When the first moving average moves from above to below the second average's low point, it identifies a downward momentum shift.
-
Visual Signals: Rather than requiring you to squint at lines on a busy chart, the script places clear visual markers (arrows) at the exact moment these crossovers occur. You can choose between several different arrow styles to match your visual preference.
-
Dynamic Positioning: To ensure the arrows are always visible and not overlapping with the price bars, the script calculates a "range" based on recent market volatility. It automatically places the arrows a specific distance away from the candles, ensuring they remain easy to read even during high-activity periods.
-
Notifications: The logic includes an automated alert system. If a crossover is detected, the script can be configured to:
- Trigger an instant audio/pop-up alert on your trading platform.
- Send an email notification directly to your registered email address.
- Both alerts are intelligently programmed to trigger only once per new bar, preventing the system from sending multiple alerts for the same price movement.
Summary of Benefits
- Clarity: It isolates the "signal" (the crossover) from the "noise" (the constant moving lines).
- Customization: Allows you to toggle the visibility of the moving average lines themselves, letting you use the script as a hidden "alert only" tool or a visible visual aid.
- Versatility: Because it allows for different types of Moving Averages and different price inputs (Highs vs. Lows), it can be adapted to various trading styles and timeframes.
//+------------------------------------------------------------------+
//| 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) |
+------------------------------------------------------------------+
*/
//mod ma x mahilo
#property copyright "Copyright © 2005-07, Jason Robinson (jnrtrading)"
#property link "http://www.jnrtrading.co.uk"
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_color1 Yellow
#property indicator_width1 1
#property indicator_color2 Aqua
#property indicator_width2 1
#property indicator_color3 Blue
#property indicator_color4 Maroon
#property indicator_color5 Maroon
//extern string note1 = "First Moving Average";
extern int MA1 = 5;
//extern string note2 = "0=sma, 1=ema, 2=smma, 3=lwma";
extern int MA1Mode = 1; //0=sma, 1=ema, 2=smma, 3=lwma
extern int MA1price = 0; //0=sma, 1=ema, 2=smma, 3=lwma
//extern string note3 = "--------------------------------------------";
extern int MA2 = 34;
extern int MA2Mode = 1; //0=sma, 1=ema, 2=smma, 3=lwma
extern bool drawMAs = true;
extern double arrDistance = 0.7;
extern int ArrowType=0;
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 string note12 = "--------------------------------------------";
//extern string note13 = "turn on Alert = true; turn off = false";
extern bool AlertOn = false;
//extern string note14 = "--------------------------------------------";
//xtern string note15 = "send Email Alert = true; turn off = false";
extern bool SendAnEmail=false;
extern string note5 = "0=sma, 1=ema, 2=smma, 3=lwma";
extern string note_price = "0C 1O 2H 3L 4Md 5Tp 6WghC: Md(HL/2)4,Tp(HLC/3)5,Wgh(HLCC/4)6";
extern string note4 = "Second MAprice:hilo";
//extern string note6 = "--------------------------------------------";
double CrossUp[];
double CrossDown[];
double MA1_buffer[];
double MA2hi_buffer[];
double MA2lo_buffer[];
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);
}
SetIndexEmptyValue(0, EMPTY_VALUE);
SetIndexEmptyValue(1, EMPTY_VALUE);
SetIndexBuffer(0, CrossUp);
SetIndexBuffer(1, CrossDown);
if (drawMAs)
{
SetIndexBuffer(2, MA1_buffer);
SetIndexBuffer(3, MA2hi_buffer);
SetIndexBuffer(4, MA2lo_buffer);
}
//---- 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*arrDistance;
double MA1_0 = iMA(NULL, 0, MA1, 0, MA1Mode, MA1price, i);
double MA1_1 = iMA(NULL, 0, MA1, 0, MA1Mode, MA1price, i+1);
// MA1after = iMA(NULL, 0, MA1, 0, MA1Mode, PRICE_CLOSE, i-1);
double MA2hi_0 = iMA(NULL, 0, MA2, 0, MA2Mode, PRICE_HIGH, i);
double MA2hi_1 = iMA(NULL, 0, MA2, 0, MA2Mode, PRICE_HIGH, i+1);
double MA2lo_0 = iMA(NULL, 0, MA2, 0, MA2Mode, PRICE_LOW, i);
double MA2lo_1 = iMA(NULL, 0, MA2, 0, MA2Mode, PRICE_LOW, i+1);
// MA2after = iMA(NULL, 0, MA2, 0, MA2Mode, PRICE_OPEN, i-1);
CrossUp[i]=EMPTY_VALUE; CrossDown[i]=EMPTY_VALUE;
if ((MA1_0 > MA2hi_0) && (MA1_1 < MA2hi_1))
{
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 ((MA1_0 < MA2lo_0) && (MA1_1 > MA2lo_1))
{
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+")");
}
}
if (drawMAs)
{
MA1_buffer[i] = MA1_0;
MA2hi_buffer[i]= MA2hi_0;
MA2lo_buffer[i]= MA2lo_0;
}
}
return(0);
}
Comments