English 中文 Español Deutsch 日本語 Português
Walk-Forward оптимизация в MetaTrader 5 - своими руками

Walk-Forward оптимизация в MetaTrader 5 - своими руками

MetaTrader 5Тестер | 8 июня 2017, 15:03
6 510 10
Stanislav Korotky
Stanislav Korotky

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

Цикл эксплуатации эксперта подразумевает, что этапы оптимизации и торговли повторяются из раза в раз с выбранной периодичностью, и трейдер ожидает положительных (или хотя бы безубыточных) результатов на продолжительном отрезке времени. Чтобы убедиться в дееспособности системы, следует многократно повторять в тестере этапы цикла, запуская оптимизацию и форвард-тестирование с постоянным сдвигом текущего периода из прошлого в виртуальное будущее во времени тестера.

Эта процедура называется пошаговой форвард-оптимизацией и широко применяется многими трейдерами. К сожалению, встроенный Тестер MetaTrader не позволяет её запустить одним нажатием клавиши. Вместо этого приходится автоматизировать запуск Тестера с помощью внешних инструментов и склеивать отчеты форвард-тестирования. Хотелось бы иметь возможность выполнять пошаговый форвард-анализ более простым способом, полностью средствами MetaTrader и MQL, без рутинных операций.

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


Проектирование

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

Период, на котором выполняется оптимизация, обычно называют in-sample данными. Последующий период тестирования — out-of-sample данными. Но для простоты изложения будем здесь также использовать соответственно термины "окно оптимизации" (или просто "окно") и "шаг тестирования" (или просто "шаг", "тест").

Идея реализации пошаговой форвард-оптимизации проста. В Тестере нужно выбрать общий период оптимизации D гораздо больше привычного окна оптимизации, отодвинув начальную дату в прошлое, в точку B. Затем надо разрешить эксперту торговать только в рамках текущего окна W предопределенного размера и последующего за ним шага тестирования S, причем D > W >> S. Например, в D должно укладываться 1 окно W и еще десяток шагов S.

Сперва окно будет начинаться в начальной точке B, но потом должно сдвигаться на размер шага вправо, последовательно много раз, вплоть до того, когда правая граница окна упрется в конечную дату общего диапазона оптимизации D.

Показатели для оптимизации следует рассчитывать только на основе торговли в пределах окна W. Показатели торговли на отрезке S также будем считать и сохранять для последующего анализа. Таким образом, для каждого конкретного окна можно определить оптимальные параметры и, зная номер прохода, получить ссылку на соответствующие показатели тестирования.

Это полностью повторяет канонический walk-forward за исключением одного очевидного нюанса: торговля на S начинается не с начального депозита, а с суммы, которую советник успел заработать за время W. Эта особенность ограничивает применимость библиотеки только для стратегий с постоянным лотом. Но большинство трейдеров, пожалуй, согласятся, что проверка с постоянным лотом — обязательный первый пункт программы анализа любого эксперта, даже если планируется включить money management на последующих этапах.

Осуществить вышеописанную "фрагментарную" торговлю, мы можем, добавив в советник специальные входные параметры, которые задавали бы размеры окна W, шага S и номер шага, определяющего смещение окна внутри общего периода D как количество шагов. Например, когда смещение равно 0, окно начинается в стартовой точке B. Когда оно равно 1, окно начинается в момент S и заканчивается в момент S+W. При смещении, равном 2, окно начинается в точке 2*S и заканчивается в 2*S+W, и так далее. Перебор различных смещений мы можем поручить Тестеру, включив оптимизацию по соответствующему параметру. Так мы организуем множество прогонов тестера на участках, включающих in-sample и out-of-sample данные, двигая их по оси виртуального времени.

Остается приспособить этот механизм для работы в качестве последовательной форвард-оптимизации. Для этого надо обеспечить, чтобы оптимизация производилась только по показателям торговли в каждом окне W и игнорировала все последующие тестовые периоды S. Для этого можно выбрать в настройках тестера пользовательский критерий оптимизации и рассчитывать его в библиотеке на основе сделок внутри текущего окна W, возвращая затем в тестер с помощью обработчика события OnTester. Кроме этого, библиотека должна рассчитывать и сохранять где-то показатели торговли на каждом последующем тестовом периоде S. После завершения оптимизации мы будем иметь для каждого окна W со смещением в i шагов множество наборов параметров, среди которых уже будет определен наилучший набор. По номеру этого прохода мы сразу же можем получить показатели торговли на последующем тестовом участке S. Объединив их вместе, мы получим полный отчет о форвард-тестировании на протяжении нескольких циклов внутри D.

Формирование walk-forward теста

Рис.1 Формирование walk-forward теста

Размеры W и S могут варьироваться по усмотрению трейдера. Например, можно выбрать окно оптимизации в 3 месяца и форвард-шаг 1 месяц. Если общий период проверки D равен 12 месяцам, то в тестере нужно перебрать шаги S со смещениями от 0 до 9 (включительно). 9 получено простым расчетом:

N = (D - W) / S = (12 - 3) / 1 = 9 (1)

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

Успешность форвард-оптимизации можно оценить по разным критериям, которые мы рассмотрим ниже. Хотя нам уже интуитивно понятно, что склеенные вместе шаги форвард-тестирования формируют кривую баланса, которая характеризуется привычными показателями профит-фактора, коэффициента Шарпа, матожиданием выигрыша и т.д.

Между тем остановимся на другом вопросе: какие размеры окна W и шага S нужно выбирать. Логично поручить поиск оптимальных значений все тому же Тестеру. Действительно, по аналогии с тем, как мы выполняем перебор шагов форвард-тестирования с помощью специального входного параметра, предоставляемого библиотекой, мы можем включить в список оптимизируемых и её параметры, задающие размер окна и размер шага.

Выполнение пошаговой форвард-оптимизации вместе с подбором лучших размеров окна и шага называется кластерным анализом (cluster walk-forward analysis).

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

Помимо двух описанных режимов работы — кластерного анализа и последовательного форвард-тестирования (которое в англоязычной литературе называется еще rolling walk forward) — библиотека поддерживает и еще один режим — якорный (anchored walk forward optimization). Он отличается от последовательного тем, что стартовая дата окна W никогда не меняется, но на каждом шаге размер окна увеличивается, включая в себя тестовый период предыдущей итерации. Например, если продолжить пример с начальным размером окна 3 месяца и предположить, что общий период D начинается с января, то после первого шага, на котором оптимизация делается за январь-март, а тестирование — на апреле, второй шаг включит оптимизацию на январе-апреле с тестированием в мае, третий — оптимизацию на январе-мае с тестированием в июне, и так далее.

Дело остается за малым — реализовать идею. Программисты, авторы экспертов смогут сами создать для себя такой инструмент. Это хоть и объемная, но прозрачная задача. Для тех же, кто предпочитает получить готовый продукт, имеется уже готовая библиотека WalkForwardOptimizer (WFO), как для MetaTrader 4, так и для MetaTrader 5. Они отличаются некоторыми нюансами, делающими версию для MetaTrader 5 более привлекательной. В частности, в ней:

  • библиотека выполнена в виде единого модуля, который собирает данные оптимизации и строит на их основе отчет. В версии же для MetaTrader 4 файлы генерируются в папке tester/Files, откуда их нужно вручную переносить в папку MQL4/Files, и затем для построения на их основе отчета — запускать отдельный скрипт (все ссылки приведены в конце статьи);
  • исключено большинство рутинных ручных операций, таких как удаление промежуточных файлов перед началом новой оптимизации;
  • происходит автоматическое определение названий и значений рабочих параметров советника (в МТ4 эту информацию нужно явным образом передавать с помощью вызовов соответствующих функций);
  • поддерживается оптимизация в несколько потоков, в том числе с использованием сетевых агентов и вычислительного облака MQL.
В целом, версия для MetaTrader 5 более эффективна и проста в использовании. Это обусловлено более широким набором полезных средств, предоставляемых MQL5 API Тестера.


Реализация

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

input WFO_TIME_PERIOD wfo_windowSize = year;
input int wfo_customWindowSizeDays = 0;
input WFO_TIME_PERIOD wfo_stepSize = quarter;
input int wfo_customStepSizePercent = 0;
input int wfo_stepOffset = 0;
input string wfo_outputFile = "";
input WFO_ESTIMATION_METHOD wfo_estimation = wfo_built_in_loose;
input string wfo_formula = "";

Параметры wfo_windowSize и wfo_stepSize позволяют задать размер окна и шага оптимизации. Для их указания в стандартных единицах определено перечисление WFO_TIME_PERIOD:

#define DAYS_PER_WEEK    7
#define DAYS_PER_MONTH   30
#define DAYS_PER_QUARTER (DAYS_PER_MONTH*3)
#define DAYS_PER_HALF    (DAYS_PER_MONTH*6)
#define DAYS_PER_YEAR    (DAYS_PER_MONTH*12)

#define SEC_PER_DAY     (60*60*24)
#define SEC_PER_WEEK    (SEC_PER_DAY*DAYS_PER_WEEK)
#define SEC_PER_MONTH   (SEC_PER_DAY*DAYS_PER_MONTH)
#define SEC_PER_QUARTER (SEC_PER_MONTH*3)
#define SEC_PER_HALF    (SEC_PER_MONTH*6)
#define SEC_PER_YEAR    (SEC_PER_MONTH*12)

#define CUSTOM_DAYS     -1

enum WFO_TIME_PERIOD
{
  none = 0,
  year = DAYS_PER_YEAR,
  halfyear = DAYS_PER_HALF,
  quarter = DAYS_PER_QUARTER,
  month = DAYS_PER_MONTH,
  week = DAYS_PER_WEEK,
  day = 1,
  custom = CUSTOM_DAYS
};

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

Обратите внимание, что элементы неделя, месяц, квартал, год определены как константы (фиксированное число дней). Выравнивания по календарным границам периодов не происходит. Это позволяет повысить эффективность расчетов и унифицированным образом перемещать окно произвольного размера без привязки к границам недель или месяцев. Если выбран период "месяц" (month), определенный как 30 дней, и отсчет ведется с начала какого-либо месяца, очевидно, что смена каждого последующего календарного месяца может происходить до или после "месячного" шага (поскольку месяцы различаются по числу дней). Если начать процесс с середины месяца, то шаг будет приходиться на середину последующих месяцев, но также со смещением порядкового дня месяца.

Значение custom в wfo_windowSize или wfo_stepSize позволяет задать в следующих параметрах — соответственно, wfo_customWindowSizeDays и wfo_customStepSizePercent — произвольные размеры окна и шага. Как видно из названий параметров, окно определяется в днях, а шаг — в процентах от окна.

Именно с помощью этих параметров организуется перебор размеров во время кластерной оптимизации. Следует выбирать размеры так, чтобы минимальный (начальный) процент и его изменения с заданным приращением, будучи применены к минимальному окну, давали целое число дней. Например, если окно меняется от 10 до 50 с шагом 10, то шаг не имеет смысла делать меньше 10%, поскольку это составляет 1 день от минимального окна. Кроме того, приращение для форвард-шага тоже не стоит брать меньше 10%, поскольку, например, если бы оно было равно 5%, то при размере окна 30 вторая итерация подразумевала бы тест на отрезке 15% (начальные 10% плюс один шаг 5%) от 30, что дало бы 4.5. Подобная настройка, конечно же, не приведет к фатальной ошибке, и библиотека продолжит работу штатно, однако шаги форвард-тестирования могут оказаться не подогнанными точно друг к другу, что скажется на точности расчетов.

К сожалению, в данном контексте библиотека не может предложить удобных средств для упрощения настройки и проверки её корректности. Пользователь (а в нашем случае он хотя бы чуть-чуть программист) должен проверить параметры самостоятельно. Одним из способов решения этой проблемы может быть иная организация библиотеки — в частности, работа с точностью до бара. Поговорим об этом ниже.

Когда размеры wfo_windowSize и wfo_stepSize равны none, библиотека фактически отключается.

Параметр wfo_stepOffset, будучи включенным в число оптимизируемых, позволяет перебирать шаги форвард-тестов. Приращение для него всегда должно быть равно 1. Максимальное значение вычисляется по формуле (1), в которую подставляется максимальный размер окна W и минимальный размер шага S.

Параметр wfo_outputFile задает имя csv-файла, в который будут записываться финансовые показатели прогонов оптимизации. Файл создается в папке MQL5/Files (МТ5) или tester/Files (МТ4).

Параметр wfo_estimation определяет показатель, который будет передаваться в Тестер для оптимизации. Значение может быть одним из перечисления WFO_ESTIMATION_METHOD:

enum WFO_ESTIMATION_METHOD
{
  wfo_built_in_loose,
  wfo_built_in_strict,
  wfo_profit,
  wfo_sharpe,
  wfo_pf,
  wfo_drawdown,
  wfo_profit_by_drawdown,
  wfo_profit_trades_by_drawdown,
  wfo_average,
  wfo_expression
};
  • wfo_built_in_loose (по умолчанию) и wfo_built_in_strict — комплексные индикаторы, составленные из коэффициента Шарпа, фактора прибыли, размера прибыли и количества сделок;
  • wfo_profit — прибыль;
  • wfo_sharpe — коэффициент Шарпа;
  • wfo_pf — профит-фактор;
  • wfo_drawdown — инвертированная относительная просадка  (100 - DD), рассчитываемая на кривой баланса;
  • wfo_profit_by_drawdown — прибыль, деленная на относительную просадку;
  • wfo_profit_trades_by_drawdown — прибыль умноженная на количество сделок и деленная на относительную просадку;
  • wfo_average — средняя прибыль сделки;
  • wfo_expression — пользовательская формула показателя.

Наконец, параметр wfo_formula — это та самая пользовательская формула для расчета показателя, если wfo_estimation задан равным wfo_expression. Более подробно про допустимые формулы и прочие настройки можно прочитать в руководстве пользователя библиотеки.

Все параметры имеют префикс wfo_, чтобы их легко было отличить от рабочих параметров эксперта.

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

Также следует отметить, что заголовок лишь декларирует необходимые типы и мета-параметры. Чтобы заданная с их помощью информация попала внутрь библиотеки, требуется набор открытых функций — программный интерфейс библиотеки. Они также описаны в заголовочном файле в виде директивы импорта (здесь и далее рассматривается версия для МetaTrader 5):

#import "WalkForwardOptimizer.ex5"
void wfo_setEstimationMethod(WFO_ESTIMATION_METHOD estimation, string formula);
void wfo_setPFmax(double max);
void wfo_setCloseTradesOnSeparationLine(bool b);
void wfo_OnTesterPass();
int wfo_OnInit(WFO_TIME_PERIOD optimizeWindow, WFO_TIME_PERIOD optimizeStep, int optimizeStepOffset, int optimizeCustomW, int optimizeCustomS);
int wfo_OnTick();
double wfo_OnTester();
void wfo_OnTesterInit(string optimizeLog);
void wfo_OnTesterDeinit();
#import

Функции с префиксом wfo_set опциональны. Они позволяют установить тот или иной режим работы, но если их не вызвать, будут использоваться значения по умолчанию. Функции с префиксом wfo_On — обработчики соответствующих событий. Они должны быть обязательно добавлены в исходный код эксперта.

Вот пример исходного кода эксперта со встроенной библиотекой. Все параметры функций берутся напрямую из входных мета-параметров.

#include <WalkForwardOptimizer.mqh>

...

int OnInit(void)
{
  // ваш рабочий код здесь
  ...

  // опционально, по умолчанию wfo_built_in_loose
  wfo_setEstimationMethod(wfo_estimation, wfo_formula);

  // опционально, по умолчанию DBL_MAX
  wfo_setPFmax(100);

  // опционально, по умолчанию false
  // wfo_setCloseTradesOnSeparationLine(true);
  
  // обязательно, все параметры из заголовочного файла
  int r = wfo_OnInit(wfo_windowSize, wfo_stepSize, wfo_stepOffset, wfo_customWindowSizeDays, wfo_customStepSizePercent);
  
  return(r);
}

void OnTesterInit()
{
  wfo_OnTesterInit(wfo_outputFile); // обязательно
}

void OnTesterDeinit()
{
  wfo_OnTesterDeinit(); // обязательно
}

void OnTesterPass()
{
  wfo_OnTesterPass(); // обязательно
}

double OnTester()
{
  return wfo_OnTester(); // обязательно
}

void OnTick(void)
{
  int wfo = wfo_OnTick();
  if(wfo == -1)
  {
    // ждем когда начнется окно
    // не торгуем
    return;
  }
  else if(wfo == +1)
  {
    // ждем окончания теста после окна и форварда
    // не торгуем
    return;
  }

  // ваш рабочий код здесь
  ...
}

wfo_OnInit передает все необходимые данные в библиотеку: размер окна, размер шага, номер шага, пользовательский размер окна в днях, пользовательский размер шага в процентах от окна. Она возвращает 0 в случае успеха или код ошибки (например, INIT_PARAMETERS_INCORRECT), если были заданы некорректные параметры.

wfo_OnTick управляет оптимизацией советника внутри окна оптимизации и форвард-теста. Она возвращает 0, если текущий тик (бар) попадает внутрь движущегося фрейма, где советнику разрешено торговать, а также -1 или +1, если тик находится вне окна и торговля должна быть временно отключена (-1 означает, что окно еще не наступило, а +1 - что окно уже прошло).

wfo_OnTester рассчитывает и возвращает тестеру заданный показатель эффективности.

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


Практика

Когда эксперт со встроенной библиотекой скомпилирован, можно приступать к настройке Тестера.

Выберем конкретный диапазон дат в группе полей Интервал: это тот самый общий период D, описанный выше. Обычно конечная дата — это реальное сегодня или нечто близкое к нему.

В поле Форвард следует выбрать вариант Нет (встроенный форвард-тест нам не подходит).

Режим исполнения рекомендуется Обычный, по барам или контрольным точкам. Напомним, что наш walk-forward работает за счет добавления мета-параметров, которые включаются в оптимизацию (в дополнение к рабочим параметрам советника) и тем самым увеличивают вычислительную нагрузку.

В поле Оптимизация можно выбрать медленный режим (полный перебор) или быстрый (с использованием генетики), а Критерий оптимизации обязательно должен быть пользовательским.

Использование генетического алгоритма оптимизации допускается, но нужно иметь в виду некоторые нюансы. Генетический алгоритм пропускает многие комбинации входных параметров, включая сочетания мета-параметров, задающих размер окна, размер форвард-шага и номер шага, из-за чего некоторые форвард-тесты могут отсутствовать. Эта проблема может быть заметной при очень большой размерности пространства поиска (если много рабочих параметров эксперта или их приращений), но в остальных случаях этим можно пренебречь. В формируемом отчете пропуски помечаются, и на основе этой информации можно принять решение, нужно ли попытаться уменьшить пространство оптимизации.

Эта проблема чаще возникает при кластерной оптимизации. Последовательная или якорная форвард-оптимизации менее подвержены ей.

Генетический алгоритм может неравномерно "расставлять приоритеты" между окнами оптимизации с различными смещениями, в зависимости от их прибыльности. Например, если первый месяц торговли был объективно более трудным, чем второй, тестер, скорее всего, уделит больше внимания параметру wfo_stepOffset со значением 1, чем 0. Иными словами, генетическая оптимизация на множестве окон внутри диапазона дат D дает не такие оптимальные результаты, как генетическая оптимизация на конкретном окне W (с отключенной библиотекой). Единственное решение этой проблемы — использование медленного полного перебора всех параметров и мета-параметров.

С другой стороны, walk-forward выполняет задачи по проверке устойчивости алгоритма на out-of-sample данных, а также по подбору наилучшей глубины истории для оптимизации и шага переоптимизации (как часто искать новые настройки). Эти функции нормально выполняются и без нахождения оптимальных параметров.

Настройте рабочие параметры эксперта, требующие оптимизации, как обычно. Конфигурация мета-параметров зависит от того, какой режим walk-forward оптимизации нужно включить.

Последовательная пошаговая форвард-оптимизация на предопределенных периодах
  1. Выберите окно оптимизации из списка с помощью wfo_WindowSize
  2. Выберите размер форвард-шага из списка в wfo_stepSize
  3. Включите оптимизацию для wfo_stepOffset в диапазоне от 0 до любого количества шагов, умещающегося в доступной истории, с шагом 1.
Последовательная пошаговая форвард-оптимизация на произвольных периодах
  1. Выберите custom из списка параметра wfo_WindowSize
  2. Введите количество дней в wfo_customWindowSizeDays
  3. Выберите custom размер для параметра wfo_stepSize
  4. Введите размер в wfo_customStepSizePercent, как процент от размера окна
  5. Включите оптимизацию для wfo_stepOffset в диапазоне от 0 до любого количества шагов, умещающегося в доступной истории, с шагом 1.
Кластерная пошаговая форвард-оптимизация
  1. Выберите размер окна оптимизации в wfo_WindowSize как custom.
  2. Включите оптимизацию для wfo_customWindowSizeDays для любого подходящего диапазона и приращения в днях.
  3. Выберите размер форвард-шага в wfo_stepSize как custom.
  4. Включите оптимизацию для wfo_customStepSizePercent для любого подходящего диапазона и приращения в процентах от размера окна (рекомендуемый диапазон значений 5-30%, шаг 5-10%).
  5. Включите оптимизацию для wfo_stepOffset в диапазоне от 0 до любого количества шагов, умещающегося в доступной истории, с шагом 1.
Если у вас есть предпочтительный размер окна оптимизации, можете запустить кластерный анализ только для меняющегося шага, а если у вас уже подобран размер шага, то можно менять только размер окна.

Якорная пошаговая форвард-оптимизация
  1. Выберите размер окна оптимизации в wfo_WindowSize как custom.
  2. Включите оптимизацию для wfo_customWindowSizeDays на желаемом диапазоне. В качестве приращения выберите количество дней, равное длине предопределенного периода, который будет установлен на следующем этапе (например, введите приращение 30 дней, если собираетесь использовать шаг "месяц").
  3. Выберите размер шага из списка предопределенных констант wfo_stepSize, причем константа должна быть равна приращению, указанному выше для размера окна.
  4. Отключите оптимизацию для wfo_stepOffset и установите его значение в 0.

Когда все настроено, запустим оптимизацию и дождемся её завершения. Приостанавливать и затем продолжать оптимизацию, как это разрешено делать для штатной оптимизации, в случае работы с библиотекой нельзя. Связано это с тем, что приостановка и продолжение работы тестера не имеют соответствующих программных событий в MQL5 API, и потому кэш данных библиотеки невозможно синхронизировать с кэшем тестера. Иными словами, каждое нажатие кнопки Старт вызывает полную инициализацию библиотеки, вне зависимости от внутреннего состояния Тестера, и библиотека начинает собирать данные проходов заново, с нуля. Если это было возобновление ранее приостановленной оптимизации, то все данные собранные библиотекой до паузы, будут потеряны. Рекомендуется на всякий случай очищать папку tester/cache перед началом walk-forward оптимизации.

В процессе оптимизации WFO создает специальные глобальные переменные (они сохраняются в "архивный" файл с расширением GVF) и CSV-файл с данными в папке MQL5/Files. После этого на их основе автоматически формируется html-страница с расшифровкой результатов. Имена GVF и HTML файлов совпадают с именем CSV-файла, заданного в библиотеке через параметр wfo_outputFile.

Возьмем простой эксперт и на его примере рассмотрим, какие отчеты можно получить с помощью библиотеки в разных режимах. Эксперт был сгенерирован мастером MQL5 на основе двух торговых стратегий — Envelopes и WPR. Он доступен в Маркете как бесплатный продукт.

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

Эксперименты будем проводить на графике EURUSD D1. Для начала попробуем получить простой rolling walk-forward отчет. Зададим общий период тестирования 2015.01.01-2017.06.01.

Настройки тестера

Рис.2 Настройки тестера

В эксперте предусмотрен параметр EnableWFO, который по умолчанию равен false. В этом случае библиотека отключена, и эксперт торгует в обычном режиме. Для включения библиотеки следует поменять значение флага на true.

Оставим значение по умолчанию в wfo_windowSize, то есть year, а также значение по умолчанию quarter в параметре wfo_stepSize. Это задает перемещение окна оптимизации размером 1 год со смещениями в 1 квартал, и квартал является одиночным форвард-тестом. Это дает (2.5 года - 1 год) / 3 месяца = (30 - 12) / 3 = 6 шагов форвард-тестирования.

Зададим имя файла demo.csv в wfo_outputFile.

Из числа рабочих параметров советника будем оптимизировать уровни Stop Loss и Take Profit, период и девиацию Envelopes, а также период WPR. Набор параметров (wfo-demo-rolling.set) приложен в конце статьи.

Настройки эксперта

Рис.3 Настройки эксперта

После оптимизации получим отчет demo.html следующего вида.

Отчет rolling walk-forward

Рис.4 Отчет rolling walk-forward

Как видно из отчета, эксперт очень плохо ведет себя на форвард-периодах. Но из научной практики известно, что отрицательный результат — тоже полезный результат.

Теперь попробуем получить кластерный отчет и подобрать размеры окна оптимизации и шага, в которых прибыль будет стабильной. Для этого в параметрах wfo_windowSize и wfo_stepSize выберем вариант custom, а затем настроим wfo_customWindowSizeDays для оптимизации от 90 до 180 дней с шагом 30 и wfo_customStepSizePercent — от 10 до 30% с шагом 10. Максимальное количество шагов в wfo_stepOffset получим как частное от (2.5 года - 90 дней) / (90 дней * 10%) = 810 / 9 = 90. Набор параметров (wfo-demo-cluster.set) приложен в конце статьи.    

Ниже показан пример полученного отчета (более подробно показатели рассмотрены в следующем разделе — Анализ).

Кластерный walk-forward отчет

Рис.5 Кластерный walk-forward отчет

Многие ячейки таблицы демонстрируют удовлетворительные результаты. Уточним, например, что именно скрывается под конфигурацией с окном 120 дней и шагом 30%. Для этого кликнем на соответствующей ячейке и увидим детализацию форвард-тестирования.

Уточняющий rolling walk-forward отчет

Рис.6 Уточняющий rolling walk-forward отчет

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

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


Анализ

Генерируемый отчет содержит разные данные, в зависимости от выбранного режима работы библиотеки. При кластерном анализе отчет начинается с нескольких таблиц, содержащих итоговые показатели множества последовательных walk-forward тестов. В каждой таблице, колонки соответствуют размерам окна W в днях, а строки — размерам шага S в процентах. Каждая ячейка в таблице — гиперссылка, по нажатию на которую осуществляется переход к соответствующему отчету последовательного walk-forward теста. Таким образом, можно уточнить, как получился любой итоговый показатель.

В таблицах кластерного анализа выводятся следующие показатели:

  • Годовая прибыль (annualized profit/loss) — гипотетическая прибыль советника за год при пересчете заработанного пропорционально периодам оптимизации и тестирования.
  • Эффективность (efficiency) — соотношение годовой прибыли на тестовом периоде и периоде оптимизации одного и того же прогона.
  • Стабильность (consistency) — процент прибыльных проходов среди всех тестовых проходов "склеенного" форварда.
  • Полнота (completness) — количество форвард-шагов, выполненных для конкретных сочетаний размеров окна и форвард-шага; оно может быть меньше запрошенного числа во время генетической оптимизации, из-за пропуска некоторых значений параметров; количество пропущенных шагов указывается мелким шрифтом в круглых скобках.
  • Количество дней (days in step) — количество дней в шаге для каждого сочетания размеров окна и шага, используется для перевода размера шага из процентов в дни.

Годовая прибыль, эффективность и стабильность — основные критерии оценки успешности форвард-тестирования. Понятно, что, чем они выше, тем лучше. Рекомендуется иметь стабильность выше 50%. Наилучшие варианты подсвечиваются в таблицах кластерного анализа зеленым цветом.

Дополнительно имеет смысл обращать внимание на просадку, матожидание и стандартное отклонение прибыли — они доступны в уточняющих стандартных отчетах.

Отчеты стандартных (последовательных) тестов строятся не только как уточняющие для вариантов кластерного анализа, но и сами по себе — как результаты простой rolling walk-forward оптимизации.

Для стандартного (последовательного) или якорного walk-forward теста отчет представляет собой таблицу со всеми прогонами тестера, сформировавшими данный объединенный форвард. В каждой строке выводятся торговые показатели — прибыль, профит-фактор, общее количество сделок и прибыльных сделок, просадка, коэффициент Шарпа — раздельно для периодов оптимизации и тестирования. Показатели оптимизации подсвечены голубым, а на тестовом периоде — желтым. Если последний шаг захватывает "текущее" время (конечную дату тестирования), он подсвечивается зеленым, указывая на то, что это последние известные параметры, а потому применимые для "текущей" торговли. Разумеется, "текущее" время является настоящим текущим только в том случае, если конечной датой оптимизации установлен сегодняшний день.

В первых трех колонках форвард-отчета выводятся номер прохода тестера, начальная дата окна оптимизации (in-sample), начальная дата тестового периода (out-of-sample) и дата его окончания. В последней колонке отчета выводятся значения параметров, найденные в результате оптимизации в пределах окна. Подсказку по названиям параметров можно получить, наведя курсор мыши на заголовок колонки.

При использовании генетического метода оптимизации номера проходов во встроенном отчете отображаются не как число, а в виде "номер поколения, номер экземпляра", поэтому установить соответствие между строками встроенного отчета и строками отчета библиотеки WFO можно только по параметрам. При использовании медленного метода оптимизации этой проблемы нет, и номера проходов в обоих отчетах совпадают. Это особенность платформы MetaTrader 5, а не библиотеки.

Выполнив двойной клик на соответствующей строке встроенного отчета тестера, пользователь может воспроизвести торговлю эксперта в конкретном окне walk-forward оптимизации и последующем шаге walk-forward тестирования. Обратите внимание, что торговля вне этого диапазона дат вестись не будет. Чтобы увидеть, как бы эксперт торговал с этим набором вне окна, следует отключить библиотеку или поставить wfo_windowSize в значение none.

После таблицы изображается схематический график кривой баланса.    

Подведем промежуточный итог. Мы сумели организовать в упрощенном виде walk-forward оптимизацию непосредственно в тестере МетаТрейдер. Она работает и дает интересные результаты. Однако настройка параметров библиотеки — процесс нетривиальный. У некоторых пользователей подбор корректных мета-параметров вызывает затруднения. Другая проблема связана с производительностью. Поскольку работа библиотеки основывается на дополнительных мета-параметрах, которые участвуют в оптимизации, пространство поиска существенно увеличивается, а следовательно, требуется больше вычислительных ресурсов. Можно ли как-то упростить ситуацию? Да, можно. Но для этого нам придется изобрести велосипед еще раз, то есть пересмотреть принципы работы библиотеки и фактически реализовать другую библиотеку. 


Walk-forward для ленивых и занятых

Новая библиотека также будет встраиваться в эксперт, но параметров не экспонирует и настройки не предполагает. Эксперт будет запускаться на оптимизацию на общем (увеличенном) периоде D. Отличие от обычной оптимизации здесь только в этом периоде, поскольку штатная оптимизация выполняется пользователем на выбранном им окне W. В процессе оптимизации на D новая библиотека собирает информацию о всех сделках, исполняемых экспертом (для различных наборов параметров). Иными словами, для каждого прохода тестера формируется файл, куда на каждом баре записывается текущий баланс, плавающая прибыль и количество открытых позиций. Оказывается, что после завершения оптимизации на основе этих данных можно построить различные walk-forward отчеты, аналогичные рассмотренным выше. В случае MetaTrader 4 это может сделать отдельный скрипт, а в случае MetaTrader 5 - сама библиотека.

У этой библиотеки также доступны версии и для MetaTrader 4, и MetaTrader 5, но для разнообразия рассмотрим здесь реализацию для MetaTrader 4. Полная документация вместе с нюансами о различии версий опубликована в блоге.

Поясним принцип работы облегченной библиотеки.

При её использовании тестер фактически не выполняет оптимизацию как таковую, а перебирает различные комбинации входных параметров. Выбор оптимальных наборов для каждого окна выполняется во время построения отчета. Скрипт выделяет из общего периода D требуемое in-sample окно W, вычисляет в нем показатели эффективности для всех проходов тестера (каждый проход — отдельный набор параметров) и находит наилучший вариант. Далее из этого же прохода остается вычислить показатели эффективности торговли на последующего шаге out-of-sample тестирования S.

Данный алгоритм реализует walk-forward нестандартным образом. Это позволяет добиться простоты использования, но имеет и побочные эффекты. В частности, при использовании генетического метода оптимизации вносится некоторая предвзятость из-за того, что проверяемые наборы параметров оптимальны в глобальном смысле (на всем периоде D, а не текущем окне W). Это можно расценивать как заглядывание в будущее. Однако, с другой стороны, наилучшие в глобальном смысле параметры, скорее всего, будут давать меньшие прибыли, чем параметры, которые могли бы быть найдены при локальной оптимизации на окне W.

В любом случае, данная проблема отсутствует при медленном полном переборе параметров.

Также следует отметить, что эксперт торгует на всем периоде D, и из этого есть 2 следствия.

Во-первых, к началу конкретного окна W баланс может быть произвольным. По аналогии с WFO, это означает, что новая библиотека применима только для стратегий с постоянным лотом.

Во-вторых, некоторые позиции могут во время своего существования пересекать начальную или конечную границы окна, т.е. в момент начала окна открытая позиция может уже существовать и иметь плавающую прибыль, или позиция может быть открыта внутри окна, а закрываться — уже на этапе форвард-теста. Эта неточность — плата за упрощение процесса. С увеличением количества сделок негативный эффект от этого снизится до пренебрежимо малой величины. Например, при использовании неттингового счета максимум одна позиция может исказить показатели на входе окна, и максимум одна позиция — на выходе. Если в окно W попадает 100 удвоенных сделок вход/выход, то средняя погрешность вычислений составит не более 2% от среднего размера сделки.

Интерфейс библиотеки в заголовочном файле wfL.mqh очень прост. 

#import "wfL.ex4"
  int wfl_OnInit(const int cleanUpTimeout);
  void wfl_OnTick();
#import

Процедура встраивания в код эксперта также существенно упрощается.

#include <wfL.mqh>

int OnInit()
{
  // ... рабочий код
  wfl_OnInit(60);
}

void OnTick()
{
  // ... рабочий код
  wfl_OnTick();
}

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

Период оптимизации должен содержать минимум 200 баров, но рекомендуется 1000 и более. Это связано с тем, что разбивка общего периода на окна и шаги форвард-тестов производится по барам, и наборы проверяемых значений размеров окон и смещений предопределены в коде библиотеки: размер окон варьируется от 10% до 50% с приращением 10% (заметьте, что здесь размер окна задается как процент от общего диапазона тестирования D), а размер шага S — от 5% до 30% с приращением 5%.

После завершения оптимизации в папке Tester/Files создается каталог вида:

<EA name>-<Symbol>-<Timeframe>-<Date>-<Time>

В нем находятся csv-файлы с метаданными, собранными библиотекой во время каждого прохода тестера. Каждая запись в файле содержит информацию по одному бару: дату и время, баланс, плавающая прибыль и количество открытых сделок. С помощью этой информации можно рассчитать прибыли и убытки на любом окне внутри периода. Информация об отдельных сделках не хранится и не анализируется.

Переместив указанную папку вместе со всеми файлами из Tester/Files в MQL4/Files, можно запустить скрипт построения отчета — название папки укажите во входном параметре. Указывается и критерий оптимизации, по которому будут отбираться лучшие наборы параметров внутри конкретных окон. Доступные критерии — те же, что в полной версии библиотеки WFO. В итоге получается кластерный отчет с уточняющими последовательными walk-forward тестами (его пример приведен выше).

Все небольшие минусы, упомянутые выше, с лихвой компенсируются суперпроизводительностью и простотой применения. За счет того, что мета-параметров в данном случае нет, walk-forward оптимизация не привносит никаких накладных расходов по сравнению с привычной оптимизацией по выбранным рабочим параметрам эксперта.


Заключение

Итак, мы рассмотрели возможные принципы построения и реализации технологии walk-forward оптимизации в рамках имеющихся на данный момент средств встроенного Тестера терминалов. Описанные готовые библиотеки позволяют протестировать подход с минимальными усилиями. Некоторые упрощения и ограничения библиотек, с одной стороны, отличают получившийся вариант walk-forward от канонического, но с другой стороны, обеспечивают простоту использования и не требуют никаких внешних программ. До тех пор, пока MetaTrader не имеет встроенной возможности проводить walk-forward оптимизацию, подобные библиотеки предоставляют приемлемую альтернативу.


Сводная таблица продуктов

Продукт MT4 MT5

WFO: WalkForwardOptimizer & WalkForwardReporter

WalkForwardOptimizer
Библиотека
https://www.mql5.com/ru/market/product/17683 https://www.mql5.com/ru/market/product/23068
WalkForwardReporter
Скрипт
https://www.mql5.com/ru/market/product/17750 (не требуется,
библиотека MT5 WFO строит отчеты автоматически)
WalkForwardDemo
Эксперт
(нет) https://www.mql5.com/ru/market/product/23069

WFL: WalkForwardLight & WalkForwardBuilder

WalkForwardLight
Библиотека
https://www.mql5.com/ru/market/product/23223 https://www.mql5.com/ru/market/product/23224
WalkForwardBuilder
Скрипт
https://www.mql5.com/ru/market/product/23225 https://www.mql5.com/ru/market/product/23226
(опция)

Щелчок по значку ведет на страницу соответствующего продукта.



Параметры для последовательного (rolling) WF-анализа демо-эксперта — wfo-demo-rolling.set

Параметры для кластерного WF-анализа демо-эксперта — wfo-demo-cluster.set

Прикрепленные файлы |
Последние комментарии | Перейти к обсуждению на форуме трейдеров (10)
Luchezar Shalomaev
Luchezar Shalomaev | 3 дек. 2019 в 10:33

Здравствуйте. Подскажите пожалуйста, можно ли средствами MT5 реализовать подобный подход по следующему алгоритму:

1. Оптимизация на отрезке (например месяц) потом тест на следующем отрезке (например тоже месяц) на параметрах лучшей прибыли/большего числа трейдов или других заданных пользователем.

2. Сдвиг на определенный период (пусть опять будет месяц) с записью результатов в файл. Например - исследуем 2018 год.

1 месяц - оптимизация, 2 месяц тест на настройках с лучшей прибылью - запись результатов

2 месяц - оптимизация 3-месяц тест на настройках с лучшей прибылью - запись результатов

......

11 месяц - оптимизация 12-месяц тест на настройках с лучшей прибылью - запись результатов?

fxsaber
fxsaber | 3 дек. 2019 в 10:44
Luchezar Shalomaev:

Здравствуйте. Подскажите пожалуйста, можно ли средствами MT5 реализовать подобный подход по следующему алгоритму:

1. Оптимизация на отрезке (например месяц) потом тест на следующем отрезке (например тоже месяц) на параметрах лучшей прибыли/большего числа трейдов или других заданных пользователем.

2. Сдвиг на определенный период (пусть опять будет месяц) с записью результатов в файл. Например - исследуем 2018 год.

1 месяц - оптимизация, 2 месяц тест на настройках с лучшей прибылью - запись результатов

2 месяц - оптимизация 3-месяц тест на настройках с лучшей прибылью - запись результатов

......

11 месяц - оптимизация 12-месяц тест на настройках с лучшей прибылью - запись результатов?

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

Делается через средства автоматического управления Тестером. Руки еще не дошли выложить готовое решение.

Luchezar Shalomaev
Luchezar Shalomaev | 3 дек. 2019 в 13:18
fxsaber:

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

Делается через средства автоматического управления Тестером. Руки еще не дошли выложить готовое решение.

Спасибо вот это будет работать если вставить туда свой советник?

#include <WalkForwardOptimizer.mqh>

...

int OnInit(void)
{
  // ваш рабочий код здесь
  ...

  // опционально, по умолчанию wfo_built_in_loose
  wfo_setEstimationMethod(wfo_estimation, wfo_formula);

  // опционально, по умолчанию DBL_MAX
  wfo_setPFmax(100);

  // опционально, по умолчанию false
  // wfo_setCloseTradesOnSeparationLine(true);
  
  // обязательно, все параметры из заголовочного файла
  int r = wfo_OnInit(wfo_windowSize, wfo_stepSize, wfo_stepOffset, wfo_customWindowSizeDays, wfo_customStepSizePercent);...............
fxsaber
fxsaber | 3 дек. 2019 в 13:39
Luchezar Shalomaev:

Спасибо вот это будет работать если вставить туда свой советник?

Это к автору статью. Но она все же рассчитана на программистов.

Stanislav Korotky
Stanislav Korotky | 3 дек. 2019 в 15:11
Luchezar Shalomaev:

Спасибо вот это будет работать если вставить туда свой советник?

Приведенный код неполный - нужно задействовать еще несколько обработчиков - это есть в примерах. Но, размеется, нужно сама библиотека (не только заголовочный файл). Если Вы приобрели библиотеку, пишите в личку.

Кроссплатформенный торговый советник: Сигналы Кроссплатформенный торговый советник: Сигналы
В статье обсуждаются классы CSignal и CSignals, которые будут использоваться в кроссплатформенных торговых советниках. Рассмотрены различия между MQL4 и MQL5 в организации данных, необходимых для оценки полученных торговых сигналов. Итог — код, совместимый с компиляторами обеих версий.
Паттерн Флаг Паттерн Флаг
В статье рассматриваются паттерны Флаг, Вымпел, Клин, Прямоугольная формация, Сужающийся треугольник, Расширяющийся треугольник. Анализируются их сходство и различия, создаются индикаторы для их поиска на графике и индикатор-тестер для быстрой оценки их эффективности
Пользовательские индикаторы и инфографика в CCanvas Пользовательские индикаторы и инфографика в CCanvas
В статье рассматриваются новые виды индикаторов с более сложной структурной реализацией. Описывается построение псевдообъемных типов индикаторов и создание динамично изменяющейся инфографики.
Кроссплатфоменный торговый советник: Менеджер ордеров Кроссплатфоменный торговый советник: Менеджер ордеров
В статье обсуждается создание менеджера ордеров для кроссплатформенного торгового советника. Менеджер ордеров отвечает за открытие и закрытие экспертом ордеров или позиций, а также за ведение независимой записи о них, и будет доступен для обеих версий терминала.