Как использовать базовые модели машинного обучения для прогнозирования фондового рынка?

Введение :

Анализ / прогнозирование фондового рынка считается наиболее сложной областью, конкретно управляемой «Управляющим фондом», который предоставляет индивидуальные услуги институциональным инвесторам через такие учреждения, как хедж-фонды, фонды фондов и другие, а также другие инвестиционные инструменты. Традиционно эти менеджеры хедж-фондов использовали для выполнения анализа или создания стратегии, в основном, путем анализа прошлых финансовых отчетов, показателей рынка и прихода к выводу, какую позицию занять для этой конкретной ценной бумаги или класса активов. Однако с годами, когда объем финансовых данных резко увеличился, традиционный подход к анализу и составлению краткого списка различных стратегий выбора акций изменился, и появилась новая область, называемая количественными финансами. Прежде всего, что такое количественные финансы?

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

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

Давайте копаемся и начинаем кодировать.

Мы рассматриваем набор данных о ценах на акции Infosys, экспериментируем с различными моделями машинного обучения и измеряем, насколько хорошо / точно они предсказывают цены на акции на будущие даты. (Вы можете скачать набор данных здесь)

Импорт необходимых зависимостей

Чтение набора данных и присвоение его Fraud_detection_df. Печать первой строки и проверка любых нулевых значений в наборе данных.

>

(284807, 31)
   Time        V1        V2        V3        V4        V5        V6        V7  \
0   0.0 -1.359807 -0.072781  2.536347  1.378155 -0.338321  0.462388  0.239599   

         V8        V9  ...         V21       V22       V23       V24  \
0  0.098698  0.363787  ...   -0.018307  0.277838 -0.110474  0.066928   

        V25       V26       V27       V28  Amount  Class  
0  0.128539 -0.189115  0.133558 -0.021053  149.62      0  

[1 rows x 31 columns]
False

Давайте изучим наш набор данных.

Набор данных состоит из 284807 строк и 31 столбца. Столбцы с V1 по V28 - это основные компоненты, полученные с помощью PCA, основная причина их получения - обеспечение конфиденциальности данных. Единственные функции, которые не были преобразованы с помощью PCA, - это «Время» и «Сумма». В настоящее время нет нулевых значений.

Всего имеется 8 столбцов, включая дату, открытие, максимум, минимум, последний, закрытие, общее количество сделок, оборот (Lacs). Теперь мы рассмотрим каждый конкретный столбец.

Дата - диапазон дат нашего набора данных с 29 июня 2011 г. по 7 декабря 18 г.
Открытие - представляет собой цену, по которой акции начали торговаться в определенную дату. .
Закрытие - представляет собой цену, по которой акция закрылась в конкретную дату.
Высокая - представляет собой максимальную цену, по которой акции торгуются на конкретную дату.
Низкая - представляет собой минимальную цену акций на определенную дату.
Общее количество сделок - общее количество акций / акций, купленных или проданных в конкретную дату
Оборот (Lacs) - общий объем продаж, произведенных Infosys за один день.

>

Date     Open     High     Low    Last    Close  \
1843  2011-06-29  2868.00  2907.00  2868.0  2880.0  2881.75   
1842  2011-06-30  2886.05  2919.00  2881.5  2903.1  2910.45   
1841  2011-07-01  2935.00  2969.95  2924.1  2928.0  2934.15   
1840  2011-07-04  2966.65  2977.00  2935.0  2941.0  2938.95   
1839  2011-07-05  2957.00  2969.90  2926.0  2959.0  2956.45   

      Total Trade Quantity  Turnover (Lacs)  
1843              600094.0         17320.05  
1842             1417730.0         41163.32  
1841              800308.0         23549.85  
1840              514324.0         15162.29  
1839              802966.0         23701.22  
         Date    Open    High     Low    Last   Close  Total Trade Quantity  \
4  2018-12-03  673.15  679.00  665.95  672.45  670.35             8260890.0   
3  2018-12-04  672.55  688.25  671.30  683.00  685.25             7827923.0   
2  2018-12-05  683.00  683.65  672.50  682.05  681.40             5177288.0   
1  2018-12-06  676.10  685.45  664.55  669.70  668.50             8039771.0   
0  2018-12-07  672.00  685.75  665.60  681.00  682.80             5553948.0   

   Turnover (Lacs)  
4         55395.97  
3         53451.33  
2         35152.07  
1         54036.60  
0         37715.09

Установка индекса набора данных как «Дата»

Цена закрытия акции учитывается для расчета общей прибыли / убытка в конкретный день. Это относительно того, по какой цене мы купили / продали эти акции за один торговый день. Попробуем построить график цены закрытия по годам с 2011 по 2018 год.

>

Функциональная инженерия

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

>

             Close    HL_PCT  PCT_CHNG          Total Trade Quantity
Date                                                         
2011-06-29  2881.75  0.000136  0.000048              600094.0

Давайте рассмотрим прогноз цены акций на 50 дней в будущем, для этого нам нужно установить новую переменную в качестве прогноза_50. Затем мы создадим новый столбец в нашем фрейме данных, который будет служить меткой (также известной как наш вывод). Чтобы заполнить наши выходные данные данными для обучения, мы установим наш столбец меток равным нашему столбцу Close, но сдвинем на 50 единиц вверх.

>

Date        Close   HL_PCT   PCT_CHNG  Total Trade Quantity    label

2011-06-29  2881.75  0.000136  0.000048      600094.0        2198.45
2011-06-30  2910.45  0.000130  0.000085      1417730.0       2222.05


            Close    HL_PCT  PCT_CHNG  Total Trade Quantity  label
Date                                                              
2018-12-06  668.5  0.000314 -0.000112             8039771.0    NaN
2018-12-07  682.8  0.000303  0.000161             5553948.0    NaN


length of our dataset = 1844 and forecast_50 = 50

Определение обучающих данных (X) путем исключения столбца выходной метки и масштабирования данных с использованием

Первоначально наш X содержит последние строки «n = прогноз_50», для которых у нас нет данных ярлыков. Мы поместим это в другую переменную. Итак, изначально у нашего X были строки 1844, а теперь они будут строками 1794 (исключая прогноз_50).

>

Length of X_forecast_out: 50 & Length of X : 1794

Теперь давайте установим нашу зависимую переменную Y со значениями метки (выходного столбца). Обратите внимание: X и Y должны быть одинаковой длины.

>

Length of y:  1794

Обучить и протестировать разделение с помощью cross_validation.

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

>

shape of X_train, X_test, y_train, y_testt:  (1435, 4) (359, 4) (1435,) (359,)

Наша X (зависимая переменная) будет массивом, состоящим из наших значений цен закрытия, поэтому нам нужно удалить столбец Label (output). Нам также необходимо масштабировать наши входные (X) значения с помощью StandardScaler, он в основном преобразует данные так, что их распределение будет иметь среднее значение 0 и стандартное отклонение 1. Учитывая распределение данных, каждое значение в наборе данных будет иметь среднее значение выборки вычитается и затем делится на стандартное отклонение всего набора данных. Как всегда, будет стандартизация fit_transform для данных поездов и преобразование обучения в тестовые данные.

Модель ML: линейная регрессия

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

Подгонка линейной регрессии к данным обучения и получение точности

>

Accuracy of Linear Regression:  0.8102708939416399

Прогнозирование по тестовым данным и расчет RMSE

Среднеквадратичная ошибка (RMSE) - это мера того, насколько хорошо работает наша модель. Это делается путем измерения разницы между прогнозируемыми и фактическими значениями. Это формула описана ниже

>

431.7469839858023

Прогнозирование Infosys на следующие 50 дней.

>

[772.4202455  836.27743045 691.84617824 804.95831536 814.89325432
 846.64498054 865.65689106 791.0668764  819.89489457 816.86055317
 812.88188158 770.34404918 763.3324254  808.77369297 765.49406789
 626.19564885 712.85489885 804.78672085 791.33038646 776.19514655
 735.86146731 782.47744382 737.44817738 740.43107387 723.29979418
 852.66396118 766.90709397 760.80772127 758.73018129 819.39567382
 768.44651906 754.36254123 783.60870196 794.20866184 781.97540993
 747.18203695 762.84516906 777.81785395 692.41414817 717.02659752
 656.95884086 646.60448321 619.83071838 681.87754187 690.12050985
 741.62814397 751.63187717 786.18169166 774.28182633 794.1453933 ]

Вот так! мы только что рассчитали стоимость следующих 50 акций Infosys. Давайте построим график этих курсов акций, добавив следующие 50 будущих дат к нашему существующему набору данных.

>

Модель ML: ARIMA

Давайте выполним прогноз с помощью другой модели машинного обучения под названием ARIMA. ARIMA расшифровывается как Autoregressive Integrated Moving Average. Это очень популярный статистический метод прогнозирования временных рядов. Информация временного ряда - это точки данных, измеренные через согласованные интервалы времени. Это просто означает, что конкретные значения записываются с постоянным интервалом, который может быть ежечасным, ежедневным, еженедельным, ежегодным и т. Д. В данных временных рядов каждая точка данных в серии зависит от предыдущих точек данных. Цены на акции за определенный промежуток времени (в нашем случае из цен между определенными датами) являются примерами данных временных рядов.

ARIMA состоит в основном из трех компонентов - AR (член авторегрессии), I (член дифференцирования) и MA (член скользящего среднего).

Давайте разберемся с каждым из этих компонентов -

Термин AR относится к прошлым значениям, используемым для прогнозирования следующего значения. Термин AR определяется параметром «p» в ариме.

Дифференцирование (I-для интегрированного) - это включает в себя дифференцирование данных временных рядов для удаления тренда и преобразования нестационарных временных рядов в стационарные. На это указывает значение «d» в модели ARIMA. Если d = 1, он смотрит на разницу между записями двух временных рядов, если d = 2, он смотрит на различия различий, полученных при d = 1, и так далее.

Термин MA используется для определения количества прошлых ошибок прогноза, используемых для прогнозирования будущих значений. Термин AR определяется параметром «q» в ариме.

Несмотря на то, что существует традиционная модель ARIMA, в нашем случае мы будем использовать auto_arima, в котором настройка параметров или выбор лучшей комбинации входов (p, q, d) автоматически включается в короткий список, что обеспечивает наименьшую ошибку.

>

Fit ARIMA: order=(1, 1, 1) seasonal_order=(0, 1, 1, 12); AIC=14767.997, BIC=14793.758, Fit time=6.892 seconds
Fit ARIMA: order=(0, 1, 0) seasonal_order=(0, 1, 0, 12); AIC=15637.143, BIC=15647.448, Fit time=0.157 seconds
Fit ARIMA: order=(1, 1, 0) seasonal_order=(1, 1, 0, 12); AIC=15236.193, BIC=15256.802, Fit time=3.451 seconds
Fit ARIMA: order=(0, 1, 1) seasonal_order=(0, 1, 1, 12); AIC=14766.004, BIC=14786.613, Fit time=4.151 seconds
Fit ARIMA: order=(0, 1, 1) seasonal_order=(1, 1, 1, 12); AIC=14767.066, BIC=14792.827, Fit time=5.477 seconds
Fit ARIMA: order=(0, 1, 1) seasonal_order=(0, 1, 0, 12); AIC=15637.689, BIC=15653.146, Fit time=0.329 seconds
Fit ARIMA: order=(0, 1, 1) seasonal_order=(0, 1, 2, 12); AIC=14767.100, BIC=14792.861, Fit time=12.697 seconds
Fit ARIMA: order=(0, 1, 1) seasonal_order=(1, 1, 2, 12); AIC=14761.010, BIC=14791.924, Fit time=28.633 seconds
Fit ARIMA: order=(1, 1, 1) seasonal_order=(1, 1, 2, 12); AIC=14764.508, BIC=14800.574, Fit time=42.835 seconds
Fit ARIMA: order=(0, 1, 0) seasonal_order=(1, 1, 2, 12); AIC=14766.902, BIC=14792.664, Fit time=20.870 seconds
Fit ARIMA: order=(0, 1, 2) seasonal_order=(1, 1, 2, 12); AIC=14764.195, BIC=14800.261, Fit time=31.710 seconds
Fit ARIMA: order=(1, 1, 2) seasonal_order=(1, 1, 2, 12); AIC=14772.617, BIC=14813.835, Fit time=34.641 seconds
Fit ARIMA: order=(0, 1, 1) seasonal_order=(2, 1, 2, 12); AIC=14761.190, BIC=14797.255, Fit time=42.619 seconds
Total fit time: 234.469 seconds

Построение прогнозируемого значения

>

Расчет RMSE

>

1010.0021389097408

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

Модель ML: Пророк

позволяет выполнять прогнозирование с помощью другой модели машинного обучения под названием Prophet. Facebook выпустил документ, описывающий способ делать прогнозы в масштабах Facebook (огромных). Идея состоит в том, что аналитикам нужен способ быстро и надежно делать прогнозы, сохраняя при этом способность повышать ценность своего опыта. Результатом этого стал Пророк. По словам самих Facebook. Prophet - это процедура для прогнозирования данных временных рядов. Он основан на аддитивной модели, в которой нелинейные тренды соответствуют годовой и еженедельной сезонности, а также праздникам. Лучше всего он работает с данными ежедневной периодичности с историческими данными не менее одного года. Prophet устойчив к отсутствию данных, сдвигам в тренде и большим выбросам.

Построение прогнозируемого значения

>

Оранжевый линейный график представляет значения прогнозов нашей модели.

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

Расчет RMSE

>

352.0543292850981

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

Модель ML: LSTM

Теперь давайте спрогнозируем цены закрытия с помощью простой рекуррентной нейронной сети LSTM.

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

1.) Состояние ячейки: здесь хранятся кратковременная и долговременная память. 2.) Скрытое состояние: скрытое состояние можно использовать для восстановления краткосрочной и долгосрочной памяти. 3 ..) Входные данные: решает, сколько информации поступает в состояние ячейки. 4.) Забудьте данные: сколько информации из текущего ввода и предыдущего состояния ячейки переходит в текущее состояние ячейки. 5.) Выходной шлюз: решено, сколько данных перетекает в скрытое состояние из текущего состояния.

(Подробное объяснение работы LSTM см. В этой статье. Http://colah.github.io/posts/2015-08-Understanding-LSTMs/)

Построение модели, разделение поездов-тестов, подгонка по данным поезда и прогнозирование.

Расчет RMSE

>

56.66400958563059

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

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

Прогнозирование запасов по нашей собственной стратегии

Ниже мы рассматриваем функции «Открытые», «Высокие», «Низкие», «Закрытые» из нашего набора данных.

Для нашей собственной рыночной стратегии мы обновляем набор данных, добавляя новые функции, такие как: -

Максимум минус Минимальная цена Закрытие минус Цена открытия Трехдневное скользящее среднее Десятидневное скользящее среднее 30-дневное скользящее среднее Стандартное отклонение за период в 10 дней

Скользящая средняя (MA) - это простой инструмент технического анализа, который сглаживает ценовые данные, создавая постоянно обновляемую среднюю цену. Среднее значение берется за определенный период времени, например 10 дней, 20 минут, 30 недель или любой период времени, выбранный трейдером. Стандартное отклонение - это статистическое измерение, которое измеряет историческую волатильность конкретной акции. В нашем случае мы рассматриваем волатильность на 10 дней.

Здесь мы устанавливаем выходное значение - рост цены как «1» всякий раз, когда цена закрытия завтрашнего дня больше, чем цена закрытия сегодня.

Создание фреймов входных (X) и выходных (Y) данных. Здесь входной объект X состоит из 4-го столбца индекса (H-L) до 9-го индекса (Std_dev) Выходной объект Y состоит из 10-го столбца индекса (Rise_in_Price).

Terain-Test_split и нормализация данных

Создание искусственной нейронной сети

Мы используем библиотеку Sequential для создания нейронной сети нашей нейронной сети, Dense используется для создания слоев нашей искусственной нейронной сети.

Мы используем функцию add () для добавления слоев в нашу neural_network.

Параметры плотной функции

Единицы: № узлов или нейронов в слое. В нашем случае это 135, что означает, что в нашем скрытом слое будет 135 нейронов.

Kernel_initializer: это начальные значения весов различных нейронов в скрытом слое. В нашем случае его «однородные» веса будут иметь значение равномерного распределения.

Активация: это функция активации нейронов скрытого слоя.

Input_dim: определяет количество входов в скрытый слой.

Давайте теперь добавим второй слой к нашей neural_network, что сделает нашу neural_network включающей только два слоя.

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

Здесь мы компилируем neural_network, передавая следующие параметры

Оптимизатор: мы передали оптимизатору как «adam», который является расширением стохастического градиентного спуска.

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

Метрики: определяет список метрик, которые будут оцениваться моделью на этапе тестирования и обучения.

Подгонка модели к обучающим данным путем передачи следующих параметров

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

epochs - количество раз, когда обучение модели будет выполнено на обучающем наборе данных.

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

Предсказание тестовых данных и сохранение прогнозов обратно в y_pred, которые больше 0,5, то есть y-pred будет состоять из логических значений.

Создание нового столбца y_pred в нашем наборе данных, а затем добавление наших прогнозируемых значений в этот столбец, начиная со строк тестового набора данных. Падение значений nan наконец.

Теперь, когда у нас есть прогнозируемые значения, мы рассчитываем стратегии, как показано ниже.

Мы рассматриваем длинную позицию, когда прогнозируемое значение y является истинным, и короткую позицию, когда оно ложно.

Создаем новый столбец «Tomorrows Returns» в trade_Infy и присваиваем ему значение 0. Затем мы берем логарифм сегодняшней цены закрытия, деленной на цену закрытия вчерашнего дня. Затем мы сдвигаем эти значения вверх на один элемент, чтобы завтрашняя прибыль сохранялась по сравнению с сегодняшними ценами.

Теперь мы рассчитаем возврат стратегии с помощью функции np.where (), затем мы сохраним значение в столбце Tomorrows Returns, если значение в столбце y_pred хранит True (длинная позиция), иначе мы сохраним отрицательное значение значение в столбце Tomorrows Returns (короткая позиция); в столбец «Стратегия возврата»

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

Похоже, что наша стратегия приносит больше прибыли, чем рыночная цена акций Infosys.

Вывод :

Мы выполнили прогнозирование запасов на основе набора данных Infosys с использованием четырех различных моделей машинного обучения: линейной регрессии, ARIMA, Prophet, LSTM. Из них LSTM неплохо показал себя, а ARIMA - хуже всех. Кроме того, я хотел бы упомянуть, что мы можем значительно повысить производительность нашей модели, настроив гиперпараметры и дополнительную разработку функций. Наконец, мы смоделировали нашу стратегию и сравнили результаты с ценами на традиционных фондовых рынках Infosys и ценами на них (пожалуйста, не стесняйтесь экспериментировать с этими моделями и копаться в них подробнее)