MT5EA / 策略编译通过 · EX5 28KB 10 6

黄金亚盘区间突破 EA

XAUOF 官方·3 小时前发布

记录亚盘高低点,欧盘开盘后突破区间进场,止盈是止损的 2 倍

黄金亚盘区间突破 EA
AsiaBreakoutEA.mq5180
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
//+------------------------------------------------------------------+
//|                                          AsiaBreakoutEA.mq5      |
//|                        突破亚盘区间 EA - 适合 XAUUSD M15          |
//+------------------------------------------------------------------+
#property copyright "Kiro"
#property version   "1.00"
#property strict

#include <Trade\Trade.mqh>

//--- 输入参数
input group "=== 亚盘区间设置 ==="
input int    InpAsiaStartHour   = 1;      // 亚盘开始小时(服务器时间,推荐1)
input int    InpAsiaEndHour     = 7;      // 亚盘结束小时(服务器时间,推荐7)

input group "=== 交易设置 ==="
input double InpLotSize         = 0.01;   // 手数(推荐0.01起)
input double InpTPMultiplier    = 2.0;    // 止盈倍数(推荐2.0,即盈亏比1:2)
input int    InpSLBufferPoints  = 50;     // 止损缓冲点数(区间外额外加的距离,推荐50点)
input int    InpMagicNumber     = 888123; // 魔术号(用于识别本EA订单)
input int    InpMaxTradesPerDay = 2;      // 每天最大下单数(推荐2,做多+做空各1次)
input int    InpLatestTradeHour = 20;     // 允许交易的最晚小时(推荐20,避免隔夜)

//--- 全局变量
CTrade trade;                              // 交易类
datetime g_currentTradeDay = 0;            // 当前交易日期(用于判断是否新的一天)
double   g_asiaHigh        = 0.0;          // 亚盘区间最高价
double   g_asiaLow         = 0.0;          // 亚盘区间最低价
bool     g_buyDoneToday    = false;        // 今天是否已做多
bool     g_sellDoneToday   = false;        // 今天是否已做空
datetime g_lastBarTime     = 0;            // 最后处理的K线时间(防止同一根K线重复信号)
int      g_todayTradeCount = 0;            // 今天已下单数

//+------------------------------------------------------------------+
//| 初始化函数                                                         |
//+------------------------------------------------------------------+
int OnInit()
{
   trade.SetExpertMagicNumber(InpMagicNumber);
   trade.SetDeviationInPoints(10);
   trade.SetTypeFilling(ORDER_FILLING_FOK);
   trade.SetAsyncMode(false);
   
   Print("AsiaBreakoutEA 初始化成功 | 亚盘时段: ", InpAsiaStartHour, ":00 - ", InpAsiaEndHour, ":00");
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| 主逻辑函数                                                         |
//+------------------------------------------------------------------+
void OnTick()
{
   //--- 获取当前服务器时间
   datetime serverTime = TimeCurrent();
   MqlDateTime timeStruct;
   TimeToStruct(serverTime, timeStruct);
   
   int currentHour = timeStruct.hour;
   datetime currentDay = StringToTime(TimeToString(serverTime, TIME_DATE)); // 只取日期部分
   
   //--- 检查是否新的一天,重置状态
   if(currentDay != g_currentTradeDay)
   {
      g_currentTradeDay = currentDay;
      g_asiaHigh = 0.0;
      g_asiaLow = 0.0;
      g_buyDoneToday = false;
      g_sellDoneToday = false;
      g_todayTradeCount = 0;
      Print("新交易日开始: ", TimeToString(currentDay, TIME_DATE), " | 状态已重置");
   }
   
   //--- 在亚盘时间段内更新区间最高最低价
   if(currentHour >= InpAsiaStartHour && currentHour < InpAsiaEndHour)
   {
      double high = iHigh(_Symbol, PERIOD_CURRENT, 0);
      double low  = iLow(_Symbol, PERIOD_CURRENT, 0);
      
      if(g_asiaHigh == 0.0 || high > g_asiaHigh)
         g_asiaHigh = high;
      
      if(g_asiaLow == 0.0 || low < g_asiaLow)
         g_asiaLow = low;
      
      return; // 亚盘时段内只记录区间,不交易
   }
   
   //--- 亚盘结束后才开始交易逻辑
   if(currentHour < InpAsiaEndHour || g_asiaHigh == 0.0 || g_asiaLow == 0.0)
      return;
   
   //--- 检查是否超过允许交易的最晚小时
   if(currentHour >= InpLatestTradeHour)
      return;
   
   //--- 检查今天是否已达到最大下单数
   if(g_todayTradeCount >= InpMaxTradesPerDay)
      return;
   
   //--- 防止同一根K线重复信号
   datetime currentBarTime = iTime(_Symbol, PERIOD_CURRENT, 0);
   if(currentBarTime == g_lastBarTime)
      return;
   
   //--- 获取当前收盘价(使用上一根K线的收盘价,确保K线已完成)
   double closePrice = iClose(_Symbol, PERIOD_CURRENT, 1);
   if(closePrice == 0.0)
      return;
   
   //--- 计算点值(兼容3位和5位小数报价)
   double point = _Point;
   if(_Digits == 3 || _Digits == 5)
      point = _Point;
   
   double bufferPrice = InpSLBufferPoints * point;
   
   //--- 获取经纪商最小止损距离
   long stopsLevel = SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL);
   double minStopDistance = stopsLevel * point;
   
   //--- 突破上沿做多逻辑
   if(!g_buyDoneToday && closePrice > g_asiaHigh)
   {
      double entryPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
      double sl = g_asiaLow - bufferPrice;
      double slDistance = entryPrice - sl;
      
      // 检查止损距离是否满足最小要求
      if(slDistance < minStopDistance && minStopDistance > 0)
      {
         Print("做多止损距离不足 | 当前:", slDistance / point, "点 | 最小要求:", minStopDistance / point, "点");
         return;
      }
      
      double tp = entryPrice + (slDistance * InpTPMultiplier);
      
      if(trade.PositionOpen(_Symbol, ORDER_TYPE_BUY, InpLotSize, entryPrice, sl, tp, "AsiaBreakout_BUY"))
      {
         Print("做多开仓成功 | 入场:", entryPrice, " | 止损:", sl, " | 止盈:", tp);
         g_buyDoneToday = true;
         g_todayTradeCount++;
         g_lastBarTime = currentBarTime;
      }
      else
      {
         Print("做多开仓失败 | 错误码:", GetLastError());
      }
   }
   
   //--- 突破下沿做空逻辑
   if(!g_sellDoneToday && closePrice < g_asiaLow)
   {
      double entryPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
      double sl = g_asiaHigh + bufferPrice;
      double slDistance = sl - entryPrice;
      
      // 检查止损距离是否满足最小要求
      if(slDistance < minStopDistance && minStopDistance > 0)
      {
         Print("做空止损距离不足 | 当前:", slDistance / point, "点 | 最小要求:", minStopDistance / point, "点");
         return;
      }
      
      double tp = entryPrice - (slDistance * InpTPMultiplier);
      
      if(trade.PositionOpen(_Symbol, ORDER_TYPE_SELL, InpLotSize, entryPrice, sl, tp, "AsiaBreakout_SELL"))
      {
         Print("做空开仓成功 | 入场:", entryPrice, " | 止损:", sl, " | 止盈:", tp);
         g_sellDoneToday = true;
         g_todayTradeCount++;
         g_lastBarTime = currentBarTime;
      }
      else
      {
         Print("做空开仓失败 | 错误码:", GetLastError());
      }
   }
}

//+------------------------------------------------------------------+

作品说明

思路说明

每天服务器时间 1:00-7:00 记录亚盘区间(最高/最低价),7:00 后收盘价突破上沿则做多、突破下沿则做空,每个方向每天只触发一次。止损设在区间对面+缓冲点数,止盈为止损距离的倍数。用当日日期判断是否新的一天并重置状态,用最后K线时间戳防止同一根K线重复信号。下单前检查止损距离是否满足经纪商最小要求,兼容3位和5位小数报价。

使用说明

AsiaBreakoutEA.mq5 保存到 MT5 数据文件夹的 MQL5\Experts\ 目录,在 MetaEditor 中编译,然后在图表上拖拽到 XAUUSD M15 图表启用。

  1. 安装方法
  1. 参数调节
  • 亚盘时段:默认 1:00-7:00(服务器时间),根据你的经纪商时区调整
  • 手数:建议从 0.01 起测试,黄金波动大,需谨慎
  • 止盈倍数:默认 2.0(盈亏比 1:2),可根据回测调整到 1.5-3.0
  • 止损缓冲:默认 50 点,黄金噪音大,太小容易被扫
  • 每天最大下单数:默认 2(做多+做空各1次),避免过度交易
  • 最晚交易小时:默认 20 点,避免持仓过夜
  1. 信号识别
  • EA 会在专家日志中打印"新交易日开始"和开仓信息
  • 可在图表上看到挂单或持仓的止损止盈线
  • 订单备注为 AsiaBreakout_BUYAsiaBreakout_SELL
  1. 注意事项
  • 必须先在模拟账户回测,验证参数和经纪商兼容性
  • 黄金点差较大,建议在流动性好的时段交易
  • 周一亚盘可能因跳空导致区间失真,建议观察一周后再实盘
  • 确保 MT5 允许自动交易(工具栏绿色"自动交易"按钮已启用)
  • 经纪商如果要求最小止损距离,EA 会自动检查并拒绝不合规订单

评论

后可以留言,比如反馈用着怎么样、想加什么功能。

还没有人评论,来抢个沙发。