轻松快捷开发 MetaTrader 程序的函数库(第五部分):交易事件集合类,向程序发送事件·进阶篇
🧩

轻松快捷开发 MetaTrader 程序的函数库(第五部分):交易事件集合类,向程序发送事件·进阶篇

(2/3)·当订单、历史事件、行情集合混在一个数组里,靠标志位区分类型只会让代码腐烂,本篇用虚方法ID根治

含代码示例偏理论 第 2/3 篇
把不同集合的对象塞进同一个 CArrayObj 再用整型标志判断类型,是 MT4/MT5 函数库最常见的架构债。一旦集合数量上来,标志位漏改一个,事件就可能被发到错误的图表对象上。

◍ 订单排序字段与事件状态枚举拆解

在 MT5 的订单容器排序逻辑里,双精度属性排序从 FIRST_ORD_DBL_PROP 基址偏移,止盈价占 +3、盈利占 +4、佣金 +5、隔夜利息 +6、交易量 +7、未执行量 +8、全利润(含佣息)+9、StopLimit 激活限价 +10;字符串属性则从 FIRST_ORD_STR_PROP 起算,品种为基址、注释 +1、外部系统订单 ID +2。 写 EA 时若要用 CTrade 或自定义数组给持仓排序,直接引用这些枚举值比手写字符串比对更稳,也避免不同 broker 点差导致的小数精度误判。 事件状态枚举 ENUM_EVENT_STATUS 把账户动作切成五类:场内仓位(开/加减/逆转)、场内挂单放置、历史挂单删除、历史仓位平仓、余额操作(出金入金及 DEAL 类事件)。回测看,同一毫秒内 EVENT_STATUS_MARKET_POSITION 与 EVENT_STATUS_BALANCE 可能连续触发,监听器里不分流就会重复统计净值。 事件原因枚举 ENUM_EVENT_REASON 目前片断只给到两个:挂单激活=0、挂单部分激活=1,说明部分成交在真实流动性薄的黄金时段(如周日开盘后 30 秒内)概率偏高,排序和事件过滤最好分开处理。

MQL5 / C++
SORT_BY_ORDER_TP                 =   FIRST_ORD_DBL_PROP+class="num">3,   class=class="str">"cmt">// 按止盈价排序
SORT_BY_ORDER_PROFIT             =   FIRST_ORD_DBL_PROP+class="num">4,   class=class="str">"cmt">// 按盈利排序
SORT_BY_ORDER_COMMISSION         =   FIRST_ORD_DBL_PROP+class="num">5,   class=class="str">"cmt">// 按佣金排序
SORT_BY_ORDER_SWAP               =   FIRST_ORD_DBL_PROP+class="num">6,   class=class="str">"cmt">// 按隔夜利息排序
SORT_BY_ORDER_VOLUME             =   FIRST_ORD_DBL_PROP+class="num">7,   class=class="str">"cmt">// 按交易量排序
SORT_BY_ORDER_VOLUME_CURRENT     =   FIRST_ORD_DBL_PROP+class="num">8,   class=class="str">"cmt">// 按未执行交易量排序
SORT_BY_ORDER_PROFIT_FULL        =   FIRST_ORD_DBL_PROP+class="num">9,   class=class="str">"cmt">// 按利润+佣金+隔夜利息标准排序
SORT_BY_ORDER_PRICE_STOP_LIMIT=   FIRST_ORD_DBL_PROP+class="num">10,   class=class="str">"cmt">// 按由 StopLimit 订单激活的限价订单排序
class=class="str">"cmt">//--- 按字符串型属性排序
SORT_BY_ORDER_SYMBOL             =   FIRST_ORD_STR_PROP,     class=class="str">"cmt">// 按品种排序
SORT_BY_ORDER_COMMENT            =   FIRST_ORD_STR_PROP+class="num">1,   class=class="str">"cmt">// 按注释排序
SORT_BY_ORDER_EXT_ID             =   FIRST_ORD_STR_PROP+class="num">2    class=class="str">"cmt">// 按外部交易系统中的订单 ID 排序
};
enum ENUM_EVENT_STATUS
  {
   EVENT_STATUS_MARKET_POSITION,                                                    class=class="str">"cmt">// 场内仓位事件(开仓,部分开仓,部分平仓,增加交易量,逆转)
   EVENT_STATUS_MARKET_PENDING,                                                     class=class="str">"cmt">// 场内挂单事件(放置)
   EVENT_STATUS_HISTORY_PENDING,                                                    class=class="str">"cmt">// 历史挂单事件(删除)
   EVENT_STATUS_HISTORY_POSITION,                                                   class=class="str">"cmt">// 历史仓位事件(平仓)
   EVENT_STATUS_BALANCE,                                                            class=class="str">"cmt">// 余额操作事件(累计余额,出金和来自 ENUM_DEAL_TYPE 枚举的事件)
   };
enum ENUM_EVENT_REASON
  {
   EVENT_REASON_ACTIVATED_PENDING           =  class="num">0,       class=class="str">"cmt">// 挂单激活
   EVENT_REASON_ACTIVATED_PENDING_PARTIALLY =  class="num">1,       class=class="str">"cmt">// 挂单部分激活

「成交事件原因枚举的数值分布」

在 MT5 的订单与成交事件回调里,EVENT_REASON 系列常量用整数标记一笔交易动作是怎么发生的。从取消、过期到完整执行、部分执行,再到 SL/TP 触发以及逆向仓位对冲,编号从 2 一路排到 13,中间 1 留空未用。 账户层面的变动另起一套偏移:从充值(14)、出金(15) 到信贷(16)、费用(17)、更正(18)、奖励(19),再到日/月佣金(21/22) 与代理日佣金(23),这批常量相对 ACCOUNT_CREDIT 事件基准做了 +13 偏移。写 EA 时若用 OnTradeTransaction 抓 reason 参数,直接比对这些枚举值就能区分平仓到底是止损打掉还是止盈落袋。 实盘里黄金和外汇品种跳空常见,挂单过期(3) 与部分执行(5/7/9) 出现频率可能高于股票品种;拿历史成交回放验证时,建议先 Print 出 reason 数值分布,确认经纪商是否复写了默认枚举。

MQL5 / C++
EVENT_REASON_CANCEL                        =  class="num">2,     class=class="str">"cmt">// 取消
EVENT_REASON_EXPIRED                      =  class="num">3,     class=class="str">"cmt">// 挂单过期
EVENT_REASON_DONE                         =  class="num">4,     class=class="str">"cmt">// 请求已完整执行
EVENT_REASON_DONE_PARTIALLY               =  class="num">5,     class=class="str">"cmt">// 请求已部分执行
EVENT_REASON_DONE_SL                      =  class="num">6,     class=class="str">"cmt">// 由止损平仓
EVENT_REASON_DONE_SL_PARTIALLY            =  class="num">7,     class=class="str">"cmt">// 由止损部分平仓
EVENT_REASON_DONE_TP                      =  class="num">8,     class=class="str">"cmt">// 由止盈平仓
EVENT_REASON_DONE_TP_PARTIALLY            =  class="num">9,     class=class="str">"cmt">// 由止盈部分平仓
EVENT_REASON_DONE_BY_POS                  =  class="num">10,    class=class="str">"cmt">// 由逆向仓位平仓
EVENT_REASON_DONE_PARTIALLY_BY_POS        =  class="num">11,    class=class="str">"cmt">// 由逆向仓位部分平仓
EVENT_REASON_DONE_BY_POS_PARTIALLY        =  class="num">12,    class=class="str">"cmt">// 由部分交易量将逆向仓位平仓
EVENT_REASON_DONE_PARTIALLY_BY_POS_PARTIALLY = class="num">13,  class=class="str">"cmt">// 由部分交易量将逆向仓位部分平仓
class=class="str">"cmt">//--- 与 ENUM_DEAL_TYPE 枚举中的 DEAL_TYPE_BALANCE 成交类型相关的常量
EVENT_REASON_BALANCE_REFILL               =  class="num">14,    class=class="str">"cmt">// 充值
EVENT_REASON_BALANCE_WITHDRAWAL           =  class="num">15,    class=class="str">"cmt">// 从账户出金
class=class="str">"cmt">//--- 常量列表与 ENUM_TRADE_EVENT 枚举中的 TRADE_EVENT_ACCOUNT_CREDIT 相关,并相对于 ENUM_DEAL_TYPE(EVENT_REASON_ACCOUNT_CREDIT-class="num">3)偏移了 +class="num">13
EVENT_REASON_ACCOUNT_CREDIT               =  class="num">16,    class=class="str">"cmt">// 积累信贷
EVENT_REASON_ACCOUNT_CHARGE               =  class="num">17,    class=class="str">"cmt">// 额外费用
EVENT_REASON_ACCOUNT_CORRECTION           =  class="num">18,    class=class="str">"cmt">// 更正账目
EVENT_REASON_ACCOUNT_BONUS                =  class="num">19,    class=class="str">"cmt">// 累积奖励
EVENT_REASON_ACCOUNT_COMISSION            =  class="num">20,    class=class="str">"cmt">// 额外佣金
EVENT_REASON_ACCOUNT_COMISSION_DAILY      =  class="num">21,    class=class="str">"cmt">// 在交易日结束时收取的佣金
EVENT_REASON_ACCOUNT_COMISSION_MONTHLY    =  class="num">22,    class=class="str">"cmt">// 在交易月结束时收取的佣金
EVENT_REASON_ACCOUNT_COMISSION_AGENT_DAILY = class="num">23,    class=class="str">"cmt">// 在交易日结束时收取的代理佣金

账户事件枚举与整数属性映射

在 MT5 的账户事件体系里,事件原因码从 24 到 30 覆盖了一组非交易类的资金变动:代理月佣金(24)、资金利息(25)、撤买(26)、撤卖(27)、红利(28)、含税红利(29)与税款(30)。写 EA 监听账户流水时,这几个值能帮你把「真成交」和「账务事件」分开处理。 宏 REASON_EVENT_SHIFT 被定义为 EVENT_REASON_ACCOUNT_CREDIT 减 3,作用是将事件原因枚举整体偏移成一个紧凑的整数区间,方便在 OnEvent 里用位运算或数组下标快速查表,而不是写一长串 if-else。 事件自身的整数型属性由 ENUM_EVENT_PROP_INTEGER 枚举给出,从 0 开始:0 是事件类型,1 是毫秒级时间,2 是状态,3 是原因码,4~5 是成交层面的类型与票据,6~11 则细化到订单与仓位的首笔/末笔关联 ID。实盘里抓 EVENT_PROP_REASON_EVENT 配合 24~30 区间,就能在日志里标出「这笔是利息而非滑点」——外汇与贵金属杠杆高,账务事件和交易事件混淆会直接导致风控误判。

MQL5 / C++
  EVENT_REASON_ACCOUNT_COMISSION_AGENT_MONTHLY =  class="num">24,       class=class="str">"cmt">// 在交易月结束时收取的代理佣金
  EVENT_REASON_ACCOUNT_INTEREST                    =  class="num">25,       class=class="str">"cmt">// 可用资金的累积利息
  EVENT_REASON_BUY_CANCELLED                        =  class="num">26,       class=class="str">"cmt">// 取消购买成交
  EVENT_REASON_SELL_CANCELLED                       =  class="num">27,       class=class="str">"cmt">// 取消卖出成交
  EVENT_REASON_DIVIDENT                             =  class="num">28,       class=class="str">"cmt">// 累积红利
  EVENT_REASON_DIVIDENT_FRANKED                     =  class="num">29,       class=class="str">"cmt">// 累积分红
  EVENT_REASON_TAX                                  =  class="num">30        class=class="str">"cmt">// 税款
  };
class="macro">#define REASON_EVENT_SHIFT(EVENT_REASON_ACCOUNT_CREDIT-class="num">3)
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| 事件的整数型属性                                                  |
class=class="str">"cmt">//+------------------------------------------------------------------+
enum ENUM_EVENT_PROP_INTEGER
  {
  EVENT_PROP_TYPE_EVENT = class="num">0,                                            class=class="str">"cmt">// 帐户交易事件类型(来自 ENUM_TRADE_EVENT 枚举)
  EVENT_PROP_TIME_EVENT,                                                class=class="str">"cmt">// 事件时间(以毫秒为单位)
  EVENT_PROP_STATUS_EVENT,                                              class=class="str">"cmt">// 事件状态(来自 ENUM_EVENT_STATUS 枚举)
  EVENT_PROP_REASON_EVENT,                                              class=class="str">"cmt">// 事件原因(来自 ENUM_EVENT_REASON 枚举)
  EVENT_PROP_TYPE_DEAL_EVENT,                                           class=class="str">"cmt">// 成交事件类型
  EVENT_PROP_TICKET_DEAL_EVENT,                                         class=class="str">"cmt">// 成交事件票据
  EVENT_PROP_TYPE_ORDER_EVENT,                                          class=class="str">"cmt">// 基于开立成交事件的订单类型(最后的开仓订单)
  EVENT_PROP_TICKET_ORDER_EVENT,                                        class=class="str">"cmt">// 基于成交开立事件的订单票据(最后的开仓订单)
  EVENT_PROP_TIME_ORDER_POSITION,                                       class=class="str">"cmt">// 基于成交开立事件的订单时间(首笔开仓订单)
  EVENT_PROP_TYPE_ORDER_POSITION,                                       class=class="str">"cmt">// 基于成交开立事件的订单类型(首笔开仓订单)
  EVENT_PROP_TICKET_ORDER_POSITION,                                     class=class="str">"cmt">// 基于成交开立事件的订单票据(首笔开仓订单)
  EVENT_PROP_POSITION_ID                                                class=class="str">"cmt">// 仓位 ID

◍ 事件属性的三段式枚举拆解

在 MT5 自建事件监控器时,事件属性被硬拆成整数、实数、字符串三类枚举,分别用 ENUM_EVENT_PROP_INTEGER、ENUM_EVENT_PROP_DOUBLE、ENUM_EVENT_PROP_STRING 承载。整数段以 EVENT_PROP_POSITION_BY_ID 收尾,宏 EVENT_PROP_INTEGER_TOTAL 定为 14,意味着前 14 个属性槽全留给整型字段。 实数段从 EVENT_PROP_PRICE_EVENT 起步,其枚举值直接挂接在整数总数 14 上,所以首个双精度属性编号是 14 而非 0。该段覆盖开平价格、SL/TP、三档成交量及盈利,宏 EVENT_PROP_DOUBLE_TOTAL 标为 9,实数属性共占 9 个槽。 字符串段极简,仅 EVENT_PROP_SYMBOL 一项,枚举值 = 14 + 9 = 23,宏 EVENT_PROP_STRING_TOTAL 为 1。排序时可用 FIRST_EVN_DBL_PROP(14) 与 FIRST_EVN_STR_PROP(23) 快速切到对应段,避免手写魔法数字。外汇与贵金属事件回放请留意点差跳变导致 SL/TP 价格属性可能偏离预期,属高风险验证项。

MQL5 / C++
  EVENT_PROP_POSITION_BY_ID,                                                    class=class="str">"cmt">// 逆向仓位 ID
  EVENT_PROP_MAGIC_ORDER,                                                        class=class="str">"cmt">// 订单/成交/仓位的魔幻数字
  };
class="macro">#define EVENT_PROP_INTEGER_TOTAL(class="num">14)                                            class=class="str">"cmt">// 整数型事件属性的总数
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| 事件的实数型属性                                                                |
class=class="str">"cmt">//+------------------------------------------------------------------+
enum ENUM_EVENT_PROP_DOUBLE
  {
  EVENT_PROP_PRICE_EVENT = (EVENT_PROP_INTEGER_TOTAL),                           class=class="str">"cmt">// 事件发生的价格所在
  EVENT_PROP_PRICE_OPEN,                                                         class=class="str">"cmt">// 订单/成交/仓位开立价格
  EVENT_PROP_PRICE_CLOSE,                                                        class=class="str">"cmt">// 订单/成交/仓位平仓价格
  EVENT_PROP_PRICE_SL,                                                           class=class="str">"cmt">// 订单/成交/仓位止损价格
  EVENT_PROP_PRICE_TP,                                                           class=class="str">"cmt">// 订单/成交/仓位止盈价格
  EVENT_PROP_VOLUME_INITIAL,                                                     class=class="str">"cmt">// 请求的交易量
  EVENT_PROP_VOLUME_EXECUTED,                                                    class=class="str">"cmt">// 执行的交易量
  EVENT_PROP_VOLUME_CURRENT,                                                     class=class="str">"cmt">// 剩余的交易量
  EVENT_PROP_PROFIT                                                              class=class="str">"cmt">// 盈利
  };
class="macro">#define EVENT_PROP_DOUBLE_TOTAL(class="num">9)                                             class=class="str">"cmt">// 事件的实数型属性总数
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| 事件的字符串型属性                                                              |
class=class="str">"cmt">//+------------------------------------------------------------------+
enum ENUM_EVENT_PROP_STRING
  {
  EVENT_PROP_SYMBOL = (EVENT_PROP_INTEGER_TOTAL+EVENT_PROP_DOUBLE_TOTAL),        class=class="str">"cmt">// 订单品种
  };
class="macro">#define EVENT_PROP_STRING_TOTAL(class="num">1)                                           class=class="str">"cmt">// 事件的字符串型属性总数
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| 可能的事件排序标准                                                              |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="macro">#define FIRST_EVN_DBL_PROP(EVENT_PROP_INTEGER_TOTAL)
class="macro">#define FIRST_EVN_STR_PROP(EVENT_PROP_INTEGER_TOTAL+EVENT_PROP_DOUBLE_TOTAL)
enum ENUM_SORT_EVENTS_MODE
  {
  class=class="str">"cmt">//--- 按整数型属性排序

「事件排序枚举的字段映射」

在 MT5 的历史事件检索接口里,排序方向由一组枚举常量决定,从 0 到 13 覆盖了事件类型、时间、状态、原因以及订单/成交/仓位的关联标识。比如 SORT_BY_EVENT_TIME_EVENT=1 是按事件时间排,SORT_BY_EVENT_MAGIC_ORDER=12 则是按魔幻数字把 EA 自己的痕迹挑出来。 实数型属性从 FIRST_EVN_DBL_PROP 开始偏移,SORT_BY_EVENT_PRICE_EVENT 对应该基值,之后每加 1 就是一种价格或成交量维度:开仓价、平仓价、SL、TP、初始量、当前量、剩余量,直到 SORT_BY_EVENT_PROFIT 落在 FIRST_EVN_DBL_PROP+8,直接按盈亏给事件排队。 写回测或做账户诊断时,若想快速抽取某魔幻数字下的首笔开仓,可用 SORT_BY_EVENT_TYPE_ORDER_POSITION=7 配合 SORT_BY_EVENT_TICKET_ORDER_POSITION=9;外汇与贵金属杠杆高,这类排序只帮你看清已发生结构,不预示后续波动。

MQL5 / C++
  SORT_BY_EVENT_TYPE_EVENT                 = class="num">0,                class=class="str">"cmt">// 按事件类型排序
  SORT_BY_EVENT_TIME_EVENT                 = class="num">1,                class=class="str">"cmt">// 按事件时间排序
  SORT_BY_EVENT_STATUS_EVENT              = class="num">2,                class=class="str">"cmt">// 按事件状态排序 (来自 ENUM_EVENT_STATUS 枚举)
  SORT_BY_EVENT_REASON_EVENT              = class="num">3,                class=class="str">"cmt">// 按事件原因排序 (来自 ENUM_EVENT_REASON 枚举)
  SORT_BY_EVENT_TYPE_DEAL_EVENT           = class="num">4,                class=class="str">"cmt">// 按成交事件类型排序
  SORT_BY_EVENT_TICKET_DEAL_EVENT         = class="num">5,                class=class="str">"cmt">// 按成交事件票据排序
  SORT_BY_EVENT_TYPE_ORDER_EVENT          = class="num">6,                class=class="str">"cmt">// 根据成交开立事件的订单类型排序(最后的开仓订单)
  SORT_BY_EVENT_TYPE_ORDER_POSITION       = class="num">7,                class=class="str">"cmt">// 根据成交开立事件的订单类型排序(首笔开仓订单)
  SORT_BY_EVENT_TICKET_ORDER_EVENT        = class="num">8,                class=class="str">"cmt">// 根据成交开立事件的订单票据排序(最后的开仓订单)
  SORT_BY_EVENT_TICKET_ORDER_POSITION     = class="num">9,                class=class="str">"cmt">// 根据成交开立事件的订单票据排序(首笔开仓订单)
  SORT_BY_EVENT_POSITION_ID               = class="num">10,               class=class="str">"cmt">// 按仓位 ID 排序
  SORT_BY_EVENT_POSITION_BY_ID            = class="num">11,               class=class="str">"cmt">// 按逆向仓位 ID 排序
  SORT_BY_EVENT_MAGIC_ORDER              = class="num">12,               class=class="str">"cmt">// 按订单/成交/仓位魔幻数字排序
  SORT_BY_EVENT_TIME_ORDER_POSITION       = class="num">13,               class=class="str">"cmt">// 根据成交开立事件的订单时间排序(首笔开仓订单)
  class=class="str">"cmt">//--- 按实数型属性排序
  SORT_BY_EVENT_PRICE_EVENT               =  FIRST_EVN_DBL_PROP,    class=class="str">"cmt">// 按事件发生时的价格排序
  SORT_BY_EVENT_PRICE_OPEN                =  FIRST_EVN_DBL_PROP+class="num">1,  class=class="str">"cmt">// 按开仓价排序
  SORT_BY_EVENT_PRICE_CLOSE               =  FIRST_EVN_DBL_PROP+class="num">2,  class=class="str">"cmt">// 按平仓价排序
  SORT_BY_EVENT_PRICE_SL                  =  FIRST_EVN_DBL_PROP+class="num">3,  class=class="str">"cmt">// 按仓位止损价排序
  SORT_BY_EVENT_PRICE_TP                  =  FIRST_EVN_DBL_PROP+class="num">4,  class=class="str">"cmt">// 按仓位止盈价排序
  SORT_BY_EVENT_VOLUME_INITIAL            =  FIRST_EVN_DBL_PROP+class="num">5,  class=class="str">"cmt">// 按仓位初始交易量排序
  SORT_BY_EVENT_VOLUME                    =  FIRST_EVN_DBL_PROP+class="num">6,  class=class="str">"cmt">// 按仓位当前交易量排序
  SORT_BY_EVENT_VOLUME_CURRENT            =  FIRST_EVN_DBL_PROP+class="num">7,  class=class="str">"cmt">// 按仓位剩余交易量排序
  SORT_BY_EVENT_PROFIT                    =  FIRST_EVN_DBL_PROP+class="num">8,  class=class="str">"cmt">// 按盈利排序
  class=class="str">"cmt">//--- 按字符串型属性排序

给订单类型配上可读的中文标签

在 MT5 的 EA 或脚本里直接打印 ENUM_ORDER_TYPE 数值,日志里只是一串整数,排查挂单异常时很不直观。下面这段函数把 13 种常见订单类型映射成字符串,MQL5 环境下市价单前缀为 "Market order",MQL4 则退化为 "Position"。 函数用预编译宏 __MQL5__ 区分环境:MQL5 多出 BUY_STOP_LIMIT、SELL_STOP_LIMIT、CLOSE_BY 三类,MQL4 则补 BALANCE、CREDIT 操作类型。实际跑起来,若收到一笔 ORDER_TYPE_SELL_STOP_LIMIT,返回文本就是 "Sell Stop Limit",比看枚举值快得多。 外汇与贵金属杠杆高,挂单类型识别错可能引发非预期平仓,建议在回测和实盘前先用 Print(OrderTypeDescription(type)) 自验一遍输出。

MQL5 / C++
class="type">class="kw">string OrderTypeDescription(const ENUM_ORDER_TYPE type)
  {
   class="type">class="kw">string pref=(class="macro">#ifdef __MQL5__ "Market order" class="macro">#else "Position" class="macro">#endif );
   class="kw">return
     (
       type==ORDER_TYPE_BUY_LIMIT      ?  "Buy Limit"             :
       type==ORDER_TYPE_BUY_STOP       ?  "Buy Stop"             :
       type==ORDER_TYPE_SELL_LIMIT     ?  "Sell Limit"           :
       type==ORDER_TYPE_SELL_STOP      ?  "Sell Stop"            :
     class="macro">#ifdef __MQL5__
       type==ORDER_TYPE_BUY_STOP_LIMIT ?  "Buy Stop Limit"       :
       type==ORDER_TYPE_SELL_STOP_LIMIT?  "Sell Stop Limit"      :
       type==ORDER_TYPE_CLOSE_BY       ?  TextByLanguage("Закрывающий ордер","Order for closing by") :
     class="macro">#else
       type==ORDER_TYPE_BALANCE        ?  TextByLanguage("Балансовая операция","Balance operation") :
       type==ORDER_TYPE_CREDIT         ?  TextByLanguage("Кредитная операция","Credit operation")   :
     class="macro">#endif
       type==ORDER_TYPE_BUY            ?  pref+" Buy"             :
把类型识别交给小布盯盘辅助阅读
这些关于集合归属和虚方法重载的判定逻辑,小布盯盘的 AIGC 已内置代码脉络视图,打开对应 EA 源码页即可看到类继承与事件流向标注,你专注决策而非翻头文件。

常见问题

标志位需要调用方时刻记清,且编译器无法校验。用 CArrayObj 派生类重载 Type() 返回唯一 ID,可在方法内用虚方法自识别,避免额外参数和误传。
各集合只持有本类对象,包含路径随物理结构清晰化,后续新增市场事件或历史集合时不会污染订单类的编译单元。
在保有数组能力的同时,可挂载返回完整集合列表指针的方法,使引擎对象能按所属集合精确反向定位,不必遍历全局标志。
可以,小布盯盘对 MT5 程序结构做了静态分析,能标出事件类从集合到 Engine 基准对象的传递路径,省去手动追 include。
Order.mqh、HistoryCollection.mqh、MarketCollection.mqh 里的 include 相对地址需随文件夹迁移同步替换,Select.mqh 移到 Services 后引用路径也要改。