В этой статье я рассмотрю несколько алгоритмов классификации, чтобы попытаться найти подходящие модели для прогнозирования рынка. В частности, SPDR S&P 500 Trust ETF (SPY) выбран как удобный способ анализа S&P 500.

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

Оглавление

  1. Классификационные модели
  2. Данные
  3. Одномерный выбор функций
  4. Выбор характеристик на основе корреляции
  5. Рекурсивное исключение признаков с перекрестной проверкой
  6. Комментарии о перекрестной проверке финансовых временных рядов
  7. Анализ главных компонентов
  8. Оптимизация гиперпараметров
  9. Оценка производительности модели
  10. Аналитика торговых стратегий
  11. Заключение

1. Классификационные модели

Целью этого исследования будет построение классификационных моделей для прогнозирования знака форвардной доходности (процентной доходности открытия-закрытия на следующий день) SPY. Если форвардный доход выше 0%, то нашей целевой переменной y будет присвоено значение 1, в противном случае - 0.

Приведенный ниже словарь охватывает различные модели классификации, включенные в это исследование. Мы сравним различные семейства классификационных моделей от традиционных линейных моделей до более сложных моделей на основе ансамблей.

2. Данные

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

Все модели будут обучены на данных с февраля 2000 г. по апрель 2016 г., протестированы на данных с апреля 2016 г. по апрель 2020 г.

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

Поскольку статья нацелена больше на выбор функций и алгоритмы классификации, я пропущу разделы, посвященные предварительной обработке данных. Более подробную информацию о данных, использованных в этом исследовании, можно увидеть в моем блокноте, ссылка на который приведена в конце статьи. Все наборы данных получены из Quandl и Yahoo Finance.

3. Одномерный выбор функций

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

Из-за нелинейного характера финансовых данных используется взаимная информация, а не F-тест. F-тест оценивает степень линейной зависимости между двумя случайными величинами. С другой стороны, методы взаимной информации могут фиксировать любой вид статистической зависимости, но, будучи непараметрическими, они требуют большего количества выборок для точной оценки.

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

Feature Selection Results - Univariate Feature Selection
Filter Result:
Number of features:  623

Здесь я вычислил взаимную информацию о каждой функции относительно нашей целевой переменной, удалив функции, которые находятся в нижних 40 процентилях. На приведенном ниже графике показаны 10 основных характеристик, ранжированных по шкале взаимной информации:

Обратите внимание, что все производные характеристики были рассчитаны на основе дневной доходности, поэтому USDCNY_rolling_mean_5 представляет собой пятидневное скользящее среднее дневной доходности USDCNY. Четкое определение имени каждой переменной можно увидеть в моем блокноте.

4. Выбор характеристик на основе корреляции

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

В этом разделе я отфильтровал сильно коррелированные функции (корреляция ›0,95), чтобы еще больше уменьшить размер наших функций. Прилагаются тепловые карты корреляции до и после.

Correlation Filter Result:
Number of features:  462

5. Рекурсивное исключение признаков с перекрестной проверкой

После использования двух методов фильтрации (взаимная информация и корреляция) следующим шагом будет использование метода оболочки RFECV для каждого отдельного классификатора. Функция RFECV использует рекурсивное исключение функций для определяемой пользователем базовой оценки для ранжирования функций и использования перекрестной проверки для выбора наилучшего числа функций. Таким образом, у нас будет оптимизированный набор функций для каждой модели.

Ниже приведен один из результатов с использованием классификатора Ridge в качестве базовой оценки, где я отфильтровал функции на основе оценки AUC.

Number of features selected by RFECV
12

Здесь 12 - количество функций, получивших наивысший средний балл после перекрестной проверки с 10 разделениями. Итак, какие функции были «важны» для модели?

Пять основных характеристик этой модели: спотовый обменный курс юаня к доллару США (USDCNY), эффективная ставка федерального бюджета (DFF), индекс промышленного производства (INDPRO ), Energy Select Sector SPDR (XLE) и фьючерсы на евродоллар - непрерывный контракт на первый месяц (евродоллар).

6. Комментарии о перекрестной проверке финансовых временных рядов

Вместо традиционной k-кратной перекрестной проверки в этом проекте используется TimeSeriesSplit из scikit-learn (10 разделений).

TimeSeriesSplit предоставляет индексы поездов / тестов для разделения выборок данных временных рядов, которые наблюдаются через фиксированные интервалы времени, в наборах поездов / тестов. В каждом сплите тестовые показатели должны быть выше, чем раньше.

Я предпочитаю не использовать k-кратное резюме при обучении торговых моделей, потому что нельзя предположить, что большинство наблюдений основано на процессах IID (независимых и идентично распределенных). Смещение прогнозирования появляется, когда модели обучаются на будущих данных и проверяются на прошлых данных.

Вместо k-кратного CV функция TimeSeriesSplit предлагает процедуру, которая очень похожа на то, что происходит, когда модель машинного обучения развертывается на реальном рынке. Он не предполагает IID, и нет предвзятости в обучении, учитывая, что в каждом сплите показатели теста должны быть выше, чем раньше.

7. Анализ главных компонентов (PCA)

После получения наилучшего подмножества функций с RFECV будет применен PCA, чтобы еще больше уменьшить размер выбранных нами функций. Чтобы сохранить как можно больше информации, мы сохраняем количество компонентов, которые могут объяснить не менее 99% общей дисперсии.

Здесь мы продолжаем пример для классификатора Ridge.

Number of principal components selected by PCA
7

Мы заметили, что мы можем использовать 7 основных компонентов, чтобы объяснить почти 100% общей дисперсии наших 12 функций. (На самом деле нет необходимости выполнять PCA, когда у нас есть только 12 функций, но для некоторых других моделей, таких как Random Forest, гораздо больше функций будет выбрано на этапе RFECV.)

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

8. Оптимизация гиперпараметров.

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

В приведенном ниже коде перечислены все различные параметры, которые мы будем перебирать для каждой модели, используя GridSearchCV, предоставленный scikit-learn. Подобно RFECV, перекрестная проверка будет выполняться с помощью функции TimeSeriesSplit, а оценка AUC будет выбрана в качестве метрики для оптимизации.

9. Оценка производительности модели.

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

Простая торговая стратегия разработана следующим образом: в конце дня t получить и предварительно обработать новые точки данных для наших функций. Затем эти данные будут введены в модель для прогнозирования направления доходности в день t + 1. Если выход модели равен 1, тогда мы будем открывать длинную позицию SPY от открытия до закрытия в день t + 1, если это 0, тогда мы будет удерживать наличные в день t + 1.

Как мы можем видеть на графике, хотя количество функций, по-видимому, связано с точностью в наборе поездов, это не обязательно означает более высокую точность вне выборки. Некоторые из наиболее сложных моделей, такие как Random Forest с 286 функциями, хорошо подходят для набора поездов, но не дают аналогичных результатов на невидимых данных. С другой стороны, некоторые из менее сложных моделей оказались более надежными. Классификатор Ridge Classifier с 7 функциями смог достичь наилучшего показателя точности (54,32%) за период нашего тестирования.

10. Аналитика торговых стратегий.

Теперь давайте подробнее рассмотрим эффективность одной из протестированных торговых стратегий - мы продолжим с примером Ridge Classifier. Ниже приведены некоторые из интересных графиков, которые я создал с помощью библиотеки Quantopian Pyfolio:

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

10. Заключение

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

Некоторые идеи:

  • Включите фильтр стационарности, чтобы включить только стационарные функции для наших моделей.
  • Больше возможностей: дробная дифференциация кажется интересной темой, на которую стоит потратить некоторое время.
  • Более точное тестирование на истории: учитывайте более точные оценки транзакционной стоимости.
  • Больше данных: я думаю, было бы полезно включить больше экономических / фундаментальных данных не только из США, но и из других крупных стран.

Примечание редакторам Data Science. Хотя мы разрешаем независимым авторам публиковать статьи в соответствии с нашими правилами и рекомендациями, мы не поддерживаем вклад каждого автора. Не следует полагаться на работы автора без консультации с профессионалами. См. Подробности в наших Условиях для читателей.

Ссылка на Github: