开源EA上实盘前的代码审查清单与风险排查实战指南
开源EA上实盘前的代码审查清单与风险排查实战指南
很多人拿到一个GitHub上star数不错的开源EA,回测曲线漂亮,就敢直接挂到实盘跑。我见过最夸张的一个案例:某趋势EA在三年历史数据上盈利因子2.1,实盘第一周亏掉本金的18%。问题出在哪?不是策略逻辑本身,而是代码里那些回测引擎自动帮你兜住、实盘却会要命的细节。开源代码不等于可交易代码,这两者之间隔着一份代码审查清单。

先搞清楚:回测赚钱和实盘能活,是两套评价体系
MT4/MT5的策略测试器有个特点——它默认按K线开盘价或收盘价撮合,点差固定,滑点为零,订单几乎瞬时成交。实盘呢?点差浮动、滑点随机、订单排队。一个EA在回测里胜率58%、盈利因子1.6,实盘可能因为每笔多滑1.2个点,盈利因子直接掉到0.9以下。这不是策略失效,是执行成本吃掉了利润。
所以审查的第一步不是看策略逻辑,而是看代码有没有把回测环境「理想化假设」带进实盘。具体查什么?
- 下单函数是否硬编码了固定点差(比如用Ask-Bid算成本时写死2个点)
- 是否用市价单开仓却按挂单价计算盈亏
- 止损止盈是否依赖tick级触发,而回测是bar级模拟
我在审查一个基于均线交叉的开源EA时发现,它的止损用的是「前一根K线低点减去固定点数」,但代码里那个固定点数写的是20,而回测品种是EUR/USD、实盘品种是XAU/USD。黄金20个点约等于2美元波动,对黄金来说太窄了。改成一个基于ATR的动态值后,同一段历史数据回测最大回撤从31%降到17%。
订单管理模块:这里藏着最多「回测能跑、实盘报错」的坑
开源EA的订单管理代码通常是最薄弱的部分。因为回测时订单总能成交,很多人写代码时默认OrderSend一定返回成功,不做错误处理。实盘一遇到Requote、Invalid price、Not enough money,整个EA就卡死了。
审查订单模块,我习惯按这个顺序过一遍:
- OrderSend返回值是否检查了retcode?错误码130(无效止损)和134(资金不足)必须分别处理
- 是否有重试机制?重试次数和间隔是多少?
- MagicNumber是否唯一且非零?多个EA共用一个MagicNumber会导致平仓混乱
- 平仓逻辑是按订单号还是按品种?按品种平仓在净持仓账户上会误伤其他策略的仓位
举个具体例子。一个开源网格EA用OrderCloseBy对冲平仓,但Exness的Standard账户是净持仓模式,不支持对冲平仓,调用后直接返回错误。改成先平亏损单再平盈利单的顺序平仓逻辑,问题解决。这里要注意:不同经纪商的账户模式差异很大,XM的Micro账户是逐笔持仓,Exness的Standard是净持仓,同一份代码在两家跑出来的持仓结构完全不同。
还有一个容易忽略的点——合约参数。XM的GOLD合约1手是100盎司,Exness的XAUUSDm 1手也是100盎司,但最小手数不同:XM最小0.01手,Exness某些账户最小0.01手但步长是0.01。如果你的EA用Lots=0.015下单,在步长0.01的平台上会被拒绝。审查时把LotStep和MinLot打印出来,跟经纪商规格对一遍。
资金管理与风控:回测不爆仓不代表实盘不爆
回测引擎通常不会因为保证金不足而强制平仓——它只是拒绝新订单。实盘呢?保证金比例低于经纪商要求时,会触发追加保证金甚至强平。一个开源EA在回测里最大回撤25%,看起来可控,但实盘如果同时开了5个货币对的仓位,保证金占用可能超过账户净值的60%,一波反向波动就触发强平。
审查风控模块,重点看三个数:
- 单笔风险占比:是否按账户净值的固定百分比计算手数?还是写死了手数?
- 总敞口限制:有没有限制同时持仓的最大订单数或最大手数?
- 回撤熔断:账户净值从高点回撤超过X%时,EA是否停止开新仓?
我自己的习惯是在EA里加一层「影子风控」——不管原策略逻辑怎么算手数,外面再包一个函数,强制把单笔风险压到净值的1%以内。这个函数不依赖策略内部变量,只读账户净值和当前持仓。实测下来,一个原本在2023年某段震荡行情中回撤38%的EA,加了这层后回撤控制在19%,代价是同期收益少了约12%。值不值?看你更怕回撤还是更怕少赚。
时间与品种适配:代码里写死的数字,换到实盘就是事故
开源EA经常在代码里硬编码交易时段。比如「只在伦敦和纽约重叠时段交易」,写的是GMT 12:00到16:00。但你的VPS时区可能是GMT+2或GMT+3,经纪商服务器时间又可能是GMT+2且带夏令时。结果EA在错误的时间段开仓,滑点大、点差高。
审查时把所有跟时间相关的常量列出来,逐个确认:
- TimeCurrent()返回的是服务器时间,不是本地时间
- 如果策略依赖特定时段,用TimeGMT()转换后再比较
- 周五收盘前是否强制平仓?周末跳空风险在回测里几乎体现不出来
- 品种后缀处理:XM用「.m」后缀(如EURUSD.m),Exness用「m」后缀(如EURUSDm),代码里取Symbol()时要考虑后缀拼接
有个细节值得单独说:点值计算。黄金和外汇的点值不一样,JPY货币对的点值计算又跟非JPY不同。一个开源EA用固定公式计算每点价值,在EUR/USD上正确,换成USD/JPY就错了。审查时找到计算点值的函数,用MarketInfo(MODE_TICKVALUE)或SymbolInfoDouble(SYMBOL_TRADE_TICK_VALUE)替代手写公式。
实盘前最后一道关:用最小手数跑一周模拟
代码审查完,别急着上正常仓位。我的做法是:用最小手数(0.01手)在实盘账户跑至少一周,同时开着模拟账户跑同样参数。每天对比两者的成交价差、滑点分布、订单执行时间。如果实盘滑点中位数超过回测假设的2倍,或者出现回测里从未出现的错误码,说明还有隐藏问题。
这一周里重点观察:非农或央行决议前后,EA的下单行为是否正常?点差扩大时有没有保护逻辑?我遇到过EA在点差突然扩大到50个点时仍然市价开仓,一单滑了30个点。后来加了个点差过滤器,当前点差超过过去20根K线平均点差的3倍时暂停开仓,这类异常交易减少了九成以上。
最核心的建议就一句:把开源EA当成半成品,审查的重点不是它赚不赚钱,而是它在极端情况下会不会让你亏得莫名其妙。
你在审查开源EA时踩过哪些坑?比如订单错误码处理、点值计算、时区转换,留言说说你的排查过程。
免责声明:本文仅代表作者观点,不构成任何投资建议。市场有风险,交易需谨慎。
