构建自动运行的 EA(第 07 部分):账户类型(II)·综合运用
「EA 被踢出图表时析构函数怎么清场」
析构函数不像普通类方法那样由你主动调用,它只在类对象消亡那一刻由系统触发一次。问题在于,对象何时消亡往往由编译器决定,你很难精确干预;但当 EA 从图表被移除时,恰恰是析构函数派上用场的时机。 我们可以在管理类里加一个自定义错误枚举值,比如 ERR_Excommunicate,用来标记“EA 因严重错误被强制踢出图表”。析构函数内部不去接收参数,而是读取 _LastError 判断是不是这个值,进而决定要不要替 EA 擦屁股。 代码逻辑很直接:若 _LastError 等于 ERR_USER_ERROR_FIRST + ERR_Excommunicate,说明 EA 是被赶走的。此时若有挂单(m_TicketPending > 0)就发删除请求,若有持仓(m_Position.Ticket > 0)就发平仓请求,最后在终端打印一句被踢原因。 别把这套当保险丝。EA 可能因为极端行情或平台强制回收而被瞬间终止,析构函数根本来不及跑。外汇和贵金属杠杆高、滑点凶,你作为交易者得自己养成习惯:每次手动移除 EA 后,去工具箱确认挂单和持仓是否真清零。 下面这段 MQL5 是析构函数的实际写法,注意高亮行的判断与两个 if 分支:
class C_Manager : class="kw">private C_Orders { enum eErrUser {ERR_Unknown, ERR_Excommunicate}; class="kw">private : ~C_Manager() { if (_LastError == (ERR_USER_ERROR_FIRST + ERR_Excommunicate)) { if (m_TicketPending > class="num">0) RemoveOrderPendent(m_TicketPending); if (m_Position.Ticket > class="num">0) ClosePosition(m_Position.Ticket); Print("EA was kicked off the chart for making a serious mistake."); } }
◍ 给 EA 留一点容错余地
把 C_Manager 写成零容忍并不现实。市场休市返回的 TRADE_RETCODE_MARKET_CLOSED,或终端里禁用了算法交易导致的 TRADE_RETCODE_CLIENT_DISABLES_AT,都不是 EA 逻辑本身的错,这类情形应当被放过。 我们在 C_Manager 里放了一个公开的 CheckToleranceLevel,让 EA 在怀疑出错时来问一句“这错严不严重”。它只按 _LastError 做分流:成功就直接 return;未知类严重错误打印后调用 SetUserError 挂异常并 ExpertRemove 把自己从图表踢掉;其余低严重度错误仅提示并 ResetLastError 清掉标记。 下面这段就是该函数的骨架,注意 ERR_USER_ERROR_FIRST + ERR_Unknown 分支代表不可恢复故障,default 分支代表可容忍噪声: 别把容错写成摆设 原文示例里 C_Manager 并未主动调用 CheckToleranceLevel,容错能力只是“理论上很高”。实战中你应在下单、改仓、查持仓等固定代码点插入调用,否则真出错时 EA 会静默留在图上继续乱跑。外汇与贵金属杠杆高,这类静默故障可能放大滑点与错单风险。
class="type">void CheckToleranceLevel(class="type">void) { class="kw">switch (_LastError) { case ERR_SUCCESS: class="kw">return; case ERR_USER_ERROR_FIRST + ERR_Unknown: Print("A serious error has occurred in the EA system. This one cannot class="kw">continue on the chart."); SetUserError(ERR_Excommunicate); ExpertRemove(); break; class="kw">default: Print("A low severity error has occurred in the EA system. Your code is:", _LastError); ResetLastError(); } }
下一篇才碰 EA 编码的雷
前两篇把类系统的底层逻辑铺开了,这一节只是个过渡:手动验证能跑通,不代表自动 EA 能直接搬。MT5 里挂 EA 涉及计时、滑点和上下文丢失,坑比看代码多。 作者原序列里下一篇才讲 EA 编码的预防措施和风险,现在你能做的只有一件事——把前两层例子在策略测试器里手跑一遍,确认自己对类生命周期的理解没偏差。 外汇和贵金属杠杆高,EA 任何自动化都先当会爆仓的玩具看。等下篇出来,再决定哪些逻辑值得写成自动单。