EA订单管理模块编写指南正确打开方式(附实操步骤)

新帖
登录发帖
Exness 推荐平台

入金门槛低,出金到账快,支持多种账户类型

FSA(塞舌尔)/FCA(英国) / CySEC(塞浦路斯) · 最低入金 $130
wind201
wind201 楼主 1 小时前 浏览 2 回复 0 阅读 1 分钟
Lv.3 资深汇友 等级 Lv.3 主题 2 帖数 7 积分 2168 汇币 1814
1楼
上周把一套改了四版的订单管理模块丢进复盘环境跑,结果三天里出现了17次重复开仓,其中11次是在镑美M15上同一根K线内触发的——这还只是回测,要是实盘,光那点差和滑点就够我喝一壶了。问题不在策略信号,全出在订单管理层。今天不聊什么高深架构,就说说我踩过的坑和最后怎么把这块理顺的。
先说最核心的问题:EA到底该怎么判断“我已经有单了”?新手最容易犯的错是直接拿OrdersTotal()做全局判断。我早期就这么干的,结果账户里只要有任何品种的持仓,我的欧美策略就罢工。正确的做法是封装一个按品种+魔术号过滤的函数,遍历OrdersTotal()时用OrderSelect(i, SELECT_BY_POS, MODE_TRADES),然后比对OrderSymbol()和OrderMagicNumber()。这里有个坑:魔术号必须每个策略独立分配,我见过有人所有EA共用0,最后平仓平错单子。另外注意MODE_TRADES和MODE_HISTORY的区别,查持仓用前者,查历史盈亏用后者,别混。
解决了识别问题,接下来是开仓环节的重复触发。回测里同一根K线反复开仓,十有八九是因为没做K线时间戳校验。我的做法是在全局变量里存一个lastBarTime,每次OnTick开头先判断Time[0]是否等于lastBarTime,相等就直接return。但这里有个细节:Time[0]在M15和H1上返回的时间粒度不同,如果你是多周期EA,得统一用iTime(_Symbol, PERIOD_CURRENT, 0)来取。还有个更隐蔽的坑——周末跳空后第一根K线,有时候Time[0]会跟上一根差出好几小时,别用固定秒数做差,直接比时间戳是否相等最稳。
再往下是止损止盈和移动止损的订单修改。这块我踩的坑最多。首先,OrderModify()在价格没变化时会返回错误1或错误4109,不是代码写错了,是平台认为你没必要改。解决办法是先算一下新SL和当前OrderStopLoss()的差值,小于Point*10就别发请求。然后,移动止损别用固定点数,镑美这种波动大的品种,我试过20点移动止损,结果一个正常回撤就被扫出去,后来改成基于ATR的动态步长,用iATR(_Symbol, PERIOD_H1, 14)取当前值乘以0.5作为移动距离,回撤容忍度明显合理了。还有,多单和空单的止损方向判断千万别写反,我见过有人用MathMax给空单算止损,直接报错。
最后说平仓和挂单管理。如果你用挂单,OrderDelete()之前一定要先确认OrderType()是OP_BUYLIMIT/OP_SELLLIMIT这类挂单类型,别对着市价单调删除。平仓的时候,部分平仓和全平要分开处理,OrderClose()的第三个参数是手数,写错就是部分平。我习惯在平仓前先记录OrderTicket(),平完再校验一次该ticket是否还在持仓列表里,防止重复平仓导致“订单不存在”的错误刷屏。
整套模块跑顺之后,我现在的EA结构基本是:OnTick里先做K线时间戳过滤,再调CheckPosition()确认无持仓,然后才走信号逻辑,最后统一走订单执行层。这样拆开之后,回测重复开仓次数从17次降到了0。你们写订单管理的时候,是习惯把所有逻辑塞在OnTick里,还是单独封一个OrderManager类?评论区聊聊,我也想看看有没有更清爽的写法。
0 回复 众裁0 复制
#1
💬
暂无回复,来抢沙发吧!
THE END
本帖内容仅供学习交流,不构成任何投资建议。外汇交易存在高风险,请谨慎参与。
← 上一帖 IC Markets Raw账户跑EA半年的成本账 下一帖 → 折腾EA参数调优入门指南半天,终于搞明白了