Библиотеки: Virtual - страница 11

 
Sergey Chalyshev:

А что стоит за этой одной строчкой кода? )))

Например, возьмем, нашего подопытного. И попробуем запустить его одиночный прогон в скрипте.

// Скрипт запускает виртуальный Тестер для советника
#property script_show_inputs

input string inFileName = "Report.htm";    // FileName
input double inBalance = 10000;            // Start Balance for Virtual Tester
input datetime inFromTime = D'2018.10.01'; // Start Date for Virtual Tester

#define VIRTUAL_LIMITS_TP_SLIPPAGE // Лимитники и TP исполняются по первой цене акцепта - положительные проскальзывания
#include <fxsaber\Virtual\Virtual.mqh> // https://www.mql5.com/ru/code/22577

#include <Report.mqh> // https://www.mql5.com/ru/code/18801

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

// Раз запускаем советник без изменений, переименовываем OnTick и OnDeinit
#define OnTick SystemOnTick
#define OnDeinit SystemOnDeinit
#include <..\Experts\fxsaber\TesterEA\TesterEA.mq4> // https://www.mql5.com/ru/code/22770

// Получает тики с даты по дату
int GetTicks( MqlTick &Ticks[], const datetime From = 0, const datetime To = INT_MAX )
{
  return(CopyTicksRange(_Symbol, Ticks, COPY_TICKS_ALL, (ulong)From * 1000, (ulong)To * 1000));
}

// Нужно для автоматического открытия отчета - удобно.
#import "shell32.dll"
  int ShellExecuteW( int hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, int nShowCmd );
#import

void OnStart()
{
  MqlTick Ticks[];
  
  const int Size = GetTicks(Ticks, inFromTime); // Получили тики для Тестера
  
  const ulong StartTime = GetMicrosecondCount();

  if (VIRTUAL::Tester(Ticks, SystemOnTick, inBalance) != -1) // Сделали одиночный прогон Тестера на тиках
  {
    // Вывели данные о производительности Тестера.
    const ulong Interval = GetMicrosecondCount() - StartTime;
    Print("Virtual Tester Pass Time is " + DoubleToString(Interval / 1e6, 3) + " s.");
    Print("Total Ticks = " + (string)Size);
    Print("Performance = " + DoubleToString((double)Size / Interval, 3) + " MTicks/sec.");
    
    // Сформировали отчет Тестера - REPORT не в курсе, что работает с виртуальным окружением.
    if (REPORT::ToFile(inFileName) && MQLInfoInteger(MQL_DLLS_ALLOWED))
      ShellExecuteW(0, "Open", TerminalInfoString(TERMINAL_PATH) + "\\MQL5\\Files\\" + inFileName, NULL, NULL, 3);
        
    VIRTUAL::Delete(); // Удалили виртуальное окружение, в котором запускался Тестер.
  }
  
  SystemOnDeinit(0); // Выполнили OnDeinit исходного советника.
}

Сразу обращу внимание, что нет никакого MT4Orders. Почти весь код - красивости. Основа - строка, что выделена красным.


После запуска скрипта выскочет предложение задать исходные параметры Тестера


После выполнения появится торговый отчет Тестера в браузере. При этом в логе будет

Virtual Tester Pass Time is 0.210 s.
Total Ticks = 3412767
Performance = 16.253 MTicks/sec.

Производительность что-то около 16 миллионов тиков в секунду. Надо будет сравнить с MT5-Тестером.

 
fxsaber:

Производительность что-то около 16 миллионов тиков в секунду. Надо будет сравнить с MT5-Тестером.

Запускаем все тот же советник, но в MT5-Тестере

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

#define VIRTUAL_TESTER // Запуск в виртуальном торговом окружении
#define VIRTUAL_LIMITS_TP_SLIPPAGE // Лимитники и TP исполняются по первой цене акцепта - положительные проскальзывания
#define VIRTUAL_CLOSEALL_BYEND // Закрывает принудительно все ордера в конце тестирования
#include <fxsaber\Virtual\Virtual.mqh> // https://www.mql5.com/ru/code/22577

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

//#define REPORT_TESTER // В тестере будут автоматически записываться отчеты
#include <Report.mqh> // https://www.mql5.com/ru/code/18801

#include <..\Experts\fxsaber\TesterEA\TesterEA.mq4> // https://www.mql5.com/ru/code/22770


MT5-Tester

shortest pass 0:00:01.513, longest pass 0:00:01.747, average pass 0:00:01.574
EURUSD,M1: 3365744 ticks, 51787 bars generated. Test passed in 0:00:01.841.


Тиков несколько меньше, чем в скрипте постом ранее. Но не сильно.


MT5-Tester + Virtual

shortest pass 0:00:00.811, longest pass 0:00:01.997, average pass 0:00:00.982


Добавка Virtual к Тестеру дала двукратный прирост скорости. Однако, если запускать в виде скрипта, то в восемь раз быстрее выходит.

 
// Пример тестера реального времени в действии

input double inBalance = 10000;            // Start Balance for Virtual Tester
input datetime inFromTime = D'2018.11.12'; // Start Date for Virtual Tester

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

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

bool InitTester = false;

void OnInit()
{
  MqlTick Ticks[];
  
  // Прогнали на исторических данных советник
  InitTester = (CopyTicksRange(_Symbol, Ticks, COPY_TICKS_INFO, (ulong)inFromTime * 1000, LONG_MAX) > 0) &&
               (VIRTUAL::Tester(Ticks, SystemOnTick, inBalance, false) != -1);
}

void OnTick()
{  
  // Продолжили дальше гнать в реальном времени
  if (InitTester)
  {
    VIRTUAL::NewTick(); // Пробросили в виртуальное окружение новый тик
    
    SystemOnTick();     // Выполнили советник
    
    Comment(VIRTUAL::ToString(10)); // Выводим текущее состояние советника + 10 последних исторических ордеров.
  }
}

#define OnTick SystemOnTick
#include <..\Experts\fxsaber\TesterEA\TesterEA.mq4> // https://www.mql5.com/ru/code/22770


В комментарии к чарту будет видна торговля советника в реальном времени


Советник можно выключать и включать в любое время - результат будет всегда одинаковый: будто его не выключали.

 
fxsaber:

Добавка Virtual к Тестеру дала двукратный прирост скорости. Однако, если запускать в виде скрипта, то в восемь раз быстрее выходит.

Причина, почему Virtual в самом Тестере быстрее в два раза понятна - расчет маржи и многих других условий со стороны Тестера, чего не делает Virtual (специально).

А вот почему скрипт ускоряет еще в четыре раза - сложно объяснить. Единственное отличие, в скрипте не формируются бары, а штатный Тестер их формирует. Но почему он их формирует столь медленно - загадка.

 
Добрый день! Какой режим правильнее выбрать для Virtual  - "Все тики" или "Все тики на основе реальных тиков"?
 
Sergey Seriy:
Добрый день! Какой режим правильнее выбрать для Virtual  - "Все тики" или "Все тики на основе реальных тиков"?

Будет тестировать на тех, что подадите. Сам тестирую только на кастомных реальных тиках. Но этот выбор никак с Virtual не связан.

 
Добрый день! Подскажите, как задать комиссию и спред в  Virtual, в какой части кода это можно сделать?
 
Sergey Seriy:
Добрый день! Подскажите, как задать комиссию и спред в  Virtual, в какой части кода это можно сделать?

Спред задавать не нужно - тест по тикам. Комиссия не была реализована.

В Order.mqh в начале есть такие строки

#property strict

#include "String.mqh"

#define ORDER_COMMISSION (0)
//#define ORDER_COMMISSION (-5)

Можно там задать нужное число - какой профит в пипсах приносит комиссия.

 
fxsaber:

Спред задавать не нужно - тест по тикам. Комиссия не была реализована.

В Order.mqh в начале есть такие строки

Можно там задать нужное число - какой профит в пипсах приносит комиссия.

Спасибо!

 

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

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

fxsaber, 2018.11.02 21:12

Замер производительности в MT4-тестере


Без Virtual

2715872 tick events (64699 bars, 2715972 bar states) processed in 0:00:03.572 (total time 0:00:04.009)


Через Virtual

2715890 tick events (64699 bars, 2715990 bar states) processed in 0:00:01.342 (total time 0:00:01.825)


Примерно в 2.5 раза.


"Без Virtual" - это VirtualTester = false. Т.е. библиотека подключена, но не задействовано виртуальное окружение. Плохо, что это не упомянул в сообщении выше.

Поэтому для MT4 не совсем корректное сравнение получилось.


Когда подключаешь библиотеку (#include), но не задействуешь виртуалку, то будет замедление по сранению с тем, если бы библиотеки не было вовсе. Поэтому если подключаете библиотеку (#include), то это имеет резон только для случаев задействования виртуалки. Для тестера это VirtualTester = true. И то не всегда получите ускорение.

Вот время выполнения оптимизации двух советников на MT4

ExpertNameVirtualTester = falseVirtualTester = truew/o Virtual.mqh
TesterEA0:02:050:01:140:01:30
Expert20:02:490:02:220:01:44

Везде видно замедление, когда был VirtualTester = false. При этом VirtualTester = true иногда может выиграть у варианта без библиотеки (желтый), а иногда и сильно проиграть по скорости (красный).

Причину сильного замедления именно на MT4 не выяснил.

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