ПРЕДИСЛОВИЕ

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

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

У меня также есть сценарии для удаления информации о рыночных условиях и будущих рыночных ожиданиях для тех же акций.

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

Короткий спойлер: модель успешно предсказала 75% движения акций со средней абсолютной ошибкой менее 5%.

Давайте проверим детали!

ЧАСТЬ I. СПИСОК ПЕРЕМЕННЫХ

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

  • date — день операции по торговым сделкам, по финансовым KPI показываем последние результаты. ДАТА
  • roe — рентабельность собственного капитала. ЧИСЛО
  • longTermDebtEquity — Соотношение долга к собственному капиталу для долгосрочных облигаций. ЧИСЛО
  • RevenueQoQ — доход за квартал. ЧИСЛО
  • epsQoQ — прибыль на акцию за квартал за квартал. ЧИСЛО
  • piotroskiFScore — Финансовое здоровье в диапазоне от 1 до 10. ЧИСЛО
  • currentRatio — краткосрочная ликвидность компании. ЧИСЛО
  • roa - рентабельность активов. ЧИСЛО
  • profitMargin — сколько центов прибыли было получено на каждый доллар продажи. ЧИСЛО
  • peRatio — отношение цены к прибыли. ЧИСЛО
  • pbRatio — Отношение цены к балансу. ЧИСЛО
  • trailingPEG1Y — Отношение цены/прибыли к росту. ЧИСЛО
  • VIX_high — максимальное дневное значение индекса волатильности. ЧИСЛО
  • сектор — сектор компании. КАТЕГОРИЧЕСКИЙ
  • промышленность — отрасль компании. КАТЕГОРИЧЕСКИЙ
  • 10Y_bonds — значение дневной доходности 10-летних казначейских облигаций США. ЧИСЛО
  • 10Y_bond_MoM — Месячные изменения 10-летних казначейских облигаций США. ЧИСЛО
  • Debt-to-Equity_Ratio — общие обязательства компании, разделенные на собственный капитал. ЧИСЛО
  • DividendsYield — процент от цены акций компании, который она ежегодно выплачивает в виде дивидендов. ЧИСЛО
  • PayoutRatio — часть прибыли, которую компания выплачивает в виде дивидендов. ЧИСЛО
  • Acc_Rec_Pay_Ration — Коэффициент оборачиваемости дебиторской задолженности. ЧИСЛО
  • Earnings_per_stock — прибыль на одну акцию в обращении, деленная на стоимость акции, чтобы получить процентное значение. ЧИСЛО
  • дивиденды_change — После объявления компанией новых дивидендов, насколько сильно изменились выплаты. ЧИСЛО
  • prev_div_change — Какое последнее изменение дивидендов было до последнего объявления. ЧИСЛО
  • days_after_divid_report — сколько дней прошло с момента последнего объявления изменения дивидендов. ЧИСЛО
  • неожиданность_% — разница между последней отчетной прибылью на акцию и ожиданиями рынка. ЧИСЛО
  • ожидаемый_рост — какова ожидаемая прибыль участников рынка на акцию. ЧИСЛО
  • previous_surprise — разница между заявленной прибылью и ожиданиями предыдущего отчетного периода. ЧИСЛО
  • days_after_earn_report — сколько дней прошло с даты последнего отчета, когда компания публикует официальные результаты. ЧИСЛО
  • future_30dprice_change — процент изменения цены конкретной акции за 30 дней. ЧИСЛО

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

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

Мы собрали исторические данные почти за три года.

ЧАСТЬ II. АНАЛИЗ ПЕРЕМЕННЫХ

ЧИСЛОВЫЕ ПЕРЕМЕННЫЕ

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

К сожалению, в наборе данных нет сильных корреляций. Особенно для целевой переменной нет корреляции сильнее 0,2. Это означает, что решение для нашего прогноза может быть сложным, если мы его найдем.

Теперь мы можем посмотреть на распределение данных по переменным и на то, насколько сильны выбросы.

Вот общая картина, которую мы видим на приведенных выше диаграммах:
 — Большинство компаний из списка DOW30 имеют показатель Пиотроски выше пяти, что означает, что они находятся в хорошем финансовом состоянии.
 – Рентабельность активов для у большинства компаний был выше 0 и ниже 30%. Это показывает, что большую часть времени компании были прибыльными.
- Маржа прибыли для большинства составляет менее 100%. Следует выделить всплеск компаний с рентабельностью 100%.
- Доходность 10-летних облигаций не превышала 3% на длинные позиции за указанный период.
- Компании обычно сообщают об изменении дивидендов раз в год, и в целом дивиденды растут.
- будущее изменение цены 30d выглядит как нормально распределенная кривая с выбросами на левой стороне и средним значением, близким к ' 0'. Это показывает, что наш набор данных содержит сбалансированные данные о движении акций вверх и вниз.
- Средняя рыночная рентабельность капитала составляет 38%. Значение в диапазоне 15–20% считается хорошим для компании. Стандартное отклонение составляет 326%. Он показывает, что есть компании с периодами значительных убытков (отрицательные значения) и есть компании с очень низким акционерным капиталом (очень высокие значения)
- После объявления дивиденды в среднем выросли на 9,7%. 50% компаний объявляют об изменении дивидендов каждые 213 дней.
- В среднем стоимость акций увеличивается на 0,2% каждые 30 дней.

КАТЕГОРИЧЕСКИЕ ПЕРЕМЕННЫЕ

Я должен отказаться от отрасли, так как она содержит 26 значений. Знание того, что у нас всего 30 компаний, может помешать нам обобщить будущую модель.

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

Теперь у нас есть только один категориальный столбец — Сектор. Вот количество компаний в каждом секторе, которое у нас есть.

Я бы не стал добавлять диаграммы распределения стоимости, которые я использовал для анализа компаний по секторам; вы можете проверить это в моем блокноте Jupyter.

Резюме:
- Все секторы, кроме потребительского циклического, имеют в основном положительную ROE.
- Энергетический сектор имеет самый широкий разброс доходов от квартала к кварталу;
- Секторы базовых материалов и энергетики имеют в основном отрицательную рост прибыли на акцию в квартальном исчислении по сравнению с квартальным;
 — компании в сфере здравоохранения, защиты прав потребителей и технологий имеют наивысший балл Пиотроски со средним значением 6 из 10;
 – компании в секторах основных материалов и финансов лучшее соотношение текущих активов к текущим обязательствам;
- Самая высокая рентабельность активов наблюдается в секторах технологий и потребительских циклов;
- Компании в сфере финансовых услуг имеют самую высокую рентабельность в среднем 100%;
- Потребительский цикл имеет самый высокий коэффициент PE_Ratio, равный 30, в то время как самый низкий в базовых материалах, около 3;
- В энергетическом секторе худшее соотношение долга к собственному капиталу, в среднем 2,3;
- Самые высокие темпы роста показали компании в здравоохранении около 1,3% в месяц, а энергия падает на 1% в месяц.

ЧАСТЬ III. ВРЕМЯ МАШИННОГО ОБУЧЕНИЯ

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

Мы будем хранить данные только за день из недели, чтобы их было труднее прогнозировать.

Зная, что данные не имеют сильной корреляции, а выбросов много, я решил особо не спорить и сразу поработать с мощной техникой бустинга — LightGBM.

Он быстрый и такой же мощный, как XGBoost. Это не требует обработки выбросов и даже изменения категорийных данных. Вы можете указать категориальный столбец внутри функции (кодировка метки по-прежнему необходима, так как она работает только с числовыми данными).

После обучения модели и работы с тестовыми данными я получил 5% среднюю абсолютную ошибку.

Значение ошибки может выглядеть как много. Зная, что мы пытаемся заглянуть в будущее только на 30 дней, ошибка 5% может быть большой разницей, некоторые акции могут даже не измениться так сильно за 30 дней.

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

Как мы видим, выбросы фиксируются довольно хорошо, а большая часть больших падений и подъемов покрывается нашей моделью.

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

Как видите, 74,45 % значений предсказаны правильно. Это очень хороший результат, которого я не ожидал достичь, начиная проект.

Мы можем проверить список переменных, которые наша модель считает наиболее важными.

Это трудно увидеть, поэтому я дублирую чистые значения ниже:

Значение характеристики %
VIX_high 9,27%
10Y_bonds 8,13%
10Y_bond_MoM 8,07%

peRatio 6,87%
days_after_earn_report 6,87%
ожидаемый_рост 5,53%
Earnings_per_stock 5,20%
pbRatio 5,13%
surprise_% 4,67%
Доходность дивидендов 4,13%
days_after_divid_report 4,00%
trailingPEG1Y 3,73%
roa 3,60%
previous_surprise 3,33%выручка кв/кв 3,20%
прибыльмаржа 2,60%
currentRatio 2,47%
roe 2,40%
epsкв/кв 2,33%
отношение долга к собственному капиталу 1,93%
> PayoutRatio 1,67%
Acc_Rec_Pay_Ration 1,27%
prev_div_change 1,13%
piotroskiFScore 1,07%
дивиденды_change 0,93%
сектор 0,47%

Обзор:

Факторы, выходящие за рамки финансовых отчетов компании (курсивом «рынок»), покрывают 47% колебаний цен и входят в ТОП предикторов, что делает их существенно важными для прогноза цены акций в диапазоне 30 дней.

Из финансовых KPI наиболее значимыми являются те, которые связаны с прибылью компании.

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

ЧТО ДАЛЬШЕ

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

В качестве следующего шага я попытаюсь расширить столбец данных с DOW30 на S&P500. И я хотел бы расширить диапазон дат до пяти лет. Это поможет зафиксировать периоды более высокой доходности облигаций США, которых не хватало в текущем сценарии.

Сначала я протестирую текущую модель на большом наборе данных, а затем попытаюсь создать улучшенную модель. Объема данных на следующем этапе должно быть достаточно для этапов тестирования и проверки.

Вот ссылка на Jupyter Notebook для этого проекта.

Пожалуйста, напишите комментарий, если у вас есть какие-либо вопросы или идеи, я рад услышать, что вы думаете.

Пожалуйста, нажмите кнопку «аплодисменты» и подпишитесь на следующие проекты.