Eugene Bright
Eugene Bright личный блог
Вчера в 13:55

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

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

— Вы просто не умеете их готовить!

(не помню источник)

 

 

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

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

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

              Короче, битый час общались, а понимания – ноль. Говорю, наконец, «покажи код своего бота, собака!»
Мялся-мялся горемычный, но всё-таки сдался. «Смотри, — говорит. – Только никому не показывай, пожалуйста.»

              Да не нужны мне твои секреты! Тем более, что они – секреты Полишинеля.

              5 минут изучаю, 10 минут…

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

              Итак, суть ошибки.

              Так сталось, что при написании ТС (торговой системы) автор не делает различия между завершенным фреймом и текущим фреймом.

              В большинстве случаев, используя индексацию баров (применительно к QUIK, хотя это справедливо для любых терминалов), разработчики ссылаются на системный индекс index. Этот индекс используется в Руководстве QLUA и прописан во всех индикаторах библиотеки терминала:

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

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

              Однако, нигде не отмечается, что этот индекс присваивается бару по мере формирования его первой цены Open(index). Это происходит в начале тайм-фрейма. Внимание: В НАЧАЛЕ! Т.е. ДО момента окончания периода тайм-фрейма.

              Теперь зададимся вопросом: а на каких барах строится бэк-тест?

              Опять же – правильно! На ПОЛНОСТЬЮ СФОРМИРОВАННЫХ БАРАХ, т.к. в момент прогонки теста вся база баров УЖЕ сложилась, и в ней нет ни одного незаконченного бара в выбранном тайм-фрейме!

              Итак, подытожим:

  1. Живые торги идут на основании текущих котировок по индексу index, возникшему в базе в начале тайм-фрейма, и торговая система формирует сигналы по последнему открытому в базе и незавершенному бару; реальный набор Open-High-Low-Close еще не сформировался, т.к. тайм фрейм еще не завершился.
  2. Бэк-тесты производятся по базе, где все бары закончены, т.е. набор Open-High-Low-Close зафиксирован и больше не изменится.

Очевидно, что между двумя этими наборами параметров бара в 99% случаев имеются огромные различия.

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

 

       Как решается эта проблема?

       Очень просто. Вместо index нужно использовать (index – 1) и, соответственно, все индексы нужно сдвинуть на -1.

       Получится, например, что пересечение ma1 = SМА(С, 5) и ma2 = SМА(С, 9):

-          БЫЛО:  ma1[index-1] < ma2[index-1]  AND  ma1[index] > ma2[index] 

-          СТАЛО: ma1[index-2] < ma2[index-2]  AND  ma1[index-1] > ma2[index-1] 

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

Из личного опыта: ранее я писал о способах управления текущей базой котировок. Так вот, кроме «обрезания хвостов» я перестраиваю базу так, что в начале нужного периода первый бар имеет индекс 1, а не системный 19017 (на вчерашних торгах).

              В таком случае, вышеприведенный пример пересечения «средних» у меня выглядит так:

                               ma1[#ma1-2] < ma2[#ma2-2]  AND  ma1[#ma1-1] > ma2[#ma2-1] 

 

Успехов всем!

 

Данная публикация является личным мнением автора. Мнение владельца сайта может не совпадать с мнением автора.
7 Комментариев
  • ves2010
    Вчера в 17:14
    мне кажется проблема надумана… пересчет идет в момент появления новой свечи… по всем сформированым свечкам… т.е появилась новая свеча по всем свечкам идет пересчет 


  • MoscowTrades
    Вчера в 21:34
    Ну то очень простая проблема.
    А вот есть посложнее.
    Ситуации когда заявка просто не исполнена, исполнена частично, когда сигнал работает при изменении чего-то, а заявка в этот момент не исполнилась, а на след. баре сигнала уже нет, и конечно сдвиги сработавших сигналов относительно теоретического исполнения из-за всего этого…
  • Анзорик
    Сегодня в 00:21
    У самописный бэктестер, он ничего не знает про свечки, видит только стакан и тики, эмулирует задержку сети и честное исполнение с очередью. Теперь проблема обратная — все стратегии получаются или фигней или очевидной подгонкой)

Активные форумы
Что сейчас обсуждают

Старый дизайн
Старый
дизайн