伟大而可怕的MT4永远(或如何制定过渡策略) - 页 13

 
JRandomTrader:

以下是文件中的内容。

"这些交易到达终端的顺序是不保证的,所以你不能把你的交易算法建立在等待一些交易在其他交易到达后才到达。" https://www.mql5.com/ru/docs/event_handlers/ontradetransaction

而根据经验,TRADE_TRANSACTION_ORDER_DELETETRADE_TRANSACTION_DEAL_ADDTRADE_TRANSACTION_HISTORY_ADD 交易可以按任何顺序到达

因此,我们有这样的情况:历史上还没有交易或秩序,但秩序已经存在。或者反过来说,订单还在那里,但交易已经执行了。但是,当秩序存在于积极的,以及历史中的时候,这种情况就很难出现了。

我不抓事件,我在新的蜱虫上看全貌。


JRandomTrader:

事实上,这就是为什么我一直拒绝使用 CTrade 类--它正踩着所有这些陷阱。

我有一个解决方案--每个EA都保留一个其订单的列表,并监控其状态。这包括 "非标准 "状态--"订单已发送但尚未出现在活动订单中"(这是他们可能重复的地方),"订单已删除但未出现在历史中"。这也有助于织网时在同一个符号上同时工作。

直到最近,我还在使用一个通用的拐杖,它能检查出缺失的订单。但在某些时候,它开始失效了。

我在专家顾问中又增加了一个个人拐杖,现在它可以单独监控自己的订单。

那是一个很大的拐杖...

 
Andrey Khatimlianskii:

那是一个很大的拐杖...

研究这个问题。我甚至遇到了这样的情况:OrderSend market order true,那么PositionsTotal= 0,OrdersTotal = 0,历史表格不变。

似乎已经成功地编写了IsSynchronized()。这段代码有点重。还没有决定以何种形式发布。

 
// Демонстрация открытия дубля позиции в MT5.

#include <Trade\Trade.mqh>

void OnStart()
{
  CTrade Trade;
  
  while (!IsStopped() && (PositionsTotal() <= 1)) // Закончим, когда появится более одной позиции.
    if (PositionsTotal() == 1)
      Trade.PositionClose(PositionGetTicket(0)); // Если есть позиция - закрываем.
    else if (!OrdersTotal())
      Trade.Buy(0.01); // Если нет позиции и ордера - открываем позицию.
}

在一个空的模拟账户上运行这段代码,看看几秒钟后是否有两个仓位打开。


同样的逻辑在MT4上看起来是这样的。

void OnStart()
{
  while (!IsStopped() && (OrdersTotal() <= 1)) // Закончим, когда появится более одной позиции.
    if (OrderSelect(0, SELECT_BY_POS))
      OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0) // Если есть позиция - закрываем.
    else
      OrderSend(_Symbol, OP_BUY, 0.01, Ask, 0, 0, 0) // Если нет позиции и ордера - открываем позицию.
}

很明显,MT4上的这种代码不会导致仓位逆转。但在MT5上不是。

 
fxsaber:

在一个空的模拟账户上运行这段代码,看看几秒钟后是否有两个仓位打开。


同样的逻辑在MT4上看起来是这样的。

很明显,MT4上的这种代码不会导致仓位逆转。但在MT5上不是。

最后,你是否刚刚发现?这个问题和终端本身一样古老。但最终终端用户注意到了它...十年后。

当你自己执行交易动作时,可以用一个简单的方法来解决这个问题--在执行完动作后插入Sleep() 一秒钟。但当EA使用止损/止盈和市场收盘时,就有可能遇到这个问题,在这种情况下,没有解决办法。

 
Dmitry Fedoseev:

最后!你刚刚发现这个吗?这个问题和终端本身一样古老。但终端用户终于注意到了它...十年后。

这个问题已经讨论了很久了。几乎每个人都遇到过这种情况。这是第一次有稳定的代码再现它。

当你自己执行一个交易动作时,你可以用一个简单的方法来解决这个问题--在执行动作后插入Sleep() 一秒钟。但是,当在EA中使用止损/堆积利润和市场收盘时,就有可能遇到这个问题,而且在这种情况下没有解决方案。

解决办法已经找到。

 
fxsaber:

在一个空的模拟账户上运行这段代码,看看几秒钟后是否有两个仓位打开。

很奇怪。它没有繁殖。在MQ的演示中进行了检查,构建2900,欧元兑美元,零点差。等了大约5分钟。

也许我需要使用真正的DC/经纪商的某些特定服务器,而不是MQ服务器?

 
Ihor Herasko:

很奇怪。它没有繁殖。在MQ的演示中进行了检查,构建2900,欧元兑美元,零点差。等了大约5分钟。

也许我需要使用真正的DC/经纪商的某些特定服务器,而不是MQ服务器?

ForexTimeFXTM-Demo01

 
fxsaber:

ForexTimeFXTM-Demo01

是的,现在脚本停止了。但仍有一个职位空缺。我想第二个人有时间关闭?

 
Ihor Herasko:

是的,现在脚本停止了。但仍有一个职位空缺。第二个必须有时间来关闭?

我总是剩下两个。如果留下一个,那就更是一个错误了。

  1. PositionsTotal= 1 - 发出平仓指令。
  2. 然后PositionsTotal=2,从第1点开始的订单被关闭。
 
fxsaber:

我总是剩下两个。如果留下一个,那就是一个更大的错误。

  1. PositionsTotal= 1 - 发出平仓指令。
  2. 然后PositionsTotal=2,从第1点开始的订单被关闭。

是的,这就是我的意思。结果发现,脚本设法关闭了其中一个头寸,而实际上有两个头寸,但PositionsTotal()返回1。然后,在关闭之后,循环终止的条件得到满足,即PositionsTotal()返回2。