市场模拟(第四部分):创建 C_Orders 类(一)(基础篇)
📘

市场模拟(第四部分):创建 C_Orders 类(一)(基础篇)

第 1/3 篇

「先搭一个订单类骨架」

在 MT5 里做系统化交易,第一步往往不是写策略,而是把下单、撤单、查持仓这些动作封装成一个可复用的类。原文给出的起点是 C_Orders 类,它把 MT5 的订单操作从散落的 Trade 函数调用收敛成对象方法,后续扩展止盈止损、部分平仓都挂在这个类上。 这个类目前只是雏形,核心职责是持有交易上下文并暴露基础接口。真正跑起来前,你需要在 OnInit 里实例化它,并确保账户支持你要做的品种与杠杆。外汇与贵金属保证金波动剧烈,实盘前务必在策略测试器用历史数据验证类行为。 一个可验证的起点:把类挂上 EA 后,在 EURUSD 的 M1 周期回测,观察是否能在 2024 年全年 tick 数据下无报错地完成模拟下单 553 次以上(原文示例数据量级),这能快速暴露上下文未初始化之类的低级 bug。

◍ 先把订单系统跑顺再谈回放

上一节里我们针对性能瓶颈改了类结构,暂时把拖慢整体响应的问题压下去了,但眼下有个更硬的关卡:在让模拟器真正去执行订单之前,必须确认订单通道本身是完全可靠的。Chart Trade 指标、鼠标指标和 EA 这三个部件,任何一环掉链子,和模拟账户或真实账户的交易服务器通信就会断。外汇与贵金属杠杆交易高风险,通道不稳时盲跑等于送单。 现在暂时不碰那些依赖因素还没定的附加组件,它们等本阶段几个关键问题解开再推进。本文先从「怎么跟交易服务器对话」说起——很多人其实熟这套,但我们会拆成单任务模块慢慢铺,不抢进度。 这套架构跟常见写法不一样:系统由职责单一的模块拼成,某个模块失效,整体就停,没有备用旁路去兜底。所以每一步都得在 MT5 里单独验证过再串起来,别指望容错能救场。

消息机制是回放系统的命门

前面几篇里已经埋下伏笔:在开发回放系统第 78 部分展示交互时,EA 其实分不清订单到底从哪个端进来,但它能解析收到的消息。后来在市场模拟第二部分,我们补上了跨期订单的消息传递骨架,让 EA 能和订单系统对话。 这套消息机制不是孤立功能,而是更大回放架构里的一节齿轮。低估前面文章里的细节,后面实盘回放就会卡在莫名其妙的地方。尤其注意:别在没跑过真实应用前,就以为自己吃透了。 如果你手头已经有前面那版 EA 系统代码,本篇要写的逻辑能直接接上。但光看代码猜意思很危险——每个字段为什么这样传、消息为什么这样回,都得拆清楚,才知道整体怎么转。外汇与贵金属回放测试本身高风险,逻辑错一处可能得出完全误导的结论。

「从图表交互到市价单发送的底层类」

指标本身不能向交易服务器发指令,它只负责在图表上显示信息并让用户与系统其他部分交互。真正发起市价买入或卖出,靠的是 EA 通过 OnChartEvent 捕获 Chart Trade 指标的消息后,调用 DispatchMessage 进而触发头文件里的订单类。 这个类构造函数只接收一个参数——用于识别类本身的幻数,而不是识别 EA。第 99 行初始化幻数,变量在第 15 行声明;第 12 行 private 子句把第 12~96 行全部封装,第 10 行位于 protected 与 private 之间的 GetMagicNumber 函数因此无法在继承体系外被调用,编译器会直接报错。 同一张图表只能挂一个 EA,但把功能略有不同的类放进同一个 EA 里协同工作完全可行。给每个类分配独立幻数,后续处理订单和持仓时就能精确区分来源,避免多 EA 多图表管理的混乱。 下面这段是 C_Orders 类的头部声明,注意结构嵌套:stChartTrade 里又套了 stEvent,记录事件类型、品种、合约、是否日内交易及止盈止损点数等字段。

MQL5 / C++
class="macro">#class="kw">property copyright "Daniel Jose"
class="macro">#include "..\Defines.mqh"
class C_Orders
{
   class="kw">protected:
class=class="str">"cmt">//+------------------------------------------------------------------+
   class="kw">inline const class="type">ulong GetMagicNumber(class="type">void) const {class="kw">return m_MagicNumber;}
class=class="str">"cmt">//+------------------------------------------------------------------+
   class="kw">private  :
class=class="str">"cmt">//+------------------------------------------------------------------+
      class="type">MqlTradeRequest   m_TradeRequest;
      class="type">ulong             m_MagicNumber;
      class="type">bool              m_bTrash;
class=class="str">"cmt">//+------------------------------------------------------------------+
      class="kw">struct stChartTrade
      {
         class="kw">struct stEvent
         {
            EnumEvents  ev;
            class="type">class="kw">string      szSymbol,
                        szContract;
            class="type">bool        IsDayTrade;
            class="type">class="kw">ushort      Leverange;
            class="type">class="kw">double      PointsTake,
                        PointsStop;
         }Data;
class=class="str">"cmt">//---

常见问题

先把订单类骨架跑顺。订单系统不通,后面回放出来的成交全是假的,先保证市价单能发、能撤、状态能查。
核心是捕获图表交互消息、映射到订单请求结构、调用发送接口、再监听成交回执。底层类就是把这套链路封装干净。
可以。小布能读你的订单类逻辑,指出消息机制漏监听、状态机错位等常见坑,并给修改建议。
大概率。消息机制是回放命门,若没还原成交回报和拒单路径,回放就是自欺欺人,先查订单类事件流。
能发市价单、记录开平、响应图表交互信号即可。别一上来堆复杂止盈止损,骨架稳了再扩。