Библиотеки: TesterBenchmark - страница 2

 

Идея хорошая, но реализация не правильная. Ответил в личке:

fxsaber

Добрый день!

Могли бы Вы адаптировать торговую логику под Вашу торговую библиотеку, чтобы сделать замер ее производительности?

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

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

fxsaber, 2017.08.15 19:31

Места распределились следующим образом

  1. Чистый MQL5 - 100% производительность.
  2. MT4Orders.mqh  - ~95% производительность.
  3. СБ Trade\Trade.mqh - ~84% производительность.
СБ стала меньше отставать.


ЗЫ Интересно, сколько показывают другие торговые библиотеки...

Спасибо!

Не понятно производительности чего? Библиотеки? Она без стратегии не работает. Нужна стратегия. Тогда нужно замерять производительность стратегии, написанной при помощи библиотеки. Допустим замерили, получили результат. С чем его сравнить? Нужно сравнить с такой же стратегией, написанной на чистом MQL. Где взять две стратегии? Предположим у нас есть такие две стратегии. Но где гарантия что они идентичны по торговым входам/выходам друг с другом? Предположим у нас есть две стратегии, которые гарантированно идентичны друг другу, мы измеряем их скорости. Скорости различаются незначительно. Означает ли это, что движок эффективный? Нет, не означает, потому что стратегия не использует все возможности движка/MQL. Вдруг оказывается, что если в другой стратегии запрашивать длинную историю котировок, то движок начинает работать в разы медленней. Значит движок работает в разы медленней чем чистый MQL? Нет не значит, просто конкретно эта операция работает медленней, но допустим если оптимизировать классы предоставляющие данные, в новых версиях окажется что движок на этой же операции будет работать быстрее чем системный CopyXXX. Поэтому во всей этой истории не ясно главное: что мы и с чем мы сравниваем.

 
Vasiliy Sokolov:

Идея хорошая, но реализация не правильная. Ответил в личке:


В нем записана одна и та же простая торговая логика, но тремя способами: чистый MQL5, Trade.mqh и MT4Orders.mqh

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

Пока выходит так, что СБ Trade.mqh отстает на 15%. Но подход замера производительности универсальный - можно повторить торговую логику на любом торговом API. Вот я Вам и предлагаю написать ее на своей кроссплатформенной библе и замерить скорость, сравнив с чистым MQL5.

Благодаря таким замерам, мне удалось найти в своей библе узкие места и искоренить их. А при оптимизации это выливается иногда в сэкономленные часы. В общем, полезно, по-моему.


В своем советнике делаете только
#include <TesterBenchmark.mqh>

и больше ничего не нужно. Дальше выбираете Оптимизацию и запускаете. В логах увидите производительность.

 

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

if (HistorySelect(0, TimeCurrent()))
    {
      const int Total = HistoryDealsTotal() - 1;
      double SumProfit = 0;
      double SumLots = 0;
      for (int i = Total, Count = 0; (i >= 0) && (Count < AmountLastDeals); i--)
      {
        const ulong Ticket = HistoryDealGetTicket(i);

        if ((ENUM_DEAL_ENTRY)HistoryDealGetInteger(Ticket, DEAL_ENTRY) == DEAL_ENTRY_OUT)
        {
          SumProfit += HistoryDealGetDouble(Ticket, DEAL_PROFIT) * (AmountLastDeals - Count);
          SumLots += HistoryDealGetDouble(Ticket, DEAL_VOLUME) * (AmountLastDeals - Count);

          Count++;
        }
      }
      SumLots /= (AmountLastDeals * (1 + AmountLastDeals)) >> 1;
      ...
   }

Ничего кроме нагрузки на HistorySelect Ваш эксперт не делает. Следовательно он не может являться каким-либо бенчмарком для измерения производительности чего бы то не было, кроме самого HistorySelect. Поэтому Ваши заявления о том, что я цитирую: "MT5 быстрее MT4  в 4.4 раза!" как минимум необходимо скорректировать до HistorySelect в МТ5 работает в 4.4 раза быстрее аналогичной, внутренней процедуры в МТ4.

Что касается моего движка CStrategy, то он на текущий момент вообще не позволяет работать с сделками, а работает только с позициями, поэтому пример в том виде, в котором он написан сейчас, не может быть использован в CStrategy.

P.S. Замечу, что в Вашем примере скорость работы равна O(n). И единственная разница между МТ4 и МТ5 в этом случае будет проявляться в скорости HistorySelect/HistoryOrderSelect. Естественно CStrategy в задачах со сложностью O(n) будет использовать базовые вызовы, в данном случае HistorySelect и естественно, он будет чуть медленней чем вызов HistorySelect напрямую. Но вот когда потребуется вызов допустим HistoryOrderSelect(ticket) - здесь все может быть гораздо интересней и в некоторых задача CStrategy будет рвать стандартный доступ к окружению, за счет доступа по словарю и хранению данных в памяти программы. 

 
Vasiliy Sokolov:

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

Ничего кроме нагрузки на HistorySelect Ваш эксперт не делает. Следовательно он не может являться каким-либо бенчмарком для измерения производительности чего бы то не было, кроме самого HistorySelect. Поэтому Ваши заявления о том, что я цитирую: "MT5 быстрее MT4  в 4.4 раза!" как минимум необходимо скорректировать до HistorySelect в МТ5 работает в 4.4 раза быстрее аналогичной, внутренней процедуры в МТ4.

Вы поторопились с выводами. Приведенный кусок выполняется только на открытии позиции раз в Interval-секунд. Т.е. очень редко.

Что касается моего движка CStrategy, то он на текущий момент вообще не позволяет работать с сделками, а работает только с позициями, поэтому пример в том виде, в котором он написан сейчас, не может быть использован в CStrategy. 

Вот MQL4-код OnTick тестового советника, который так же работает только с позициями.

if (!OrderSelect(0, SELECT_BY_POS))
{
  const int Total = OrdersHistoryTotal() - 1;

  double SumProfit = 0;
  double SumLots = 0;

  for (int i = Total, Count = 0; (i >= 0) && (Count < AmountLastDeals); i--)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderType() <= OP_SELL))
    {
      SumProfit += OrderProfit() * (AmountLastDeals - Count);
      SumLots += OrderLots() * (AmountLastDeals - Count);

      Count++;
    }

  SumLots /= (AmountLastDeals * (1 + AmountLastDeals)) >> 1;

  const int Type = (Total >= 0) && OrderSelect(Total, SELECT_BY_POS, MODE_HISTORY) && (OrderType() == OP_BUY) ? OP_SELL : OP_BUY;

  OrderSend(_Symbol, Type, (SumProfit >= 0) ? Lots : CorrectLot(SumLots),
            SymbolInfoDouble(_Symbol, (Type == OP_BUY) ? SYMBOL_ASK : SYMBOL_BID), 0, 0, 0); // , NULL, 0, 0, INT_MIN);
}
else if (TimeCurrent() - OrderOpenTime() >= Interval)
  OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0);

Переписать на свой API такую простую логику не составит труда, конечно. Но если есть предложение лучшего советника для анализа производительности торгового API (именно торгового, а не таймсерии и т.д.), то буду рад увидеть Ваш вариант торговой логики. А там переписать под чистый MQL5, MQL4 и Trade.mqh смогу быстро.


ЗЫ При запуске тестового советника выбирают баланс = 1e7. Чтобы всегда хватало средств на открытие позиции.

 
fxsaber:

Вы поторопились с выводами. Приведенный кусок выполняется только на открытии позиции раз в Interval-секунд. Т.е. очень редко.

Вот MQL4-код OnTick тестового советника, который так же работает только с позициями.

Переписать на свой API такую простую логику не составит труда, конечно. Но если есть предложение лучшего советника для анализа производительности торгового API (именно торгового, а не таймсерии и т.д.), то буду рад увидеть Ваш вариант торговой логики. А там переписать под чистый MQL5, MQL4 и Trade.mqh смогу быстро.

Вы внимательно посмотрите на свой код, и скажите: что он измеряет

if (!OrderSelect(0, SELECT_BY_POS))
{
  const int Total = OrdersHistoryTotal() - 1;

  double SumProfit = 0;
  double SumLots = 0;

  for (int i = Total, Count = 0; (i >= 0) && (Count < AmountLastDeals); i--)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderType() <= OP_SELL))
    {
      SumProfit += OrderProfit() * (AmountLastDeals - Count);
      SumLots += OrderLots() * (AmountLastDeals - Count);

      Count++;
    }

  SumLots /= (AmountLastDeals * (1 + AmountLastDeals)) >> 1;

  const int Type = (Total >= 0) && OrderSelect(Total, SELECT_BY_POS, MODE_HISTORY) && (OrderType() == OP_BUY) ? OP_SELL : OP_BUY;

  OrderSend(_Symbol, Type, (SumProfit >= 0) ? Lots : CorrectLot(SumLots),
            SymbolInfoDouble(_Symbol, (Type == OP_BUY) ? SYMBOL_ASK : SYMBOL_BID), 0, 0, 0); // , NULL, 0, 0, INT_MIN);
}
else if (TimeCurrent() - OrderOpenTime() >= Interval)
  OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0);

Узких мест здесь два, это цикл for и собственно отправка ордера. Вы хотите сравнить, где быстрее цикл for работает?  В CTrade или в чистом MQL? Где быстрее идет отправка ордера? В CTrade или OrderSend? Естественно в чистом OrderSend идет быстрее, т.к. в CTrade делается масса проверок, прежде чем этот ордер будет отправлен. Но какие выводы из этого должны последовать? 

 
Vasiliy Sokolov:

Вы внимательно посмотрите на свой код, и скажите: что он измеряет

Узких мест здесь два, это цикл for и собственно отправка ордера. Вы хотите сравнить, где быстрее цикл for работает?

Вы почему-то не видите этого

fxsaber:

Приведенный кусок выполняется только на открытии позиции раз в Interval-секунд. Т.е. очень редко.


Vasiliy Sokolov:

Где быстрее идет отправка ордера? В CTrade или OrderSend? Естественно в чистом OrderSend идет быстрее, т.к. в CTrade делается масса проверок, прежде чем этот ордер будет отправлен. Но какие выводы из этого должны последовать? 

CTrade делает значительно меньше проверок, чем тот же MT4Orders. Выводы простые сейчас - СБ отстает от чистого MQL5 на 16% и может быть ускорена абсолютно точно. И любой, кто использует CTrade теряет в Облаке доп. деньги при Оптимизации и время на саму Оптимизацию.

 

Вы все-таки не понимаете чем занимается Ваш код. Я специально запустил профилировщик и в течении часа набивал 1800 сделок с периодичностью 1 секунда. 99,66% времени выполнения OnTick занимают две функции OrderSend:

Что Вы собрались оптимизировать? Оставшиеся 0.34% - это бессмысленно. Оптимизировать OrderSend Вы не можете. 

Ок. Самое интересно. Ставим  #include <Trade\Trade.mqh> и смотрим, что изменилось при использовании библиотеки CTrade:


Теперь 100% времени занимает вызов Trade.Buy/Sell и Trade.PositionClose. Идем в Trade.PositionClose и та-да-ммм:

Т.е. все 99.97% времени Trade.PositionClose занимает таже OrderSend. Аналогично с Trade.Buy и Trade.Sell.

Так чего Вы собрались оптимизировать в СБ? Где предмет теста? Что Вы тестируете вообще?

(Для тех, кто не понимает цифры профилирования объясню: 99.97% времени выполнения программы занимает непосредственная отправка ордера через OrderSend, оставшиеся 0.03% занимает обвязка CTrade с необходимыми проверками перед отправкой ордера. Т.е. использование грамотного ООП вносит настолько ничтожные задержки, что ими можно пренебречь, и считать что они равны нулю. Это не 0.03% а даже меньше, т.к. большую часть времени из этих 0.03 занимают обязательные проверки, которые по грамотному все равно необходимо реализовать, в процедурном ли коде или где-то еще).

 
Vasiliy Sokolov:

Я специально запустил профилировщик и в течении часа набивал 1800 сделок с периодичностью 1 секунда.

А при чем здесь онлайн? Речь о тестере.

 
Andrey Khatimlianskii:

А при чем здесь онлайн? Речь о тестере.

Если речь идет о МТ5 и его тестере стратегий, то там те же 99% времени (ну может чуть меньше) занимает работа по воссозданию торгового окружения (отсюда такие медленные прогоны по сравнению с МТ4). И нет причин думать что если OrderSend в реале занимает 99.9% времени, то в тестере стратегий она вдруг будет работать на два порядка быстрей.
 
Vasiliy Sokolov:
Если речь идет о МТ5 и его тестере стратегий, то там те же 99% времени (ну может чуть меньше) занимает работа по воссозданию торгового окружения (отсюда такие медленные прогоны по сравнению с МТ4). И нет причин думать что если OrderSend в реале занимает 99.9% времени, то в тестере стратегий она вдруг будет работать на два порядка быстрей.

Василий, вы серьезно говорите о соизмеримости скорости выполнения OrderSend в тестере и в реале?

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

Задача этой библиотеки - как раз скорость тестера и измерить (с точки зрения торговых функций).

Причина обращения: