首页 > 博客 > 彻底解决 Market closed(10018 / 错误132)

MT5MQL5错误故障排查EA

彻底解决 Market closed(10018 / 错误132)

发布日: 2026-07-07阅读时间:约 2 分钟
本文为发布之日的信息。EA的业绩数值(PF、DD、年化)会随实盘运行与重新验证而变动,最新数值请在各EA页面确认。 查看最新EA业绩

彻底解决 Market closed(MT5/MQL5)

当EA日志中出现 Market closedmarket is closed 时,只有一半的情况能用"周末很正常"来解释。明明是工作日白天却报错,或者其他品种能正常下单,唯独某个品种报错——被这类问题困扰的人非常多。

原因并不仅限于"周末",还包括各品种独有的交易时段(黄金、股指等的每日休市)、经纪商服务器时间与本地时间的偏差、品种交易模式限制(close-only 等)等多种因素。本文面向所有在MT5上使用EA、以及用MQL5编写EA的人,全面梳理 Market closed本质、6种成因、30秒排查法,以及代码层面的永久防范措施。关于错误代码的完整列表,请参阅 MQL5 / MT5 错误代码应对方法全指南

本文以2026年7月时的MT5(build 4xxx系列)为准。交易时段与界面名称可能因经纪商和版本不同而有所差异。


Market closed 是什么(10018 与 132 的区别)

表示"市场已关闭"的代码,在MT5与MT4(MQL4)中是不同的。请根据你使用的平台以及获取该值的位置来对应理解。

① TRADE_RETCODE_MARKET_CLOSED = 10018(MT5 / OrderSend() 的返回代码)

在MQL5中下单后,OrderSend() 的结果会存入 MqlTradeResult.retcode。当交易服务器判定"该品种当前不在交易时间内"并拒绝下单时,返回的代码就是 10018。这并非MT5内部错误,而是来自经纪商服务器的拒绝通知

含义: 市场已关闭(Market is closed)
常量: TRADE_RETCODE_MARKET_CLOSED
值  : 10018
// 日志中常见的典型输出示例
2026.07.06 23:05:11.204 EA_NAME XAUUSD,M5: OrderSend error 10018 [Market closed]

② ERR_MARKET_CLOSED = 132(MT4 / MQL4 的 GetLastError()

在MT4(MQL4)中,OrderSend() 失败后调用 GetLastError() 会返回 132。含义与10018相同,都是"市场关闭中"。如果同时使用MT4版本的EA,同一个原因会在MT5中表现为10018,在MT4中表现为132

含义: 市场已关闭(Market is closed)
常量: ERR_MARKET_CLOSED(MQL4)
值  : 132

实际使用中的区分方式:

平台获取来源
MT5 (MQL5)MqlTradeResult.retcode / CTrade.ResultRetcode()10018
MT4 (MQL4)OrderSend() 失败后的 GetLastError()132

两者的根本原因是一致的:"在服务器交易时段之外发送了订单(或该品种的交易受到限制)"。应对方法也是通用的,下文将统一讲解。


先用30秒排查

在盲目重启EA之前,看这4点就能大致锁定原因。

  1. 查看品种的交易时段 — 在市场报价(Market Watch)中右键点击对应品种 → "规格(Specification)"→ "交易时段"。上面会列出按星期划分的可交易时间(服务器时间)。如果当前时间不在这个范围内,那就是答案。
  2. 确认服务器时间 — 市场报价窗口上方显示的时间即为经纪商的服务器时间。交易时段的判定依据不是你电脑的时钟,而是这个时间。它通常与日本时间相差数小时,与中国时间同样存在时差。
  3. 确认交易模式 — 在同一"规格"界面的"交易"栏中,检查是否不是 Full access(例如显示 Disabled / Close only 等)。若是,即便在交易时段内,新开仓也会被拒绝。
  4. 换一个品种试试 — 如果EURUSD等主要外汇货币对能正常执行同一EA/手动下单,就可以确定问题不在账户或EA本身,而是集中在该品种的交易时段/限制上。

成因与对策(6种情况)

① 周末或节假日导致整体市场关闭

症状: 周六、周日,或元旦、圣诞节等时段出现报错。所有品种都会出现。

原因: 外汇市场大致在服务器时间的周五收盘至周一开盘之间无法交易。节假日(元旦、圣诞节等)即使是工作日,也可能休市或缩短交易时间。如果EA因K线残留处理或时间周期原因,在周末仍尝试下单,就会连续出现10018/132。

对策:

  1. 该错误本身无害,市场开盘后会自然消失
  2. 若不想让日志变乱,可在EA中加入星期/时段检查,从源头上不发送订单(代码见下文)
  3. 由于各经纪商的节假日日历不同,请务必查看经纪商公布的休市安排

② 品种独有的交易时段之外(每日休市)

症状: 明明是工作日,但特定品种(黄金、白银、股指CFD、能源等)报错。且几乎每天在同一时段出现。

原因: 外汇货币对在工作日基本可实现近24小时交易,但贵金属和股指CFD每天都有数十分钟至数小时的交易休止时间(每日休市)。这通常与标的资产交易所的维护或展期安排有关,具体时段因经纪商和品种而异。若EA在此休市时段下单,就会返回10018。

对策:

  1. 在"规格 → 交易时段"中确认该品种准确的休市时间段(这里显示的时间才是唯一正确答案,切勿轻信他人博客上的时间——不同经纪商各不相同)
  2. 通过EA的时间过滤器(TradeStartHour/TradeEndHour 等)规避休市时段
  3. 开发者可在代码中通过 SymbolInfoSessionTrade() 查询(详见下文)

另外,部分经纪商支持加密货币(BTCUSD等)在周末交易,但这同样取决于经纪商。请勿想当然地认为"加密货币应该是24/7交易",务必在规格界面中确认。


③ 服务器时间与本地时间混淆

症状: "规格中显示的交易时段明明是可交易时间"却仍然报错。使用海外经纪商时较为常见。

原因: 无论是规格中显示的交易时段,还是MT5内的时间显示,全部都是经纪商的服务器时间。许多海外经纪商采用GMT+2/+3(以纽约收盘作为0点的设定),与中国时间相差6~8小时左右。用中国时间看"还是周五晚上",但按服务器时间可能早已是周六,这是典型的偏差场景。

对策:

  1. 养成以市场报价窗口显示的时间(=服务器时间)为基准思考的习惯
  2. EA的参数(交易时间过滤器等)通常都是按服务器时间设定的规范。请检查自己是否误以为按本地时间设置
  3. 代码中应使用 TimeTradeServer()(不要用 TimeLocal() 来判定交易时段)

④ 品种被设为禁止交易/仅可平仓(SYMBOL_TRADE_MODE)

症状: 明明在交易时段内、又是工作日,但特定品种的新开仓全部被拒绝。有时平仓操作仍可执行。

原因: 经纪商可以按品种单独设置交易模式。

SYMBOL_TRADE_MODE含义
SYMBOL_TRADE_MODE_FULL无限制(正常状态)
SYMBOL_TRADE_MODE_CLOSEONLY仅可平仓(禁止新开仓)。常见于即将下市或临近合约到期的CFD
SYMBOL_TRADE_MODE_DISABLED完全禁止交易
SYMBOL_TRADE_MODE_LONGONLY / SHORTONLY仅可做多/仅可做空

模拟账户与实盘账户的设置可能不同,账户类型不同,可交易品种也可能不同。

对策:

  1. 查看"规格"界面中"交易"栏的设置
  2. 若为 Close only,应放弃新开仓,转而整理现有持仓。如需长期使用该品种,可查看是否存在同名不同到期月份、或不同后缀的替代品种(如 US500.f 等)
  3. 若持续显示 Disabled,请向经纪商确认该账户类型下是否可交易该品种

⑤ 周一开盘后或休市结束后的瞬间

症状: 仅在周一市场开盘后的最初几分钟,或每日休市结束后的瞬间,出现报错或成交被拒。

原因: 从交易时段"开启"的那一刻到实际能够稳定成交之间,存在一个过渡期。开盘瞬间往往流动性稀薄、点差极端扩大,部分经纪商在报价开始正常流转之前会暂不接受订单(即按市场关闭处理并拒绝)。在周一开盘第一时间发出信号的EA、以及瞄准休市结束后突破行情的黄金EA,都容易碰到这个问题。

对策:

  1. 设置开盘后N分钟内暂不新开仓的过滤条件(如 AvoidMondayOpen)。本站提供的EA默认会规避周一0-3点(服务器时间)正是出于这个原因
  2. 务必同时配合使用点差过滤器(MaxSpread)。开盘瞬间异常点差下的成交,其造成的损失往往比报错本身更痛
  3. 出现10018时不要立即重试,而应设计为等待至下一根K线

⑥ 因新闻或重大事件导致的交易暂停

症状: 在重要经济数据公布前后,或个别品种出现异常波动时,暂时出现报错。

原因: 部分经纪商或品种在重大事件发生时,会临时暂停交易(熔断)或限制新开仓。股指CFD有时会随标的市场的熔断机制联动暂停。此期间的订单会被作为市场关闭类型拒绝。

对策:

  1. 属于临时性问题,过一段时间即可恢复
  2. 使用经济数据过滤器(本站EA的 UseEconomicFilter)在数据公布前后暂停新开仓,可同时规避报错风险与剧烈波动风险

用MQL5防范该错误的代码(面向EA开发者)

Market closed 不应"出错后再处理",而应在下单前先确认交易时段与交易模式,若市场关闭则不发送订单,这才是正确的设计思路。这样不仅能让日志更清晰,还能避免无谓的服务器请求与失控重试。

确认是否处于交易时段内

SymbolInfoSessionTrade() 会返回指定星期第 i 个交易时段的开始/结束时间(以服务器时间0点为起点的秒数)。为兼容存在多个时段的品种(如包含每日休市的指数),需要用循环遍历所有时段。

// 判断当前服务器时间是否处于该品种的交易时段内
bool IsTradeSessionOpen(const string symbol)
{
   MqlDateTime dt;
   TimeToStruct(TimeTradeServer(), dt);           // 必须以服务器时间为准判定
   int now = dt.hour*3600 + dt.min*60 + dt.sec;   // 从0点起的经过秒数

   datetime from, to;
   for(uint i = 0; SymbolInfoSessionTrade(symbol, (ENUM_DAY_OF_WEEK)dt.day_of_week, i, from, to); i++)
   {
      int f = (int)from;                 // 从0点起的秒数
      int t = (int)to;                   // 24:00结束时为 86400
      if(now >= f && now < t)
         return true;
   }
   return false;   // 当天无对应时段(如周末)或不在任何时段内
}

确认交易模式(SYMBOL_TRADE_MODE)

// 判断当前交易模式是否允许新开仓
bool IsNewEntryAllowed(const string symbol, ENUM_ORDER_TYPE type)
{
   long mode = SymbolInfoInteger(symbol, SYMBOL_TRADE_MODE);
   if(mode == SYMBOL_TRADE_MODE_DISABLED)  return false; // 禁止交易
   if(mode == SYMBOL_TRADE_MODE_CLOSEONLY) return false; // 仅可平仓=禁止新开仓
   if(mode == SYMBOL_TRADE_MODE_LONGONLY  && type != ORDER_TYPE_BUY)  return false;
   if(mode == SYMBOL_TRADE_MODE_SHORTONLY && type != ORDER_TYPE_SELL) return false;
   return true;   // SYMBOL_TRADE_MODE_FULL 等情况
}

整合为下单前的统一检查

// OnTick 内: 即使信号成立,只要市场关闭就不发送订单
if(!IsTradeSessionOpen(_Symbol) || !IsNewEntryAllowed(_Symbol, ORDER_TYPE_BUY))
{
   // 提前防止10018。只留一行日志,等待下一根K线
   return;
}

即便如此仍返回10018时的处理

由于交易时段信息的更新时机、开盘瞬间的拒绝等原因,总有极少数情况会绕过前置检查。查看 OrderSend() 的retcode,对于10018绝不立即重试(应等待至下一根K线),这是铁律。在市场关闭期间连续重试,只会让日志变乱,没有任何实际改善。

MqlTradeRequest req; MqlTradeResult res;
ZeroMemory(req); ZeroMemory(res);
// ... 构建 req ...
if(!OrderSend(req, res) || res.retcode != TRADE_RETCODE_DONE)
{
   if(res.retcode == TRADE_RETCODE_MARKET_CLOSED)   // 10018
      Print("Market closed. Skip and wait for the next session.");
   else
      PrintFormat("OrderSend failed: retcode=%d, lastError=%d", res.retcode, GetLastError());
}

坦白说,在周一开盘瞬间或每日休市前后(尤其是黄金、股指)下单的EA,会经常性地遇到这个错误。具备时间调度意识的EA——包含时段确认、开盘瞬间暂缓、周末前平仓等机制——不仅能避免无谓的报错,还能规避流动性稀薄时段的糟糕成交。FXEA365提供的EA标准搭载了**周一开盘规避(AvoidMondayOpen)、时间过滤器、周末前平仓(CloseAllBeforeWeekend)**等功能。


优先级检查清单

优先级检查项对策
🚨 首先当前是否为周末/节假日(以服务器时间为准)只需等待。该错误本身无害
🚨 首先是否在规格中"交易时段"的范围内用时间过滤器规避该品种的休市时段
⚠️ 其次是否混淆了服务器时间与本地时间以市场报价显示的时间为基准重新设置
⚠️ 其次交易模式是否为 Full access若为 Close only / Disabled,请确认经纪商规范
✅ 确认是否处于开盘瞬间/休市结束瞬间暂缓N分钟+点差过滤器
🛠 开发下单前是否已确认交易时段/模式实现 SymbolInfoSessionTrade 前置检查

总结

  • Market closedMT5中为10018(TRADE_RETCODE_MARKET_CLOSED),在MT4中为132(ERR_MARKET_CLOSED)。含义相同,都是"在交易时段之外/交易受限期间发出的订单"。
  • 不仅限于周末,品种独有的每日休市(黄金、指数)、服务器时间偏差、SYMBOL_TRADE_MODE限制、开盘瞬间的拒绝同样会触发该错误。若在工作日出现,请先查看"规格 → 交易时段"。
  • 交易时段因经纪商和品种而异。只有你MT5规格界面中显示的时间才是正确答案。
  • EA开发者应通过 SymbolInfoSessionTrade() + SYMBOL_TRADE_MODE + TimeTradeServer() 构建下单前检查,实现永久防范。返回10018时不要立即重试,应等待至下一根K线。

关于错误代码的完整列表,请参阅 MQL5 / MT5 错误代码应对方法全指南;标准搭载时段规避与时间过滤器的免费EA,请参阅 EA一览


常见问题

Q: 明明是工作日白天,却出现 Market closed。这是为什么?

原因通常是该品种独有的交易休止时段(每日休市),或品种交易模式受限。黄金、白银、股指CFD即使在工作日也存在每天固定的不可交易时段。请在市场报价中右键点击该品种 → "规格"→ 确认"交易时段"和"交易"栏。

Q: 10018 与 132 有什么区别?

两者含义相同,只是平台不同。10018(TRADE_RETCODE_MARKET_CLOSED)是MT5中 OrderSend() 的返回代码,132(ERR_MARKET_CLOSED)是MT4(MQL4)中 GetLastError() 的返回值。应对方法是通用的。

Q: EA在周末持续报错。放着不管可以吗?

不会造成实际损害,市场开盘后会自然停止。但如果日志变乱、或推送通知持续不断让人在意,根本对策是在EA中加入星期/时段检查,直接跳过下单动作(详见正文代码)。

Q: 加密货币(BTCUSD)也出现了 Market closed。它不是应该24小时可交易吗?

加密货币CFD在周末是否可交易取决于经纪商。部分经纪商会在周末暂停交易,或设有短暂的维护休市时段。与外汇货币对一样,请通过"规格 → 交易时段"确认你所用经纪商的实际可交易时间。

📧 涨价预告 + 免费5天邮件课程

所有EA目前均为首发价,并将随销量阶梯式上调。在每次涨价前收到通知,另有每日一封邮件:自动交易本质、正确解读回测、券商选择技巧。

※ 严格保护隐私。可随时取消订阅。

评论与提问