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

 
fxsaber:

Оказывается, частое явление. Торговые функции не вызывал.

SymbolInfoTick нехило иногда тормозит. HFT может оказаться очень опысным с такими неожиданным лагами.

Просьба к Разработчикам найти причины. Пока же становится очевидным, что в боевых советниках свой профайлер - обязательная вещь.

Что покажет тест на "пустом" терминале?

void OnStart()
  {
   MqlTick Tick;
//---
   ulong start,end,max_time=0,avr_time=0;
   int   count=100000;
   for(int i=0; i<count; i++)
     {
      start=GetMicrosecondCount();
      SymbolInfoTick(_Symbol, Tick);
      end=GetMicrosecondCount()-start;
      //--- >1 ms
      if(end>1000)
         Print(" > 1 ms for one SymbolInfoTick: ",DoubleToString(end/1000.0,2)," ms");
      //---
      if(end>max_time)
         max_time=end;
      avr_time+=end;
     }
   Print("SymbolInfoTick max time: ",DoubleToString(max_time/1000.0,3)," ms; avr time: ",DoubleToString(avr_time/1000.0/count,3)," ms; ",count," iterations");
//---
   start=GetMicrosecondCount();
   for(int i=0; i<count; i++)
      SymbolInfoTick(_Symbol, Tick);
   end=GetMicrosecondCount()-start;
   Print(count," SymbolInfoTick = ",DoubleToString(end/1000.0,2)," ms");
  }

Должно быть примерно так:

2020.06.04 11:02:30.123 TestSymbolInfoTick (EURUSD,H1)  SymbolInfoTick max time: 0.138 ms; avr time: 0.000 ms; 100000 iterations
2020.06.04 11:02:30.138 TestSymbolInfoTick (EURUSD,H1)  100000 SymbolInfoTick = 14.85 ms
2020.06.04 11:02:31.433 TestSymbolInfoTick (EURUSD,H1)  SymbolInfoTick max time: 0.051 ms; avr time: 0.000 ms; 100000 iterations
2020.06.04 11:02:31.448 TestSymbolInfoTick (EURUSD,H1)  100000 SymbolInfoTick = 15.17 ms
2020.06.04 11:02:33.064 TestSymbolInfoTick (EURUSD,H1)  SymbolInfoTick max time: 0.035 ms; avr time: 0.000 ms; 100000 iterations
2020.06.04 11:02:33.079 TestSymbolInfoTick (EURUSD,H1)  100000 SymbolInfoTick = 15.12 ms

Если детально не рассказываете что вы делаете, как именно вы создаете нагрузку на терминал, то нам будет сложно найти причины.

 
Anton:

Что покажет тест на "пустом" терминале?

Должно быть примерно так:

        SymbolInfoTick max time: 0.034 ms; avr time: 0.000 ms; 100000 iterations
        100000 SymbolInfoTick = 8.56 ms
        SymbolInfoTick max time: 0.047 ms; avr time: 0.000 ms; 100000 iterations
        100000 SymbolInfoTick = 9.04 ms
        SymbolInfoTick max time: 0.045 ms; avr time: 0.000 ms; 100000 iterations
        100000 SymbolInfoTick = 9.02 ms

Если детально не рассказываете что вы делаете, как именно вы создаете нагрузку на терминал, то нам будет сложно найти причины.

100K итераций - не показатель. Т.к. функция тормозит не всегда, а иногда.

Фактически мне надо отключать куски боевого советника до тех пор, пока не прекратятся тормоза. Тогда смогу предоставить код. Надо подождать.

 
fxsaber:

Фактически мне надо отключать куски боевого советника до тех пор, пока не прекратятся тормоза. Тогда смогу предоставить код. Надо подождать.

Для быстрого получения результата запустить этот советник на нескольких символах.

#include <fxsaber\Benchmark.mqh> // https://c.mql5.com/3/321/Benchmark.mqh

void OnTick()
{
  MqlTick Tick[1];
  
  if (_B(CopyTicks(_Symbol, Tick, COPY_TICKS_ALL, 0, 1), 1)) // Не знаю, влияет это или нет.
    _B(SymbolInfoTick(_Symbol, Tick[0]), 1);
}


За пять минут получил.

        Alert: Time[Test6.mq5 8: SymbolInfoTick(_Symbol,Tick[0])] = 9 ms.
        Alert: Time[Test6.mq5 8: SymbolInfoTick(_Symbol,Tick[0])] = 3 ms.
        Alert: Time[Test6.mq5 8: SymbolInfoTick(_Symbol,Tick[0])] = 4 ms.
        Alert: Time[Test6.mq5 8: SymbolInfoTick(_Symbol,Tick[0])] = 1 ms.
        Alert: Time[Test6.mq5 8: SymbolInfoTick(_Symbol,Tick[0])] = 2 ms.
        Alert: Time[Test6.mq5 8: SymbolInfoTick(_Symbol,Tick[0])] = 5 ms.
        Alert: Time[Test6.mq5 8: SymbolInfoTick(_Symbol,Tick[0])] = 2 ms.
        Alert: Time[Test6.mq5 8: SymbolInfoTick(_Symbol,Tick[0])] = 1 ms.
        Alert: Time[Test6.mq5 8: SymbolInfoTick(_Symbol,Tick[0])] = 16 ms.
        Alert: Time[Test6.mq5 8: SymbolInfoTick(_Symbol,Tick[0])] = 16 ms.


Похоже, достаточно оставить только это (без CopyTicks) в советнике.

    _B(SymbolInfoTick(_Symbol, Tick[0]), 1);
 
fxsaber:

100K итераций - не показатель. Т.к. функция тормозит не всегда, а иногда.

Предлагаю изменить концепцию определения быстроты функции.

Функция быстрая, если нет пиков длительности ее выполнения.


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


Нужно добиться, чтобы пиков не было хотя бы на пустом Терминале. Быстрые 100К итераций, как оказалось, - ни о чем.

 
fxsaber:

Предлагаю изменить концепцию определения быстроты функции.

Функция быстрая, если нет пиков длительности ее выполнения.


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


Нужно добиться, чтобы пиков не было хотя бы на пустом Терминале. Быстрые 100К итераций, как оказалось, - ни о чем.

Иногда бывает что таймер показывает совокупный объем времени если запущена другая задача. К примеру такое бывает при работе с канвасом - при отображении функция ставит задачу на отображения не создавая изображения и возвращаеться. Далее выполняется любая другая функция которая идет обязательно последовательно - к примеру тот же комент, однако на языке проца начинает проиходить процес отображения канваса и только после отображение комента. И при измерении тайминга можно увидеть что комент очень долго выводиться. а вот функция отображения канваса сработала за 0 мс.

 
fxsaber:

запускаем и мониторим пики больше миллисекунды в течение пары часов.

Нужно добиться, чтобы пиков не было хотя бы на пустом Терминале. Быстрые 100К итераций, как оказалось, - ни о чем.

Набросал такой советник-мониторинг.

// Мониторинг длительных пиков выполнения важных функций для торговли.
#include <fxsaber\Benchmark.mqh> // https://c.mql5.com/3/321/Benchmark.mqh

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

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

void Check( const string Symb, const int AlertTime = 1 )
{
  MqlTick Tick;
  
  if (_B2(SymbolInfoTick(Symb, Tick)))
  {
    MqlTick Ticks[];
    
    _B2(CopyTicks(Symb, Ticks, COPY_TICKS_ALL, 0, 1));
    _B2(CopyTicks(Symb, Ticks, COPY_TICKS_ALL, Tick.time_msc));
    _B2(CopyTicksRange(Symb, Ticks, COPY_TICKS_ALL, Tick.time_msc));

    _B2(HistorySelect(Tick.time, INT_MAX));
    
    _B2(HistoryDealsTotal());
    _B2(HistoryDealGetTicket(0));
    _B2(HistoryDealGetInteger(0, DEAL_MAGIC));
    _B2(HistoryDealGetDouble(0, DEAL_PRICE));
    _B2(HistoryDealSelect(0));

    _B2(HistoryOrdersTotal());
    _B2(HistoryOrderGetTicket(0));
    _B2(HistoryOrderGetInteger(0, ORDER_MAGIC));
    _B2(HistoryOrderGetDouble(0, ORDER_PRICE_CURRENT));
    _B2(HistoryOrderSelect(0));
    
    _B2(GetLastError());
    _B2(IsStopped());
    
    _B2(SymbolInfoDouble(Symb, SYMBOL_ASK));
    _B2(SymbolInfoDouble(Symb, SYMBOL_TRADE_TICK_VALUE));
    _B2(SymbolInfoDouble(Symb, SYMBOL_POINT));
    _B2(SymbolInfoInteger(Symb, SYMBOL_DIGITS));

    _B2(TimeCurrent());
    _B2(TimeLocal());
    _B2(TimeTradeServer());
    
    _B2(OrdersTotal());
    _B2(OrderSelect(0));
    _B2(OrderGetDouble(ORDER_PRICE_CURRENT));
    _B2(OrderGetInteger(ORDER_MAGIC));
    _B2(OrderGetString(ORDER_SYMBOL));
    
    _B2(PositionsTotal());
    _B2(PositionSelect(Symb));
    _B2(PositionSelectByTicket(0));
    _B2(PositionGetDouble(POSITION_PRICE_CURRENT));
    _B2(PositionGetInteger(POSITION_MAGIC));
    _B2(PositionGetString(POSITION_SYMBOL));
    
    _B2(AccountInfoDouble(ACCOUNT_EQUITY));
    _B2(AccountInfoInteger(ACCOUNT_MARGIN_MODE));
    
    MqlTradeRequest Request = {0};
    MqlTradeCheckResult CheckResult;

    _B2(OrderCheck(Request, CheckResult));
    
    _B2(MQLInfoInteger(MQL_TRADE_ALLOWED));
    _B2(AccountInfoInteger(ACCOUNT_TRADE_EXPERT));
    _B2(AccountInfoInteger(ACCOUNT_TRADE_ALLOWED));
    _B2(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED));
    
    _B2(SymbolsTotal(true));
    _B2(SymbolName(0, true));
    _B2(Symbol());
    
    _B2(GlobalVariableCheck(NULL));
    _B2(GlobalVariableGet(NULL));
    
    _B2(ResourceFree(NULL));
  }
}

void OnTick()
{
  for (int i = 0; i < inCycle; i++)
    Check(_Symbol, inAlertTime);
}


Результат за пять минут мониторинга.

        Alert: Time[Test6.mq5 18: HistorySelect(Tick.time,INT_MAX)] = 21 ms.
        Alert: Time[Test6.mq5 24: HistoryDealSelect(0)] = 4 ms.
        Alert: Time[Test6.mq5 10: SymbolInfoTick(Symb,Tick)] = 24 ms.
        Alert: Time[Test6.mq5 14: CopyTicks(Symb,Ticks,COPY_TICKS_ALL,0,1)] = 4 ms.
        Alert: Time[Test6.mq5 30: HistoryOrderSelect(0)] = 3 ms.
        Alert: Time[Test6.mq5 35: SymbolInfoDouble(Symb,SYMBOL_ASK)] = 2 ms.


ЗЫ При таком значении входного параметра алертов гораздо меньше.

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


Но и результат показательнее.

        Alert: Time[Test6.mq5 21: HistorySelect(Tick.time,INT_MAX)] = 19 ms.
        Alert: Time[Test6.mq5 21: HistorySelect(Tick.time,INT_MAX)] = 10 ms.
        Alert: Time[Test6.mq5 38: SymbolInfoDouble(Symb,SYMBOL_ASK)] = 10 ms.
        Alert: Time[Test6.mq5 13: SymbolInfoTick(Symb,Tick)] = 10 ms.
        Alert: Time[Test6.mq5 38: SymbolInfoDouble(Symb,SYMBOL_ASK)] = 10 ms.
        Alert: Time[Test6.mq5 17: CopyTicks(Symb,Ticks,COPY_TICKS_ALL,0,1)] = 148 ms.
        Alert: Time[Test6.mq5 74: SymbolName(0,true)] = 11 ms.
 

Наконец, у меня модификация пачки ордеров иногда занимает по 3-10 секунд на каждый ордер. После чего снова долгое время по 0.1 секунды.

Поднимали логи сервера - там мгновенно.


На боевом советнике очень неприятно.

2020.06.04 15:24:48.771 Alert: Time[NewTicks.mqh 31: ::SymbolInfoTick(_Symbol,Tick)] = 61 ms.
2020.06.04 15:25:21.729 Alert: Time[NewTicks.mqh 31: ::SymbolInfoTick(_Symbol,Tick)] = 29 ms.
2020.06.04 15:27:57.842 Alert: Time[NewTicks.mqh 31: ::SymbolInfoTick(_Symbol,Tick)] = 142 ms.


Какие-то фантастические значения.

 
fxsaber:

Наконец, у меня модификация пачки ордеров иногда занимает по 3-10 секунд на каждый ордер. После чего снова долгое время по 0.1 секунды.

Поднимали логи сервера - там мгновенно.

Ситуация повторилась на другом торговом сервере.

Терминал модифицировал тейк открытой позиции 2.5 секунды. На сервере - 2 миллисекунды.

Скорее всего, и отсюда растут ноги проблем с ФОРТС-исполнением.

ФОРТС. Вопросы по исполнению
ФОРТС. Вопросы по исполнению
  • 2020.03.30
  • www.mql5.com
С большими проблемами удалось это сделать (начальник отдела по работе с профессиональными клиентами ДЦ Открытие Евгений Сергеевич,.
 

Ретрансмиты.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Бета-версия платформы MetaTrader 5 build 1700: Проекты в MetaEditor и синтетические инструменты

Renat Fatkhullin, 2017.12.14 12:47

Это показатель качества связи. Процент повторно отправляемых сетевых пакетов в TCP/IP протоколе.

Считается глобально на уровне сетевого интерфейса для всех приложений всей операционки. Когда есть подозрения на тормоза и проблемы, смотрите этот показатель. Критически важно, когда сервер брокера очень далеко. Например, для азиатских трейдеров и брокером в Европе.

Уже при 3% ретрансмитов можно сказать, что торговать нельзя. Запредельный уровень ретрансмитов дает плохой вайфай.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Новая версия платформы MetaTrader 5 build 2360: Расширение интеграции с SQLite

Renat Fatkhullin, 2020.04.06 12:33

Норма должна быть меньше 1%. И уже 3% сетевых потерь убивают low latency сервисы.

Например, у нас ретрансмиты 0.68 - 0.75% при заведомо бОльшем количестве пользователей (сейчас 17к в онлайне на MetaQuotes-Demo) . Причем мы обслуживаем весь мир, а не Москву/Россию.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

Renat Fatkhullin, 2017.12.17 23:03

Это статистика сетевого интерфейса всего компьютера, где Метатрейдер лишь один из пользователей. Не обязательно это связано с торговым сервером.

Общую статистику легко испортить веб-броузером после неудачного обращения на какой-то глючащий и далекий сайт. А можно и локальным вайфаем словить сетевой конфликт и получить десятки процентов ретрансмитов в случайные моменты времени.

При 20% ретрансмиттов в принципе не будет поддерживаться связь с торговым сервером, реконнекты будут постоянными и бесконечными. У терминала постоянное соединение и для него(для TCP/IP вернее) даже 3-5% ретрансмитов фатальны в задаче удержания долгих коннектов.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

Renat Fatkhullin, 2017.12.18 11:36

Учтите, что это техническая характеристика вашего локального TCP/IP стека, репорт о котором дает операционка, а не показатель качества конкретного соединения к торговым серверам. В него входит вся сетевая активность, включая системную/фоновую.


У торгового кластера заведомо связь качественная и мы штатно протоколируем массу параметров (это штатный функционал платформы), собирая минутные снапшоты с последующим анализом.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

Renat Fatkhullin, 2017.12.18 00:13

Проверил.

Ни на одном узле нашего демо-кластера, включая Азию, не было рестартов или повышения уровня ретрансмитов за весь день (да и в другие дни тоже). Все в норме от 0.5% до 1.5%.


Похоже, у меня очень много.

Сейчас полночь, котиры редко обновляются. Ретрансмиты увеличиваются на глазах. Хочется на VPS поставить Алерт на высокое значение > 1% для low latency торговли. Но с такими огромными значениями эта идея становится бессмысленной.


Что можно порекомендовать? Делать tracert до торгового сервера? Какая-нибудь программа мониторинга? В общем, как убедиться, что MT5 готов к low latency?


ЗЫ Как только котиры начинают шевелиться быстрее, показатель падает в разы.

 
fxsaber:

Ретрансмиты.


Похоже, у меня очень много.

5-6 утра:

Дома (оптика, ETH в роутер, кабель в компьютер) - 8-19%, пинг 60-70

VPS в Нидерландах (в моменте 1 MT5 с 9 валютами/11 графиками) - 1.2-1.6%, пинг 3.7