Simulink: EA 交易开发人员指南·综合运用
📘

Simulink: EA 交易开发人员指南·综合运用

第 3/3 篇

市价卖单的 MQL5 结构填法

在 MT5 里用 EA 下市价卖单,核心是把 MqlTradeRequest 的各字段填对,再交给 OrderSend 执行。下面这段是实盘里能直接抄的卖单请求骨架。 mrequest.action 设成 TRADE_ACTION_DEAL 表示立即成交;type 用 ORDER_TYPE_SELL 明确方向为卖。price 取 latest_price.bid 并 NormalizeDouble 到 _Digits 精度,避免报价小数位不匹配被拒。 sl 放在 ask 上方 STP*_Point 处,tp 放在 ask 下方 TKP*_Point 处——注意卖单止损在卖价之上、止盈在之下,跟买单正好反过来。type_filling 用 ORDER_FILLING_FOK 意味着要么按指定量全部成交、要么不成交,deviation 设 100 点容忍滑点。 OrderSend 之后必须查 retcode:10009(已完成)或 10008(已接受)都算下单成功,其他值要用 GetLastError 抓原因并 return 中断,否则后续逻辑可能基于假仓位跑。外汇与贵金属杠杆高,这类市价单在跳空时可能触发远超 deviation 的成交价,回测之外务必在模拟盘验证。

MQL5 / C++
mrequest.action = TRADE_ACTION_DEAL;                                                                     class=class="str">"cmt">// 市价卖
mrequest.price = NormalizeDouble(latest_price.bid,_Digits);                                                  class=class="str">"cmt">// 最近的卖价
mrequest.sl = NormalizeDouble(latest_price.ask + STP*_Point,_Digits);  class=class="str">"cmt">// 设置止损
mrequest.tp = NormalizeDouble(latest_price.ask - TKP*_Point,_Digits); class=class="str">"cmt">// 设置获利
mrequest.symbol = _Symbol;                                                                                    class=class="str">"cmt">// 交易品种
mrequest.volume = Lot;                                                                                        class=class="str">"cmt">// 交易量
mrequest.magic = EA_Magic;                                                                                    class=class="str">"cmt">// EA的编号
mrequest.type= ORDER_TYPE_SELL;                                                                               class=class="str">"cmt">// 卖单
mrequest.type_filling = ORDER_FILLING_FOK;                                                                    class=class="str">"cmt">// 指定交易量,
class=class="str">"cmt">// 且对某一价格来说,不差于订单中指定的
mrequest.deviation=class="num">100;                                                                                       class=class="str">"cmt">// 滑点
OrderSend(mrequest,mresult);
if(mresult.retcode==class="num">10009 || mresult.retcode==class="num">10008) class=class="str">"cmt">// 请求完成或者成功下单
   {
    Alert("A sell order placed, ticket #:",mresult.order);
   }
else
   {
    Alert("A sell order is not placed; error:",GetLastError());
    class="kw">return;
   }

◍ 可视化建模与手写代码的边界

以一个简单的交易理念做样本,作者在 Simulink 里搭出自动化系统的方框图,并跑了一轮历史数据的事后检验。起初有个疑问很现实:既然用 MQL5 几行代码就能落地一套系统,何必绕去可视化建模? 答案落在人群差异上。跳过图形化逻辑直接写代码,通常只有老练程序员或天赋型选手能稳稳搞定;一旦系统叠了新的条件与函数,方框图就把“交易者在想什么”摊开成可追踪的任务链,降低认知负担。 这里没有要拉踩 Simulink 与 MQL5 的意思。核心只是演示:用一个代码块设计思路,你也能拼出可跑的 EA;往后 MQL5 生态若出官方可视策略构造器,写 EA 的门槛还会再降。 附带工程文件里,mts.mq5 体积 16.83 KB、testclose.mq5 为 6.91 KB、matlab.zip 压缩包 28.68 KB,在 MT5 里直接编译 mts.mq5 即可验证主逻辑;有用户反馈 testclose.mq5 编译出 8 次警告且止损止盈参数表现一致,建议自查告警后再上模拟盘。外汇与贵金属杠杆交易高风险,回测顺滑不代表实盘概率占优。

「把 Simulink 模型接进 MT5 的坑」

论坛里有人提到错误码 4756 相关讨论,但更实际的卡点在 MATLAB/Simulink 往 MT5 搬策略。Christian 在 2017 年用 Matlab 2016b 重建了两组 InputBus(open、ema21、ema55、num 四个信号)和两组 OutputBus(其余 10 个信号),信号不存 Simulink 文件而是落工作区,这一步不做就跑不起来。 他实测只能通过 Embedded Coder 出 DLL,直连 Visual Studio 通信不稳定:有的机器 VS 能加载项目,有的直接崩。外汇和贵金属策略这样接进去后,回测结果仅代表历史样本,实盘仍属高风险,参数漂移可能让信号失效。 下面这段是原文里 EMA 双线平滑的 MATLAB 写法,对应 MT5 里 iMA 的 21/55 周期指数均值,可照着核对缓冲区逻辑。 [ema21, ema55] = movavg(close, 21, 55, 'e'); [ema21, ema55] = gltDurch(schließen, 21, 55, 'e');

MQL5 / C++
[ema21, ema55] = movavg(close, class="num">21, class="num">55, &class="macro">#x27;e&class="macro">#x27;);
[ema21, ema55] = gltDurch(schließen, class="num">21, class="num">55, &class="macro">#x27;e&class="macro">#x27;);

常见问题

最易错的是请求类型字段和填充方式字段,必须显式设为市价卖与即时成交,否则会被终端拒绝。建议对照官方结构示例逐字段核对。
不能。可视化适合理清信号流,但仓位管理与异常分支仍要手写,边界在于模型生成代码可读性差且难调试。
可以。小布能读取你的结构填法和信号链路,标出未处理的市场关闭、滑点超限等坑,并给出改法建议。
常见是数据类型不匹配与采样周期冲突,模型输出双精度而终端要整型时会直接报错,需加转换层。
贵金属高风险,点差扩大时即时成交可能部分填充,需预设填充策略并监控回报代码,避免漏单。