This article provides a complete, compilable MQL4 indicator source code that detects RSI divergences – one of the most powerful reversal signals in technical analysis. The indicator scans for bullish divergence (price makes lower low, RSI makes higher low) and bearish divergence (price makes higher high, RSI makes lower high), then draws trend lines directly on the chart.
Indicator Logic:
Parameters Explanation:
MQL4 Source Code:
```mql4
//+------------------------------------------------------------------+
//| RSIDivergenceIndicator.mq4 |
//| |
//| 自主编译 / Self-compiled |
//+------------------------------------------------------------------+
#property copyright "Forex Trading Tools"
#property link ""
#property version "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 0
#property indicator_color1 Red
#property indicator_color2 Green
//--- input parameters
input int RSIPeriod = 14;
input int RSILevelOverbought = 70;
input int RSILevelOversold = 30;
input int MinSwingSize = 5;
input bool ShowDivergenceLines = true;
input bool EnableAlert = true;
input string AlertSound = "alert.wav";
//--- global variables
double rsiBuffer[];
int lastAlertBar = 0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
IndicatorBuffers(1);
SetIndexBuffer(0, rsiBuffer);
SetIndexStyle(0, DRAW_LINE);
SetIndexLabel(0, "RSI(" + IntegerToString(RSIPeriod) + ")");
IndicatorShortName("RSI Divergence Detector");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
int limit = rates_total - prev_calculated;
if(limit > 1) limit = rates_total - 2;
// Calculate RSI
for(int i = limit; i >= 0; i--)
{
rsiBuffer[i] = iRSI(_Symbol, _Period, RSIPeriod, PRICE_CLOSE, i);
}
// Detect divergences
if(rates_total > MinSwingSize * 3)
{
for(int i = rates_total - MinSwingSize - 2; i >= 1; i--)
{
// Bullish divergence: price lower low, RSI higher low
if(IsSwingLow(i, low) && IsSwingLowRSI(i, rsiBuffer))
{
int prevSwingLow = FindPrevSwingLow(i, low);
int prevSwingLowRSI = FindPrevSwingLowRSI(i, rsiBuffer);
if(prevSwingLow > 0 && prevSwingLowRSI > 0)
{
if(low[i] < low[prevSwingLow] && rsiBuffer[i] > rsiBuffer[prevSwingLowRSI])
{
DrawDivergenceLine(i, prevSwingLow, low[i], low[prevSwingLow], "BullDiv", Green);
if(EnableAlert && lastAlertBar != i)
{
Alert("Bullish divergence detected on ", _Symbol, " at ", TimeToString(time[i]));
if(AlertSound != "") PlaySound(AlertSound);
lastAlertBar = i;
}
}
}
}
// Bearish divergence: price higher high, RSI lower high
if(IsSwingHigh(i, high) && IsSwingHighRSI(i, rsiBuffer))
{
int prevSwingHigh = FindPrevSwingHigh(i, high);
int prevSwingHighRSI = FindPrevSwingHighRSI(i, rsiBuffer);
if(prevSwingHigh > 0 && prevSwingHighRSI > 0)
{
if(high[i] > high[prevSwingHigh] && rsiBuffer[i] < rsiBuffer[prevSwingHighRSI])
{
DrawDivergenceLine(i, prevSwingHigh, high[i], high[prevSwingHigh], "BearDiv", Red);
if(EnableAlert && lastAlertBar != i)
{
Alert("Bearish divergence detected on ", _Symbol, " at ", TimeToString(time[i]));
if(AlertSound != "") PlaySound(AlertSound);
lastAlertBar = i;
}
}
}
}
}
}
return(rates_total);
}
//+------------------------------------------------------------------+
//| Check if price is a swing low |
//+------------------------------------------------------------------+
bool IsSwingLow(int index, const double &low[])
{
for(int i = 1; i <= MinSwingSize; i++)
{
if(low[index] >= low[index - i] || low[index] >= low[index + i])
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| Check if RSI is a swing low |
//+------------------------------------------------------------------+
bool IsSwingLowRSI(int index, const double &rsi[])
{
for(int i = 1; i <= MinSwingSize; i++)
{
if(rsi[index] >= rsi[index - i] || rsi[index] >= rsi[index + i])
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| Check if price is a swing high |
//+------------------------------------------------------------------+
bool IsSwingHigh(int index, const double &high[])
{
for(int i = 1; i <= MinSwingSize; i++)
{
if(high[index] <= high[index - i] || high[index] <= high[index + i])
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| Check if RSI is a swing high |
//+------------------------------------------------------------------+
bool IsSwingHighRSI(int index, const double &rsi[])
{
for(int i = 1; i <= MinSwingSize; i++)
{
if(rsi[index] <= rsi[index - i] || rsi[index] <= rsi[index + i])
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| Find previous swing low in price |
//+------------------------------------------------------------------+
int FindPrevSwingLow(int currentIndex, const double &low[])
{
for(int i = currentIndex - MinSwingSize - 1; i >= MinSwingSize; i--)
{
if(IsSwingLow(i, low))
return i;
}
return -1;
}
//+------------------------------------------------------------------+
//| Find previous swing low in RSI |
//+------------------------------------------------------------------+
int FindPrevSwingLowRSI(int currentIndex, const double &rsi[])
{
for(int i = currentIndex - MinSwingSize - 1; i >= MinSwingSize; i--)
{
if(IsSwingLowRSI(i, rsi))
return i;
}
return -1;
}
//+------------------------------------------------------------------+
//| Find previous swing high in price |
//+------------------------------------------------------------------+
int FindPrevSwingHigh(int currentIndex, const double &high[])
{
for(int i = currentIndex - MinSwingSize - 1; i >= MinSwingSize; i--)
{
if(IsSwingHigh(i, high))
return i;
}
return -1;
}
//+------------------------------------------------------------------+
//| Find previous swing high in RSI |
//+------------------------------------------------------------------+
int FindPrevSwingHighRSI(int currentIndex, const double &rsi[])
{
for(int i = currentIndex - MinSwingSize - 1; i >= MinSwingSize; i--)
{
if(IsSwingHighRSI(i, rsi))
return i;
}
return -1;
}
//+------------------------------------------------------------------+
//| Draw divergence line on chart |
//+------------------------------------------------------------------+
void DrawDivergenceLine(int index1, int index2, double price1, double price2, string prefix, color lineColor)
{
if(!ShowDivergenceLines) return;
string lineName = prefix + "_" + IntegerToString(index1) + "_" + IntegerToString(index2);
ObjectDelete(0, lineName);
ObjectCreate(0, lineName, OBJ_TREND, 0, Time[index1], price1, Time[index2], price2);
ObjectSetInteger(0, lineName, OBJPROP_COLOR, lineColor);
ObjectSetInteger(0, lineName, OBJPROP_STYLE, STYLE_DASH);
ObjectSetInteger(0, lineName, OBJPROP_WIDTH, 1);
ObjectSetInteger(0, lineName, OBJPROP_BACK, false);
ObjectSetInteger(0, lineName, OBJPROP_RAY_RIGHT, false);
}
//+------------------------------------------------------------------+
```
Installation & Usage Guide:
1. Save the code as `RSIDivergenceIndicator.mq4` in `MQL4/Indicators/` folder
2. Press F4 to open MetaEditor, then F7 to compile
3. Refresh Navigator (F5), drag indicator onto chart
4. Adjust RSI period and swing size based on your trading timeframe
Interpretation Tips:
Compilation & Modification:
Reference: 自主编译 / Self-compiled based on standard divergence detection methodology.
For premium indicators with multi-timeframe scanning, automatic trade execution, and real-time push notifications, check out our advanced indicator suite.