Заметка

Тестирование и оптимизация — как не обмануть самого себя. Форвардное тестирование.

  4  

Хочу в данной заметке обсудить варианты правильного тестирования систем касаемо оптимизации параметров. Главная цель данной заметки – это выбор такой методики тестирования и оптимизации, которая исключит шанс подгонки результатов под исторические данные.

Под подгонкой будем понимать хорошие результаты тестов на выбранных для оптимизации исторических данных и последующее отвратительное поведение системы на реальных торгах – в общем, любое несоответствие между результатами реальной торговли и исторического тестирования. Хорошо, когда у системы нет никаких настраиваемых параметров, или параметры выбраны из здравого смысла – то есть автор может объяснить, почему он взял именно такие значения, а не иные, какая идея в этих значениях заложена (вариант «а почему бы и нет?» не катит). Тогда обычный бектест покажет, работает ли наша система или нет.

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

Для иллюстрирования дальнейших выкладок, я буду в пример приводить простейшую трендовую систему на основе пробоев. Код системы применительно к Амиброкеру будет в конце.

Правила:

  1. Вход. Пробой канала, построенного по хаям/лоям свечей на каком-то периоде. Под пробоем будем понимать закрытие свечки выше/ниже границ канала. Вход осуществляется на открытии следующего после пробоя баре. Тут у нас будет первый оптимизируемый параметр – период пробоя.
  2. Ведение позиции. Позицию будем держать, пока не выбьют по стопу, она ведь у нас трендовая? Если свечка пробьет стоп и закроется ниже (для лонга) или выше (шорт), то выходим из позиции на открытии следующего бара.
  3. Стоп. Это будет трейл-стоп на основе ATR, отсчитываемого от цен закрытия баров. Формула такая (для лонга): STOP[bar] = C[bar-1] – ATR[bar-1]*factor. Тут у нас, вообще-то говоря, 2 параметра – это период расчета ATR и множитель, на который он умножается для последующего расчета стопа. Будем для простоты считать, что период расчета ATR будет совпадать с периодом пробоя, а оптимизировать мы будем только множитель factor.
  4. ММ. Опять же для простоты возьмем самое примитивное правило управления капиталом – входим всегда процентом от доступного капитала. Скажем – 200%, мы же хотим скорее  разбогатеть и забросить этот трейдинг, найдя более спокойные и приятные способы времяпрепровождения

Период тестирования: 1 августа 2005 – 31 декабря 2011, инструмент – фьючерс на индекс РТС. Вкратце, данных для тестирования должно быть достаточно, чтобы система наторговала от 50 сделок и выше, и состояния рынка должны быть самыми разнообразными – должны быть и тренды различной величины и направленности, и боковики.

Таймфрейм: 15 минут. Типичный таймфрейм для интрадейной системы. Это, кстати, один из неявных параметров системы, который тоже можно попытаться соптимизировать.

Проскальзывание – 25п на каждую сторону сделки, комиссия 5п на сделку.

Под оптимизацией будем понимать подбор параметров системы, при которых достигается оптимальное значение какого-либо критерия типа прибыли или прибыли/риск – кому что важнее. При этом для оптимизации стоит выбирать только те параметры, которые могут значительно повлиять на конечный результат торговли. К примеру, оптимизация по CAR/MDD поможет получить как можно более гладкую кривую эквити, а по Profit Factor'у наиболее безрисковую торговлю (с точки зрения просадки).

Далее, важно при оптимизации выбирать такие значения параметров, незначительные изменения которых не приводят к значительному изменению конечного результата. Другими словами, если построить график зависимости конечного результата от значений оптимизируемого параметра, то его оптимум должен лежать на равномерной части графика без резких пиков/впадин. Такой график называется «картой оптимизации». Рассмотрим для примера карту оптимизации для периода пробоя:

При расчете графика считалось, что множитель ATR постоянен и равен 1.6. Из графика видно, что логично брать оптимальный параметр, лежащий в области от 50 до 80. Вне этих пределов доходность резко падает. А что же будет, если мы будем просто брать лучшие значения параметров? Тогда есть вероятность попасть на такой график (все совпадения с реальными системами чисто случайно):

При полном переборе значений тестером будет выбрана точка на пике, а не область левее на плато.

А так как система редко ведет себя в будущем так же, как и в прошлом, то конечно существует ошибка расчета оптимального параметра, которая приведет к тому, что мы попадем не на пик, а чуть левее/правее – и получим совсем другую доходность, отличную от ожидаемой.

Возвращаюсь к нашему периоду пробоя, видим, что лучшие результаты достигаются на плато с интервалом изменения параметра от 50 до 80. Этот диапазон отвечает критерию более-менее равномерного распределения зависимости доходности от параметра. В качестве оптимального параметра рекомендуется брать то значение, соответствующее наиболее глубокому спаду на этом плато – в данном случае, этот параметр равен 78.

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

А как быть с 3, 4, и так далее число параметров? По-хорошему, а зачем нам столько параметров? Историческое тестирование и оптимизация таят в себе огромную опасность, заключающуюся в подгонке под историческую кривую цен. Обычно чем больше в системе правил и настраиваемых параметров, тем сильнее риск подгонки – то, что мы выберем параметры, лежащие на пике кривой доходности. В идеале, число параметров, поддающихся периодической настройке, не должно превышать 4 – 5. При этом, чем грубее будет осуществляться оптимизация (шаг изменения параметра), тем меньше риск подгонки.

Если же требуется проводить оптимизацию сразу 3х и больше параметров, то лучше призвать для этого генетические алгоритмы оптимизации типа CMA-ES в Амиброкере или Монте-Карло в Велс-лаб. Главное свойство этих алгоритмов в том, что они ищут субоптимальные значения параметров, которые лежат на гладкой (дифференцируемой) части графика, где доходность спадает и нарастает плавно. Тут, конечно возникает другой вопрос – мы можем недооценить потенциал системы и получать в тестах худшие результаты, на которые она могла бы быть способна в реальности. К примеру, на карте оптимизации может существовать несколько плато с разными уровнями доходности, и генетический оптимизатор выберет не самое высокое. Но это только повышает надежность полученных результатов.

Ок, допустим мы тем или иным способом выбрали оптимальные параметры и получили примерно такой график эквити на истории:

Вроде все здорово, рост похож на экспоненту. За 6 с небольшим лет заработали 6500%, не 100500% но тоже неплохо, сделок 1676 – хорошее значение для статистической значимости результатов. Смущает только макс. просадка в почти 40%, невысокий Profit Factor (1.18) и средняя прибыль на сделку (0.16%).

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

Ввод системы в эксплуатацию проходит в 2 этапа: сначала проводится оптимизация на существующих данных, а потом уже торговля – на текущих неизвестных рыночных. После чего ведется сравнение поведения системы в реальности с  результатом бектеста.

Для приближения результатов тестирования на истории к реальным торгам был придуман форвардный тест. Смысл его следующий. Выбирается 2 временных окна:

1.            IS (in-sample). Окно, на котором проводится оптимизация параметров системы, их подстройка под текущее состояние рынка. Размер окна может быть в пределах от месяца до года и более. Требования примерно те же, что и для выбора всего периода тестирования – данные должны включать самые различные состояния рынков – система должна или зарабатывать или, по крайней мере, не сильно сливать на любой фазе рынка. Тут мы приходим к палке о двух концах. Если выбрать слишком длинное окно IS, то система не будет реагировать на новую рыночную  моду, и обучение будет проходить медленно. Если же данных будет мало, то рискуем ее тупо подогнать под котировки. Истина как обычно где-то посередине.

2.            OOS (out-of-sample). Окно, на котором проводятся торги теми оптимальными параметрами, полученными для IS-окна. Размер окна колеблется от недели до месяца и более. Главное требование – число сделок от 20 и выше для статистической валидности результата торгов. В Амиброкере есть еще один ньюанс, который влияет на конечный результат: если в конце OOS-периода система была в рынке, тестер закроет сделку, что вряд-ли согласуется с правилами выхода из позиции.

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

Алгоритм теста следующий. Сначала берется временное окно IS и на нем оптимизируется система, потом на интервале OOS, следующим за IS, приводится торговля. Далее окно IS сдвигается на размер OOS и уже на этом интервале проводится оптимизация. Потом снова торговля. И так далее. То есть торговля идет постоянно, а исторические данные, на которых оптимизируется система, периодически меняются. Система постоянно торгует на неизвестных ей данных, периодически подстраиваясь под рынок на новых данных. Тем самым мы полностью исключаем риск подгонки.
В описании к программе Amibroker есть очень наглядная графическая схема этого теста:

На желтых отрезках данных проводится оптимизация системы, на синих отрезках – торговля. В этом примере я решил взять IS = 6 месяцев, OOS = 1месяц. Оптимизация проводилась генетическим алгоритмом, критерий оптимальности – CAR/MDD.

Далее, объединяя результаты отдельных OOS-тестов, получаем совокупный результат за весь тестируемый период. Ниже график доходности в экспоненциальном масштабе:

Хм, этот график немного не совпадает с тем, что мы получили при простой оптимизации. Для системы, которая стабильно зарабатывает из месяца в месяц, график доходности в экспоненциальном масштабе должен примерно выглядеть как наклонная прямая. У нас тут скорее 2 прямых – одна наклонная (хорошо), другая горизонтальная (не очень хорошо). Видно, что система не рабочая, с 2007 года система зарабатывает разве что только брокеру на комиссию. Если попытаться протестировать систему на 2012 году с оптимальными параметрами 2005-2011 теста, то результаты также оказались плачевными (-15% за 8 месяцев).

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

Прикрепленные файлы

·   example.rar

Комментарии

spitfire — 27 августа 2012 г.

Пардон, не разобрался как выложить код с системой - жду комментариев :)

0 +

KoDeMe — 27 августа 2012 г.

Ну что сказать? С почином :)

В статье вроде все верно, вот только для большей адекватности "карту оптимизации" нужно строить в логарифмическом масштабе по оси Х, чтобы избежать искажения результатов.
Нас же интересует не просто пиковое значение CAR/MDD, а наиболее стабильная область значений. Так чтобы при незначительном изменении оптимизируемого параметра результат не сильно менялся.
При этом нужно понимать, что в % соотношении изменение параметра на 5 единиц в начале оси Х значительно больше, чем где-то в отдалении от точки 0.
Короче эксель с этим хорошо справляется.

Хотя конечно ами оптимизирует тупо по пиковому значению CAR/MDD.

0 +

spitfire — 27 августа 2012 г.

KoDeMe, не вижу большой разницы в каком масштабе смотреть карту - и там и там надо искать стабильную область параметров. Насчет оптимизации в Ами - тупо оптимизирует если брать Exhaustive Engine, если же в настройках кода прописать генетику, то будет оптимизировать не тупо и пик отфильтрует :)

0 +

KoDeMe — 27 августа 2012 г.

ну не видишь и хорошо :)

0 +

OmegaJN — 28 августа 2012 г.

Пришлите файл который хотите вложить в заметку по адресу - yreshetnikov@msk.bcs.ru

0 +

OmegaJN — 28 августа 2012 г.

Выложен. Файл в формате АМБ. Можно просмотреть через "Блокнот".

0 +

Shara — 18 февраля 2013 г.

OmegaJN, а почему файл для скачки просит СМС отправить с сотового?

0 +

orekton — 18 февраля 2013 г.

Shara, отправлять не нужно. Нужно ввести код с полученной смс

0 +

ALendi — 29 августа 2012 г.

spitfire, спасибо за статью! Каким образом по результатам форвардного теста мы вибираем оптимальные параметры? Или это просто првоерка системы на устойчивость к оптимизации?

0 +

spitfire — 29 августа 2012 г.

ALendi, я лично торгую в точности как в форвардном тесте. То есть по шагам:
1. Ты сделал систему - тебя все устраивает. Ты выбрал IS=6 месяцев, OOS=1месяц. Торги начнешь в начале след месяца для удобства отчета.
2. В конце месяца проводишь оптимизацию системы за 6 последних месяцев.
3. Торгуешь с этими параметрами месяц.
4. В конце месяца проводишь снова оптимизацию за 6 месяцев.
5 Торгуешь с новыми параметрами.
6. И т.д.
ХХ. Профит!

0 +

ALendi — 30 августа 2012 г.

spitfire, сколько сделок на периоде IS?

0 +

spitfire — 30 августа 2012 г.

ALendi, в данном примере в среднем число сделок на IS 171, в OOS 30.

0 +

ALendi — 3 сентября 2012 г.

spitfire, результаты серьезно улучшает?

0 +

spitfire — 3 сентября 2012 г.

ALendi, статья не про улучшательства результатов, а про реалистичность тестов.

0 +

ALendi — 4 сентября 2012 г.

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

0 +

spitfire — 4 сентября 2012 г.

ALendi, как я говорил выше, для каждой системы надо подбирать свои длительности IS/OOS. И сравнивая результаты форвардного теста с разными IS/OOS выбирается их длительность. Твой же вариант это по сути частный случай, когда IS взят побольше и OOS тоже большой, вот и все. Что лучше - покажет только тест.

0 +

Написать комментарий

Чтобы написать комментарий, необходимо авторизоваться.

Написать администратору