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

 
Edgar:

Отлавливаю события срабатывания SL и TP для установки следующих ордеров. Это позволяет не проверять на каждом тике. Для сопровождения позиций (TS, BE) всё же приходится использовать OnTick, но более простым кодом. Пока не факт, что это ускоряет, надо проверять. В общем, это не приоритетно.

Звучит логично. Хотелось бы увидеть пример замера скорости OnTick+OnTrade и OnTick only.


А вот что действительно важно - OnTester. Т.е. реализовать TesterStatistics() в виртуале. Без пользовательских критериев что мы оптимизируем? Баланс? Пусть даже в комбинации с дополнительным параметром. Я оптимизирую не по прибыли, а по качеству торговли.

По эквити. Последняя позиция специально не закрывается, в отличие от MT-тестеров. Можно реализовать подобную схему

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

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

fxsaber, 2018.11.11 18:25

Если прописать такую строку

#define BESTINTERVAL_ONTESTER_FORMULA BestInterval.GetProfit() * BestInterval.GetRecoveryFactor()

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

Дело в том, что без BestInterval не оптимизирую. Поэтому если и хочу задать OnTester, то делаю это, как показано выше. Правда, BestInterval считает MaxDD только по балансу. Соответственно, и фактор восстановления.


Реализовать TesterStatistics() Вам будет несложно, все данные для них в движке есть.

Кроме просадки по эквити. Если и добавлять, то еще и данные о КПД каждой сделки (такого в других Тестерах не видел). В общем, TesterStatistics сделать можно.

Единственное но - для той же MaxDD_Equity нужно делать проверку на каждом тике. Как сильно погасит это скорость - сложно сказать.


ЗЫ Несколько удивила заинтересованность в ускорении Оптимизации. Давал несколько рецептов по ускорению. Возможно, помогут.

ЗЫЫ Могли бы Вы предоставить время выполнения прогона с/без Virtual?

 
fxsaber:

Хотелось бы увидеть пример замера скорости OnTick+OnTrade и OnTick only.

Пока идёт работа по переносу, адаптации, очистке и оптимизации кода

По эквити.

Я видел в коде. Это детали.

Дело в том, что без BestInterval не оптимизирую. Поэтому если и хочу задать OnTester, то делаю это, как показано выше.

До BestInterval пока не дошёл. Но формулой я не обойдусь. У меня сложный OnTester (включая линейную регрессию по кривой баланса).

Единственное но - для той же MaxDD_Equity нужно делать проверку на каждом тике. Как сильно погасит это скорость - сложно сказать.

Лично мне она нужна. Можно сделать это недефолтной опцией, при помощи дефайна перед инклудом. Как, кстати, и размер STRING. И ещё чего-нибудь, возможно.

ЗЫ Несколько удивила заинтересованность в ускорении Оптимизации. Давал несколько рецептов по ускорению. Возможно, помогут.

ЗЫЫ Могли бы Вы предоставить время выполнения прогона с/без Virtual?

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

Кстати, тиковая история у меня занимает в памяти под 4Гб. И, что хуже, временные файлы в Tester/Agent-* подготавливаются перед каждой оптимизацией, на 20-30Гб для 8 агентов. Зачем. Это занимает очень много времени, диск занят на 100%. Приходится отключать половину агентов. Возможно, найдётся решение для более эффективной работы с большой тиковой историей. Может быть, готовить постоянный файл с историей и в Virtual загружать его в массив. Или SQLite?

Замеры под Virtual я сделаю, когда закончу перенос.

 
Edgar:

До BestInterval пока не дошёл. Но формулой я не обойдусь. У меня сложный OnTester (включая линейную регрессию по кривой баланса).

Вы сможете обойтись формулой.


Лично мне она нужна. Можно сделать это недефолтной опцией, при помощи дефайна перед инклудом. Как, кстати, и размер STRING. И ещё чего-нибудь, возможно.

Да, дефайнами настройки будут. Как уже рабочий пример

#define VIRTUAL_LIMITS_TP_SLIPPAGE // Лимитники и TP исполняются по первой цене акцепта - положительные проскальзывания


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

Кстати, тиковая история у меня занимает в памяти под 4Гб. И, что хуже, временные файлы в Tester/Agent-* подготавливаются перед каждой оптимизацией, на 20-30Гб для 8 агентов. Зачем. Это занимает очень много времени, диск занят на 100%. Приходится отключать половину агентов. Возможно, найдётся решение для более эффективной работы с большой тиковой историей. Может быть, готовить постоянный файл с историей и в Virtual загружать его в массив. Или SQLite?

Вы можете перенести папку tester на RAMDrive. Мне это существенно помогло, хоть и не работаю со столь большой историей.

Так же можете написать на основе Virtual свой Оптимизатор. Здесь пример одиночного прохода вне Тестера.

 

В описание добавлены следующие сценарии, где Virtual может сильно помочь

  1. Торговля нескольких ТС на Netting-счете. С помощью виртуального торгового окружения процесс запуска любого количества ТС на Netting-счете значительно упрощается. ТС не будут мешать друг другу.
  2. Однонаправленные позиции на Netting-счете. Можно открывать в одном направлении несколько позиций, каждая из которых будет иметь свои Magic, OpenTime, OpenPrice, Comment и т.д. Это, например,позволяет на Netting-счете создавать сеточные ТС, где у каждой однонаправленной позиции разные TP.
  3. Скрытие Limit/Stop/SL/TP-уровней. Если возникает задача скрыть значимые торговые уровни от чужих глаз, то она быстро решается с помощью виртуального торгового окружения.
  4. Запуск Hedge-ТС на Netting-счете.  Все ТС запускаются в Hedge-виртуальном окружении. Netting-реальное окружение только синхронизируется с виртуальным.
 
Однонаправленные позиции на Netting-счете. Можно открывать в одном направлении несколько позиций, каждая из которых будет иметь свои Magic, OpenTime, OpenPrice, Comment и т.д. Это, например,позволяет на Netting-счете создавать сеточные ТС, где у каждой однонаправленной позиции разные TP.

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

Ниже пример, как это обходится

// Пример Netting с поддержкой множества однонаправленных позиций (у каждой могут быть свои Magic, SL/TP, Comment, OpenTime и т.д.).
// Запустите этот пример на Netting-счете в Тестере с влюченной Визуализацией.

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

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

#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

input int iAmount = 5;   // Количество ордеров в сетке
input int iOffset = 120; // На каком расстоянии (в пипсах) ставить ордера сетки
input int iTP = 120;     // TakeProfit каждого ордера сетки

// Выставляем один раз сетку из Amount ордеров на Offset-расстоянии друг от друга с заданным TP.
void System( const int Amount, const int Offset, const int TP )
{
  static bool FirstRun = true;
  
  if (FirstRun)  
  {
    for (int i = 1; i <= Amount; i++)
    {
      const double PriceOpen = Ask - i * Offset * _Point;
      const double PriceTP = PriceOpen + TP * _Point;
      
      OrderSend(_Symbol, OP_BUYLIMIT, 1, PriceOpen, 0, 0, PriceTP, (string)i); // Выставляем каждый ордер сетки
    }
    
    FirstRun = false;
  }
}

void OnTick()
{  
  static const bool Init = VIRTUAL::Select(VIRTUAL::Create()); // Система будет работать в этом виртуальном окружении
  static const bool IsVisual = MQLInfoInteger(MQL_VISUAL_MODE);
  static bool FirstRun = true;

  VIRTUAL::NewTick();            // Добавили тик в виртуальное торговое окружение
  System(iAmount, iOffset, iTP); // Запустили ТС на выбранном торговом окружении (виртуальное)
  
  SYNC::Positions<ISTIME>(); // Синхронизировли реальное торговое окружение с виртуальным

  if (IsVisual)
    Comment(VIRTUAL::ToString(true)); // Вывели на чарт состояние виртуального торгового окружения (true - вместе с историей торгов)
}


Идея простейшая. Запустили ТС в виртуальном, а в реальном просто синхронизируем. Исходник ТС менять не нужно (функция System в примере).


ЗЫ Точно так же на той же Бирже можно уменьшить количество реальных торговых приказов, чтобы не превышать лимит на них.

 
fxsaber:

Вы сможете обойтись формулой.

Вы джедай.

Я смогу обойтись формулой. Если Вы не реализуете OnTester. Что логично, если следовать идее, что эта библиотека позволяет минимально вмешиваться в код эксперта (если он изначально MT4-style).

Вы можете перенести папку tester на RAMDrive. Мне это существенно помогло, хоть и не работаю со столь большой историей.

И мне помогало, пока папка занимала < 2Гб (у меня RAM 8Гб). Но теперь - до 30Гб (основной объём - тики за несколько лет для всех 8 агентов).

Так же можете написать на основе Virtual свой Оптимизатор. Здесь пример одиночного прохода вне Тестера.

Да, в этом направлении. Держать тики не у каждого агента, а в одном бинарном файле, и загружать в память. Можно ещё упаковать MqlTick.  Цены в целое беззнаковое 3 байта.  Время из абсолютного в относительное. Миллисекунды опционально вообще убрать (мой случай). Объёмы тоже можно сжать, а мне - вообще убрать. Флаги уместятся в 1 байт. Выравнивание данных по границам слов по-моему в байткоде роли не играет. Конвертация PackedTick в MqlTick на лету требует лишнего времени, но при большой длине тиковой истории однозначно даст выигрыш за счёт отсутствия постоянной подкачки с диска.

Для меня это работа где-то на следующих этапах. Возможно, Вы сами захотите сделать либу, как самый крутой кодер здесь.

 
Edgar:

Я смогу обойтись формулой. Если Вы не реализуете OnTester. Что логично, если следовать идее, что эта библиотека позволяет минимально вмешиваться в код эксперта (если он изначально MT4-style).

Формула может включать вызовы любых функций. Т.е. она ничего не уступает любого рода мат. расчетам.

И мне помогало, пока папка занимала < 2Гб (у меня RAM 8Гб). Но теперь - до 30Гб (основной объём - тики за несколько лет для всех 8 агентов).

Что тестируете? Какой смысл в столь длительной истории тиков? И что за источник? Покажите логи одиночного прохода на советнике-пустышке (открывает только одну позицию на символ).

Где-то приводил цифры, насколько быстро все считаться может. По-моему, Вы боретесь со следствием, а не с причиной.

 

Пока не в состоянии что-то серьезное написать, решил сделать замеры.

Тестовый советник

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

//#define VIRTUAL_ON // Тестер или Virtual

#ifdef VIRTUAL_ON
  #include <fxsaber\Virtual\Virtual.mqh> // https://www.mql5.com/ru/code/22577
  
  const int Init = VIRTUAL::Select(VIRTUAL::Create());
  
  void OnTick()
  {
    VIRTUAL::NewTick();
  }
/*  
  double OnTester()
  {
    return(AccountEquity());
  } */
#endif // VIRTUAL_ON

input int inRange = 0;          // 1 .. 5
input int inAmount = 1;         // Amount of positions
input int iTakeProfit  = 10000; // TakeProfit in pips

uint iStartTime;

void OnInit()
{  
  iStartTime = GetTickCount(); // Начинается замер специально в OnInit, а не снаружи
  
  const double Price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
  
  for (int i = 0; i < inAmount; i++)
    OrderSend(_Symbol, OP_BUY, 0.1, Price, 100, 0, Price + iTakeProfit * _Point);
}

double OnTester()
{
  return(GetTickCount() - iStartTime);
}


22 млн тиков в режиме по всем тикам. Терминалы запускались с RAMDrive. Только одно ядро задействовано. Выбран лучший результат из Оптимизации в 5 прогонов. Кросс-перерасчет выключен. Время указано в секундах. Hedge, Forex, MaxCustom. Исходный баланс 10 млн. В MT5 кастомный символ (свопы и комиссия отсутствуют).

AmountMT5-TesterMT4-TesterMT5-Virtual (x64) MT4-Virtual (x32) (w/o strict)
002.88603.43203.86906.209
108.23711.24704.08706.677
214.36713.08904.19708.159
317.58117.03604.49310.998
420.90522.21504.69610.296
523.11925.61604.94513.558
2061.21568.85807.59735.568


С увеличением одновременно открытых позиций (Amount) заметно растет время выполнения. MT4 проигрывает MT5 по скорости в режиме Тестера и в режиме Virtual.

Virtual значительно быстрее MT5-тестера и слабо зависит от Amount.


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

Virtual не затачивался на большое количество одновременных ордеров, но переваривает их неплохо. Чего не скажешь про MT-тестеры. Там, похоже, отсутствует совсем оптимизация в этом месте.


До теста пришла в голову идея, как ускорить Virtual, чтобы количество ордеров почти не влияло на производительность. Но полученные результаты, честно говоря, удивили. Сложно сказать, стоит ли этим заниматься в Virtual. Но 100% это нужно делать в MT5-Тестере.


ЗЫ После замеров понял, что в MT4 не использовал strict-режим. Перезамерять не стал

 
fxsaber:

До теста пришла в голову идея, как ускорить Virtual, чтобы количество ордеров почти не влияло на производительность.

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

Что же касается вычисления эквити и профита каждого ордера на каждом тике, то это делать только по запросу - AccountEquity, OrderProfit и т.д.


Когда же с ордерами что-то происходит (выставили, модифицировали, исполнился и т.д.), то хранить их в отсортированном виде по Bid/Ask-ценам.


Все в купе позволит почти полностью избавиться от зависимости с количеством одновременных ордеров. Тестеру будет ровно, 5 или 105 ордеров сейчас висит. Скорость будет отличаться незначительно.

 
fxsaber:

Что тестируете? Какой смысл в столь длительной истории тиков? И что за источник? Покажите логи одиночного прохода на советнике-пустышке (открывает только одну позицию на символ).

Где-то приводил цифры, насколько быстро все считаться может. По-моему, Вы боретесь со следствием, а не с причиной.

Смысл в следующем. Основная оптимизация идёт на OHLC M1, а затем на тиках оптимизируются sl, tp, и при необходимости ts, be в некоторой окрестности полученных ранее значений. Результаты на OHLC и тиках очень различаются. Хочется ещё до реальной торговли "внести реалии". Длительная история берется для большей статистики - чтобы включить больше нештатных ситуаций в истории брокера и исключить подгонку под историю.

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

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