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

 
Renat Fatkhullin:

Миллисекундный таймер давно есть: EventSetMillisecondTimer()

Вы совсем не в теме. Допустим, надо открыть две позиции в OnTick. Первый OrderSend - это несколько миллисекунд. После него надо делать снепшот. И тогда вызывать второй OrderSend.

Один только OnTick может выполняться сотни миллисекунд. А вы предлагаете в каком-то OnTimer снепшотиться.

 
Renat Fatkhullin:

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

Аргументы в студию!

 
Renat Fatkhullin:

Вот мой код и стабильное время отработки: никаких сотен и тысяч микросекунд на 20 графиках параллельно

Сколько у вас ядер и какой процессор? i7-2600?

8 ядер.

2020.10.06 02:27:59.464 Terminal        MetaTrader 5 x64 build 2630 started for MetaQuotes Software Corp.
2020.10.06 02:27:59.465 Terminal        Windows 10 build 19042, Intel Core i7-2700K  @ 3.50GHz, 7 / 15 Gb memory, 19 / 29 Gb disk, IE 11, Admin, GMT+3

Снова скрытый стресс-тест с миллионами запросов параллельно?

Много раз говорил, что боевой советник. Максимально минимизировал количество вызовов. В теории (тупо не замерял) до 10 вызовов на один OnTick.


Будьте прозрачнее. То, что вы опубликовали пару простых _B вызовов, не является доказательством ваших остальных заявлений. Вы резко забываете про код и реальное описание условий, как только делаете запредельные заявления.

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

Публикую результаты с боевого советника. Там 70 mqh файлов, включая WinAPI. Если не на словах, а реально будете разбираться, то предоставлю исходник. Воспроизведете тормоза довольно быстро.

 
fxsaber:

Вы совсем не в теме. Допустим, надо открыть две позиции в OnTick. Первый OrderSend - это несколько миллисекунд. После него надо делать снепшот. И тогда вызывать второй OrderSend.

Один только OnTick может выполняться сотни миллисекунд. А вы предлагаете в каком-то OnTimer снепшотиться.

Я не предлагал снепшотиться, а ответил на прямой вопрос о миллисекундном таймере.

Он есть, хотя в текущем тестере он все равно срабатывает с частотой 1 сек. В новом тестере, который пишем, постараемся это изменить.
 
fxsaber:

8 ядер.

Много раз говорил, что боевой советник. Максимально минимизировал количество вызовов. В теории (тупо не замерял) до 10 вызовов на один OnTick.


Публикую результаты с боевого советника. Там 70 mqh файлов, включая WinAPI. Если не на словах, а реально будете разбираться, то предоставлю исходник. Воспроизведете тормоза довольно быстро.

Будем разбираться, дайте исходники.
 
fxsaber:

Аргументы в студию!

Весь ваш бенчмарк перегружен мусором и по факту вот его чистая и понятная (в отличие от вашего нагромождения кода) версия:


//--- benchmark macros
#define _B(_function,_alert_interval)               \
          {                                         \
           ulong _latency=GetMicrosecondCount();    \
           _function;                               \
           _latency=GetMicrosecondCount()-_latency; \
           if(_latency > _alert_interval)           \
              ::Alert("Time[" + __FILE__ + " " + (string)__LINE__ + " in " + __FUNCTION__+ ": " + #_function + "] = " + (string)_latency + " mсs"); \
          }



//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlTick Tick;
   
   _B(SymbolInfoTick(_Symbol,Tick),0);
   _B(SymbolInfoTick(_Symbol,Tick),0);
  }

Какие проблемы у вас:

  1. нечитаемый код

  2. обвязка в класс с массой оверхеда

  3. расходы на хранение в стеке 50 результатов
      static bool Set( const string Str )
      {
        if (BENCHMARK::Amount == BENCHMARK::ReserveSize)
          BENCHMARK::ReserveSize = ::ArrayResize(BENCHMARK::Bench, BENCHMARK::ReserveSize + BENCHMARK_RESERVE);
    
        BENCHMARK::Bench[BENCHMARK::Amount++].Set(Str);
    
        return(true);
      }
    
  4. взятие результатов - один сплошной оверхед и мусор в объектной обвязке
      static ulong Get( const uint AlertInterval = 0 )
      {
        const int Pos = BENCHMARK::Amount - 1;
        const ulong Res = (Pos < 0) ? 0 : BENCHMARK::Bench[Pos].Get();
    
        if (Pos >= 0)
        {
          if (AlertInterval && (Res > AlertInterval))
            ::Alert("Time[" + BENCHMARK::Bench[Pos].Str + "] = " + (string)Res + " mсs.");
    
          BENCHMARK::Amount = Pos;
        }
    
        return(Res);
      }
    


Надеюсь, вы для тестов не отключали оптимизацию кода?

Я имею в виду глобальный параметр Optimize=0 в metaeditor.ini

 
Renat Fatkhullin:

Весь ваш бенчмарк перегружен мусором и по факту вот его чистая и понятная (в отличие от вашего нагромождения кода) версия:

Ваша версия, к сожалению, на начальной стадии понимания удобства. Удобно, это когда вот так можно.

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

Библиотеки: Benchmark

fxsaber, 2020.10.01 23:49

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

    for (long Chart = _B2(::ChartFirst()); (Chart != -1) && !Res; Chart = _B2(::ChartNext(Chart)))
      Res = (Chart != chartID) && _B2(::ChartGetInteger(Chart, CHART_IS_MAXIMIZED));

И сразу видим причину.

2020.10.02 00:45:14.113 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 878 mсs.
2020.10.02 00:45:14.114 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 943 mсs.
2020.10.02 00:45:14.114 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 297 mсs.
2020.10.02 00:45:14.116 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 1787 mсs.
2020.10.02 00:45:14.116 Alert: Time[Test9.mq5 35 in IsInvisible: ::ChartNext(Chart)] = 2 mсs.
2020.10.02 00:45:14.117 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 980 mсs.
2020.10.02 00:45:14.117 Alert: Time[Test9.mq5 35 in IsInvisible: ::ChartNext(Chart)] = 2 mсs.
2020.10.02 00:45:14.117 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 59 mсs.
2020.10.02 00:45:14.118 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 803 mсs.
2020.10.02 00:45:14.119 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 1059 mсs.

CHART_IS_MAXIMIZED тормозит для чужих чартов. Баг-репорт готов! С библиотекой это было очень просто.


Какие проблемы у вас:

  1. нечитаемый код

  2. обвязка в класс с массой оверхеда

  3. расходы на хранение в стеке 50 результатов
  4. взятие результатов - один сплошной оверхед и мусор в объектной обвязке

Удобство использования перекрывает мизерный оверхед. Он мизерный, если смотреть внимательно, как реализовано. Например, ArrayResize - это оверхед, поэтому сведено к минимуму его использование.

Надеюсь, вы для тестов не отключали оптимизацию кода?

Я имею в виду глобальный параметр Optimize=0 в metaeditor.ini

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

 
Renat Fatkhullin:

Весь ваш бенчмарк перегружен мусором и по факту вот его чистая и понятная (в отличие от вашего нагромождения кода) версия:

Какие проблемы у вас:

  1. нечитаемый код

  2. обвязка в класс с массой оверхеда

  3. расходы на хранение в стеке 50 результатов
  4. взятие результатов - один сплошной оверхед и мусор в объектной обвязке


Надеюсь, вы для тестов не отключали оптимизацию кода?

Я имею в виду глобальный параметр Optimize=0 в metaeditor.ini

Вот он C-style, всё просто и действительно без мусора. Благодарю за пример.

Один из преподавателей языка Си, дал рекомендацию лучше не использовать в пользовательских именах нижнее подчёркивание _B 
По причине того, что этот префикс используют разработчики библиотек, програм и т.д. 
И чтобы не нарваться на пересечение, рекомендовал лучше не использовать.

А в mql5 есть ли вероятность нарваться на пересечение с вашими именами ?
Или пользовательские имена полностью ограждёны от имён MQ ?

 
Roman:

Один из преподавателей языка Си, дал рекомендацию лучше не использовать в пользовательских именах нижнее подчёркивание _B 
По причине того, что этот префикс используют разработчики библиотек, програм и т.д. 
И чтобы не нарваться на пересечение, рекомендовал лучше не использовать.

Имена, начинающиеся с "_", в Си используются как служебные, системные или специальные. В данном случае - допустимо, я считаю. Т.к. эта функция используется для обслуживания и исследования кода.

 
Edgar Akhmadeev:

Имена, начинающиеся с "_", в Си используются как служебные, системные или специальные. В данном случае - допустимо, я считаю. Т.к. эта функция используется для обслуживания и исследования кода.

В том то и вопрос, что помимо mql5, есть служебные имена MQ разработчика.