FX5_MACD_Divergence_V1.0
Download scriptThis script is a specialized trading tool designed to identify "divergences" by comparing the movement of an asset's price with its momentum via the Moving Average Convergence Divergence (MACD) indicator. In simple terms, it looks for instances where the price and the momentum are moving in opposite directions, which can often signal a potential upcoming change in market trend.
Core Functionality
The script monitors the relationship between two different types of data:
- Price Action: The actual high and low values of the asset on your chart.
- MACD Momentum: The mathematical "strength" or "speed" of the price movement as calculated by the MACD indicator.
By comparing these two, the script identifies four specific types of market conditions:
1. Bullish Divergences (Potential Buy Signals)
The tool looks for "low points" (troughs) in the momentum and compares them to previous low points.
- Classical Bullish: This occurs when the price reaches a new lower low, but the MACD momentum is actually higher than it was at the previous low. This suggests that while the price is dropping, the downward "push" is weakening, potentially indicating a reversal to the upside.
- Reverse Bullish: This occurs when the price is higher than a previous low, but the MACD momentum is lower. This is flagged with a dotted line to distinguish it from the classical version.
2. Bearish Divergences (Potential Sell Signals)
The tool looks for "high points" (peaks) in the momentum and compares them to previous high points.
- Classical Bearish: This occurs when the price reaches a new higher high, but the MACD momentum is lower than it was at the previous high. This suggests that even though the price is rising, the upward "strength" is fading, potentially signaling a move downward.
- Reverse Bearish: This occurs when the price is lower than a previous high, but the MACD momentum is higher. Like the reverse bullish, this is highlighted with a dotted line.
Visual and Interactive Features
To make this data easy for a trader to read at a glance, the script includes several automated visual aids:
- On-Chart Markers: It places specific arrows on the chart to pinpoint exactly where a divergence has been detected.
- Trend Lines: The script automatically draws physical lines connecting the price points and the indicator points. This helps you see the "gap" between price and momentum clearly.
- Color Coding: It uses distinct colors (Green for bullish/upward potential and Red for bearish/downward potential) to ensure quick identification.
- Real-Time Alerts: The script can send an immediate pop-up notification on your trading platform the moment a divergence is detected, so you don't have to constantly watch the charts.
Summary of Logic Flow
- Scan: The script continuously scans the historical data to calculate the MACD values.
- Identify: It looks for specific peaks and troughs in that data.
- Compare: It checks if the price at those peaks/troughs moved in the opposite direction of the momentum.
- Execute: If a mismatch is found, it draws the corresponding lines and arrows on your screen and triggers an alert.
//+------------------------------------------------------------------+
//| FX5_MACD_Divergence_V1.0.mq4 |
//| FX5 |
//| hazem@uk2.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, FX5"
#property link "hazem@uk2.net"
//----
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 Green
#property indicator_color2 Red
#property indicator_color3 Magenta
#property indicator_color4 Blue
//----
#define arrowsDisplacement 0.0001
//---- input parameters
extern string separator1 = "*** MACD Settings ***";
extern int fastEMA = 12;
extern int slowEMA = 26;
extern int signalSMA = 9;
extern string separator2 = "*** Indicator Settings ***";
extern bool drawIndicatorTrendLines = true;
extern bool drawPriceTrendLines = true;
extern bool displayAlert = true;
//---- buffers
double bullishDivergence[];
double bearishDivergence[];
double macd[];
double signal[];
//----
static datetime lastAlertTime;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexStyle(0, DRAW_ARROW);
SetIndexStyle(1, DRAW_ARROW);
SetIndexStyle(2, DRAW_LINE);
SetIndexStyle(3, DRAW_LINE);
//----
SetIndexBuffer(0, bullishDivergence);
SetIndexBuffer(1, bearishDivergence);
SetIndexBuffer(2, macd);
SetIndexBuffer(3, signal);
//----
SetIndexArrow(0, 233);
SetIndexArrow(1, 234);
//----
SetIndexDrawBegin(3, signalSMA);
IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)+2);
IndicatorShortName("FX5_MACD_Divergence_v1.0(" + fastEMA + ", " +
slowEMA + ", " + signalSMA + ")");
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
for(int i = ObjectsTotal() - 1; i >= 0; i--)
{
string label = ObjectName(i);
if(StringSubstr(label, 0, 19) != "MACD_DivergenceLine")
continue;
ObjectDelete(label);
}
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int countedBars = IndicatorCounted();
if(countedBars < 0)
countedBars = 0;
CalculateIndicator(countedBars);
//----
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CalculateIndicator(int countedBars)
{
for (int i = Bars - countedBars; i >= 0; i--)
{
CalculateMACD(i);
CatchBullishDivergence(i + 1);
CatchBearishDivergence(i + 1);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CalculateMACD(int i)
{
macd[i] = iMACD(NULL, 0, fastEMA, slowEMA, signalSMA,
PRICE_CLOSE, MODE_MAIN, i);
signal[i] = iMACD(NULL, 0, fastEMA, slowEMA, signalSMA,
PRICE_CLOSE, MODE_SIGNAL, i);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CatchBullishDivergence(int shift)
{
if(IsIndicatorTrough(shift) == false)
return;
int currentTrough = shift;
int lastTrough = GetIndicatorLastTrough(shift);
if(macd[currentTrough] > macd[lastTrough] &&
Low[currentTrough] < Low[lastTrough])
{
bullishDivergence[currentTrough] = macd[currentTrough] -
arrowsDisplacement;
if(drawPriceTrendLines == true)
DrawPriceTrendLine(Time[currentTrough], Time[lastTrough],
Low[currentTrough],
Low[lastTrough], Green, STYLE_SOLID);
if(drawIndicatorTrendLines == true)
DrawIndicatorTrendLine(Time[currentTrough],
Time[lastTrough], macd[currentTrough],
macd[lastTrough], Green, STYLE_SOLID);
if(displayAlert == true)
DisplayAlert("Classical bullish divergence on: ",
currentTrough);
}
if(macd[currentTrough] < macd[lastTrough] &&
Low[currentTrough] > Low[lastTrough])
{
bullishDivergence[currentTrough] = macd[currentTrough] -
arrowsDisplacement;
if(drawPriceTrendLines == true)
DrawPriceTrendLine(Time[currentTrough], Time[lastTrough],
Low[currentTrough],
Low[lastTrough], Green, STYLE_DOT);
if(drawIndicatorTrendLines == true)
DrawIndicatorTrendLine(Time[currentTrough], Time[lastTrough],
macd[currentTrough],
macd[lastTrough], Green, STYLE_DOT);
if(displayAlert == true)
DisplayAlert("Reverse bullish divergence on: ", currentTrough);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CatchBearishDivergence(int shift)
{
if(IsIndicatorPeak(shift) == false)
return;
int currentPeak = shift;
int lastPeak = GetIndicatorLastPeak(shift);
if(macd[currentPeak] < macd[lastPeak] &&
High[currentPeak] > High[lastPeak])
{
bearishDivergence[currentPeak] = macd[currentPeak] +
arrowsDisplacement;
if(drawPriceTrendLines == true)
DrawPriceTrendLine(Time[currentPeak], Time[lastPeak],
High[currentPeak],
High[lastPeak], Red, STYLE_SOLID);
if(drawIndicatorTrendLines == true)
DrawIndicatorTrendLine(Time[currentPeak], Time[lastPeak],
macd[currentPeak],
macd[lastPeak], Red, STYLE_SOLID);
if(displayAlert == true)
DisplayAlert("Classical bearish divergence on: ", currentPeak);
}
if(macd[currentPeak] > macd[lastPeak] &&
High[currentPeak] < High[lastPeak])
{
bearishDivergence[currentPeak] = macd[currentPeak] +
arrowsDisplacement;
if (drawPriceTrendLines == true)
DrawPriceTrendLine(Time[currentPeak], Time[lastPeak],
High[currentPeak],
High[lastPeak], Red, STYLE_DOT);
if (drawIndicatorTrendLines == true)
DrawIndicatorTrendLine(Time[currentPeak], Time[lastPeak],
macd[currentPeak],
macd[lastPeak], Red, STYLE_DOT);
if (displayAlert == true)
DisplayAlert("Reverse bearish divergence on: ", currentPeak);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool IsIndicatorPeak(int shift)
{
if(macd[shift] >= macd[shift+1] && macd[shift] > macd[shift+2] &&
macd[shift] > macd[shift-1])
return(true);
else
return(false);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool IsIndicatorTrough(int shift)
{
if(macd[shift] <= macd[shift+1] && macd[shift] < macd[shift+2] &&
macd[shift] < macd[shift-1])
return(true);
else
return(false);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int GetIndicatorLastPeak(int shift)
{
for(int i = shift + 5; i < Bars; i++)
{
if(signal[i] >= signal[i+1] && signal[i] >= signal[i+2] &&
signal[i] >= signal[i-1] && signal[i] >= signal[i-2])
{
for(int j = i; j < Bars; j++)
{
if(macd[j] >= macd[j+1] && macd[j] > macd[j+2] &&
macd[j] >= macd[j-1] && macd[j] > macd[j-2])
return(j);
}
}
}
return(-1);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int GetIndicatorLastTrough(int shift)
{
for(int i = shift + 5; i < Bars; i++)
{
if(signal[i] <= signal[i+1] && signal[i] <= signal[i+2] &&
signal[i] <= signal[i-1] && signal[i] <= signal[i-2])
{
for(int j = i; j < Bars; j++)
{
if(macd[j] <= macd[j+1] && macd[j] < macd[j+2] &&
macd[j] <= macd[j-1] && macd[j] < macd[j-2])
return(j);
}
}
}
return(-1);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void DisplayAlert(string message, int shift)
{
if(shift <= 2 && Time[shift] != lastAlertTime)
{
lastAlertTime = Time[shift];
Alert(message, Symbol(), " , ", Period(), " minutes chart");
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void DrawPriceTrendLine(datetime x1, datetime x2, double y1,
double y2, color lineColor, double style)
{
string label = "MACD_DivergenceLine_v1.0# " + DoubleToStr(x1, 0);
ObjectDelete(label);
ObjectCreate(label, OBJ_TREND, 0, x1, y1, x2, y2, 0, 0);
ObjectSet(label, OBJPROP_RAY, 0);
ObjectSet(label, OBJPROP_COLOR, lineColor);
ObjectSet(label, OBJPROP_STYLE, style);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void DrawIndicatorTrendLine(datetime x1, datetime x2, double y1,
double y2, color lineColor, double style)
{
int indicatorWindow = WindowFind("FX5_MACD_Divergence_v1.0(" +
fastEMA + "," + slowEMA + "," +
signalSMA + ")");
if(indicatorWindow < 0)
return;
string label = "MACD_DivergenceLine_v1.0$# " + DoubleToStr(x1, 0);
ObjectDelete(label);
ObjectCreate(label, OBJ_TREND, indicatorWindow, x1, y1, x2, y2, 0, 0);
ObjectSet(label, OBJPROP_RAY, 0);
ObjectSet(label, OBJPROP_COLOR, lineColor);
ObjectSet(label, OBJPROP_STYLE, style);
}
//+------------------------------------------------------------------+
Comments