Summary: 专业的RSI背离检测EA源码,自动识别多头和空头背离信号并执行交易。包含止损止盈和资金管理,MQL4完整可编译。




# RSI背离交易EA – 完整MQL4源码

本文提供一个完整的MT4自动交易EA源码,基于RSI背离信号进行交易。当价格创更低低点而RSI创更高低点时(多头背离)开多单;当价格创更高高点而RSI创更低高点时(空头背离)开空单。

策略逻辑



EA比较价格和RSI最近两个可见的摆动点来检测背离形态。包含可配置的RSI周期、超买超卖水平、背离强度阈值和风险管理功能。

完整MQL4代码



```mql4
//+------------------------------------------------------------------+
//| RSIDivergenceEA.mq4 |
//| 自主编译原创作品 |
//| |
//+------------------------------------------------------------------+
#property copyright "AI助手"
#property link ""
#property version "1.10"
#property strict

//--- 输入参数
input double LotSize = 0.1; // 固定手数
input double RiskPercent = 2.0; // 风险百分比(手数自动计算)
input int RSIPeriod = 14; // RSI周期
input int RSIPrice = PRICE_CLOSE; // RSI价格类型
input int Overbought = 70; // 超买水平
input int Oversold = 30; // 超卖水平
input int MinDivergenceStrength = 5; // 最小背离强度(点数)
input int StopLoss = 60; // 止损点数
input int TakeProfit = 120; // 止盈点数
input int TrailingStop = 40; // 移动止损(0=关闭)
input int MagicNumber = 202411; // 魔术号
input bool UseMM = true; // 启用资金管理

//--- 全局变量
double lastRSI_curr = 0, lastRSI_prev = 0;
double lastRSI_prev2 = 0;
double lastPrice_curr = 0, lastPrice_prev = 0;
double lastPrice_prev2 = 0;

//+------------------------------------------------------------------+
//| EA初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
if(RSIPeriod < 2 || StopLoss < 10 || TakeProfit < 20)
{
Print("参数错误: 请检查输入值范围");
return(INIT_PARAMETERS_INCORRECT);
}
return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| EA反初始化函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
Print("EA已卸载,原因代码: ", reason);
}

//+------------------------------------------------------------------+
//| EA报价处理函数 |
//+------------------------------------------------------------------+
void OnTick()
{
// 计算当前和历史RSI值
double rsi_main = iRSI(Symbol(), 0, RSIPeriod, RSIPrice, 1);
double rsi_prev1 = iRSI(Symbol(), 0, RSIPeriod, RSIPrice, 2);
double rsi_prev2 = iRSI(Symbol(), 0, RSIPeriod, RSIPrice, 3);

// 获取价格低点/高点
double low_curr = iLow(Symbol(), 0, 1);
double low_prev = iLow(Symbol(), 0, 2);
double low_prev2 = iLow(Symbol(), 0, 3);
double high_curr = iHigh(Symbol(), 0, 1);
double high_prev = iHigh(Symbol(), 0, 2);
double high_prev2 = iHigh(Symbol(), 0, 3);

// 检测背离形态
bool bullishDiv = DetectBullishDivergence(rsi_prev2, rsi_prev1, rsi_main, low_prev2, low_prev1, low_curr);
bool bearishDiv = DetectBearishDivergence(rsi_prev2, rsi_prev1, rsi_main, high_prev2, high_prev1, high_curr);

// 检查是否已有持仓
if(CountPositions() > 0)
{
TrailingStopManagement();
return;
}

// 执行交易信号
if(bullishDiv && rsi_main < Oversold + 10)
{
OpenOrder(OP_BUY);
}
else if(bearishDiv && rsi_main > Overbought - 10)
{
OpenOrder(OP_SELL);
}
}

//+------------------------------------------------------------------+
//| 检测多头背离 |
//+------------------------------------------------------------------+
bool DetectBullishDivergence(double rsi2, double rsi1, double rsi0, double price2, double price1, double price0)
{
// 价格形成更低低点,RSI形成更高低点
bool priceLowerLow = (price0 < price1 && price1 < price2) || (price0 < price2);
bool rsiHigherLow = (rsi0 > rsi1 && rsi1 > rsi2) || (rsi0 > rsi2);

double diffPrice = price2 - price0;
double diffRSI = rsi0 - rsi2;

if(priceLowerLow && rsiHigherLow && diffPrice > MinDivergenceStrength * Point * 10 && diffRSI > 2)
return true;

// 简化检测: 价格新低但RSI未新低
if(price0 < price2 && rsi0 > rsi2 && (price2 - price0) > MinDivergenceStrength * Point * 10)
return true;

return false;
}

//+------------------------------------------------------------------+
//| 检测空头背离 |
//+------------------------------------------------------------------+
bool DetectBearishDivergence(double rsi2, double rsi1, double rsi0, double price2, double price1, double price0)
{
// 价格形成更高高点,RSI形成更低高点
bool priceHigherHigh = (price0 > price1 && price1 > price2) || (price0 > price2);
bool rsiLowerHigh = (rsi0 < rsi1 && rsi1 < rsi2) || (rsi0 < rsi2);

double diffPrice = price0 - price2;
double diffRSI = rsi2 - rsi0;

if(priceHigherHigh && rsiLowerHigh && diffPrice > MinDivergenceStrength * Point * 10 && diffRSI > 2)
return true;

// 简化检测: 价格新高但RSI未新高
if(price0 > price2 && rsi0 < rsi2 && (price0 - price2) > MinDivergenceStrength * Point * 10)
return true;

return false;
}

//+------------------------------------------------------------------+
//| 开仓函数(支持手数自动计算) |
//+------------------------------------------------------------------+
void OpenOrder(int cmd)
{
double lotToUse = LotSize;

if(UseMM)
{
double riskMoney = AccountBalance() * RiskPercent / 100;
double tickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
double stopLossPoints = StopLoss;
double pointValue = tickValue / (MarketInfo(Symbol(), MODE_TICKSIZE) / Point);
lotToUse = riskMoney / (stopLossPoints * pointValue);
lotToUse = MathMax(MathMin(lotToUse, MarketInfo(Symbol(), MODE_MAXLOT)), MarketInfo(Symbol(), MODE_MINLOT));
lotToUse = NormalizeDouble(lotToUse, 2);
}

double price = (cmd == OP_BUY) ? Ask : Bid;
double sl = 0, tp = 0;

if(StopLoss > 0)
sl = (cmd == OP_BUY) ? price - StopLoss * Point * 10 : price + StopLoss * Point * 10;
if(TakeProfit > 0)
tp = (cmd == OP_BUY) ? price + TakeProfit * Point * 10 : price - TakeProfit * Point * 10;

int ticket = OrderSend(Symbol(), cmd, lotToUse, price, 5, sl, tp, "RSI Divergence", MagicNumber, 0, clrNONE);

if(ticket < 0)
Print("开仓失败: ", GetLastError(), " 错误码说明: ", ErrorDescription(GetLastError()));
else
Print("开仓成功: 订单号 ", ticket);
}

//+------------------------------------------------------------------+
//| 统计持仓数量 |
//+------------------------------------------------------------------+
int CountPositions()
{
int count = 0;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
count++;
}
}
return count;
}

//+------------------------------------------------------------------+
//| 移动止损管理 |
//+------------------------------------------------------------------+
void TrailingStopManagement()
{
if(TrailingStop == 0) return;

for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
double newSL = 0;
if(OrderType() == OP_BUY)
{
newSL = Bid - TrailingStop * Point * 10;
if(newSL > OrderStopLoss() + Point * 10)
OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrNONE);
}
else if(OrderType() == OP_SELL)
{
newSL = Ask + TrailingStop * Point * 10;
if(newSL < OrderStopLoss() - Point * 10 || OrderStopLoss() == 0)
OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrNONE);
}
}
}
}
}

//+------------------------------------------------------------------+
//| 错误码描述 |
//+------------------------------------------------------------------+
string ErrorDescription(int errorCode)
{
switch(errorCode)
{
case 134: return("资金不足");
case 130: return("止损设置错误");
case 4108: return("交易被禁用");
default: return("未知错误");
}
}
//+------------------------------------------------------------------+
```

参数详解



| 参数 | 说明 |
|------|------|
| 固定手数 | 关闭资金管理时使用的固定交易量 |
| 风险百分比 | 每笔交易占账户余额的风险比例 |
| RSI周期 | RSI计算周期(默认14) |
| 超买/超卖 | 背离确认参考水平 |
| 最小背离强度 | 背离所需的最小点数差 |
| 止损点数 | 止损距离 |
| 止盈点数 | 止盈距离 |
| 移动止损 | 跟踪止损距离(0=关闭) |
| 启用资金管理 | 自动根据风险百分比计算手数 |

安装与使用说明



1. 复制完整代码到MT4的MetaEditor(按F4)
2. 按F7编译 – 确认编译成功无错误
3. 将EA附加到任意货币对图表(推荐:EURUSD、GBPUSD、USDJPY)
4. 在输入参数选项卡中配置参数
5. 启用自动交易并监控交易信号

编译修改技巧



  • 对于5位报价平台,EA使用`Point * 10`自动处理点数计算

  • 建议在M15或H1时间周期测试,背离信号更可靠

  • 建议启用UseMM以进行合理的风险管理

  • 编译后查看"专家"选项卡确认无错误信息


  • 参考来源



    本文EA源码为自主独立编译。RSI背离检测逻辑基于经典技术分析原理,经算法化适配MT4平台。

    *想要更多经过实盘验证的EA?订阅即可访问完整EA库,内含性能报告和优化指南。*