本文提供一个完整的、可编译的MQL4指标源码,用于检测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);
}
//+------------------------------------------------------------------+
`
安装与使用教程:
将代码保存为 RSIDivergenceIndicator.mq4,放入 MQL4/Indicators/ 文件夹
按F4打开MetaEditor,再按F7编译
刷新导航器(F5),将指标拖拽到图表上
根据交易时间周期调整RSI周期和摆动点大小
背离解读方法:
看涨背离(价格更低低点,RSI更高低点)→ 潜在向上反转,寻找买入机会
看跌背离(价格更高高点,RSI更低高点)→ 潜在向下反转,寻找卖出机会
更高时间周期(H4、日线)产生的信号更可靠
结合支撑阻力位进行确认
编译与修改:
要修改提醒声音,更改 AlertSound 参数为你的.wav文件名
增大 MinSwingSize 可得到更少但更强的信号;减小则信号更频繁
编译时保持 #property strict` 启用,便于错误检查参考来源: 自主编译,基于标准背离检测方法。
需要带多时间周期扫描、自动执行交易和实时推送通知的高级指标?欢迎查看我们的进阶指标套装。