MT5和速度在行动

 

MT5是一个灵活的平台。但有一些瓶颈,否定了所有快速交易的努力。

我想在这里收集问题,讨论并解决它们,在我自己的努力下,在开发者的帮助下,在某个地方。

 

HistorySelect.


这是一个极其昂贵的功能。而且,不幸的是,现在无论多少缓存都无法使其速度变得可以接受。


例如,在战场上,用实际的数据工作是很重要的。特别是,如果可能的话,来自Market Watch和CopyTicks的ticks没有过期。

要做到这一点,没有很好的,但被迫的机制来检查当前价格数据的相关性。这个机制的一部分是检测一个符号上的交易比最后一个tick晚的情况。这种情况并不罕见,因此了解当前的蜱虫是否仍然是最新的,这一点很重要。


为了进行这种检测,你需要能够访问最近交易的历史。它是通过使用HistorySelect以如下示意方式完成的。

void OnTick()
{
  MqlTick Tick;

  if (SymbolInfo(_Symbol, Tick) && HistorySelect(Tick.time, INT_MAX)) // Взяли история торгов со времени текущего тика.
    // Проверяем актуальность тика через сравнение Tick.time_msc и DEAL_TIME_MSC.
}


不幸的是,调用HistorySelect需要5-30毫秒(我在Release-EX5中亲自测量过)。 当Expert Advisor在OnTick中进行几次这样的更新时(应该在任何暂停后进行,例如,在每次OrderSend后。例如,在每次OrderSend.)之后,一切都变得异常昂贵/漫长。HistorySelect可以在一次OnTick中集体吃掉几秒钟。


亲爱的开发商,为什么这么贵?通过适当的实施,这个功能可以立即执行。


请考虑引入这样的功能来处理历史问题。

HistoryDealsSelect( const int Index, const int Count = WHOLE_ARRAY );  // Из внутренней таблицы сделок взять сделки, начиная с заданного индекса в таблице.
HistoryOrdersSelect( const int Index, const int Count = WHOLE_ARRAY ); // Из внутренней таблицы ордеров взять ордера, начиная с заданного индекса в таблице.

他们将完全关闭HistorySelect的刹车。因为这将解决非常便宜地获得最新交易的问题。现在,它是战斗执行中的一种煎熬。


并不总是能够通过OnTradeTransaction 来控制最后的交易。 因此,快速处理历史的工作是很紧迫的。

 

访问ChartEvent和TradeTransaction事件。


已经提出了一个想法和一个可能的实施方案。所以我只是在这里复制它。

关于交易、自动交易系统和交易策略测试的论坛

错误、漏洞、问题

Sergey Dzyublik, 2020.05.20 00:47

对开发者的建议。
请考虑在MQL中添加一个函数,允许用户从自定义代码中独立调用OnChartEvent中的累积 "消息 "的处理。
1)这将允许在耗时计算的迭代之间调用OnChartEvent处理,使用户GUI至少有一定的响应,而不需要构建一个菜园子:任务池、数据传输、状态同步、上下文保存和恢复。
2) 这将允许在脚本中使用OnChartEvent。

谢谢。

关于交易、自动交易系统和交易策略测试的论坛

虫子,虫子,问题

Sergey Dzyublik, 2020.05.20 13:39

不完全是,我宁愿把这个函数称为HandleNextEvent,这是一个可能的签名。

bool HandleNextEvent (ENUM_EVENT_TYPE);


当被调用时,类似于GetNextEvent,它检查指定的ENUM_EVENT_TYPE是否存在于队列中,
,如果此事件存在,它自动将控制权传递给相应处理程序的用户代码(OnChartEvent, OnTrade, OnTradeTransaction, ...(感谢fxsaber 的 补充))。
如果队列中有一个事件,则返回 true,否则返回 false。


可能的用例。

//....
for(int i = 0; i < 10^6; ++i){
   // .... Data Calculations

   if((i % 10^3) == 0){
       while(HandleNextEvent(EVENT_TYPE_ALL));
   }
}
//....

关于交易、自动交易系统和交易策略测试的论坛

错误, 漏洞, 问题

Sergey Dzyublik, 2020.05.20 14:38

2)这就对了。如果我对某一特定事件的处理感兴趣,而不是对系统中的所有事件感兴趣,那么最好是能够只处理这种类型的事件,而将其他事件的处理留在常规模式下。
3) 如果HandleNextEvent在处理过程中被再次调用--调用并处理。唯一可能发生的是堆栈溢出,但这是用户和代码的问题,不是开发者的问题。
4) 不属于过滤器的事件仍然在同一序列中,当用户将控制权返回给系统时,将像往常一样被调用。


现在,我们必须制作拐杖,以便在运行的代码中获得相同的TradeTransaction-events。

专家顾问的战斗应用真的需要这个功能。

 
fxsaber:

通过 OnTradeTransaction监测最近的交易并不总是可能的 。 因此,快速的历史工作是相关的

请举例说明什么时候无法控制?

 
prostotrader:

请给我举一个没有控制的例子?

关于交易、自动交易系统和交易策略测试的论坛

mql5的特殊性,技巧和窍门

fxsaber, 2020.04.23 19:51

MT5实时自动放置的开仓/平仓箭头是基于TradeTransaction事件的。


我刚刚看到,这些事件(开仓和平仓约十几个仓位)没有到达终端,因为一时的连接中断--这太巧了,我坐在电脑前,亲眼看着它们。因此,没有相应的箭头。


而且,正如有时在这里所说的,你不能在战斗的EA中依赖OnTradeTransaction。很遗憾,没有可靠的公共机制来处理OrderSendAsync。


还有,当几个OrderSend被放置在代码中时。当一个OrderSend依赖于前一个OrderSend时。

 
fxsaber:

另外,在代码内放置多个OrderSend时。当一个OrderSend依赖于前一个OrderSend时。

如果通信中断,也不会有任何东西被添加到历史记录中!

我已经使用OrderSendAsync 超过5年了(那时OrderSend也有问题)+OnTradeTransaction() 只是在战斗模式下使用--没有问题!我已经使用了5年。

如果出现连接中断,则由分配给每个订单的向导发现(在外汇交易中很难做到这一点,因为符号名称没有标准化)。

Документация по MQL5: Основы языка / Функции / Функции обработки событий
Документация по MQL5: Основы языка / Функции / Функции обработки событий
  • www.mql5.com
В языке MQL5 предусмотрена обработка некоторых предопределенных событий. Функции для обработки этих событий должны быть определены в программе MQL5: имя функции, тип возвращаемого значения, состав параметров (если они есть) и их типы должны строго соответствовать описанию функции-обработчика события. Именно по типу возвращаемого значения и по...
 
prostotrader:

如果通信中断,也不会有任何东西被添加到历史记录中!

我已经使用OrderSendAsync 超过5年了(那时OrderSend也有问题)+OnTradeTransaction() 只是在战斗模式下使用--没有问题!我已经使用了5年。

你不能不注意到,你已经在Async+OnTrade中沉淀了多年。你通过这个机制做数据实化,其余的都是,因为没有问题。

请不要在这里说 "你就是不会做饭",至少是这样。

 
fxsaber:

你不能不注意到,多年来你一直在推动Async+OnTrade的发展。你也通过这个机制做数据更新和其他一切,因为没有问题。

请至少不要在这里声称 "你就是不会做饭"。

你在为微秒而 "战斗",同时你在写大量的代码,这也会耗费时间。

而且99%的时间你都不需要它。

 
我鼓励你只以建设性的方式发表意见。
 
fxsaber:

访问ChartEvent和TradeTransaction事件。

已经提出了一个想法和一个可能的实施方案。所以我只是把它复制到这里。

现在,为了在运行的代码中访问这些TradeTransaction-events,我们必须使用拐杖

你在错误的方向上制作拐杖。

在OnXXX函数中只留下复制队列中的事件(参数)和调用主OnMain函数。将他们的所有代码移到重复的On2XX函数中。并从OnMain中按你需要的顺序调用这些重复的On2XX函数,依次将队列中的数据作为参数传递给它们。

然后运行测量并显示速度的提高,然后你可以建议用适当的功能来补充MQL。但是,如果你已经在这里和现在自己做了一切,为什么还要加呢?

 
A100:

留下的OnXXX函数只是将事件(参数)复制到队列中,并调用主OnMain函数。将所有代码移至重复的On2XX功能。并从OnMain中按你需要的顺序调用这些重复的On2XX函数,依次将队列中的数据作为参数传递给它们。

请给我一个这个想法的基本方案代码。乍听起来,这完全是一种误解。

在执行OnMain函数时,没有办法知道当前真实队列的状态。要做到这一点,唯一的解决办法是使用链接中给出的间谍软件。