In this post, you can download the RSI divergence indicator for MetaTrader 4 for free coded with MQL. The RSI indicator has always been the most used indicator to anticipate both downward and upward trend reversals.
The RSI indicator is an oscillator that signals the most extreme phases of oversold and overbought. Using the classic 14-period RSI, the buy signal will trigger when the RSI line exceeds 70, while a buy signal will trigger when the indicator’s value is below 30.
This type of analysis is flanked by another with which divergences are sought between the RSI movement and the asset prices.
Identifying bearish or bullish divergences through the RSI could allow you to anticipate the price movement without having to wait for the overbought and oversold phases.
One of the significant problems encountered using an RSI indicator as an input signal is the scarcity of signals. This indicator rarely reaches the overbought and oversold areas; this is the main difference between the RSI and other oscillators, such as the stochastic. You can learn more by reading our article: RSI vs stochastic.
Researching divergences in a discretionary way can be a very tiring and tedious activity, much better to use our free RSI Divergence indicator for metatrader4, which can be downloaded for free at the end of this article.
With our RSI Divergence indicator for MetaTrader4 you can set up an alert that will warn you every time a divergence will form, without having to spend hours in front of the screen.
How the RSI Divergence Indicator Works
Let’s see how the RSI divergence indicator works with some real examples in the forex market.
To set the indicator, drag it on the chart, and it will be positioned on the lower window of the MT4, where it will draw the line of the relative strength index with the divergences dashed.
As you can see in this example on EurUsd on an hourly chart, prices rise while the RSI is falling, so the indicator is signaling a divergence.
Looking closely at the chart, we can see that the RSI had previously broken out of 70, thus signaling a possible bearish entry. Still, following the divergences, we would only enter many candles later.
Using the RSI divergence indicator for MT4 would have prevented us from entering a position long before the trend changed.
It is not a foolproof system, and you have to accept many RSI false signals. Therefore, it must always be used within an overall strategy and not the only factor to consider when opening a trade.
The RSI divergences should be considered on a par with the classic overbought and oversold signal, i.e., an alarm bell, a warning that the trend could change.
However, it is possible to carry out backtests of this indicator to evaluate its effectiveness on a past historical series. This will not guarantee the future but will make us understand if the starting idea can work in the real world.
MQL Code for MetaTrade4
property copyright "Copyright Finance Strategy System"
property link "https://financestrategysystem.com/"
property indicator_separate_window
property indicator_buffers 4
property indicator_color1 Green
property indicator_color2 Red
property indicator_color3 White
property indicator_color4 Blue
define arrowsDisplacement 0.0001
string separator = "RSI Settings";
extern int RSIPeriod = 14;
string separator2 = "Indicator Settings";
bool draw_TrendLines = true;
bool draw_TrendLines_On_Price = true;
extern bool displayAlert = true;
extern bool displayHiddenDiv = false;
double bullishDivergence[];
double bearishDivergence[];
double rsi[];
double signal[];
static datetime lastAlertTimePk; // last alert on a Peak
static datetime lastAlertTimeTr; // last alert on a Trough
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexStyle(2, DRAW_LINE);
SetIndexStyle(3, DRAW_LINE);
SetIndexStyle(0, DRAW_ARROW);
SetIndexStyle(1, DRAW_ARROW);
//----
SetIndexBuffer(0, bullishDivergence);
SetIndexBuffer(1, bearishDivergence);
SetIndexBuffer(2, rsi);
//----
SetIndexArrow(0, 233);
SetIndexArrow(1, 234);
//----
SetIndexDrawBegin(3, RSIPeriod);
IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)+2);
IndicatorShortName("Divergence_RSI_Indicator(" + RSIPeriod + ")");
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
for(int i = ObjectsTotal() - 1; i >= 0; i--)
{
string label = ObjectName(i);
if(StringSubstr(label, 0, 18) != "RSI_Divergence_Line")
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--)
{
Calculatersi(i);
CatchBullishDivergence(i + 1);
CatchBearishDivergence(i + 1);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void Calculatersi(int i)
{
rsi[i] = iRSI(NULL, 0, RSIPeriod, PRICE_CLOSE,i);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CatchBullishDivergence(int shift)
{
if(IsIndicatorTrough(shift) == false)
return;
int currentTrough = shift;
int lastTrough = GetIndicatorLastTrough(shift);
if(rsi[currentTrough] > rsi[lastTrough] &&
Low[currentTrough] < Low[lastTrough]) { bullishDivergence[currentTrough] = rsi[currentTrough] - arrowsDisplacement; if(draw_TrendLines_On_Price == true) DrawPriceTrendLine(Time[currentTrough], Time[lastTrough], Low[currentTrough], Low[lastTrough], DarkGreen, STYLE_SOLID); if(draw_TrendLines == true) DrawIndicatorTrendLine(Time[currentTrough], Time[lastTrough], rsi[currentTrough], rsi[lastTrough], DarkGreen, STYLE_SOLID); if(displayAlert == true) DisplayAlert("RSI Classical bullish divergence on: ", currentTrough, False); // was not a Peak } if(rsi[currentTrough] < rsi[lastTrough] && Low[currentTrough] > Low[lastTrough])
{
bullishDivergence[currentTrough] = rsi[currentTrough] -
arrowsDisplacement;
if(draw_TrendLines_On_Price == true && displayHiddenDiv == true)
DrawPriceTrendLine(Time[currentTrough], Time[lastTrough],
Low[currentTrough],
Low[lastTrough], DarkGreen, STYLE_DOT);
if(draw_TrendLines == true && displayHiddenDiv == true)
DrawIndicatorTrendLine(Time[currentTrough], Time[lastTrough],
rsi[currentTrough],
rsi[lastTrough], DarkGreen, STYLE_DOT);
if(displayAlert == true && displayHiddenDiv == true) DisplayAlert("RSI Hidden bullish divergence on: ", currentTrough,False); // was not a Peak }
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CatchBearishDivergence(int shift)
{
if(IsIndicatorPeak(shift) == false)
return;
int currentPeak = shift;
int lastPeak = GetIndicatorLastPeak(shift);
if(rsi[currentPeak] < rsi[lastPeak] && High[currentPeak] > High[lastPeak])
{
bearishDivergence[currentPeak] = rsi[currentPeak] +
arrowsDisplacement;
if(draw_TrendLines_On_Price == true)
DrawPriceTrendLine(Time[currentPeak], Time[lastPeak],
High[currentPeak],
High[lastPeak], Maroon, STYLE_SOLID);
if(draw_TrendLines == true)
DrawIndicatorTrendLine(Time[currentPeak], Time[lastPeak],
rsi[currentPeak],
rsi[lastPeak], Maroon, STYLE_SOLID);
if(displayAlert == true)
DisplayAlert("RSI Classical bearish divergence on: ", currentPeak, True); // was a Peak
}
if(rsi[currentPeak] > rsi[lastPeak] &&
High[currentPeak] < High[lastPeak]) { bearishDivergence[currentPeak] = rsi[currentPeak] + arrowsDisplacement; if (draw_TrendLines_On_Price == true && displayHiddenDiv == true) DrawPriceTrendLine(Time[currentPeak], Time[lastPeak], High[currentPeak], High[lastPeak], Maroon, STYLE_DOT); if (draw_TrendLines == true && displayHiddenDiv == true) DrawIndicatorTrendLine(Time[currentPeak], Time[lastPeak], rsi[currentPeak], rsi[lastPeak], Maroon, STYLE_DOT); if (displayAlert == true && displayHiddenDiv == true) DisplayAlert("RSI Hidden bearish divergence on: ", currentPeak, True); // was a Peak } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool IsIndicatorPeak(int shift) { if(rsi[shift] >= rsi[shift+1] && rsi[shift] > rsi[shift+2] &&
rsi[shift] > rsi[shift-1])
return(true);
else
return(false);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool IsIndicatorTrough(int shift)
{
if(rsi[shift] <= rsi[shift+1] && rsi[shift] < rsi[shift+2] && rsi[shift] < rsi[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(rsi[j] >= rsi[j+1] && rsi[j] > rsi[j+2] &&
rsi[j] >= rsi[j-1] && rsi[j] > rsi[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(rsi[j] <= rsi[j+1] && rsi[j] < rsi[j+2] &&
rsi[j] <= rsi[j-1] && rsi[j] < rsi[j-2])
return(j);
}
}
}
return(-1);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void DisplayAlert(string message, int shift, bool peak)
{if (peak){
if(shift <= 2 && Time[shift] != lastAlertTimePk)
{
lastAlertTimePk = Time[shift];
Alert(message, Symbol(), " , ", Period(), " minutes chart");
}
} // was a Peak
if (!peak){
if(shift <= 2 && Time[shift] != lastAlertTimeTr)
{
lastAlertTimeTr = Time[shift];
Alert(message, Symbol(), " , ", Period(), " minutes chart");
}
} // not a Peak
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void DrawPriceTrendLine(datetime x1, datetime x2, double y1,
double y2, color lineColor, double style)
{
string label = "Divergence_RSI_Indicator " + 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("Divergence_RSI_Indicator(" + RSIPeriod + ")");
if(indicatorWindow < 0)
return;
string label = "Divergence_RSI_Indicator " + 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);
}
//+------------------------------------------------------------------+