# RSI Divergence Trading EA – Full MQL4 Source Code
This article provides a complete Expert Advisor (EA) for MT4 that trades based on RSI divergence signals. Bullish divergence (price makes lower low, RSI makes higher low) triggers a BUY. Bearish divergence (price makes higher high, RSI makes lower high) triggers a SELL.
Strategy Logic
The EA compares the last two visible swing points on both price and RSI to detect divergences. It includes configurable RSI period, overbought/oversold levels, divergence strength threshold, and risk management features.
Complete MQL4 Code
```mql4
//+------------------------------------------------------------------+
//| RSIDivergenceEA.mq4 |
//| 自主编译原创作品 |
//| |
//+------------------------------------------------------------------+
#property copyright "AI Assistant"
#property link ""
#property version "1.10"
#property strict
//--- Input parameters
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; // 启用资金管理
//--- Global variables
double lastRSI_curr = 0, lastRSI_prev = 0;
double lastRSI_prev2 = 0;
double lastPrice_curr = 0, lastPrice_prev = 0;
double lastPrice_prev2 = 0;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
if(RSIPeriod < 2 || StopLoss < 10 || TakeProfit < 20)
{
Print("参数错误: 请检查输入值范围");
return(INIT_PARAMETERS_INCORRECT);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
Print("EA已卸载,原因代码: ", reason);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
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("未知错误");
}
}
//+------------------------------------------------------------------+
```
Parameter Explanation
| Parameter | Description |
|-----------|-------------|
| LotSize | Fixed lot size when UseMM=false |
| RiskPercent | Percentage of balance to risk per trade |
| RSIPeriod | RSI calculation period (default 14) |
| Overbought/Oversold | Divergence confirmation levels |
| MinDivergenceStrength | Minimum pip difference for divergence |
| StopLoss | Stop loss in pips |
| TakeProfit | Take profit in pips |
| TrailingStop | Trailing stop distance (0=disabled) |
| UseMM | Enable automatic money management |
Installation & Usage
1. Copy full code to MetaEditor (F4)
2. Compile with F7 – verify successful compilation
3. Attach EA to any currency pair chart (recommended: EURUSD, GBPUSD, USDJPY)
4. Configure parameters in Inputs tab
5. Enable AutoTrading and monitor trades
Compilation Tips
Reference
This EA source code is independently developed and compiled. RSI divergence detection logic is based on classical technical analysis principles applied to algorithmic trading.
*Looking for more verified EAs with live trading results? Subscribe to access our complete EA library with performance reports and optimization guides.*