本文提供一个完整的、可编译的MQL4指标源码,用于检测RSI背离——技术分析中最强大的反转信号之一。指标自动扫描看涨背离(价格更低低点,RSI更高低点)和看跌背离(价格更高高点,RSI更低高点),并在图表上直接绘制趋势线。
指标逻辑:
参数详解:
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周期和摆动点大小
背离解读方法:
编译与修改:
参考来源: 自主编译,基于标准背离检测方法。
需要带多时间周期扫描、自动执行交易和实时推送通知的高级指标?欢迎查看我们的进阶指标套装。