Блог им. gavrovis
Здравствуйте. Уже достаточно давно я интересуюсь машинным обучением для инвестиций в акции и разработал систему, которая позволяет выбирать наиболее перспективные активы. Система, на длительном сроке, стабильно и значительно превосходит рынок, показывая среднюю доходность за последние 15 лет более 35% годовых в €, с просадкой, сопоставимой с рыночной (доходность может быть и больше, в зависимости от количества акций в портфеле и стратегии фиксации прибыли и убытков). Прогнозы публикуются на smart-lab с октября, в реальном времени, проект называется Investington. В этой статье описаны основные принципы стратегии. Сразу оговорюсь, что я не экономист, а инженер, поэтому и описывать буду именно техническую составляющую модели.
Идеей было сделать систему, которая позволяет автоматизировать выбор акций в портфель, сократить потраченное на это время, а также избежать человеческого фактора при принятии решения. Для начала нужно было придумать некий концепт, и я начал бродить по сайтам типа Yahoo, смотреть на графики котировок и изучать показатели предприятий. В процессе поиска мой интерес привлекла компания Renault. В то время я работал у их прямого конкурента и знал, что дела у них идут прекрасно – они утягивали у нас специалистов одного за одним. Но при этом, их акции постоянно падали. Как выяснилось, из-за глобальных факторов – рынки перестраивались, некоторые производители испытывали трудности, особенно в Азии, и случился громкий скандал с их директором, которого вывозили в рояле из Японской тюрьмы. В итоге их акции упали со 100€ до 50€, хотя компания работала нормально. Посмотрев на графики, я решил, что котировки должны вернутся на прежние уровни, то есть с доходностью 100%, в горизонте 3-4 лет (25%/год). Решено было эту идею формализовать :
— компания с большой капитализацией (размер)
— компания не убыточная, но дешевая. (Как критерий — либо PER, либо текущая цена по сравнению с максимуму за 5 лет + стабильно положительная отчётность)
— отсутствие макроэкономических негативных факторов (санкции, вымирающий сектор)
Подбирая таким образом около 10 акций и фиксируя прибыль при значении 25%/год, на горизонте 3-4 года, можно получить вполне интересную доходность при минимальных усилиях. Но что, если акция не вырастет или продолжит падение? По сути стратегия сводилась к фильтрам по критерию.
Я решил проверить эту логику на истории. Написал простой скрипт, который «торговал» по моему алгоритму на данных за последние 15 лет, выбирая подходящие под критерий акции и обновляя портфель день за днем. Прогон подтвердил мои сомнения – многие акции не возвращались к изначальным значениям и продолжали падать. Процент получился в среднем 12-13%, но было очевидно, что критерии слишком примитивны. Кроме того, не понятно было в какой момент закрывать убыточные позиции. Я сделал несколько важных наблюдений:
— Я стал рассчитывать не абсолютное значение процента, а процент за промежуток времени. Например доходность 100% за год и 150% за два, я учитывал как 100% и 75% за год. Позже я пришел к расчету доходности на рабочий день (в году 250 рабочих дней, 25% годовых -> 0.1% в день).
— Я всегда ограничивал позицию по времени. По окончании промежутка я закрывал ее.
— Я не пытался спрогнозировать точную будущую цену, но определял уровень который акция должна достичь. Это, пожалуй, самый важный момент, который в дальнейшем я буду называть «гипотезой»
— Я не использовал стопы. Почему? Стопы пришли к нам из трейдинга. И там они более чем уместны – нельзя позволить себе просадку в 20% при плече в х5. В то же время, большинство знает феномен срабатывания на Форексе, когда цена касается стопа и позиция закрывается, а затем следует разворот. И так потихоньку съедается депозит. Я решил использовать обратный подход – ставить фиксированные тейки и не следить за падениями. А как же риски скажете вы? При диверсификации на 10 акций, падение одной из них на 50% – это всего лишь 5% от депозита. При этом, вероятность того что две акции в портфеле разорятся одновременно менее 0.5%. Так как я планировал именно инвестировать а не трейдить, я счёл что диверсификация будет достаточной для защиты от рисков. При этом, все стратегии, которые я тестировал на долгосрочной перспективе, со стопами всегда давали результат хуже, чем без них
Исходя из этого, я вывел достаточно интересную формулу, по которой смог оценить потенциальную прибыль стратегии:
— я ожидал 100% за два года —> 50%/год
— 65% сделок в симуляции были прибыльными
Исходя из этого приблизительная прогнозируемая прибыль будет:
Прибыль = (2*Вероятность-1)*Цель
Пример: (2*0.65-1)*50 = 15
Этот простой расчет совпадал с симуляцией с точностью в +-5%. Исходя из этого, я понял, что можно найти оптимальное соотношение длительности позиции и прибыли, а затем максимизировать точность прогноза. Проблема в том, что эти значения зависят друг от друга. И тут на помощь приходит машинное обучение.
Итак, идея достаточно проста – зачем искать критерии выбора акций самому, если можно оптимизировать их. Машинное обучение идеально подходит для решения этой задачи. Оно позволяет построить модель, которая оценивает некую величину (выход, Y) на основе набора критериев (вход, X). Существует достаточно большое количество методов. Приведу очень краткое описание что это вообще такое.
Начнём с основ: есть три основных класса задач: supervised (1), non-supervised (2) и reinforcement learning (3). В первом случае есть набор данных, каждый элемент которого соответствует паре (X, Y), обучаемая модель описывает связь между ними. Во втором случае для каждого элемента известен только X и модель группирует схожие элементы, как бы «придумывает» Y. Третий, наиболее сложный вариант: предполагается что есть некая среда, которая, в ответ на действие Y, выдает вознаграждение R. Мы пытаемся построить модель, так связывающую X и Y, чтобы получить максимальное R. Предполагается что X известен и можно рассчитать R через Y. Мы будем использовать первый метод, supervised learning. Почему? На сегодняшний день он наиболее эффективен и изучен.
Различают два основных типа задач – регрессию и классификации. В случае регрессии – Y непрерывная величина, а в случае классификации – Y соответствует некой категории и принимает фиксированные значения, например 0 и 1. Большинство существующих решений для биржи пытается предсказать цену акции (регрессия). Но результаты таких моделей, как правило, недостаточно точны, и при этом они страдают от численных условий задачи (например, модель оценки цены по 100 предыдущим значениям скорее всего выдаст наиболее вероятной цену равную текущей :). Я же предлагаю задаться вопросом –- а зачем мне прогнозировать цену? Изменение рынка — случайный процесс. Важно понимать, что случайный – значит не то, что процесс полностью непредсказуемый (белый шум), а то, что его состояние нельзя описать точно. Но можно статистически оценить при этом некую зону неопределенности, которая будет включать реальное значение. Значит нужно смоделировать эту неопределенность.
Что же мы хотим узнать на самом деле? Стоит ли покупать конкретную акцию или нет. Стоит (1) или нет (0)? Значит, модель обучения будет брать на вход (Х) доступные данные и прогнозировать – стоит ли покупать акцию (Y). Но есть один подвох – как задать Y? И тут мы возвращаемся к предыдущим наблюдениям:
— я прогнозирую уровень изменения цены, а не конкретную цену
— я ограничиваю прогноз по времени.
Бинго! Если акция за период А хоть раз пересечет уровень Б, то ее Y=1. Если нет – 0. Уровень рассчитываем как относительное значение к текущей цене. После этого, достаточно обучить модель на соответствующих данных. Получившаяся задача достаточно проста и одинаково хорошо решается большинством современных ML методов: и random forests, и boosting и небольшая рекуррентная нейронная сеть типа LSTM тоже находит достаточно точное решение без особых проблем.
Используя свою формулу доходности, я подобрал оптимальные значения для периода и % прогноза и, исходя из них, задавал Y. Так я получил свою первую торговую систему:
— каждый день, при открытии рынка, скачиваются данные по всем доступным акциям
— модель проверяет каждую акцию на потенциал роста
— составляется список из положительных акций
— если есть свободные деньги – акции покупаются в портфель (либо случайно, либо по другому правилу. Диверсификация по секторам, капитализация, доходность – любой фундаментальный критерий, какой больше нравится). Такая модель легко автоматизируется и проверяется на истории. После проверки я получил 28% годовых и свою модель v1.0. Дальше я начал ее улучшать.
Первая проблема, которую я встретил – несмотря на то, что модель давала 80%+ удачных сделок, отрицательные сделки были более убыточными. Например, если на + я зарабатывал 10%, то потерять мог и 30% и 40%. Я решил обучить ещё одну модель, которая будет проверять акции на вероятность падения. Обучение проводилось точно так же, как и для роста, но значения Y задавались иначе. Комбинация двух моделей уменьшила количество «хороших» акций, но сократило неудачные прогнозы в 2-3 раза. Это будем считать моделью v2.0.
В третью (текущую) версию я включил сразу несколько изменений. Во-первых, увидев эффективность комбинирования нескольких моделей, я начал добавлять гипотезы (долгосрочный рост, краткосрочный скачок итп.) сформировав тем самым около 30 моделей. Но когда моделей стало много, встал вопрос – как их комбинировать? Второй открытой проблемой был финальный выбор акций – непонятно было как ранжировать положительные сигналы, которых было больше 50 в день.
Тут надо сделать оговорку. Модель-классификатор даёт на выходе значение от 0 до 1. Как правило, считается что значения <0.5=0 и наоборот. Логично предположить, что чем выше значение, тем более точно предсказание. На самом деле это не (обязательно) так. Из-за того, что при обучении модель берет только метки равные 0 и 1, нет никакой возможности градуировать точность предсказания (подробнее на тему можно найти статью про дистилляцию меток). Для решения обеих проблем, я решил добавить расчет вероятности точности прогноза.
Представим, что у нас есть метка от 0 до 1. Как связать ее с вероятностью? Мое решение – эмпирически. Имея некий исторический набор данных, мы можем статистически рассчитать мат. ожидание точности прогноза для каждого значения метки и построить соответствующую калибровочную кривую. Естественно, такая оценка может быть не точной и изменяться во времени, но, оценив ее в плавающем окне в год, я вычислил, что среднеквадратичное отклонение не превышало 7% (привет всем, кто говорит что рынок не стационарен). Вероятности были рассчитаны для каждой модели отдельно и скомбинированы, используя правило условной вероятности, для расчета итогового значения. Получилась модель v3.0. Эта модель показала среднегодовую доходность уже в 42% за последние 15 лет при торговле портфелем в 10 акций.
Я использую свою модель с конца 2019 года на реальном счёте. С учётом локдауна и кризиса, результаты использования составили 34% в €, что, на мой взгляд, более чем достойно. Метод не идеален и будет мною улучшен, но он более чем интересен именно для надёжных и долгосрочных инвестиций. Я не нашел результатов какого-либо инвестора с лучшими историческими показателями на долгосрочную перспективу (я не учитываю трейдеров и не использую плечо). Несколько замечаний:
— нужно пережить первые 3-4 месяца, пока счёт стабильно не перевалит свой начальный уровень
— нужно придерживаться плана. Всегда. Даже когда это кажется неразумным. Ни одно мое действие вне стратегии не принесло большей доходности, чем потенциальные сделки системы в тот же период.
— где-то через год, действия доходят до автоматизма, каждый мелкий случай кажется простым и знакомым. Начинаешь получать реальное удовольствие от торгов.
Ну а сейчас я завершаю четвертую версию модели, которая будет более точная, чем предыдущая, и даст еще более качественный прогноз. Особое внимание будет уделено риск менеджменту, а так же добавятся новые функции.
Также в планах сделать сервис, где будут доступны прогнозы по всем акциям а не только список лучших. Надеюсь сделать это доступным в ближайшие месяцы. Следить за проектом можно в основных соц сетях, по тегу investington.
Если у вас есть вопросы, то задавайте, с удовольствием отвечу.
На самом деле вы всегда прогнозируете куда двинет рынок (почти регрессия) учитывая такую постановку задачи, если же вы использовали lstm то на выходе вы получите вероятноть, а когда делаете классификацию, то уже сами определяется в какой класс отнести, т.е. не обязательно брать 0.5.
А почему вы не делали классификацию по трем классам сразу? 1. пересечение порога вверх, 2. пересечение порога вниз, 3. осталась болтаться внутри этого корридора. Были какие-то мысли по этому поводу, хуже прогноз или?
Регрессия предполагает на выходе непрерывную величину в изначальном наборе данных. В нашем случае У принимает значение либо 0 либо 1 (не прогнозируемый а label). Мы прогнозируем пойдет ли рынок вверх или нет, что значительно упрощает задачу
Можно сделать одну модель для нескольких классов но на практике лучший результат получился если сделать две отдельные модели и скомбинировать их
Я правильно понимаю, у вас только лонг?
зы. я просто делал похожее, но во всех направлениях… правда результат меня как то не устроил :), но и фич я брал немного.
Отличная статья. Думающий автор, интересное применение ML, описан и понятен ход мысли.
Про ML в трейдинге здесь пишут не редко, но интересного не так много. Читать как очередной раз на ценовых приращениях прогнозируют ценовые приращения давно не интересно))).
Да, старшие ТФ, большие горизонты удержания, лонг-онли, трейдерские фичи — все это благодатная почва для построения хорошей модели. По сути-то, реально, надо не так много, если ты можешь лонг-онли, без плечей обыгрывать рынок, то что ещё нужно?
Сам до использования неценовых данных в моделях всё никак не доберусь).