MQL5 交易工具包(第 7 部分):使用最近取消的挂单函数扩展历史管理 EX5 库·综合运用
📘

MQL5 交易工具包(第 7 部分):使用最近取消的挂单函数扩展历史管理 EX5 库·综合运用

第 3/3 篇

◍ 抓取最近撤单的设置时间

在 MT5 回测或实盘里,想知道上一笔被撤掉的挂单当初是何时挂出来的,靠 LastCanceledPendingOrderTimeSetup() 就能拿到。它把最近取消挂单的 setting time 写进传入的 datetime 引用变量,成功返回 true,失败返回 false 且变量不被改动。 底层依赖是 GetLastCanceledPendingOrderData(),该函数先填一个 PendingOrderData 临时结构,再从中取 timeSetup 字段。逻辑很薄,但能让你在 EA 里对「撤单滞后时长」做统计——比如撤单距挂单超过 N 秒可能说明流动性判断偏慢。 外汇与贵金属点差跳变频繁,这类时间差只作行为分析,不构成方向判断。下面这段是完整实现,复制进 include 可直接用。

MQL5 / C++
class="type">bool LastCanceledPendingOrderTimeSetup(class="type">class="kw">datetime &lastCanceledPendingOrderTimeSetup) class="kw">export
  {
  PendingOrderData lastCanceledPendingOrderInfo;
  if(GetLastCanceledPendingOrderData(lastCanceledPendingOrderInfo))
    {
      lastCanceledPendingOrderTimeSetup = lastCanceledPendingOrderInfo.timeSetup;
      class="kw">return(true);
    }
  class="kw">return(false);
  }

「取回最近撤单的成交时刻」

在 MT5 的挂单管理逻辑里,LastCanceledPendingOrderTimeDone() 负责把『最近一笔被撤掉的挂单,到底什么时候正式撤成』这个时间点交出来。它不改写任何历史,只是读。 函数内部先调 GetLastCanceledPendingOrderData() 拿到那笔撤单的结构体;若成功,就把其中的 timeDone 字段塞进你传进来的引用变量 lastCanceledPendingOrderTimeDone,然后返回 true。若底层检索失败——比如账户历史里压根没有对应撤单记录——引用变量保持原状,函数返回 false。 想算『挂单从挂出到撤掉撑了多久』,就把这个函数和 LastCanceledPendingOrderTimeSetup() 搭着用:前者给撤单时刻,后者给挂出时刻,两个 datetime 一减就是存活时长。外汇与贵金属挂单受滑点、流动性影响,撤单时刻和实际成交价可能偏离,属高风险操作。 下面这段是完整实现,逐行看:bool 声明返回布尔,export 让别的文件也能调;函数体里先建 PendingOrderData 结构体接数据;if 里调获取函数,成功就把 info.timeDone 赋给引用变量并返回 true;失败直接落到底部 return false。

MQL5 / C++
class="type">bool LastCanceledPendingOrderTimeDone(class="type">class="kw">datetime &lastCanceledPendingOrderTimeDone) class="kw">export
  {
   PendingOrderData lastCanceledPendingOrderInfo;
   if(GetLastCanceledPendingOrderData(lastCanceledPendingOrderInfo))
     {
       lastCanceledPendingOrderTimeDone = lastCanceledPendingOrderInfo.timeDone;
       class="kw">return(true);
     }
   class="kw">return(false);
  }

抓最近撤掉的挂单到期时刻

想复盘被撤挂单的有效期,关键是拿到它原本的到期时间。LastCanceledPendingOrderExpirationTime() 干的事很单纯:把最近取消的那张挂单的 expirationTime 写进你传进来的引用变量里,成了就返 true,没拿到就返 false 且不动变量。 它内部先调 GetLastCanceledPendingOrderData() 取订单明细,成功才赋值。这样你在 EA 里只需声明一个 datetime 变量传引用,就能知道上一张撤单本来几点过期,用来统计挂单生命周期或写日志都直接可用。 下面这段是完整实现,注意参数带了 & 符号表示引用传递,调用方变量会被直接改写。外汇与贵金属挂单受点差和流动性影响,撤单行为本身不代表方向,仅作技术状态记录,交易有高风险。

MQL5 / C++
class="type">bool LastCanceledPendingOrderExpirationTime(class="type">class="kw">datetime &lastCanceledPendingOrderExpirationTime) class="kw">export
  {
   PendingOrderData lastCanceledPendingOrderInfo;
   if(GetLastCanceledPendingOrderData(lastCanceledPendingOrderInfo))
     {
      lastCanceledPendingOrderExpirationTime = lastCanceledPendingOrderInfo.expirationTime;
      class="kw">return(true);
     }
   class="kw">return(false);
  }

◍ 抓最后撤掉的挂单仓位号

在 EA 里跟踪被撤挂单的归属仓位,靠的是 LastCanceledPendingOrderPositionId() 这个函数。它接收一个 ulong 类型的引用变量,把最后取消的那张挂单对应的 positionId 写进去。 底层它先调 GetLastCanceledPendingOrderData() 拿完整撤单记录,成功就提取其中的 positionId 赋给引用变量并返回 true,失败则原变量不动、返回 false。 下面这段是完整实现,直接在 MT5 的 include 里建个 mqh 粘进去就能用。外汇与贵金属杠杆高,回测时撤单事件触发频率可能和实盘不一致,验证前先跑一周 tick 数据。

MQL5 / C++
class="type">bool LastCanceledPendingOrderPositionId(class="type">ulong &lastCanceledPendingOrderPositionId) class="kw">export
  {
   PendingOrderData lastCanceledPendingOrderInfo;
   if(GetLastCanceledPendingOrderData(lastCanceledPendingOrderInfo))
     {
       lastCanceledPendingOrderPositionId = lastCanceledPendingOrderInfo.positionId;
       class="kw">return(true);
     }
   class="kw">return(false);
  }

「抓最近撤掉的挂单幻数」

在 EA 回测或实盘里,撤单后想接着用那张挂单的幻数做后续逻辑,直接调 LastCanceledPendingOrderMagic() 就能拿到。它把最近取消挂单的幻数写进你传进去的引用变量,成功返回 true,失败返回 false 且变量不动。 底层靠 GetLastCanceledPendingOrderData() 先把整条撤单记录捞出来,再从中取 magic 字段。如果你的策略按幻数区分多套子策略,这个函数能让你在撤单事件后不断链。 下面这段是完整实现,复制进 MT5 的 include 或 mqh 里即可编译验证。

MQL5 / C++
class="type">bool LastCanceledPendingOrderMagic(class="type">ulong &lastCanceledPendingOrderMagic) class="kw">export
  {
   PendingOrderData lastCanceledPendingOrderInfo;
   if(GetLastCanceledPendingOrderData(lastCanceledPendingOrderInfo))
     {
      lastCanceledPendingOrderMagic = lastCanceledPendingOrderInfo.magic;
      class="kw">return(true);
     }
   class="kw">return(false);
  }

抓出挂单被撤的真实由头

在 MT5 里撤掉的挂单未必都是手动删除,搞清楚来源对复盘 EA 行为很有用。LastCanceledPendingOrderReason() 这个函数就是干这个的:它把最近一笔被取消挂单的 reason 代码写进你传进去的引用变量,底层靠 GetLastCanceledPendingOrderData() 先把订单明细捞出来。 reason 代码能区分下单通道与触发逻辑。ORDER_REASON_CLIENT 代表桌面端人工撤单,ORDER_REASON_EXPERT 是 EA 下的单,ORDER_REASON_WEB 来自网页端;也可能因止损、止盈或断线类事件被系统撤掉。外汇与贵金属杠杆高,这类来源混淆容易造成误判,建议实盘前先在策略测试器里跑一遍。 函数返回值是成败标志:数据拿到就写变量并返回 true,没拿到直接返回 false 且不动你的变量。下面这段是完整实现,复制进 include 文件就能用。 别把正态当圣经 reason 代码只说明「谁撤的」,不证明策略对错;用它在日志里标记来源,比凭记忆猜 EA 抽风更靠谱。

MQL5 / C++
class="type">bool LastCanceledPendingOrderReason(ENUM_ORDER_REASON &lastCanceledPendingOrderReason) class="kw">export
  {
   PendingOrderData lastCanceledPendingOrderInfo;
   if(GetLastCanceledPendingOrderData(lastCanceledPendingOrderInfo))
     {
       lastCanceledPendingOrderReason = lastCanceledPendingOrderInfo.reason;
       class="kw">return(true);
     }
   class="kw">return(false);
  }

◍ 抓最后撤销挂单的成交方式

在 MT5 的订单事件回调里,挂单被系统取消后,往往还需要知道它当初是按哪种成交规则挂的。LastCanceledPendingOrderTypeFilling() 就是干这个的:它把最后一条被撤挂单的完成类型写进你传进来的引用变量,成功返回 true,失败返回 false 且不改动原值。 完成类型直接决定价格碰线时订单怎么死。FOK 要求指定价全量成交,做不到就整单撤销;IOC 是能撮多少算多少,剩下的直接丢弃;Return 类型则允许部分成交,余额自动转成限价单挂在盘上,等手动或 EA 去消化。 函数本身不碰订单池,只调 GetLastCanceledPendingOrderData() 取结构。下面这段实现可以直接贴进 ex5 的库文件里验证:

MQL5 / C++
<span class="keyword">class="type">bool</span> LastCanceledPendingOrderTypeFilling(<span class="macro">ENUM_ORDER_TYPE_FILLING</span> &amp;lastCanceledPendingOrderTypeFilling) <span class="keyword">class="kw">export</span>
&nbsp;&nbsp;{
&nbsp;&nbsp; PendingOrderData lastCanceledPendingOrderInfo;
&nbsp;&nbsp; <span class="keyword">if</span>(GetLastCanceledPendingOrderData(lastCanceledPendingOrderInfo))
&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lastCanceledPendingOrderTypeFilling = lastCanceledPendingOrderInfo.typeFilling;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">class="kw">return</span>(<span class="macro">true</span>);
&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp; <span class="keyword">class="kw">return</span>(<span class="macro">false</span>);
&nbsp;&nbsp;}
逐行看:第 1 行定义导出函数,入参是完成类型的引用;第 3 行建一个挂单数据结构体;第 4 行尝试取最后撤单数据;第 6 行把结构里的 typeFilling 赋给外部变量;第 7 行取成功回 true;第 9 行失败回 false。外汇和贵金属杠杆高,挂单成交规则选错可能瞬间产生滑点外的额外撤单损耗,实盘前建议在策略测试器里跑一遍撤销路径。

MQL5 / C++
class="type">bool LastCanceledPendingOrderTypeFilling(ENUM_ORDER_TYPE_FILLING &lastCanceledPendingOrderTypeFilling) class="kw">export
  {
  PendingOrderData lastCanceledPendingOrderInfo;
  if(GetLastCanceledPendingOrderData(lastCanceledPendingOrderInfo))
    {
      lastCanceledPendingOrderTypeFilling = lastCanceledPendingOrderInfo.typeFilling;
      class="kw">return(true);
    }
  class="kw">return(false);
  }

「抓最近撤单的有效期类型」

在 MT5 的挂单跟踪里,最近被取消的那张单子「能活多久」是个常被忽略的维度。LastCanceledPendingOrderTypeTime() 这个函数就是把这个维度抠出来,写进你传进来的 lastCanceledPendingOrderTypeTime 引用变量里。 订单的 typeTime 本质就是有效期设定。MT5 里常见四种:GTC 一直挂到手动撤;当天有效,交易日结束就废;指定时间后过期;指定日期有效到当天 23:59:59,若不在交易时段则顺延到最近可交易时刻作废。 函数内部先调 GetLastCanceledPendingOrderData() 拿最近撤单的明细。成功就把 typeTime 赋给引用变量并返回 true,失败则变量不动、返回 false。你可以拿返回值判断「这一笔到底有没有撤单记录」。 下面这段是完整实现,注意参数用了 datetime& 引用,调用方变量会被直接改写:

MQL5 / C++
<span class="keyword">class="type">bool</span> LastCanceledPendingOrderTypeTime(<span class="keyword">class="type">class="kw">datetime</span> &amp;lastCanceledPendingOrderTypeTime) <span class="keyword">class="kw">export</span>
&nbsp;&nbsp;{
&nbsp;&nbsp; PendingOrderData lastCanceledPendingOrderInfo;
&nbsp;&nbsp; <span class="keyword">if</span>(GetLastCanceledPendingOrderData(lastCanceledPendingOrderInfo))
&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lastCanceledPendingOrderTypeTime = lastCanceledPendingOrderInfo.typeTime;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">class="kw">return</span>(<span class="macro">true</span>);
&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp; <span class="keyword">class="kw">return</span>(<span class="macro">false</span>);
&nbsp;&nbsp;}
逐行看:第 1 行定义函数,入参是 datetime 类型的引用,export 让其他 mqh/mq5 能直接调。第 3 行建了个 PendingOrderData 结构体装撤单数据。第 4 行尝试取最近撤单信息。第 6 行把结构体里的 typeTime 写进引用变量。第 7 行成功返回 true。第 9 行失败返回 false,原变量不受影响。 外汇和贵金属杠杆高、滑点突兀,撤单有效期类型会影响策略在休市段的挂单行为,建议开 MT5 用 OnTradeTransaction 抓几笔撤单跑一下这个函数验证返回逻辑。

MQL5 / C++
class="type">bool LastCanceledPendingOrderTypeTime(class="type">class="kw">datetime &lastCanceledPendingOrderTypeTime) class="kw">export
  {
   PendingOrderData lastCanceledPendingOrderInfo;
   if(GetLastCanceledPendingOrderData(lastCanceledPendingOrderInfo))
     {
      lastCanceledPendingOrderTypeTime = lastCanceledPendingOrderInfo.typeTime;
      class="kw">return(true);
     }
   class="kw">return(false);
  }

抓取最近撤单的注释内容

在 MT5 的挂单管理逻辑里,最近被取消的那张单子往往藏着撤单原因或策略标记。LastCanceledPendingOrderComment() 这个函数就是专门把那张单的注释文本捞出来,塞进你传进去的引用变量里。 它内部先调 GetLastCanceledPendingOrderData() 拿到整条撤单数据。只要这一步成功,就把结构体里的 comment 字段赋给你传的引用变量,然后返回 true;如果底层取数失败,引用变量原封不动,函数直接返回 false,调用方据此判断要不要继续处理。 下面这段是完整实现,注意参数用了 string& 引用传递,意味着函数内赋值会直接改你外部的变量,不用再靠返回值拿文本: bool LastCanceledPendingOrderComment(string &lastCanceledPendingOrderComment) export { PendingOrderData lastCanceledPendingOrderInfo; if(GetLastCanceledPendingOrderData(lastCanceledPendingOrderInfo)) { lastCanceledPendingOrderComment = lastCanceledPendingOrderInfo.comment; return(true); } return(false); } 实盘里你可以拿它做撤单日志:在 OnTradeTransaction 里捕获取消事件后调一次,把注释写进 CSV。外汇和贵金属波动快、滑点大,撤单频繁,这类注释追踪对复盘策略触发条件有帮助,但市场高风险,任何日志都不能当方向依据。

MQL5 / C++
class="type">bool LastCanceledPendingOrderComment(class="type">class="kw">string &lastCanceledPendingOrderComment) class="kw">export
  {
   PendingOrderData lastCanceledPendingOrderInfo;
   if(GetLastCanceledPendingOrderData(lastCanceledPendingOrderInfo))
     {
      lastCanceledPendingOrderComment = lastCanceledPendingOrderInfo.comment;
      class="kw">return(true);
     }
   class="kw">return(false);
  }

◍ 头文件补齐后就能直接挂进项目

这套历史管理库把查询、检索、分类和存储已成交与已撤销挂单、交易及持仓历史的操作收敛成一套结构化函数,处理复杂数据需求时不再需要反复手写底层循环。当前发布的 HistoryManager.mq5 源码 81.42 KB、编译好的 HistoryManager.ex5 二进制 33.63 KB,已包含前文所有函数,开 MT5 直接附到脚本目录就能调用。 下一步只差头文件封装,完成后最终用户 include 一下即可把库无缝接进自己的 EA 或指标,省掉重写历史统计模块的时间。外汇与贵金属市场杠杆风险高,任何历史管理工具只解决数据效率,不替代策略本身的胜率检验。 等头文件文档和实盘调用示例发出来,建议先拿 ex5 在策略测试器里跑一遍历史回放,确认订单分类逻辑和你的台账一致再集成。

常见问题

调用最近取消挂单函数里的设置时间接口,直接返回该笔挂单的下单时间,不用翻历史成交记录。
可以,用取回最近撤单成交时刻的接口,即使挂单未成交也能拿到系统记录的预设成交时间。
小布可接入你的账户数据,自动抓最近撤单的仓位号、幻数、撤单原因等,省去手动调函数排查。
用抓最近撤掉挂单到期时刻的函数,返回该单的到期时间戳,可核对是否因到点失效。
调抓最近撤掉挂单幻数的接口,传入最后撤单标识即可拿到对应幻数,定位策略来源。