bascomo
bascomo личный блог
22 ноября 2023, 00:22

Кросс-валидация в трейдинге

Доброй ночи вам.

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

Итак, начнём.

Само понятие кросс-валидации пришло к нам из машинного обучения.

Кросс-валидация в трейдинге



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

Давайте рассмотрим пример для ML, где мы используем 12-кратную кросс-валидацию для оценки качества модели. У нас есть набор данных, который мы разбиваем на 12 частей. Затем мы проводим обучение модели на 11 частях данных и тестируем на 1 части данных. Далее мы меняем тестовую часть и повторяем процесс обучения и тестирования. После завершения всех итераций у нас есть 12 наборов результатов (один для каждой части данных).

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

Справедливости ради, отмечу, что в ML существует много различных типов кросс-валидации, и тот, что описан выше, называется K-fold. Из популярных есть ещё 6 (наиболее распространенных) типов — Holdout, Stratified k-fold, Rolling, Monte Carlo, Leave-p-out и Leave-one-out, но большинство из них не подойдёт для задач трейдинга от слова «совсем». Кстати говоря, Holdout — это тот самый любимый большинством In Sample / Out of Sample. Видите, как много дал трейдингу ML? А вы его ругаете :)

Кросс-валидация в трейдинге

Думаю, тут практикующим алготрейдерам понятно, что данный подход в трейдинге «в лоб» не применим, поскольку «много неясного».
Более того, используя конкретные торговые терминалы, мы получаем профдеформацию, которая выглядит как представление о том, что есть только два куска: train и test или in sample и out of sample, если угодно. Если на train мы получили минус, то подавляющее большинство не видит смысла проводить с такой торговой системой какие-либо ещё упражнения в смысле тестирования / проверки её профпригодности на других временных отрезках.
Кроме того, для классической интерпретации термина не существует понятия времени. Там каждый кусок данных условно равнозначен, он как бы ни в прошлом, ни в будущем, ни в настоящем. Он просто есть. Мы же понимаем, что на небольших интервалах цена в прошлом всё-таки определяет в подавляющем большинстве случаев диапазон цены в будущем. Сбер не может стоить сегодня 15 рублей, завтра 300, потом 25. Выбросы, конечно, есть, кто же с этим спорит, но они есть везде, и их меньшинство. ML этого не учитывает, а нам стоит задуматься.

Дальше — больше. Мы ищем торговые системы на train и проверяем их на test. Если мы возьмём ценовой ряд, разобьём его на несколько кусков и скажем, что один из них — это test, а остальные — train, то что с этим делать дальше?
Обыкновенно, если результаты торговой системы на train нас не устраивают, есть ли (и какой) смысл проверять её на test?
С другой стороны, если на 5 кусках train у нас одни и те же параметры и одна и та же торговая система, как предполагает подход ML, то какие, к чёрту, это train? Train там будет только один, а остальные будут test — очевидно.

Вот и получается, что у нас, в алготрейдинге, должно быть наоборот: один train и несколько test. Нашли на train, и последовательно проверяем на всех test. А train меняем так, как это описано применительно к test в кросс-валидации для ML. Но так никто не делает, потому что у большинства выученная привычка, см. далее. Я бы даже сказал: привычка, навязанная терминалами.

Следующая проблема состоит в том, что нам эти результаты нужно сохранять, так как следует провести множество вычислений для разных инструментов, кусков train/test и самих торговых систем, а какие-то выводы можно сделать только на сводных результатах исследований. В штатной комплектации существующие торговые терминалы делать этого не позволяют. Собственно, и автоматизированно тестировать торговые системы, меняя смысл отдельных участков входных данных с train на test или наоборот, даже без записи результатов тестирования, они тоже не позволяют. Нужно всё это прикручивать сбоку руками. Как-то и где-то.

Ну и ещё вот эта привычка большинства, о которой тоже хочется сказать пару слов: взять тики лет за 20, и прогнать стратегию на них целиком. Без разделения на серии кусков. Имеет ли право такой подход на существование? Очевидно, да. Будет ли он эффективнее, чем разбиение ценовой истории на относительно небольшие куски и валидация каждого куска отдельно? Очевидно, нет, ведь в этом случае ТС должна подстроиться под 20 лет, да и оптимизируем мы её «на глаз» по кривой доходности и нашим внутренним убеждениям, зачастую, в отрыве от контекста (ведь мы не наблюдаем параллельно с кривой эквити кривую цены, чтобы чётко понимать, что происходило с доходом в моменты тех или иных движений цены, смены трендов, боковика или резких движений рынка, а главное — почему: проанализировать все эти кейсы)
В «кусочном» варианте такой задачи не стоит, поскольку мы отдаляемся от точки «торговая система должна быть эффективна всегда и вечно, как в прошлом, так и в будущем» и приближаемся к «эта конкретная торговая система должна быть эффективна здесь и сейчас, были до неё, будут и после». Не встаём на эту точку, а именно приближаемся к ней, поскольку крайностей вообще не существует.

Это всё мне напоминает про тыкать пальцем в мягкое, надеясь обнаружить нечто твёрдое. Ну, алмаз или золотой слиток в глине, что-то вроде. По сути, случайный поиск вручную. Авось, повезёт.

Первый вариант совершенно очевиден, понятен и логичен, если… мы говорим, что мы будем всегда торговать одним инструментом, одной системой и на одном таймфрейме. Что далеко от реальности, ведь сила алготрейдинга состоит именно в массовости совершения торговых операций разными алгоритмами и на разных рынках, что недоступно человеку. А чтобы торговать одним алгоритмом на одном инструменте — алготрейдинг не нужен. Всегда следует помнить, что алготрейдинг — это не про «торговать лучше, чем человек», а про «торговать больше, чем человек».

Не будучи осведомлён о всём том, что написано выше, я раньше определял для себя кросс-валидацию как валидацию ТС, найденной на одном инструменте, на ценовых данных других инструментов. Это совершенно нетривиальная задача, учитывая иногда на порядки различающиеся параметры тех или иных инструментов между собой. Я её для себя решил, а как — писал ранее.
Кросс-валидация в трейдинге
Я пришёл к моему решению задачи кросс-валидации в трейдинге интуитивно.
В моём подходе, все имеющиеся данные — это пространство поиска торговых систем, и все же имеющиеся данные — это пространство для их проверки. Условие тут, очевидно, только одно: для каждой конкретной торговой системы данные, на которых она была найдена, и данные, на которых она будет тестироваться, не должны пересекаться. Звучит очень просто, а по факту так оно и есть.

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

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

И, наконец, ещё такой: даже использование 20 лет истории не гарантирует того, что ваша ТС не подстроена. Да-да, я о том самом пресловутом курва-фиттинге. Если же использовать адаптированный K-fold, вероятность подгонки существенно снижается, как, впрочем, и число валидных торговых систем. Думаю, это нормально. И зависимость подгонки от коэффициента вероятности, про который пишу ниже, не линейная, а обратно пропорциональная. Чем на большем количестве test имеем позитивный результат, тем ниже вероятность подгонки. А в классике IS /OOS test у вас всего один, не так ли?

Гарантий заработка на финансовых рынках нет, а потому мы оперируем вероятностями.
В этом и состоит краеугольный камень моего подхода.
Разбив ценовые данные инструментов моего портфеля на отдельные дискретные интервалы, а именно — месяц, я тестирую каждую торговую систему на каждом интервале каждого инструмента. Получаю число интервалов, где она прибыльна, и число, где она убыточна и, следовательно, вероятность её успешности на заданном наборе данных — число успешных интервалов к их общему числу. Собственно, я писал об этом ранее. Тут — и меня снова не затруднит бросить камень в окно популярных и не очень терминалов — мне достаточно рассчитать один раз и записаться, между тем, как в других нужно считать снова и снова. Это на порядки сокращает число расчётов при поступлении новых данных.
Проранжировав торговые системы по рассчитанной, как описано выше, вероятности их успешности и не только на «родном» инструменте, уже и науськиваю их лучший топ на те или иные торговые инструменты. Работает превосходно.

В принципе, вроде это и кросс-валидация, если не присматриваться к деталям, но и понятие получилось шире, с одной стороны, и, с другой стороны, как-то по-другому в сравнении с классическими формулировками. Вроде бы и усреднение есть, только оно выражается в вероятности. А усреднение параметров торговой стратегии мы знаем, к чему приведёт, и это никого не порадует. Но когда читаешь классическое описание, звучит именно так: посчитайте, смешайте всё в кучу, сложите, разделите, посчитайте среднее. Авось, что-то и получится. А если говорить об усреднении чистой прибыли — какой смысл делить на отрезки? Можно и сразу тестирование захерачить на всех данных, с начала времён. И лучше, непременно, на тиках. Собственно, так большинство и делает. И, вроде, работает. А тогда зачем что-то менять?

Доброй ночи вам и приятных снов и лёгкой кросс-валидации ваших торговых систем :)
Кросс-валидация в трейдинге
24 Комментария
  • Alexey Rondine
    22 ноября 2023, 01:17
    Добрый день. Просьба научиться концентрировать мысли
  • Ho_Chu
    22 ноября 2023, 09:32
    оптимизация кривой доходности «на глаз» — это зло
    есть четко описанные математические механизмы, упрощение которых даже до уровня 8-го класса школы вполне понятно большинству читателей
  • Artemunak
    22 ноября 2023, 09:47
    Когда адекватное проскальзывание будешь учитывать? Одно это в корне поменяет твой подход, а есть ещё и другие факторы.

    Разбивка на месяцы далека от реальности, большинству систем входных данных для разгона индикаторов нужны недели, иногда месяцы. Ещё у большинства практиков среднее время удержания это неделя, а это значит что бывают сделки с удержанием месяц и больше, при таком подходе их нормально не протестируешь. В итоге получится что когда-нибудь ты откажешься от своего подхода и будешь делать типа как все, но до этого тоже ещё дожить надо,  и даже к этому прийти будет не так просто как тебе кажется.
      • Artemunak
        22 ноября 2023, 10:56
        bascomo, месяц не предел, бывают длинные тренды, и если на них перезаходить то нифига не заработаешь. Я бы сам рад торговать быстрые системы но чёто они первыми всегда умирают.
        • SergeyJu
          22 ноября 2023, 11:16
          Artemunak, чем меньше сделок в году, тем меньше транзакционные потери и тем больший объем можно в такие системы засунуть. Многие склонны недооценивать этот момент.
            • SergeyJu
              22 ноября 2023, 12:43
              bascomo, главное, чтобы при расчете чистой прибыли не были забыты все реальные издержки.
              Когда триумфатор въезжал в Рим, специальный человек шел за ним и повторял «Помни о смерти». 
              А я постоянно повторяю на смартике
              Помни о рисках.  
                • SergeyJu
                  22 ноября 2023, 13:18
                  bascomo, Вы, главное, не пропадайте. С моей точки зрения Вы делаете нечто оригинальное, хотелось бы приглядеться хотя бы в течение 2-3 лет. Лучше — больше.
                • Кирилл Гудков
                  22 ноября 2023, 16:27
                  bascomo, перекрывать проскальзывание уменьшением продолжительности сделки — это примерно как тушить пожар бензином. Чем быстрее стратегия, тем сильнее транзакционные издержки влияют на результат. Если ваша «норма доходности» образуется алгоритмами со средней сделкой < 0.1%, тестировать их без учета накладных расходов нет смысла, в топы вылезет дребедень.
  • SergeyJu
    22 ноября 2023, 10:09
    Существуют активы с ярко выраженной сезонностью, и без сезонности. Есть и другие существенные отличия активов друг от друга. И если с Си на юань системы переносятся, то на спай уже нет. Поэтому при поиске систем «на все рынки» мы теряем в эффективности. 
    Можно подбирать «системы на все рынки», а можно портфель из систем «на каждый рынок свои». Второй подход дает бОльшую робастность уже не в каждой системе, а в портфеле. 
      • SergeyJu
        22 ноября 2023, 11:14
        bascomo, вне практического смысла, не сложно написать систему, которая подстраивается под рынок на каждый новый такт данных. Достаточно жесткие системы, к которых подстраивается один, максимум два простых параметра. Например, % тейка и %профита. Но в  этой ситуации проще иметь набор систем с разными тейками и профитами в общем пятне пригодных значений, чем заниматься постоянной подгонкой. 
        С другой стороны, существенное изменение рыночных условий — это недели, месяцы, годы. Только при накоплении достаточного в каком-то смысле объема данных, переоптимизация систем начинает иметь смысл. Для меня этот параметр  примерно полгода-год, не менее, часто более. И зачастую речь идет не о перенастройке систем, сколько о вводе небольшого количества новых, изъятии нескольких старых или о просто балансировке их весов.
          • SergeyJu
            22 ноября 2023, 12:39
            bascomo, кроме финреза важно кое-что еще. Емкость, проскальзывание, просадка, устойчивость например. И ПЕРЕподгонка тоже имеет значение. 

              • SergeyJu
                22 ноября 2023, 12:45
                bascomo, блажен, кто верует, тепло ему на свете.
              • Кирилл Гудков
                22 ноября 2023, 16:39
                bascomo, финрез_посчитанный(tm) имеет нулевую ценность, если он далек от финреза, полученного в торгах. И раздувание виртуального финреза не помогает в уменьшении разницы с реальным. На тестах может быть +1000%, а в торгах нехилый минус. И оптимизация тестов до 10000% не сделает реальный минус плюсом, а скорее всего приведет к всплытию еще более стремных стратегий.
  • Дмитрий Александров
    22 ноября 2023, 10:24
    Хорошая статья
  • Riskplayer
    22 ноября 2023, 13:55
    Я не математик. Но вроде как кросс-валидация рекомендуется, если данных недостаточно. К тому же увеличение K-fold может привести к переподгонке.  Мне кажется, если данных достаточно, то форвардного тестирования вполне хватит.

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

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