Summary: 免费MT4指标,监控RSI并在超买超卖时发送弹窗、推送或邮件提醒。支持自定义周期、超买超卖阈值,可跨周期监控。含完整源码和安装教程。




免费RSI报警指标MT4源码 – 多周期超买超卖自动提醒



指标功能说明



RSI(相对强弱指数)是最受欢迎的动力震荡指标之一。但手动盯着多个图表和周期看RSI信号非常耗时。本指标自动化了监控过程:

  • <strong>监控指定周期的RSI数值</strong>

  • <strong>当RSI上穿超买线(默认70)或下穿超卖线(默认30)时触发报警</strong>

  • <strong>通过弹窗、手机推送、邮件三种方式发送提醒</strong>

  • <strong>带冷却计时器,避免报警轰炸</strong>


  • 核心功能



    | 功能 | 说明 |
    | :--- | :--- |
    | 多周期支持 | 可监控当前图表周期或任意自定义周期 |
    | 超买/超卖报警 | RSI上穿70或下穿30时触发 |
    | 回归报警 | 可选:当RSI从超买区回落或从超卖区回升时报警 |
    | 冷却计时器 | 避免横盘行情中产生大量重复报警 |
    | 三种报警方式 | 弹窗、推送通知、邮件 |
    | 可调阈值 | 自定义超买超卖数值 |
    | RSI周期可调 | 标准14或任意自定义值 |

    完整MQL4源码



    复制下方完整代码,保存为 RSI_Alert_Indicator.mq4MQL4/Indicators/ 文件夹,然后编译。

    ``cpp
    //+------------------------------------------------------------------+
    //| RSI_Alert_Indicator.mq4 |
    //| 自主编译 |
    //| |
    //+------------------------------------------------------------------+
    #property copyright "ForexEA博客"
    #property link ""
    #property version "1.00"
    #property strict
    #property indicator_chart_window

    //--- 输入参数
    input int RSI_Period = 14; // RSI周期
    input int RSI_Applied_Price = PRICE_CLOSE; // 应用价格
    input double Overbought_Level = 70.0; // 超买水平
    input double Oversold_Level = 30.0; // 超卖水平
    input int Timeframe = 0; // 周期(0=当前)
    input bool Alert_On_Cross_Up = true; // RSI上穿超买线时报警
    input bool Alert_On_Cross_Down = true; // RSI下穿超卖线时报警
    input bool Alert_On_Return_Up = false; // RSI从超买区回落时报警
    input bool Alert_On_Return_Down = false; // RSI从超卖区回升时报警
    input int Alert_Cooldown_Seconds = 300; // 最小报警间隔(秒)
    input bool Alert_Popup = true; // 弹窗提醒
    input bool Alert_Push = false; // 推送通知
    input bool Alert_Email = false; // 邮件提醒
    input string Alert_Email_Subject = "RSI报警"; // 邮件主题

    //--- 全局变量
    double last_alert_time = 0;
    int last_rsi_state = 0; // -1=超卖, 0=中性, 1=超买
    string indicator_shortname;
    int applied_timeframe;
    int rsi_handle;

    //+------------------------------------------------------------------+
    //| 初始化函数 |
    //+------------------------------------------------------------------+
    int OnInit()
    {
    //--- 设置周期
    if(Timeframe == 0)
    applied_timeframe = Period();
    else
    applied_timeframe = Timeframe;

    //--- 创建指标名称
    indicator_shortname = "RSI报警 (" + IntegerToString(RSI_Period) + ") 周期:" + GetTimeframeName(applied_timeframe);
    IndicatorShortName(indicator_shortname);

    //--- 创建RSI句柄
    rsi_handle = iRSI(Symbol(), applied_timeframe, RSI_Period, RSI_Applied_Price);
    if(rsi_handle == INVALID_HANDLE)
    {
    Print("创建RSI句柄失败,错误码:", GetLastError());
    return INIT_FAILED;
    }

    //--- 在图表上显示状态标签
    string label_text = "RSI报警已启动\n";
    label_text += "超买: " + DoubleToStr(Overbought_Level, 0) + " | 超卖: " + DoubleToStr(Oversold_Level, 0);
    CreateLabel("RSI_Alert_Status", label_text, 10, 30, clrWhite);

    Print("RSI报警指标已启动,监控 ", Symbol(), " 周期:", GetTimeframeName(applied_timeframe));

    return INIT_SUCCEEDED;
    }

    //+------------------------------------------------------------------+
    //| 反初始化函数 |
    //+------------------------------------------------------------------+
    void OnDeinit(const int reason)
    {
    if(rsi_handle != INVALID_HANDLE)
    IndicatorRelease(rsi_handle);

    DeleteLabel("RSI_Alert_Status");
    Print("RSI报警指标已移除");
    }

    //+------------------------------------------------------------------+
    //| 核心计算函数 |
    //+------------------------------------------------------------------+
    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[])
    {
    //--- 获取当前RSI值
    double rsi_array[1];
    int copied = CopyBuffer(rsi_handle, 0, 0, 1, rsi_array);
    if(copied != 1)
    return 0;

    double current_rsi = rsi_array[0];
    double previous_rsi = 0;

    //--- 获取前一根K线的RSI值用于穿越检测
    double rsi_prev_array[1];
    copied = CopyBuffer(rsi_handle, 0, 1, 1, rsi_prev_array);
    if(copied == 1)
    previous_rsi = rsi_prev_array[0];

    //--- 更新图表上的RSI状态显示
    string color_str = "Gray";
    string status_str = "中性";

    if(current_rsi >= Overbought_Level)
    {
    color_str = "Red";
    status_str = "超买区";
    }
    else if(current_rsi <= Oversold_Level)
    {
    color_str = "Lime";
    status_str = "超卖区";
    }

    string label_text = "RSI报警已启动\n";
    label_text += "当前RSI: " + DoubleToStr(current_rsi, 1) + " (" + status_str + ")\n";
    label_text += "超买: " + DoubleToStr(Overbought_Level, 0) + " | 超卖: " + DoubleToStr(Oversold_Level, 0);
    UpdateLabel("RSI_Alert_Status", label_text, color_str);

    //--- 检查报警条件
    if(previous_rsi > 0)
    {
    CheckForAlerts(current_rsi, previous_rsi);
    }

    return rates_total;
    }

    //+------------------------------------------------------------------+
    //| 检查报警条件 |
    //+------------------------------------------------------------------+
    void CheckForAlerts(double current_rsi, double previous_rsi)
    {
    //--- 冷却检查
    if(TimeCurrent() - last_alert_time < Alert_Cooldown_Seconds)
    return;

    string alert_message = "";

    //--- RSI上穿超买线(进入超买区)
    if(Alert_On_Cross_Up && previous_rsi < Overbought_Level && current_rsi >= Overbought_Level)
    {
    alert_message = StringFormat("RSI报警:%s %s - RSI上穿超买线 %.0f(当前值:%.1f)",
    Symbol(), GetTimeframeName(applied_timeframe), Overbought_Level, current_rsi);
    }

    //--- RSI下穿超卖线(进入超卖区)
    else if(Alert_On_Cross_Down && previous_rsi > Oversold_Level && current_rsi <= Oversold_Level)
    {
    alert_message = StringFormat("RSI报警:%s %s - RSI下穿超卖线 %.0f(当前值:%.1f)",
    Symbol(), GetTimeframeName(applied_timeframe), Oversold_Level, current_rsi);
    }

    //--- RSI从超买区回落
    else if(Alert_On_Return_Up && previous_rsi >= Overbought_Level && current_rsi < Overbought_Level)
    {
    alert_message = StringFormat("RSI报警:%s %s - RSI从超买区回落至 %.0f 下方(当前值:%.1f)",
    Symbol(), GetTimeframeName(applied_timeframe), Overbought_Level, current_rsi);
    }

    //--- RSI从超卖区回升
    else if(Alert_On_Return_Down && previous_rsi <= Oversold_Level && current_rsi > Oversold_Level)
    {
    alert_message = StringFormat("RSI报警:%s %s - RSI从超卖区回升至 %.0f 上方(当前值:%.1f)",
    Symbol(), GetTimeframeName(applied_timeframe), Oversold_Level, current_rsi);
    }

    //--- 发送报警
    if(alert_message != "")
    {
    last_alert_time = TimeCurrent();

    if(Alert_Popup)
    {
    Alert(alert_message);
    }

    if(Alert_Push)
    {
    SendNotification(alert_message);
    }

    if(Alert_Email)
    {
    SendMail(Alert_Email_Subject, alert_message);
    }

    Print(alert_message);
    }
    }

    //+------------------------------------------------------------------+
    //| 辅助函数:获取周期名称 |
    //+------------------------------------------------------------------+
    string GetTimeframeName(int tf)
    {
    switch(tf)
    {
    case PERIOD_M1: return "M1";
    case PERIOD_M5: return "M5";
    case PERIOD_M15: return "M15";
    case PERIOD_M30: return "M30";
    case PERIOD_H1: return "H1";
    case PERIOD_H4: return "H4";
    case PERIOD_D1: return "日线";
    case PERIOD_W1: return "周线";
    case PERIOD_MN1: return "月线";
    default: return IntegerToString(tf);
    }
    }

    //+------------------------------------------------------------------+
    //| 辅助函数:创建文本标签 |
    //+------------------------------------------------------------------+
    void CreateLabel(string name, string text, int x, int y, color clr)
    {
    ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0);
    ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);
    ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);
    ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_UPPER);
    ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
    ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 10);
    ObjectSetString(0, name, OBJPROP_FONT, "Arial");
    ObjectSetString(0, name, OBJPROP_TEXT, text);
    }

    //+------------------------------------------------------------------+
    //| 辅助函数:更新文本标签 |
    //+------------------------------------------------------------------+
    void UpdateLabel(string name, string text, string color_name)
    {
    if(ObjectFind(0, name) >= 0)
    {
    ObjectSetString(0, name, OBJPROP_TEXT, text);

    color clr;
    if(color_name == "Red")
    clr = clrRed;
    else if(color_name == "Lime")
    clr = clrLime;
    else
    clr = clrGray;

    ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
    }
    }

    //+------------------------------------------------------------------+
    //| 辅助函数:删除标签 |
    //+------------------------------------------------------------------+
    void DeleteLabel(string name)
    {
    ObjectDelete(0, name);
    }
    //+------------------------------------------------------------------+
    `

    安装步骤



    第1步: 复制上方完整代码
    第2步: 打开MT4 → 文件 → 打开数据文件夹 → MQL4 → Indicators
    第3步: 新建文件
    RSI_Alert_Indicator.mq4
    第4步: 粘贴代码,按F7编译
    第5步: 编译成功后,指标出现在导航器 → 指标 → 自定义
    第6步: 拖拽到任意图表上即可

    参数详解



    | 参数 | 默认值 | 说明 |
    | :--- | :--- | :--- |
    |
    RSI_Period | 14 | RSI计算周期 |
    |
    RSI_Applied_Price | PRICE_CLOSE | 价格类型(收盘价、开盘价、最高价、最低价) |
    |
    Overbought_Level | 70.0 | 超买阈值 |
    |
    Oversold_Level | 30.0 | 超卖阈值 |
    |
    Timeframe | 0 | 0=当前图表周期,也可选M1/H1/D1等 |
    |
    Alert_On_Cross_Up | true | RSI上穿超买线时报警 |
    |
    Alert_On_Cross_Down | true | RSI下穿超卖线时报警 |
    |
    Alert_On_Return_Up | false | RSI从超买区回落时报警 |
    |
    Alert_On_Return_Down | false | RSI从超卖区回升时报警 |
    |
    Alert_Cooldown_Seconds | 300 | 最小报警间隔(秒),防止刷屏 |
    |
    Alert_Popup | true | MT4内弹窗提醒 |
    |
    Alert_Push | false | 推送到手机MT4 |
    |
    Alert_Email | false | 发送邮件 |

    使用方法



    基础设置


  • 将指标拖拽到任意图表

  • 左上角出现状态标签,显示当前RSI

  • 当RSI穿越超买/超卖线时,收到报警


  • 跨周期监控


    想在M15图表上监控H4的RSI:
  • 设置 Timeframe = 60(H4)

  • 将指标放到M15图表上

  • 你会收到H4周期的RSI报警,同时查看M15图表


  • 手机推送设置


  • MT4:工具 → 选项 → 通知

  • 开启“推送通知”,输入MetaQuotes ID

  • 下载MT4手机App,在设置中找到ID

  • 指标中设置 Alert_Push = true


  • 邮件报警设置


  • MT4:工具 → 选项 → 邮箱

  • 开启并配置SMTP(QQ邮箱:smtp.qq.com,端口465/587)

  • 指标中设置 Alert_Email = true


  • 交易策略示例



    | 策略 | 使用方法 |
    | :--- | :--- |
    | 超买回调做空 | 等待RSI上穿70,再等待回落至70下方(开启Alert_On_Return_Up),回落后寻找做空机会 |
    | 超卖反弹做多 | 等待RSI下穿30,再等待回升至30上方(开启Alert_On_Return_Down),回升后寻找做多机会 |
    | 背离信号辅助 | 配合价格行为使用。超卖报警时,检查价格是否创新低而RSI未创新低 |
    | 多周期确认 | 同时在H4和M15上放置指标。仅当两个周期都显示超卖回升时才做多 |

    自定义修改



    | 修改需求 | 代码位置 |
    | :--- | :--- |
    | 修改标签位置 | 调整CreateLabel函数中的x、y值(约180行) |
    | 增加声音报警 | 在SendNotification前加上
    PlaySound("alert.wav")` |
    | 图表上画箭头 | 报警触发时用ObjectCreate画箭头 |
    | 监控RSI趋势方向 | 增加判断RSI连续N根K线上升/下降的条件 |

    常见问题



    | 问题 | 解决方法 |
    | :--- | :--- |
    | 指标不显示 | 检查“EA交易”标签页是否有编译错误,按F7重新编译 |
    | 没有报警 | 检查RSI数值是否真的穿越了阈值。单