如何解决设计错误的 OrderSendAsync() - 函数 [mql5]

How to work-around the misdesigned OrderSendAsync() -function [mql5]

背景: 只要您从不使用 OrderSendAsync() 函数,而是始终使用 OrderSend() 函数,就没有问题。

但是如果您想加快速度并使用 OrderSendAsync() 函数,则会出现问题:在 OrderSendAsync() 函数 returns 时,服务器尚未处理您的订单。而且,这就是 OrderSendAsync() 函数存在的全部意义所在!这意味着由于服务器尚未处理您的订单,因此 ulong 票 也尚未分配。

因此,无法匹配使用 OrderSendAsync() 函数发送的订单和作为这些订单的结果完成的交易。

许多其他 MQL5 函数采用 ulong ticket 参数,例如 CTrade 方法 PositionClose:

bool PositionClose(const ulong ticket,const ulong deviation=ULONG_MAX);

这种困境正是许多商业文件有两个字段的原因:"Our reference" 和 "Your reference"。

OrderSendAsync() 函数确实应该这样设计,它有 "Customer's reference" 作为输入字段,然后 MQL5 应该包含一个辅助函数,它将 "Customer's reference" 作为输入, 并给出 "Broker's reference" 作为结果。

不幸的是,MetaQuotes 公司。错过了这个细节,使得 OrderSendAsync() 函数不如应有的有用。

我将提出一个可能的解决方案来解决这个问题,但同时我想问一下:有没有人想出更好的解决方案来解决同样的问题。

可能的解决方案: 以不同于最初设计用途的方式使用 64 位魔法值:

MqlTradeRequest 结构(OrderSendAsync 的参数)包含此字段: ulong magic; // Expert Advisor ID (magic number)

仅使用此魔法的高 32 位作为 "Expert Advisor ID"。 然后用这个魔法的低32位作为"Customer reference".

不幸的是,这意味着 CTrade -class 需要大量的重新设计,因为它不是将幻数用作单个 64 位整数,而是用作容器对于两个单独的 32 位整数。

因此,虽然上述可能是解决此问题的一种可能方法:

有没有人想出更好的解决方案来解决同样的问题?

问题是您是否需要以某种方式存储所有 ulong's

如果不是(例如,在某些情况下需要关闭所有购买而不管任何其他条件)- 简单地循环打开交易并关闭相应的交易(通过魔法、交易品种、方向等过滤)似乎是一个很简单的解决方案。

如果需要保留未平仓交易的数据(例如,附加入场、初始止损、初始跟踪、移动到盈亏平衡的水平等)- 我会使用 MqlTradeRequest.comment 发送异步请求然后在 OnTradeTransaction(..) 中捕获结果以创建 CDeal : public CObject,其中包含所有必要的数据,如 MqlTradeResult.deal 和评论以进行匹配。