黄金亚欧盘突破策略EA
亚盘区间突破交易,欧盘开盘后突破做多空,止损1:2止盈,固定0.1手
#property copyright "XAUOF指标工坊"
#property version "1.00"
#property strict
#include <Trade\Trade.mqh>
//+------------------------------------------------------------------+
//| 可调参数 |
//+------------------------------------------------------------------+
input int InpMagicNumber = 888888; // 魔术号(用于区分不同策略)
input double InpLotSize = 0.1; // 固定手数
input int InpAsianStartHour = 8; // 亚盘开始时间(小时,北京时间)
input int InpAsianEndHour = 14; // 亚盘结束时间(小时,北京时间)
input int InpTimezoneOffset = 8; // 时区偏移(北京时间=8,UTC=0)
input double InpRiskRewardRatio = 2.0; // 止盈止损比例(倍数,默认2倍)
input bool InpUseCloseBreakout = true; // 使用收盘价确认突破(true=更保守,false=触及即突破)
input int InpSlippage = 30; // 允许滑点(点)
input string InpTradeComment = "亚欧盘突破"; // 订单备注
//+------------------------------------------------------------------+
//| 全局变量 |
//+------------------------------------------------------------------+
CTrade trade; // 交易对象
datetime currentDate = 0; // 当前日期(用于每日重置区间)
double asianHigh = 0; // 亚盘最高价
double asianLow = 0; // 亚盘最低价
bool rangeValid = false; // 区间是否有效
bool tradedToday = false; // 今天是否已交易(防止重复开仓)
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// 设置交易参数
trade.SetExpertMagicNumber(InpMagicNumber);
trade.SetDeviationInPoints(InpSlippage);
trade.SetTypeFilling(ORDER_FILLING_FOK);
trade.SetAsyncMode(false);
// 参数有效性检查
if(InpLotSize <= 0)
{
Print("错误:手数必须大于0");
return INIT_PARAMETERS_INCORRECT;
}
if(InpAsianStartHour < 0 || InpAsianStartHour > 23 || InpAsianEndHour < 0 || InpAsianEndHour > 23)
{
Print("错误:时间必须在0-23之间");
return INIT_PARAMETERS_INCORRECT;
}
if(InpRiskRewardRatio <= 0)
{
Print("错误:止盈止损比例必须大于0");
return INIT_PARAMETERS_INCORRECT;
}
Print("亚欧盘突破EA初始化成功");
Print("亚盘时段: ", InpAsianStartHour, ":00 - ", InpAsianEndHour, ":00(北京时间)");
Print("固定手数: ", InpLotSize, " 止盈止损比例: 1:", InpRiskRewardRatio);
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
Comment("");
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// 获取当前时间(转换为北京时间)
datetime serverTime = TimeCurrent();
MqlDateTime dt;
TimeToStruct(serverTime, dt);
// 转换为本地时区
int localHour = (dt.hour + InpTimezoneOffset) % 24;
// 检查是否是新的一天,重置数据
datetime todayDate = serverTime - (serverTime % 86400); // 获取今天0点的时间戳
if(todayDate != currentDate)
{
currentDate = todayDate;
asianHigh = 0;
asianLow = 0;
rangeValid = false;
tradedToday = false;
Print("新的交易日开始,重置亚盘区间");
}
// 亚盘时段:记录最高最低价
bool isAsianSession = IsAsianSession(localHour);
if(isAsianSession)
{
double high = iHigh(_Symbol, PERIOD_CURRENT, 0);
double low = iLow(_Symbol, PERIOD_CURRENT, 0);
if(asianHigh == 0 || asianLow == 0)
{
// 第一次记录
asianHigh = high;
asianLow = low;
}
else
{
// 更新区间
if(high > asianHigh) asianHigh = high;
if(low < asianLow) asianLow = low;
}
rangeValid = true;
}
// 欧盘时段:检查突破信号
if(!isAsianSession && rangeValid && !tradedToday)
{
// 检查当前是否已有持仓
if(PositionSelect(_Symbol))
{
// 已有持仓,不再开新仓
return;
}
double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double currentAsk = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
// 计算止损距离
double stopDistance = asianHigh - asianLow;
if(stopDistance <= 0) return;
// 做多信号:突破区间上沿
bool longSignal = false;
if(InpUseCloseBreakout)
{
// 使用收盘价突破
double prevClose = iClose(_Symbol, PERIOD_CURRENT, 1);
double currClose = iClose(_Symbol, PERIOD_CURRENT, 0);
longSignal = (currClose > asianHigh && prevClose <= asianHigh);
}
else
{
// 触及即突破
double currHigh = iHigh(_Symbol, PERIOD_CURRENT, 0);
longSignal = (currHigh > asianHigh);
}
// 做空信号:突破区间下沿
bool shortSignal = false;
if(InpUseCloseBreakout)
{
double prevClose = iClose(_Symbol, PERIOD_CURRENT, 1);
double currClose = iClose(_Symbol, PERIOD_CURRENT, 0);
shortSignal = (currClose < asianLow && prevClose >= asianLow);
}
else
{
double currLow = iLow(_Symbol, PERIOD_CURRENT, 0);
shortSignal = (currLow < asianLow);
}
// 执行做多
if(longSignal)
{
double sl = asianLow;
double tp = currentAsk + (stopDistance * InpRiskRewardRatio);
if(trade.Buy(InpLotSize, _Symbol, currentAsk, sl, tp, InpTradeComment))
{
Print("做多开仓成功 | 价格:", currentAsk, " 止损:", sl, " 止盈:", tp);
tradedToday = true;
}
else
{
Print("做多开仓失败,错误代码:", GetLastError());
}
}
// 执行做空
if(shortSignal)
{
double sl = asianHigh;
double tp = currentPrice - (stopDistance * InpRiskRewardRatio);
if(trade.Sell(InpLotSize, _Symbol, currentPrice, sl, tp, InpTradeComment))
{
Print("做空开仓成功 | 价格:", currentPrice, " 止损:", sl, " 止盈:", tp);
tradedToday = true;
}
else
{
Print("做空开仓失败,错误代码:", GetLastError());
}
}
}
// 显示当前状态
string status = "";
status += "========== 亚欧盘突破EA ==========\n";
status += "魔术号: " + IntegerToString(InpMagicNumber) + "\n";
status += "亚盘时段: " + IntegerToString(InpAsianStartHour) + ":00 - " + IntegerToString(InpAsianEndHour) + ":00\n";
status += "当前时间: " + IntegerToString(localHour) + ":00(本地)\n";
status += "------------------------------------\n";
if(rangeValid)
{
status += "亚盘高点: " + DoubleToString(asianHigh, _Digits) + "\n";
status += "亚盘低点: " + DoubleToString(asianLow, _Digits) + "\n";
status += "区间点数: " + DoubleToString(asianHigh - asianLow, _Digits) + "\n";
}
else
{
status += "区间状态: 未建立\n";
}
status += "------------------------------------\n";
status += "今日已交易: " + (tradedToday ? "是" : "否") + "\n";
// 显示当前持仓
if(PositionSelect(_Symbol))
{
long posType = PositionGetInteger(POSITION_TYPE);
double posProfit = PositionGetDouble(POSITION_PROFIT);
status += "持仓方向: " + (posType == POSITION_TYPE_BUY ? "做多" : "做空") + "\n";
status += "当前盈亏: " + DoubleToString(posProfit, 2) + "\n";
}
else
{
status += "当前持仓: 无\n";
}
Comment(status);
}
//+------------------------------------------------------------------+
//| 判断是否在亚盘时段 |
//+------------------------------------------------------------------+
bool IsAsianSession(int hour)
{
if(InpAsianStartHour < InpAsianEndHour)
{
// 不跨日,例如 8:00 - 14:00
return (hour >= InpAsianStartHour && hour < InpAsianEndHour);
}
else
{
// 跨日,例如 22:00 - 02:00
return (hour >= InpAsianStartHour || hour < InpAsianEndHour);
}
}
//+------------------------------------------------------------------+作品说明
问题说明
你给的是 Pine Script 代码(TradingView 专用语言),但要求编译的是 MQL5(MetaTrader 5 专用语言)。这是两种完全不同的编程语言,语法和函数库都不兼容。
我现在重新用 MQL5 写一个完整的黄金亚欧盘突破 EA,实现相同的交易逻辑:
- 亚盘时段(北京时间 8:00-14:00)记录最高最低价
- 欧盘开盘后突破区间上沿做多、下沿做空
- 止损放在区间另一侧,止盈是止损的 2 倍
- 固定手数 0.1,魔术号区分,同时只持一单
使用说明
1. 安装方法
- 打开 MetaEditor(在 MT5 中按 F4)
- 点击"文件" → "新建" → "EA交易(Expert Advisor)"
- 删除模板代码,粘贴上面的完整代码
- 点击"编译"按钮(F7),确保 0 错误 0 警告
- 在 MT5 图表上右键 → "EA交易" → "Asian_Breakout_Gold_EA" → 拖拽到图表
2. 参数调整
- 魔术号:默认 888888,如果同时运行多个 EA,需要设置不同的魔术号避免冲突
- 固定手数:默认 0.1 手,根据账户大小调整(小账户建议 0.01-0.05)
- 亚盘时段:默认 8:00-14:00(北京时间),可根据观察到的箱体形成时段调整
- 时区偏移:北京时间=8,纽约时间=-5,伦敦时间=0(夏令时需+1)
- 止盈倍数:默认 2 倍(风险回报比 1:2),激进可调到 1.5,保守可调到 3
- 突破确认方式:勾选=收盘价突破(更保守),不勾选=触及即突破(更激进)
3. 信号识别
- 右上角信息面板实时显示:当前亚盘区间、是否已交易、持仓状态
- 亚盘时段(8:00-14:00):EA 会持续记录最高价和最低价
- 欧盘时段(14:00 之后):价格突破区间上沿触发做多,突破下沿触发做空
- 止损自动设置在区间另一侧,止盈是止损距离的 2 倍
- 每天只交易一次,开仓后不再接受新信号,直到第二天重置
4. 重要注意事项
- ⚠️ 时区设置至关重要:MT5 服务器时间通常是 UTC+2 或 UTC+3(夏令时),需要根据你的经纪商调整"时区偏移"参数。如果经纪商服务器是 UTC+3,北京时间是 UTC+8,那么偏移应该设置为 8-3=5
- ⚠️ 先在模拟账户测试:至少观察 1-2 周,确认亚盘区间识别准确、开仓时机正确
- ⚠️ 窄区间风险:如果亚盘波动极小(区间<10 点),假突破概率大,建议手动暂停 EA
- ⚠️ 滑点和点差:黄金点差通常较大(3-5 美元),实际成交价可能与信号价有偏差
- ⚠️ 单笔限制:代码已实现"每天只交易一次"和"同时只持一单"的逻辑,防止过度交易
- 建议配合资金管理:账户余额 < $1000 用 0.01 手,$1000-$5000 用 0.05 手,$5000+ 用 0.1 手
- 如果连续亏损 3 天,暂停 EA 并检查市场环境(震荡市不适合突破策略)
AI 解读根据源码逐行分析写成,供参考,以实际运行为准
这是什么
这是一个基于亚盘区间突破的 MT5 自动交易 EA,专为黄金等波动品种设计。它在北京时间 8:00-14:00 记录最高最低价形成箱体,欧盘开盘后(14:00 之后)价格突破箱体上沿做多、下沿做空,止损设在箱体另一端,止盈是止损距离的 2 倍。每天只交易一次,固定 0.1 手开仓。
逻辑原理
亚盘时段(默认 8:00-14:00)黄金通常窄幅震荡形成箱体,EA 持续记录这段时间内的最高价和最低价作为区间上下沿。到欧盘时段(14:00 之后),流动性增加波动放大,当价格突破区间上沿时做多,突破下沿时做空。
开仓逻辑有两种:默认使用收盘价确认突破(前一根 K 线收盘价在区间内,当前根收盘价突破区间),更保守防假突破;也可切换为触及即突破(当前 K 线最高价超过上沿或最低价跌破下沿),更激进。
止损直接设在区间另一端(做多时止损=亚盘低点,做空时止损=亚盘高点),止盈距离是止损的 2 倍(默认 1:2 风险回报比)。开仓后当天不再接受新信号,直到第二天凌晨重置区间。同一时间只持一单,有仓位时不再开新仓。
参数说明
- 魔术号 InpMagicNumber(默认 888888):区分不同 EA 的订单标识,同时运行多个 EA 时必须设置不同值。
- 固定手数 InpLotSize(默认 0.1):每次开仓手数,小账户建议 0.01-0.05,大账户可用 0.1-0.5。
- 亚盘开始时间 InpAsianStartHour(默认 8):亚盘区间起始小时,北京时间 8 点。
- 亚盘结束时间 InpAsianEndHour(默认 14):亚盘区间结束小时,北京时间 14 点,之后开始监测突破。
- 时区偏移 InpTimezoneOffset(默认 8):关键参数,北京时间相对 UTC 的偏移量(UTC+8=8)。MT5 服务器时间通常是 UTC+2 或 UTC+3,需根据经纪商调整,例如服务器 UTC+3 时偏移应设 8-3=5。
- 止盈止损比例 InpRiskRewardRatio(默认 2.0):止盈是止损距离的倍数,默认 2 倍即 1:2,激进可调 1.5,保守可调 3。
- 收盘价确认突破 InpUseCloseBreakout(默认 true):勾选用收盘价确认突破更保守,不勾选触及即突破更激进。
- 允许滑点 InpSlippage(默认 30):允许的最大滑点点数,黄金点差大时可放宽到 50。
- 订单备注 InpTradeComment(默认"亚欧盘突破"):订单注释文字。
怎么用
在 MT5 中按 F4 打开 MetaEditor,新建 EA 文件,粘贴代码后按 F7 编译。拖到黄金图表上(XAUUSD 或 GOLD),在弹出窗口勾选"允许自动交易",点击确定。右上角会显示实时信息面板,包括亚盘区间高低点、今日是否已交易、当前持仓状态。
建议先在模拟账户跑 1-2 周观察,重点检查时区设置是否正确(区间时间是否对应实际亚盘)、突破时机是否合理。确认无误后再用小手数(0.01-0.05)实盘测试。EA 自动处理开平仓和止盈止损,无需人工干预。
建议使用 M5 或 M15 周期图表,太小的周期(M1)容易被噪音触发假突破,太大的周期(H1)反应滞后错过最佳入场点。
适用场景
适合黄金(XAUUSD)这类亚盘震荡、欧美盘放量的品种,也可用于原油(XTIUSD / XBRUSD)、欧美(EURUSD)等。最佳周期是 M5-M15,能兼顾信号及时性和过滤噪音。
策略在趋势初期效果好,欧盘单边突破时能吃到较大波段。不适合全天震荡市(区间内反复穿越不成趋势)和重大新闻前后(价格剧烈跳空导致止损失效)。如果亚盘区间极窄(小于 10 点),假突破概率大,建议当天暂停 EA。
固定手数 + 固定止损距离的方式在大波动日风险可控,但小波动日可能频繁触及止损。适合日内波段交易风格,不适合超短线剥头皮(滑点和点差侵蚀利润)。
风险提示
时区配置风险:时区偏移设置错误会导致区间记录时段完全错位,例如把欧盘当亚盘记录。必须根据经纪商服务器时间(通常在图表左下角显示)反推偏移量,用 TimeCurrent() 对比北京时间验证。
滑点和点差:黄金点差通常 3-5 美元,重大新闻时可能扩大到 10+ 美元。实际成交价可能偏离信号价,尤其是市价单在快速行情中滑点明显。代码允许 30 点滑点,不够时可调大但要接受更差的入场价。
假突破:亚盘区间窄时(波动小于 10 点),欧盘初期容易出现扫单式假突破(突破后立即回撤)。代码已用收盘价确认减少此类风险,但无法完全避免。连续亏损 2-3 天时应暂停观察市场状态。
单日单次限制:代码限制每天只交易一次,开仓后即使止损出场也不再进场。这防止过度交易,但也可能错过当天后续机会。如果希望止损后可再次入场,需修改 tradedToday 的重置逻辑。
止盈比例固定:1:2 风险回报比在趋势日能充分获利,但震荡日可能因止盈过远而回吐浮盈最终触发止损。如果市场波动减小,可手动调整比例到 1.5 或 1:1。
无持仓管理:代码不做移动止损、分批止盈等持仓优化,完全依赖初始止盈止损。大波动日可能提前止盈离场错失后续利润。需要高级功能的交易者需自行修改代码或手动管理。
常见问题
- 时区偏移怎么设置?我的 MT5 显示的是 GMT+2
- MT5 服务器时间通常是 UTC+2(冬令时)或 UTC+3(夏令时),北京时间是 UTC+8。如果你的服务器是 GMT+2,偏移量应设为 8-2=6;如果是 GMT+3(夏令时),应设为 8-3=5。可以在 EA 运行时对比面板显示的"当前时间"和实际北京时间验证。
- 为什么有时候明明突破了但 EA 没开仓?
- 代码默认使用收盘价确认突破(InpUseCloseBreakout=true),必须前一根 K 线收盘价在区间内、当前根收盘价突破区间才触发。如果只是 K 线影线触及区间但收盘价未突破,不会开仓。可以把参数改为 false 切换为触及即突破,但假信号会增多。
- 可以用在黄金以外的品种吗?参数需要调整吗?
- 代码没有限制品种,理论上可用于任何有亚盘震荡特征的品种(原油、欧美等)。但不同品种的波动幅度和点差不同,固定手数和时段可能不适用。例如欧美点差小可以用更大手数,原油可能需要调整亚盘时段为美盘休市时间。建议先模拟测试再实盘。
- 这个 EA 会重绘历史信号吗?
- 不会。区间在亚盘结束时已确定,突破信号基于实时价格判断,不依赖未来数据。但历史回测时由于时区转换和服务器时间差异,回测结果可能与实盘略有不同。测试时以模拟盘实时运行为准。
- 止损被打后当天还能再进场吗?
- 不能。代码设定每天只交易一次(tradedToday=true 后不再检测信号),即使止损出场也要等第二天重置。这是为了防止震荡市反复开仓亏损。如果想允许多次进场,需要修改 tradedToday 的逻辑或在止损后手动重置变量。
Asian Session Breakout EA for MT5
An automated EA that tracks Asian session (8:00-14:00 Beijing time) high/low range and enters long/short trades on European session breakouts. Features 1:2 risk-reward ratio, fixed lot size, and one-trade-per-day limit for gold intraday trading.
Source code is shown above. Compiled EX5 files are available to VIP members.
评论
还没有人评论,来抢个沙发。