Практическое руководство по созданию модели машинного обучения для торговли акциями
В этом посте я покажу, как создать простой классификатор моделей машинного обучения, который можно использовать, чтобы помочь инвесторам выбирать, в какие акции инвестировать.
Эта статья, хотя и является вводной, предназначена для людей, имеющих некоторые знания Python и ML. Если вас интересует более подробное объяснение машинного обучения и трейдинга, ознакомьтесь с этим постом.
Будут затронуты следующие темы:
- Подготовка данных — создание целей и функций (Pandas)
- Исследовательский анализ данных (профилирование Pandas)
- Моделирование (LightGBM)
- Оценка — классификатор и портфолио (визуализация с помощью Plotly)
Данные и код, используемые в этой статье, доступны на моей странице GitHub. Не стесняйтесь клонировать проект, чтобы следовать за ним.
В репозитории вы также найдете файл README.md, объясняющий, как настроить среду со всеми необходимыми зависимостями.
💽 Данные
Чтобы было легче следить за ходом работы, я создал пример набора данных, содержащий исторические данные для 30 составляющих индекса Доу-Джонса. Этот набор данных уже был агрегирован на уровне месяца, а также были созданы некоторые финансовые коэффициенты.
Необработанные данные поступают от Tiingo, компании, которая предлагает API финансовых данных.
🔃 Загрузите набор данных
Давайте загрузим набор данных в Pandas.
Вот значение столбцов:
- ticker: идентификатор акции.
- дата: дата (конец месяца)
- adjOpen: цена открытия (скорректированная) в первый день месяца.
- adjClose: цена закрытия (скорректированная) в последний день месяца.
- price_rate_of_change_1M: доходность акций за последний месяц.
- price_rate_of_change_3M: доходность акций за последние 3 месяца.
- epsDil: разводненная прибыль на акцию
- return_on_assets: коэффициент рентабельности активов.
- return_on_equity: коэффициент рентабельности собственного капитала.
- price_to_earnings_ratio: отношение цены к прибыли.
- debt_to_equity_ratio: соотношение d/e
🎯 Создание цели
Мы собираемся построить модель классификатора, где целью будет логическая переменная, указывающая, выросли ли акции более чем на X% за последний месяц.
Прежде чем сделать это, мы принимаем следующие предположения:
- мы покупаем в первый день месяца по цене открытия (adjOpen)
- мы продаем в последний день месяца по цене закрытия (adjClose)
- доход представляет собой разницу между ценой покупки и продажи (в %)
Затем цель примет следующие значения:
True
, если доходность акции выше или равна X%False
иначе
Выбор целевого порога X можно определить с помощью экспериментов или моделирования на основе прошлых данных. Здесь мы сохраним простоту и простоту и используем фиксированный порог 5%.
Не стесняйтесь экспериментировать с другими пороговыми значениями (10 %, 20 %…) или даже создать более сложную цель, используя тейк-профит и стоп-лосс, как в методе тройного барьера, предложенном де Прадо (Лопес де Прадо, М. (2018). Достижения в области финансового машинного обучения. John Wiley & Sons).
Вот код для создания цели.
🥗 Создание функций
Чтобы упростить блокнот, я уже предварительно вычислил некоторые функции, используя необработанные данные. Если вам интересно узнать, как я их создал, дайте мне знать в комментариях.
Для построения модели мы будем использовать следующие функции:
- price_rate_of_change_1M
- price_rate_of_change_3M
- epsDil
- return_on_assets
- доход_на_эквити
- price_to_earnings_ratio
- отношение заемного капитала к собственному
Очень важным шагом здесь является сдвиг значения функций на один период.
Почему мы это делаем?
Потому что фактические значения этих функций известны только в конце месяца. Нам нужно убедиться, что входные данные (функции), которые мы используем для прогнозирования цели, доступны в начале месяца. Сдвигая значения признаков на один период, мы гарантируем отсутствие утечки данных.
Затем нам нужно удалить первую строку для каждого тикера, чтобы удалить NaN
, созданный во время операции shift()
.
Вот как выглядит окончательный набор данных с функциями и целью.
🔍 Исследовательский анализ данных
Для быстрого исследования данных мы будем использовать библиотеку Pandas Profiling. Эта библиотека очень удобна для создания отчетов о профилировании всего одной строкой кода, как показано ниже.
Получаем вот такой симпатичный интерактивный отчет, смело прокручивайте его в блокноте.
Из отчета видно, что данные в целом достаточно чисты.
Важно отметить, что целевое распределение несбалансировано, о чем следует помнить во время моделирования!
Мы также видим некоторые выбросы для столбцов price_to_earnings_ratio
и debt_to_equity_ratio
. Я не собираюсь углубляться в это сейчас, однако это будет интересно посмотреть на более позднем этапе. Удаление или исправление этих выбросов может улучшить производительность модели.
🤖 Моделирование
Теперь, когда у нас есть набор данных для работы, мы создадим простую модель классификатора, используя LightGBM.
LightGBM — это фреймворк для повышения градиента, в котором используются алгоритмы обучения на основе дерева.
Мне нравится LightGBM из-за его высокой точности, быстрого обучения и, самое главное, простоты использования. Действительно, вам едва ли нужна какая-либо предварительная обработка, чтобы модель LightGBM работала, например, категориальные функции или NaN обрабатываются автоматически.
Поскольку он основан на дереве, он также лучше для окружающей среды (😁) и его легче объяснить и визуализировать для нетехнических людей, что приводит к большему принятию модели заинтересованными сторонами.
🪓 Разделение данных
Для простоты мы будем использовать простое разделение train/test и не будем использовать более сложные процедуры перекрестной проверки.
Данные за 2020 год будут использоваться для тестирования, а данные до этого — для обучения.
👔 Установка классификатора
Давайте создадим оценщик классификатора и подгоним его к данным поезда. Я использую гиперпараметры по умолчанию, за исключением is_unbalance, для которого задано значение True (с учетом высокого класса дисбаланс набора данных) и max_depth, num_leaves,и min_child_samples, для которых установлены соответствующие значения в соответствии с lightGBM. "документация".
Не стесняйтесь экспериментировать с другими гиперпараметрами!
🔮 Прогнозирование на тестовых данных
После того, как модель будет подобрана для обучающих данных, мы можем использовать ее для прогнозирования тестовых данных. В df_test создается новый столбец buy, содержащий прогнозы, сделанные моделью.
Теперь, когда у нас есть прогнозы для тестового набора, мы можем перейти к части оценки, где мы собираемся оценить производительность модели.
✅ Оценка модели
Мы собираемся оценить производительность модели двумя способами:
- Производительность классификатора: использование таких показателей, как достоверность, воспроизводимость и т. д. Мы можем оценить, насколько хорошо классификатор различает хорошие акции от плохих.
- Производительность портфеля: используя ретроспективное тестирование, мы можем смоделировать, сколько денег мы могли бы заработать (или нет!), и вычислить финансовые показатели, такие как общий доход, коэффициент Шарпа, просадка и т. д.
📝 Производительность классификатора
Чтобы получить общее представление о производительности классификатора, мы будем использовать classification_report
из sklearn.
Общая точность составляет 61%. Модель достаточно хорошо предсказывает класс False (точность 73 %, полнота 66 %), но хуже предсказывает класс True(точность 42%, полнота 50%).
Мы должны быть осторожны при использовании точности в этом случае, учитывая высокий дисбаланс набора данных.
📈 Эффективность портфолио
Давайте теперь больше сосредоточимся на финансовых показателях модели. То есть смогли бы мы заработать деньги с помощью этой модели?
Для этого примем следующие допущения:
- каждый месяц мы инвестируем в
n
разных акций (в зависимости от прогнозов модели) - мы инвестируем одинаковую сумму в каждую акцию (
1/n
)
Исходя из этих предположений, мы можем легко рассчитать ежемесячную доходность стратегии, а затем рассчитать финансовые показатели, такие как общий доход или коэффициент Шарпа.
Мы начинаем с выбора только тех акций, для которых модель сделала положительный прогноз (покупка).
Затем мы объединяем данные на уровне месяца, чтобы получить общее представление о том, сколько акций было выбрано моделью за месяц, и какова была средняя доходность. . Мы можем использовать среднюю доходность в месяц, потому что мы исходили из того, что будем инвестировать 1/n
в каждую выбранную акцию.
Мы можем использовать функцию describe()
, чтобы получить некоторую статистику.
Количество выбираемых акций в месяц варьируется от 3 до 27, а средний доход в месяц составляет 2,96%.
Давайте также рассчитаем коэффициент Шарпа, который является очень распространенным показателем, используемым для оценки возврата инвестиций по сравнению с их риском.
Коэффициент Шарпа 1,16, неплохо :)
🎨Визуализация
Чтобы визуализировать доход с течением времени, нам сначала нужно рассчитать совокупный доход.
Затем мы можем сделать несколько хороших графиков, используя Plotly.
Эти первые результаты совсем не выглядят плохими, даже с кризисом covid-19 в марте мы закончим в 2020 году с доходом +36%, это очень многообещающе :)
Однако, чтобы получить полную картину, нам нужно рассмотреть эти результаты в перспективе и сравнить их с эталонной стратегией. Поскольку мы использовали 30 акций индекса Доу-Джонса, мы будем использовать ETF, отслеживающий тот же индекс: DIA.
Давайте загрузим данные этого ETF.
Мы вычисляем коэффициент Шарпа для этой эталонной стратегии.
Коэффициент Шарпа 0,45, это намного ниже, чем у модели ML!
Давайте построим обе стратегии на одном графике, чтобы лучше понять разницу.
Модель машинного обучения следует той же траектории, что и эталонная стратегия, что имеет смысл, учитывая, что набор акций ограничен всего30 тикерами.
Тем не менее, кажется, что модель смогла выделить и выбрать высокоэффективные акции, что привело к 3-кратному увеличению прибыли по сравнению с эталоном и повышенному коэффициенту Шарпа, отличная работа!
🔚 Заключение
Я надеюсь, что эта вступительная статья помогла вам понять, как использовать машинное обучение для торговли.
Не стесняйтесь экспериментировать с записной книжкой, пробовать разные алгоритмы и функции или улучшать подход к тестированию на исторических данных с помощью весов, стоп-лосса, тейк-профита, комиссий и т. д.
Однако будьте осторожны, очень легко получить «хорошо выглядящий» бэктест в области финансового машинного обучения, на что часто обращают внимание финансовые специалисты. В другом посте я напишу об опасности повторного тестирования и покажу, как легко подгонять модель и как вложить -перекрестная проверка может помочь снизить этот риск.
Если у вас есть какие-либо вопросы или замечания, оставьте комментарий и подпишитесь на меня, чтобы не пропустить другие публикации, подобные этой!
Вы также можете следить за мной на торговой платформе eToro, где я использую машинное обучение в основе своей инвестиционной стратегии.
Это сообщение содержит партнерскую ссылку на платформу социального трейдинга eToro