Библиотеки: MT4Orders - страница 77

 
elavr #:

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

Во всех трех случаях конечный результат совпадает?
 
fxsaber #:
Во всех трех случаях конечный результат совпадает?

Да, конечно.

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

 
elavr #:

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

Сделал исследование.


Советник.

#include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006

#define VIRTUAL_SNAPSHOT_REFRESHTIME 1000
#include <fxsaber\Virtual\Virtual.mqh> // https://www.mql5.com/ru/code/22577

input int inMod = 5;
input int inRange = 0;
input bool inVirtual = false;

const bool Init = inVirtual ? VIRTUAL::SelectByHandle(VIRTUAL::Create()) : false;;

#define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

ulong lOnTester = 0;

void OnTick()
{  
  static int i = 0;
  
  VIRTUAL::NewTick();
  
  if (!(i++ % inMod))
    OrderClose(OrderSend(_Symbol, OP_BUY, 0.1, Ask, 0, 0, 0), 0.1, Bid, 0);
    
//  VIRTUAL::Snapshot();  
  lOnTester += LastCloseTimeMQL4() % 100;
  
//  lOnTester += LastCloseTimeMQL5() % 100;
}

double OnTester()
{
  if (HistorySelect(0, INT_MAX))
    Print(HistoryDealsTotal());
  
  return((double)lOnTester);
}

На каждом inMod-тике открывается и закрывается позиция. И на каждом тике вычисляется OrderCloseTime.

OnTester служит критерием проверки идентичности результатов при разных конфигурациях.


Соответствующие функции работы с историей.

datetime LastCloseTimeMQL4()
{  
  datetime Res = 0;
  
  for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderType() <= OP_SELL))
    {
      Res = OrderCloseTime();
      
      break;
    }

  return(Res);
}

datetime LastCloseTimeMQL5()
{
  datetime Res = 0;
  
  if (HistorySelect(0, INT_MAX))
    for (int i = HistoryDealsTotal() - 1; i >= 0; i--)
    {
      const ulong Ticket = HistoryDealGetTicket(i);
      
      if (HistoryDealGetInteger(Ticket, DEAL_ENTRY) != DEAL_ENTRY_IN)
      {
        Res = (datetime)HistoryDealGetInteger(Ticket, DEAL_TIME);
        
        break;
      }
    }
    
  return(Res);
}

#define MACROS(A, B)          \
  datetime A##_2()            \
  {                           \
    static datetime Res = 0;  \
    static int PrevTotal = 0; \
                              \
    const int Total = B;      \
                              \
    if (PrevTotal != Total)   \
    {                         \
      Res = A();              \
                              \
      PrevTotal = Total;      \
    }                         \
                              \
    return(Res);              \
  }

// LastCloseTimeMQL4_2
MACROS(LastCloseTimeMQL4, OrdersHistoryTotal())

// LastCloseTimeMQL5_2
MACROS(LastCloseTimeMQL5, HistorySelect(0, INT_MAX) ? HistoryDealsTotal() : 0)


Методика.

Одиночный запуск на настройках, как в исходнике (inMod = 5).

2023.07.06 23:59:59   28179
final balance 99996992.20 pips
OnTester result 2761115
EURUSD,M1: 274413 ticks, 70443 bars generated. Environment synchronized in 0:00:00.021. Test passed in 0:00:03.712 (including ticks preprocessing 0:00:00.031).

28K сделок, почти четыре секунды. Поскольку замерять производительность нужно в режиме оптимизации, то все следующие показания производительности делались так.

shortest pass 0:00:02.875, longest pass 0:00:03.094, average pass 0:00:02.919

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


Производительность.

Таблица производительности (время выполнения в миллисекундах) для b3815 и b2958.

MT5 build LastCloseTimeMQL4 LastCloseTimeMQL5 LastCloseTimeMQL4_2 LastCloseTimeMQL4+VIRTUAL::Snapshot LastCloseTimeMQL4+VirtualTester
b3815 2875 113 708 732 45
b2958 2718 107 675 715 50

Везде использовалась MT4Orders от 20.07.2022.


Выводы.

  • Тормозит OrderSelect. Связано с тем, что при OrderSelect идет вычисление абсолютно всех данных выбранного ордера из истории (OrderPrint - бесплатный). Это большая комбинация HistoryOrderGet* и HistoryDealGet* функций, с обработкой любой сложности рыночных ситуаций и большого количества подводных камней. Посмотрите MT4ORDERS::GetHistoryPositionData(). Это единая функция для Терминала и для Тестера, но при этом для Тестера специально сделаны ускорения, т.к. многих подводных камней Терминала в Тестере нет. Примеры конфигураций: один, два, три.
  • Соответственно, нужно добиваться уменьшения вызовов OrderSelect для исторических ордеров. Этого можно добиться способами, что указаны в правых трех столбцах таблицы.
  • Самая быстрая работа (опережает чистый MQL5) - торговля в виртуальном окружении. Рекомендовал бы оптимизацию делать в виртуальном окружении, а одиночные проходы - вне его.
  • Производительность Тестера b2958 и b3815 почти идентична.
  • Не рекомендую логику ТС для Тестера завязывать на историю торговли с обращением к ней. Например, OrderCloseTime своей ТС можно знать без обращения к истории.
 
elavr #:

Время теста  около 1 часа 10 минут.

Откатываю библиотеку до версии  __MT4ORDERS__ "2020.01.12" и компилю эксперта  в билде 2980.

Время работы эксперта с функцией get_last_order_close_time  - в районе 20 минут.

Попробуйте код выше на старой версии библиотеки (у меня ее нет).

Если будет отличие в производительности, пришлите в ЛС.

 
Спасибо огромное! Посмотрю на следующей неделе!
 
Использование библиотеки может увеличить потребление памяти до 10%.
 
fxsaber #:
Использование библиотеки может увеличить потребление памяти до 10%.

С чем это связано?

 
Vitaly Muzichenko #:

С чем это связано?

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

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

fxsaber, 2023.07.07 13:12

  • при OrderSelect идет вычисление абсолютно всех данных выбранного ордера из истории (OrderPrint - бесплатный). Это большая комбинация HistoryOrderGet* и HistoryDealGet* функций, с обработкой любой сложности рыночных ситуаций и большого количества подводных камней. Посмотрите MT4ORDERS::GetHistoryPositionData(). Это единая функция для Терминала и для Тестера, но при этом для Тестера специально сделаны ускорения, т.к. многих подводных камней Терминала в Тестере нет. Примеры конфигураций: один, два, три.
 
fxsaber #:
Использование библиотеки может увеличить потребление памяти до 10%.

Думал, вчера было обновление библиотеки, но не доглядел год :)

Буду ожидать, спасибо за поддержку!

 

саб, на сколько выгодно использовать в передачи функции const?

и за одно, есть смысл создавать член класса внутри функции, или вполне обойтись глобальной, 7 символов в торговле робот

обработка на каждом тике, через индикатор шпион.

обработка на каждом тике, в пустую обычно, не ловит аномалии, это вопрос оптимизации своих функции вопросы..