MT5和速度在行动 - 页 30

 
Renat Fatkhullin:

一个同步的符号数据库对象。读取/写入机车是混在一起的,因为有一个持续的勾选写入。

是否有一个符号数据库对象同时适用于所有符号?如果是这样,那么事实证明,对欧元兑美元的tick请求可能会减缓对英镑兑美元的tick请求。


你能在调用OnTick的时候为它准备一个MqlTick,这样它就不会在一般的基础上从数据库中被请求?

 
fxsaber:

你能为OnTick准备一个MqlTick,这样它就不会在一般的基础上被数据库调用?

这将是一件好事,然后也许MQL5将有预定义的变量,就像在4中 - 要价和出价一样。

 

最有可能的是,当许多EA 运行时,MT5方面的CPU消耗很高,导致速度变慢。不知道MT4的情况如何。否则就很难解释为什么在一个平行运行的空终端中会出现滞后。

肯定的是,尽量减少对交易环境API的使用将解决这个问题。在手鼓舞之后,我将报告结果。

 
fxsaber:

你搞错了。每个EA都是纯粹的交易(在测试器中通过真实的ticks不放慢速度),不依赖其他。所有的交易逻辑只在OnTick中执行,没有垃圾交易订单,没有递归,没有全球化,没有资源。

不使用OnTrade*, OnBook。第二个定时器和OnChartEvent用于某些键被按下时的情况。


我确信,适当地实现(由你或我)快照将大大减少对常规环境函数的调用。相应地,滞后性也将大幅降低。

我从来没有想到会有快照这一招。我正在研究这个问题,因为不幸的是,标准MT5 EA的实现是蹩脚的。

我完全不能相信你的案子。

我们展示了我们的计算结果
 
Renat Fatkhullin:
我完全不相信你的情况。

通过TeamViewer或类似软件,准备演示。

 
::TerminalInfoInteger(TERMINAL_BUILD) = 2605
(bool)::TerminalInfoInteger(TERMINAL_X64) = true
(bool)::TerminalInfoInteger(TERMINAL_VPS) = false
::HistoryDealsTotal() = 13973
::HistoryOrdersTotal() = 18606
::TerminalInfoInteger(TERMINAL_MAXBARS) = 5000
::TerminalInfoInteger(TERMINAL_MEMORY_USED) = 1464
::MQLInfoInteger(MQL_MEMORY_USED) = 5
::ObjectsTotal(0) = 462
ChartsTotal = 16
::SymbolsTotal(true) = 19 (16 + 3)

请告知如何减少终端的内存消耗?我使用的是CopyTicks的16个字符的新鲜刻度线。看起来,每个CopyTicks在内存中保留了128K的刻度。我根本不需要它们,但我把它们留在记忆中。它需要将近1.5GB的空间吗?开发人员能否看到内存的哪一部分被用于什么?一些简陋的任务管理器。

 
fxsaber:

最有可能的是,当许多EA运行时,MT5方面的CPU消耗很高,导致速度变慢。不 知道MT4的情况如何。否则就很难解释为什么在平行运行的空终端中出现滞后。

肯定的是,尽量减少对交易环境API的使用将解决这个问题。我将写下用手鼓跳舞后的结果。

这正是我在几页前说的。此外,EA可以很简单,并且基于非液体符号,也就是说,问题不在于每个EA的代码中发生的数学运算的数量。问题在于终端本身,我们将无法通过改进我们的代码来解决它。不幸的是 :(

P.S 我已经重写了我一半的EA中使用的 逻辑,从OnBook 回到OnTick,并且用Xeon E5-2678替换了Core i5。似乎速度应该增加,但可惜的是,奇迹并没有发生:(

 
HistorySelect在OnTrade函数中滞后。
// Демонстрация лага HistorySelect в OnTrade*-функциях.
#include <fxsaber\Benchmark.mqh> // https://c.mql5.com/3/321/Benchmark.mqh

input int inAlertTime = 1; // Нижний порог в миллисекундах

#define _B2(A) _B(A, inAlertTime)

const bool Init = EventSetTimer(1);

void OnTimer()
{
  static MqlTradeRequest Request = {0};
  static MqlTradeResult Result = {0};

  if (PositionSelectByTicket(Result.order)) // Если позиция открыта - закрываем.
  {
    Request.type = ORDER_TYPE_SELL;
    Request.price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
    Request.position = Result.order;
  }
  else // Иначе - открываем.
  {
    Request.action = TRADE_ACTION_DEAL;
    Request.type = ORDER_TYPE_BUY;
    Request.symbol = _Symbol;
    Request.volume = 0.1;
    Request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
    Request.position = 0;
  }

  const bool AntiWarning = OrderSendAsync(Request, Result); // Асинхронный приказ не случайно
}

void OnTrade()
{
  _B2(HistorySelect(0, INT_MAX));  
}


几乎每一步都是如此。

2020.09.23 11:59:46.351 Alert: Time[Test6.mq5 437: HistorySelect(0,INT_MAX)] = 3 ms.
2020.09.23 11:59:46.354 Alert: Time[Test6.mq5 437: HistorySelect(0,INT_MAX)] = 2 ms.
2020.09.23 11:59:48.294 Alert: Time[Test6.mq5 437: HistorySelect(0,INT_MAX)] = 4 ms.
2020.09.23 11:59:48.296 Alert: Time[Test6.mq5 437: HistorySelect(0,INT_MAX)] = 2 ms.
2020.09.23 11:59:49.283 Alert: Time[Test6.mq5 437: HistorySelect(0,INT_MAX)] = 4 ms.
2020.09.23 11:59:49.285 Alert: Time[Test6.mq5 437: HistorySelect(0,INT_MAX)] = 2 ms.
2020.09.23 11:59:50.296 Alert: Time[Test6.mq5 437: HistorySelect(0,INT_MAX)] = 4 ms.
2020.09.23 11:59:50.302 Alert: Time[Test6.mq5 437: HistorySelect(0,INT_MAX)] = 5 ms.
2020.09.23 11:59:51.275 Alert: Time[Test6.mq5 437: HistorySelect(0,INT_MAX)] = 4 ms.
2020.09.23 11:59:51.277 Alert: Time[Test6.mq5 437: HistorySelect(0,INT_MAX)] = 2 ms.
2020.09.23 11:59:52.267 Alert: Time[Test6.mq5 437: HistorySelect(0,INT_MAX)] = 4 ms.
2020.09.23 11:59:52.269 Alert: Time[Test6.mq5 437: HistorySelect(0,INT_MAX)] = 2 ms.
2020.09.23 11:59:54.277 Alert: Time[Test6.mq5 437: HistorySelect(0,INT_MAX)] = 3 ms.
2020.09.23 11:59:54.282 Alert: Time[Test6.mq5 437: HistorySelect(0,INT_MAX)] = 5 ms.


希望缓存构建不需要这么长时间,这种滞后是由于数据库更新时的数据库访问造成的。

 

知道为什么mt5没有 "佣金 "选项卡吗?它们只在交易结束后弹出。

知道为什么mt5没有 "佣金 "选项卡吗?它们只在交易结束后弹出。

 

如果你在一个没有当前头寸或订单的账户上运行这个EA。

// Создает маркет-ордер в случае, если нет текущих позиций и ордеров.
bool PositionOpen()
{
  bool Res = (!PositionsTotal() && !OrdersTotal());
  
  if (Res)
  {
    MqlTradeRequest Request = {0};
    MqlTradeResult Result;
    
    Request.action = TRADE_ACTION_DEAL;
    Request.symbol = _Symbol;
    Request.volume = 0.1;
    Request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
    
    Res = OrderSendAsync(Request, Result);    
  }
  
  return(Res);
}

void OnInit()
{
  PositionOpen();
}

void OnTrade()
{
  PositionOpen();
}

然后手动关闭EA所开的头寸,那么在对冲上就会有三个未结头寸(在净值三倍量头寸上)。


这是正确的行为吗?我可能没有正确理解 "终端"。那么请解释一下。