MT5 и скорость в боевом исполнении - страница 30

 
Renat Fatkhullin:

один синхронизирующийся объект базы символов. Read / Write локи перемешаны, так как постоянно идет запись тиков.

Один объект базы символов сразу на все символы? Если так, то получается, что запрос тика по EURUSD потенциально тормозит запрос тика по GBPUSD.


Можете к моменту вызова OnTick подготовить для него MqlTick, чтобы его не запрашивать из базы на общих основаниях?

 
fxsaber:

Можете к моменту вызова OnTick подготовить для него MqlTick, чтобы его не запрашивать из базы на общих основаниях?

было бы неплохо, тогда возможно в MQL5 появятся предопределенные переменные как было в 4-ке - Ask и Bid

 

Скорее всего, тормоза вызваны большим потреблением CPU со стороны MT5, когда запущенно много советников. Не знаю, как с этим у MT4. Иначе сложно объяснить, почему лаги появляются в параллельно запущенном пустом Терминале.

Однозначно, сведение к минимуму использование API торгового окружения, решит проблему. После плясок с бубнами отпишусь о результатах.

 
fxsaber:

Не правильно поняли. Каждый советник является исключительно торговым (в Тестере по реальным тикам не тормозит) и не зависит от других. Вся торговая логика выполняется только в OnTick, не спамит торговыми ордерами, без рекурсий, без глобалок и ресурсов.

OnTrade*, OnBook - не используются. Секундный таймер и OnChartEvent на случай нажатия определенных клавиш.


Уверен, что грамотная реализация (с вашей или моей стороны) снепшотов поможет очень сильно снизить количество вызовов штатных функций окружения. Соответственно, лаги значительно уменьшатся.

Никак не думал, что дойдет до снепшот-ухищрений. Изучаю вопрос, т.к. стандартная реализация MT5-советника хромает, к сожалению.

Вообще не верится в ваш кейс.

Мы показали свои расчеты
 
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 держит в памяти 128К тиков. Они мне не нужны совсем, но в памяти лежат - пусть. На что почти 1.5 GB уходит? Разработчики могут посмотреть у себя, какая часть памяти на что расходуется? Какой-нибудь примитивный Диспетчер задач.

 
fxsaber:

Скорее всего, тормоза вызваны большим потреблением CPU со стороны MT5, когда запущенно много советников. Не знаю, как с этим у MT4. Иначе сложно объяснить, почему лаги появляются в параллельно запущенном пустом Терминале.

Однозначно, сведение к минимуму использование API торгового окружения, решит проблему. После плясок с бубнами отпишусь о результатах.

Именно об этом и говорил несколько страниц назад. Причем советники могут быть совсем простыми и на неликвидных символах, то есть дело не в количестве математических операций, происходящих внутри кода каждого из советников. Проблема кроется в самом терминале и нам ее улучшением своего кода не побороть. К сожалению :(

P.S Переписал логику, используемую в половине своих советников, c OnBook обратно на OnTick, заменил Core i5 на Xeon E5-2678. Казалось бы скорость должна увеличится, но увы, чуда не произошло :(

 
Тормоза 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.


Надеюсь, сборка кеша не занимает столько времени, и этот лаг связан с обращением к БД во время ее обновления.

 

Any idea why mt5 does not feature the 'Commissions' tab? They only pop up after a trade is closed.

Есть идеи, почему в mt5 нет вкладки «Комиссии»? Они появляются только после закрытия сделки.

 

Если запустить этот советник на счете, где нет текущих позиций и ордеров.

// Создает маркет-ордер в случае, если нет текущих позиций и ордеров.
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();
}

и затем закрыть руками открытую советником позицию, то появятся три открытые позиции на хедже (на неттинге позиция тройного объема).


Это правильное поведение? Скорее всего, неверно понимаю работу Терминала. Тогда прошу пояснить.