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

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

Эта статья, хотя и является вводной, предназначена для людей, имеющих некоторые знания 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