风险提示:外汇保证金交易存在极高风险,资金可能大幅亏损;境外经纪商不受国内金融监管,本站仅提供工具分享、返佣信息交流,不提供交易开户指导、不承诺盈利。
汇友交流区
EA运行报错排查实录 - 07月03日更新
👁 3 💬 0
首页 / 论坛 / 汇友交流区 / EA运行报错排查实录 - 07月03日 ...

EA运行报错排查实录 - 07月03日更新

量化Coder · 2026-7-3 15:43 · 👁 3 · 💬 0 · 1分钟阅读
主题 20 帖数 143 积分 2120 金币 2340
量化Coder 楼主
3 天前
1楼
昨天一个汇友发了个EA给我看,说跑着跑着就报错,订单开不出来,日志里一堆“invalid stops”和“order modify error 1”。我让他把日志和代码贴过来,一看就知道问题出在哪了——止损设置没处理小数点精度。这种事其实很常见,尤其是新手写EA时容易踩坑,今天干脆整理一下排查实录,算是给自己留个记录,也给遇到类似问题的朋友一个参考。

先说第一个案例:止损位超出允许范围。他用的EURUSD,止损设了20点,但当前价格波动大,点差到了30点,EA直接用了MarketInfo(Symbol(), MODE_STOPLEVEL)返回值,没考虑动态点差。排查步骤是这样的:第一步,先检查日志里的错误代码,比如138就是止损位太近,130是无效参数。第二步,在代码里加个打印,把止损计算值、当前点差、最小允许距离都输出来。第三步,对比后发现他的止损值比最小允许距离还小,所以报错。解决办法很简单:要么在设置止损前加一个判断,如果目标止损小于最小允许距离,就自动调整到最小距离;要么在策略里引入动态点差处理,比如用点差乘以一个系数。

第二个案例更隐蔽:数组越界导致循环崩溃。他用了双均线交叉策略,在OnTick里循环处理多品种订单,结果数组索引直接用了OrderSelect的返回值,没检查是否成功。日志里出现“array out of range”错误,然后EA就停了。排查步骤:第一步,定位到报错的代码行,通常是OrderSelect后直接用了OrderTicket()或OrderLots()。第二步,在OrderSelect前加个if(!OrderSelect(index, SELECT_BY_POS)) continue; 跳过未选中的订单。第三步,检查数组长度是否与订单总数匹配,比如用了OrderHistoryTotal()和OrdersTotal()时,要确保循环次数动态更新,不要硬编码。这个案例让我想起以前自己写的一个多币种EA,就是因为循环里没处理订单选择失败,导致回测时经常中断。

第三个案例是最近才遇到的:时间戳溢出。他用的MQL5写的EA,在回测时发现订单开仓时间显示异常,导致止损逻辑错乱。排查步骤:第一步,打印出当前时间和订单开仓时间,发现时间戳是负数。第二步,检查代码里是否用了TimeCurrent()和OrderOpenTime()做减法,但没考虑夏令时或服务器时间差。第三步,发现他用了GetTickCount()来获取毫秒级时间戳,但MQL5的GetTickCount返回的是从系统启动开始的毫秒数,不是UNIX时间戳。解决办法:改用TimeCurrent()获取服务器时间,或者用TimeTradeServer()。如果非要毫秒级,可以用DateTimeToStruct()转换。

总结一下,EA报错排查的核心思路是:先看日志,定位错误代码;再打印关键变量,缩小范围;最后对比规则文档,比如Broker的止损限制、时间格式要求。推荐大家在代码里加个宏定义,比如#define DEBUG_PRINT 1,平时调试时开启,运行时关闭,免得日志刷屏。另外,建议用Try-Catch结构(MQL5支持)或OrderSelect的返回值判断来捕获异常,避免EA直接崩溃。

最后分享一个我常用的检查函数模板,专门用来处理止损调整:

double AdjustStopLoss(double sl, double bid, double ask, int slippage) {
   double minDist = MarketInfo(Symbol(), MODE_STOPLEVEL) * Point;
   double spread = (ask - bid) / Point;
   double adjustedSL = sl;
   if (adjustedSL < minDist + spread) {
      adjustedSL = minDist + spread;
   }
   return NormalizeDouble(adjustedSL, Digits);
}

这个函数先获取最小距离,再考虑点差,最后规范化到小数点位数。用之前记得把止损值传进来,比如OrderModify时直接调用。如果遇到“invalid stops”,八成就是这里没处理好。

今天就写到这,有问题跟帖,我看到就回。
专注交易策略编程实现,分享MQL开发技巧与代码优化方案
👍 0 💬 回复 “ 引用 🔗 复制 #1
本帖内容仅供学习交流,不构成任何投资建议。外汇交易存在高风险,请谨慎参与。
← 上一帖 从零开始学外汇的心得 下一帖 → VPS服务器搭建与优化 - 07月03日更新
1