# 免费RSI报警指标MT4源码 – 多周期超买超卖自动提醒
指标功能说明
RSI(相对强弱指数)是最受欢迎的动力震荡指标之一。但手动盯着多个图表和周期看RSI信号非常耗时。本指标自动化了监控过程:
1. 监控指定周期的RSI数值
2. 当RSI上穿超买线(默认70)或下穿超卖线(默认30)时触发报警
3. 通过弹窗、手机推送、邮件三种方式发送提醒
4. 带冷却计时器,避免报警轰炸
核心功能
| 功能 | 说明 |
| :--- | :--- |
| 多周期支持 | 可监控当前图表周期或任意自定义周期 |
| 超买/超卖报警 | RSI上穿70或下穿30时触发 |
| 回归报警 | 可选:当RSI从超买区回落或从超卖区回升时报警 |
| 冷却计时器 | 避免横盘行情中产生大量重复报警 |
| 三种报警方式 | 弹窗、推送通知、邮件 |
| 可调阈值 | 自定义超买超卖数值 |
| RSI周期可调 | 标准14或任意自定义值 |
完整MQL4源码
复制下方完整代码,保存为 `RSI_Alert_Indicator.mq4` 至 `MQL4/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 | 发送邮件 |
使用方法
基础设置
1. 将指标拖拽到任意图表
2. 左上角出现状态标签,显示当前RSI
3. 当RSI穿越超买/超卖线时,收到报警
跨周期监控
想在M15图表上监控H4的RSI:
手机推送设置
1. MT4:工具 → 选项 → 通知
2. 开启“推送通知”,输入MetaQuotes ID
3. 下载MT4手机App,在设置中找到ID
4. 指标中设置 `Alert_Push = true`
邮件报警设置
1. MT4:工具 → 选项 → 邮箱
2. 开启并配置SMTP(QQ邮箱:smtp.qq.com,端口465/587)
3. 指标中设置 `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数值是否真的穿越了阈值。单