MQL5 交易工具包(第 7 部分):使用最近取消的挂单函数扩展历史管理 EX5 库·综合运用
◍ 抓取最近撤单的设置时间
在 MT5 回测或实盘里,想知道上一笔被撤掉的挂单当初是何时挂出来的,靠 LastCanceledPendingOrderTimeSetup() 就能拿到。它把最近取消挂单的 setting time 写进传入的 datetime 引用变量,成功返回 true,失败返回 false 且变量不被改动。 底层依赖是 GetLastCanceledPendingOrderData(),该函数先填一个 PendingOrderData 临时结构,再从中取 timeSetup 字段。逻辑很薄,但能让你在 EA 里对「撤单滞后时长」做统计——比如撤单距挂单超过 N 秒可能说明流动性判断偏慢。 外汇与贵金属点差跳变频繁,这类时间差只作行为分析,不构成方向判断。下面这段是完整实现,复制进 include 可直接用。
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。
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 变量传引用,就能知道上一张撤单本来几点过期,用来统计挂单生命周期或写日志都直接可用。 下面这段是完整实现,注意参数带了 & 符号表示引用传递,调用方变量会被直接改写。外汇与贵金属挂单受点差和流动性影响,撤单行为本身不代表方向,仅作技术状态记录,交易有高风险。
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 数据。
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 里即可编译验证。
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 抽风更靠谱。
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 的库文件里验证:
<span class="keyword">class="type">bool</span> LastCanceledPendingOrderTypeFilling(<span class="macro">ENUM_ORDER_TYPE_FILLING</span> &lastCanceledPendingOrderTypeFilling) <span class="keyword">class="kw">export</span> { PendingOrderData lastCanceledPendingOrderInfo; <span class="keyword">if</span>(GetLastCanceledPendingOrderData(lastCanceledPendingOrderInfo)) { lastCanceledPendingOrderTypeFilling = lastCanceledPendingOrderInfo.typeFilling; <span class="keyword">class="kw">return</span>(<span class="macro">true</span>); } <span class="keyword">class="kw">return</span>(<span class="macro">false</span>); }
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& 引用,调用方变量会被直接改写:
<span class="keyword">class="type">bool</span> LastCanceledPendingOrderTypeTime(<span class="keyword">class="type">class="kw">datetime</span> &lastCanceledPendingOrderTypeTime) <span class="keyword">class="kw">export</span> { PendingOrderData lastCanceledPendingOrderInfo; <span class="keyword">if</span>(GetLastCanceledPendingOrderData(lastCanceledPendingOrderInfo)) { lastCanceledPendingOrderTypeTime = lastCanceledPendingOrderInfo.typeTime; <span class="keyword">class="kw">return</span>(<span class="macro">true</span>); } <span class="keyword">class="kw">return</span>(<span class="macro">false</span>); }
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。外汇和贵金属波动快、滑点大,撤单频繁,这类注释追踪对复盘策略触发条件有帮助,但市场高风险,任何日志都不能当方向依据。
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 在策略测试器里跑一遍历史回放,确认订单分类逻辑和你的台账一致再集成。