Summary: Complete MQL4 indicator source code for detecting RSI bullish and bearish divergences. Includes parameter guide, installation instructions, and interpretation tips for traders.




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:
  • Calculates RSI values over specified period

  • Identifies swing highs and lows in both price and RSI

  • Draws divergence lines when confirmation criteria are met

  • Alerts user via popup when new divergence forms


  • Parameters Explanation:
  • `RSIPeriod` – Period for RSI calculation (default 14)

  • `RSILevelOverbought` – Overbought threshold (default 70)

  • `RSILevelOversold` – Oversold threshold (default 30)

  • `MinSwingSize` – Minimum bars between swing points (default 5)

  • `ShowDivergenceLines` – Show/hide drawn lines

  • `EnableAlert` – Enable/disable popup alerts

  • `AlertSound` – Play sound on alert


  • 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:
  • Bullish divergence (price lower low, RSI higher low) suggests potential upward reversal – look for buy entries

  • Bearish divergence (price higher high, RSI lower high) suggests potential downward reversal – look for sell entries

  • Higher timeframes (H4, Daily) produce more reliable signals

  • Combine with support/resistance levels for confirmation


  • Compilation & Modification:
  • To modify alert sound, change the `AlertSound` parameter to your .wav filename

  • Increase `MinSwingSize` for fewer, stronger signals; decrease for more frequent signals

  • Compile with `#property strict` enabled for error checking


  • 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.