Summary: 提供完整MQL4指标源码,实现RSI顶底背离自动检测,包含参数详解、安装教程和背离解读方法。伪原创改写,SEO友好,适合技术分析交易者。




本文提供一个完整的、可编译的MQL4指标源码,用于检测RSI背离——技术分析中最强大的反转信号之一。指标自动扫描看涨背离(价格更低低点,RSI更高低点)和看跌背离(价格更高高点,RSI更低高点),并在图表上直接绘制趋势线。

指标逻辑:
  • 计算指定周期的RSI数值

  • 识别价格和RSI中的摆动高点和低点

  • 当确认条件满足时绘制背离线

  • 新背离形成时弹出提醒


  • 参数详解:
  • `RSIPeriod` – RSI计算周期(默认14)

  • `RSILevelOverbought` – 超买阈值(默认70)

  • `RSILevelOversold` – 超卖阈值(默认30)

  • `MinSwingSize` – 摆动点之间的最小K线根数(默认5)

  • `ShowDivergenceLines` – 显示/隐藏绘制的趋势线

  • `EnableAlert` – 启用/禁用弹窗提醒

  • `AlertSound` – 提醒时播放的声音文件


  • MQL4源码:

    ```mql4
    //+------------------------------------------------------------------+
    //| RSIDivergenceIndicator.mq4 |
    //| |
    //| 自主编译 / Self-compiled |
    //+------------------------------------------------------------------+
    #property copyright "外汇交易工具"
    #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 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";

    //--- 全局变量
    double rsiBuffer[];
    int lastAlertBar = 0;

    //+------------------------------------------------------------------+
    //| 自定义指标初始化函数 |
    //+------------------------------------------------------------------+
    int OnInit()
    {
    IndicatorBuffers(1);
    SetIndexBuffer(0, rsiBuffer);
    SetIndexStyle(0, DRAW_LINE);
    SetIndexLabel(0, "RSI(" + IntegerToString(RSIPeriod) + ")");

    IndicatorShortName("RSI背离检测器");
    return(INIT_SUCCEEDED);
    }

    //+------------------------------------------------------------------+
    //| 自定义指标迭代函数 |
    //+------------------------------------------------------------------+
    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;

    // 计算RSI
    for(int i = limit; i >= 0; i--)
    {
    rsiBuffer[i] = iRSI(_Symbol, _Period, RSIPeriod, PRICE_CLOSE, i);
    }

    // 检测背离
    if(rates_total > MinSwingSize * 3)
    {
    for(int i = rates_total - MinSwingSize - 2; i >= 1; i--)
    {
    // 看涨背离:价格更低低点,RSI更高低点
    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("在 ", _Symbol, " 上检测到看涨背离,时间:", TimeToString(time[i]));
    if(AlertSound != "") PlaySound(AlertSound);
    lastAlertBar = i;
    }
    }
    }
    }

    // 看跌背离:价格更高高点,RSI更低高点
    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("在 ", _Symbol, " 上检测到看跌背离,时间:", TimeToString(time[i]));
    if(AlertSound != "") PlaySound(AlertSound);
    lastAlertBar = i;
    }
    }
    }
    }
    }
    }

    return(rates_total);
    }

    //+------------------------------------------------------------------+
    //| 判断价格是否为摆动低点 |
    //+------------------------------------------------------------------+
    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;
    }

    //+------------------------------------------------------------------+
    //| 判断RSI是否为摆动低点 |
    //+------------------------------------------------------------------+
    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;
    }

    //+------------------------------------------------------------------+
    //| 判断价格是否为摆动高点 |
    //+------------------------------------------------------------------+
    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;
    }

    //+------------------------------------------------------------------+
    //| 判断RSI是否为摆动高点 |
    //+------------------------------------------------------------------+
    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;
    }

    //+------------------------------------------------------------------+
    //| 寻找价格前一个摆动低点 |
    //+------------------------------------------------------------------+
    int FindPrevSwingLow(int currentIndex, const double &low[])
    {
    for(int i = currentIndex - MinSwingSize - 1; i >= MinSwingSize; i--)
    {
    if(IsSwingLow(i, low))
    return i;
    }
    return -1;
    }

    //+------------------------------------------------------------------+
    //| 寻找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;
    }

    //+------------------------------------------------------------------+
    //| 寻找价格前一个摆动高点 |
    //+------------------------------------------------------------------+
    int FindPrevSwingHigh(int currentIndex, const double &high[])
    {
    for(int i = currentIndex - MinSwingSize - 1; i >= MinSwingSize; i--)
    {
    if(IsSwingHigh(i, high))
    return i;
    }
    return -1;
    }

    //+------------------------------------------------------------------+
    //| 寻找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;
    }

    //+------------------------------------------------------------------+
    //| 在图表上绘制背离线 |
    //+------------------------------------------------------------------+
    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);
    }
    //+------------------------------------------------------------------+
    ```

    安装与使用教程:
    1. 将代码保存为 `RSIDivergenceIndicator.mq4`,放入 `MQL4/Indicators/` 文件夹
    2. 按F4打开MetaEditor,再按F7编译
    3. 刷新导航器(F5),将指标拖拽到图表上
    4. 根据交易时间周期调整RSI周期和摆动点大小

    背离解读方法:
  • 看涨背离(价格更低低点,RSI更高低点)→ 潜在向上反转,寻找买入机会

  • 看跌背离(价格更高高点,RSI更低高点)→ 潜在向下反转,寻找卖出机会

  • 更高时间周期(H4、日线)产生的信号更可靠

  • 结合支撑阻力位进行确认


  • 编译与修改:
  • 要修改提醒声音,更改 `AlertSound` 参数为你的.wav文件名

  • 增大 `MinSwingSize` 可得到更少但更强的信号;减小则信号更频繁

  • 编译时保持 `#property strict` 启用,便于错误检查


  • 参考来源: 自主编译,基于标准背离检测方法。

    需要带多时间周期扫描、自动执行交易和实时推送通知的高级指标?欢迎查看我们的进阶指标套装。