Summary: 黄金安全剥头皮EA是一款专为XAUUSD设计的MQL4智能交易系统。结合RSI背离检测、波动率过滤和受控单仓位剥头皮,适合M15周期稳定运行。




黄金安全剥头皮EA专为寻求稳定、低风险黄金剥头皮交易的交易者设计。与产生过高佣金成本的高频剥头皮不同,本EA专注于最佳波动窗口期的高质量反转信号。策略检测RSI超买超卖条件配合背离确认,应用ATR波动率过滤器避开低波动盘整区,使用单仓位控制器防止过度交易。每笔交易包含基于ATR倍数的固定止损和止盈,配备每日亏损保护和周五平仓机制。

推荐加载周期: M15
策略核心逻辑:
1. RSI反转检测:等待RSI(14)进入超卖(<30)或超买(>70),随后返回阈值上方/下方。
2. 背离确认:价格创更低低点但RSI创更高低点(看涨背离),或相反(看跌背离)。
3. 波动率过滤:ATR(14)必须高于最小阈值(避免盘整)且低于最大阈值(避免极端波动)。
4. 时段过滤:仅在活跃交易时段交易(避开亚盘整理)。
5. 风险管理:固定止损250点,止盈400点,同时持仓最多1单。

```mql4
//+------------------------------------------------------------------+
//| GoldScalperSafetyEA.mq4 |
//+------------------------------------------------------------------+
#property copyright ""
#property link ""
#property version "1.00"
#property strict

//--- 输入参数及注释
input double LotSize = 0.01; // 固定交易手数(黄金0.01手)
input int RSIPeriod = 14; // RSI周期(反转检测)
input int RSIOverbought = 70; // RSI超买水平(卖出区)
input int RSIOversold = 30; // RSI超卖水平(买入区)
input int ATRPeriod = 14; // ATR周期(波动率过滤)
input double ATREnabledMin = 150; // 最小ATR点数(避免盘整)
input double ATREnabledMax = 500; // 最大ATR点数(避免极端波动)
input int StopLossPoints = 250; // 固定止损点数
input int TakeProfitPoints = 400; // 固定止盈点数
input int StartHour = 8; // 交易开始小时(GMT)
input int EndHour = 20; // 交易结束小时(GMT)
input int MagicNumber = 202422; // EA魔术号
input int MaxSpread = 35; // 最大允许点差(黄金单位:点)
input double DailyLossLimit = 5.0; // 每日亏损限额(账户余额百分比)
input bool UseFridayClose = true; // 周五21:00 GMT前平仓

//--- 全局变量
double dailyStartBalance = 0;
datetime lastBarTime = 0;
bool fridayCloseExecuted = false;

//+------------------------------------------------------------------+
//| EA初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
dailyStartBalance = AccountBalance();
lastBarTime = 0;
fridayCloseExecuted = false;
return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| EA退出函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
Comment("");
}

//+------------------------------------------------------------------+
//| 检查是否在交易时段内 |
//+------------------------------------------------------------------+
bool IsTradingHour()
{
datetime currentTime = TimeCurrent();
int hourGMT = TimeHour(currentTime);
return (hourGMT >= StartHour && hourGMT < EndHour);
}

//+------------------------------------------------------------------+
//| 检查看涨背离(价格更低低点,RSI更高低点) |
//+------------------------------------------------------------------+
bool IsBullishDivergence()
{
double priceLow1 = iLow(Symbol(), PERIOD_M15, iLowest(Symbol(), PERIOD_M15, MODE_LOW, 5, 2));
double priceLow2 = iLow(Symbol(), PERIOD_M15, iLowest(Symbol(), PERIOD_M15, MODE_LOW, 5, 8));
double rsi1 = iRSI(Symbol(), PERIOD_M15, RSIPeriod, PRICE_CLOSE, iLowest(Symbol(), PERIOD_M15, MODE_LOW, 5, 2));
double rsi2 = iRSI(Symbol(), PERIOD_M15, RSIPeriod, PRICE_CLOSE, iLowest(Symbol(), PERIOD_M15, MODE_LOW, 5, 8));

if(priceLow2 < priceLow1 && rsi2 > rsi1 && rsi2 < RSIOversold + 10)
return true;
return false;
}

//+------------------------------------------------------------------+
//| 检查看跌背离(价格更高高点,RSI更低高点) |
//+------------------------------------------------------------------+
bool IsBearishDivergence()
{
double priceHigh1 = iHigh(Symbol(), PERIOD_M15, iHighest(Symbol(), PERIOD_M15, MODE_HIGH, 5, 2));
double priceHigh2 = iHigh(Symbol(), PERIOD_M15, iHighest(Symbol(), PERIOD_M15, MODE_HIGH, 5, 8));
double rsi1 = iRSI(Symbol(), PERIOD_M15, RSIPeriod, PRICE_CLOSE, iHighest(Symbol(), PERIOD_M15, MODE_HIGH, 5, 2));
double rsi2 = iRSI(Symbol(), PERIOD_M15, RSIPeriod, PRICE_CLOSE, iHighest(Symbol(), PERIOD_M15, MODE_HIGH, 5, 8));

if(priceHigh2 > priceHigh1 && rsi2 < rsi1 && rsi2 > RSIOverbought - 10)
return true;
return false;
}

//+------------------------------------------------------------------+
//| 检查RSI出场条件 |
//+------------------------------------------------------------------+
bool RSIExtremeExit(int direction)
{
double rsi = iRSI(Symbol(), PERIOD_M15, RSIPeriod, PRICE_CLOSE, 1);

if(direction == 1) // 多头在RSI>50时出场
return (rsi > 50);
else if(direction == -1) // 空头在RSI<50时出场
return (rsi < 50);
return false;
}

//+------------------------------------------------------------------+
//| EA主循环函数(每Tick执行) |
//+------------------------------------------------------------------+
void OnTick()
{
// 每日净值保护
double currentEquity = AccountEquity();
double lossPercent = (dailyStartBalance - currentEquity) / dailyStartBalance * 100;
if(lossPercent >= DailyLossLimit)
{
Comment("已达每日亏损上限,停止开新仓");
return;
}

// 周五收盘前平仓(规避周末跳空)
if(UseFridayClose && !fridayCloseExecuted)
{
datetime currentTime = TimeCurrent();
if(TimeDayOfWeek(currentTime) == 5 && TimeHour(currentTime) >= 21)
{
CloseAllOrders();
fridayCloseExecuted = true;
return;
}
if(TimeDayOfWeek(currentTime) != 5)
fridayCloseExecuted = false;
}

// 点差过滤
if(MarketInfo(Symbol(), MODE_SPREAD) > MaxSpread)
{
Comment("当前点差过大:", MarketInfo(Symbol(), MODE_SPREAD));
return;
}

// 交易时段过滤
if(!IsTradingHour())
{
Comment("非交易时段");
return;
}

// 仅在新K线开始时检测入场(M15)
if(Time[0] == lastBarTime)
return;
lastBarTime = Time[0];

// 检查现有持仓
int posCount = CountPositions();
if(posCount > 0)
{
// 出场管理:当RSI返回中性区域时平仓
for(int i = OrdersTotal()-1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
int direction = (OrderType() == OP_BUY) ? 1 : -1;
if(RSIExtremeExit(direction))
{
if(OrderType() == OP_BUY)
OrderClose(OrderTicket(), OrderLots(), Bid, 3, clrNONE);
else if(OrderType() == OP_SELL)
OrderClose(OrderTicket(), OrderLots(), Ask, 3, clrNONE);
Print("RSI中性信号触发平仓");
}
}
}
}
return;
}

// 获取ATR用于波动率过滤
double atr = iATR(Symbol(), PERIOD_M15, ATRPeriod, 1);
if(atr < ATREnabledMin * Point || atr > ATREnabledMax * Point)
{
Comment("波动率超出可接受范围,ATR: ", atr/Point);
return;
}

// 获取RSI值
double rsi = iRSI(Symbol(), PERIOD_M15, RSIPeriod, PRICE_CLOSE, 1);
double rsi_prev = iRSI(Symbol(), PERIOD_M15, RSIPeriod, PRICE_CLOSE, 2);

int cmd = -1;
double sl = 0, tp = 0;
double ask = Ask;
double bid = Bid;

// 买入信号:RSI离开超卖区 或 看涨背离
bool buySignal = (rsi_prev <= RSIOversold && rsi > RSIOversold) || IsBullishDivergence();
// 卖出信号:RSI离开超买区 或 看跌背离
bool sellSignal = (rsi_prev >= RSIOverbought && rsi < RSIOverbought) || IsBearishDivergence();

if(buySignal)
{
cmd = OP_BUY;
sl = bid - StopLossPoints * Point;
tp = bid + TakeProfitPoints * Point;
}
else if(sellSignal)
{
cmd = OP_SELL;
sl = ask + StopLossPoints * Point;
tp = ask - TakeProfitPoints * Point;
}

if(cmd != -1)
{
int ticket = OrderSend(Symbol(), cmd, LotSize, (cmd==OP_BUY?ask:bid), 3, sl, tp, "Gold Scalper Safety", MagicNumber, 0, clrNONE);
if(ticket < 0)
Print("开仓失败,错误码:", GetLastError());
else
Print("剥头皮开仓成功,方向:", cmd==OP_BUY?"买入":"卖出");
}
}

//+------------------------------------------------------------------+
//| 统计当前魔术号的持仓数量 |
//+------------------------------------------------------------------+
int CountPositions()
{
int count = 0;
for(int i = OrdersTotal()-1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
count++;
}
}
return count;
}

//+------------------------------------------------------------------+
//| 平仓当前品种下所有属于该EA的订单 |
//+------------------------------------------------------------------+
void CloseAllOrders()
{
for(int i = OrdersTotal()-1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
if(OrderType() == OP_BUY)
OrderClose(OrderTicket(), OrderLots(), Bid, 3, clrNONE);
else if(OrderType() == OP_SELL)
OrderClose(OrderTicket(), OrderLots(), Ask, 3, clrNONE);
}
}
}
}
//+------------------------------------------------------------------+
```
参考来源: 原创MQL4代码,策略架构参考了近期社区黄金剥头皮EA的设计理念 。
免责声明: 黄金交易因高波动性具有重大风险。本EA按“原样”提供,不保证盈利。实盘部署前请在模拟账户充分测试。历史表现不代表未来结果。
```