3MA_Cross_AlertWarnSigL_NegShift
Download scriptThis script is designed as a technical analysis tool for the MetaTrader platform. It monitors price trends by calculating and visualizing three different Moving Averages (MAs) simultaneously to identify momentum shifts.
Core Functionality
The primary goal of this tool is to detect "crosses"—the specific moments when one moving average line intersects another. In trading, these intersections often signal a change in trend direction (e.g., moving from an uptrend to a downtrend).
How the Logic Works
The script processes three distinct Moving Averages: Fast, Medium, and Slow. By comparing these three lines against one another, the tool identifies three types of interactions:
- Fast vs. Medium: Identifies immediate momentum changes.
- Fast vs. Slow: Identifies aggressive trend shifts.
- Medium vs. Slow: Identifies broader, structural trend changes.
Key Features
1. Visual Signaling Instead of just showing lines, the script places visual markers (arrows) on your chart at the exact point where a crossover occurs.
- It calculates a "Range" based on recent price history to determine the best physical location for these arrows so they remain clearly visible and do not overlap with the candles.
2. Dynamic Alert System The script can be configured to proactively notify you when a crossover happens. You can choose to receive these notifications in three different ways:
- Pop-up Alerts: On-screen messages within the platform.
- Email Notifications: Sent directly to your registered email address.
- Audio Sounds: Played through your computer speakers.
To prevent the tool from "spamming" you with repetitive alerts, the logic includes a filter that ensures you only receive one notification per specific event at any given time.
3. Customization Options The script is highly adjustable to fit different trading styles:
- Visibility: You can choose to hide or show the actual moving average lines on your chart, keeping only the signals (arrows) visible if preferred.
- Timing: You can toggle whether the script looks for crosses on the live "current" candle or waits for a candle to close before confirming the signal.
- Parameters: Users can define the specific lengths and types of the Moving Averages to suit their preferred trading strategy (e.g., scalping vs. long-termswing trading).
//+--------------------------------------------------------------------------+
//| 3 MA Cross with alert.mq4 |
//| mladen |
//+--------------------------------------------------------------------------+
#property copyright "mladen"
#property link "mladenfx@gmail.com"
#property indicator_chart_window
#property indicator_buffers 7
#property indicator_color1 DodgerBlue
#property indicator_color2 Red
#property indicator_color3 Gold
#property indicator_color4 Gold
#property indicator_color5 Lime
#property indicator_color6 YellowGreen
#property indicator_color7 CadetBlue
#property indicator_width1 1
#property indicator_width2 1
#property indicator_width3 1
#property indicator_width4 1
//
//
//
//
//
extern int FasterMA = 5;
extern int FasterShift = 0;
extern int FasterMode = 1;
extern int MediumMA = 21;
extern int MediumShift = 0;
extern int MediumMode = 1;
extern int SlowerMA = 34;
extern int SlowerShift = 0;
extern int SlowerMode = 1;
extern bool showMAs = true;
extern bool crossesOnCurrent = true;
extern bool alertsOn = false;
extern bool alertsMessage = true;
extern bool alertsSound = false;
extern bool alertsEmail = false;
//
//
//
//
//
double CrossUp[];
double CrossDown[];
double CrossWUp[];
double CrossWDown[];
double ma1[];
double ma2[];
double ma3[];
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
//
//
//
//
//
int init()
{
SetIndexBuffer(0, CrossUp); SetIndexStyle(0, DRAW_ARROW); SetIndexArrow(0, 233);
SetIndexBuffer(1, CrossDown); SetIndexStyle(1, DRAW_ARROW); SetIndexArrow(1, 234);
SetIndexBuffer(2, CrossWUp); SetIndexStyle(2, DRAW_ARROW); SetIndexArrow(2, 233);
SetIndexBuffer(3, CrossWDown); SetIndexStyle(3, DRAW_ARROW); SetIndexArrow(3, 234);
SetIndexBuffer(4,ma1);
SetIndexBuffer(5,ma2);
SetIndexBuffer(6,ma3);
if (showMAs)
{
SetIndexStyle(4,DRAW_LINE);
SetIndexStyle(5,DRAW_LINE);
SetIndexStyle(6,DRAW_LINE);
SetIndexEmptyValue(4,0.00);
SetIndexEmptyValue(5,0.00);
SetIndexEmptyValue(6,0.00);
}
else
{
SetIndexStyle(4,DRAW_NONE);
SetIndexStyle(5,DRAW_NONE);
SetIndexStyle(6,DRAW_NONE);
}
return(0);
}
int deinit()
{
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
//
//
//
//
//
int start()
{
int limit, i;
int counted_bars=IndicatorCounted();
double fasterMAnow, fasterMAprevious;
double mediumMAnow, mediumMAprevious;
double slowerMAnow, slowerMAprevious;
if(counted_bars<0) return(-1);
if(counted_bars>0) counted_bars--;
limit=Bars-counted_bars;
if (FasterShift < 0) limit = MathMax(limit,-FasterShift);
if (MediumShift < 0) limit = MathMax(limit,-MediumShift);
if (SlowerShift < 0) limit = MathMax(limit,-SlowerShift);
//
//
//
//
//
//
for(i = limit; i >=0; i--)
{
ma1[i] = iMA(NULL, 0, FasterMA, FasterShift, FasterMode, PRICE_CLOSE, i);
ma2[i] = iMA(NULL, 0, MediumMA, MediumShift, MediumMode, PRICE_CLOSE, i);
ma3[i] = iMA(NULL, 0, SlowerMA, SlowerShift, SlowerMode, PRICE_CLOSE, i);
if (crossesOnCurrent==false && i==0) continue;
//
//
//
//
//
fasterMAnow = ma1[i];
fasterMAprevious = ma1[i+1];
mediumMAnow = ma2[i];
mediumMAprevious = ma2[i+1];
slowerMAnow = ma3[i];
slowerMAprevious = ma3[i+1];
//
//
//
//
//
int crossID=0;
double curr;
double prev;
double point;
while (true)
{
if (fasterMAnow > 0 && mediumMAnow > 0)
{
curr = fasterMAnow - mediumMAnow;
prev = fasterMAprevious - mediumMAprevious;
point = (fasterMAnow + fasterMAprevious)/2;
if (curr*prev<=0) { crossID=1; break; }
}
if (fasterMAnow > 0 && slowerMAnow > 0)
{
curr = fasterMAnow - slowerMAnow;
prev = fasterMAprevious - slowerMAprevious;
point = (fasterMAnow + fasterMAprevious)/2;
if (curr*prev<=0) { crossID=2; break; }
}
if (mediumMAnow > 0 && slowerMAnow > 0)
{
curr = mediumMAnow - slowerMAnow;
prev = mediumMAprevious - slowerMAprevious;
point = (mediumMAnow + mediumMAprevious)/2;
if (curr*prev<=0) { crossID=3; break; }
}
break;
}
//
//
//
//
//
CrossUp[i] = EMPTY_VALUE;
CrossDown[i] = EMPTY_VALUE;
CrossWUp[i] = EMPTY_VALUE;
CrossWDown[i] = EMPTY_VALUE;
if (crossID>0)
{
if (alertsOn)
if ((i==0 && crossesOnCurrent==true) || (i==1 && crossesOnCurrent==false))
{
switch (crossID)
{
case 1:
if(curr>0) doAlert("Fast MA crossed Medium MA UP");
else doAlert("Fast MA crossed Medium MA DOWN");
break;
case 2:
if(curr>0) doAlert("Fast MA crossed Slow MA UP");
else doAlert("Fast MA crossed Slow MA DOWN");
break;
case 3:
if(curr>0) doAlert("Medium MA crossed Slow MA UP");
else doAlert("Medium MA crossed Slow MA DOWN");
break;
}
}
//
//
//
//
//
double Range = 0.0;
for (int counter=i ;counter<=i+9;counter++) Range += MathAbs(High[counter]-Low[counter]);
Range /= 10;
//
//
//
//
//
if (i==0)
{
if (curr>0)
CrossWUp[i] = point - Range*0.5;
else CrossWDown[i] = point + Range*0.5;
}
else
{
if (curr>0)
CrossUp[i] = point - Range*0.5;
else CrossDown[i] = point + Range*0.5;
}
}
}
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
//
//
//
//
void doAlert(string doWhat)
{
static string previousAlert="nothing";
static datetime previousTime;
string message;
if (previousAlert != doWhat || previousTime != Time[0]) {
previousAlert = doWhat;
previousTime = Time[0];
//
//
//
//
//
message = StringConcatenate(Symbol()," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," ",doWhat);
if (alertsMessage) Alert(message);
if (alertsEmail) SendMail(StringConcatenate(Symbol(),"3 MA line crossing"),message);
if (alertsSound) PlaySound("alert2.wav");
}
}
Comments