Нейронные сети для анализа индикаторов рынка

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

Использование Google Colab

Пожалуй, самый простой способ реализовать нейронную сеть с Keras - запустить блокнот в Google Colab, в котором вы можете организовать свой код в несколько ячеек кода. Вам не нужно устанавливать Keras в записную книжку, как и NumPy, который также используется в примере. Однако вам все равно нужно установить библиотеки yfinance и quandl, чтобы получать цены на акции и золото соответственно.

!pip install yfinance
!pip install quandl

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

Получение данных

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

import yfinance as yf
tkr = yf.Ticker('TSLA')
hist = tkr.history(period="5y") 
import pandas_datareader.data as pdr
from datetime import date, timedelta
end = date.today()
start = end — timedelta(days=5*365+1)
index_data = pdr.get_data_stooq('^SPX', start, end)
df = hist.join(index_data, lsuffix = '_tkr', rsuffix = '_idx')
df = df[['Close_tkr','Volume_tkr','Close_idx','Volume_idx']]

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

Затем вы получите цены на золото за тот же период. Прежде чем вы сможете это сделать, вам нужно будет создать учетную запись Quandl, чтобы получить бесплатный токен API:

import quandl
gold_price = quandl.get("LBMA/GOLD",start_date=start, end_date=end, authtoken="your_quandl_token")
df = df.join(gold_price['USD (AM)'])
df = df.rename(columns={'USD (AM)': 'Gold'})

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

Создание функций из данных

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

import numpy as np
df['priceRise_tkr'] = np.log(df['Close_tkr'] / df['Close_tkr'].shift(1))
df['volumeRise_tkr'] = np.log(df['Volume_tkr'] / df['Volume_tkr'].shift(1))
df['priceRise_idx'] = np.log(df['Close_idx'] / df['Close_idx'].shift(1))
df['volumeRise_idx'] = np.log(df['Volume_idx'] / df['Volume_idx'].shift(1))
df['priceRise_gold'] = np.log(df['Gold'] / df['Gold'].shift(1))
df = df.dropna()

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

df['tkrPred'] = df['priceRise_tkr'].shift(-1)
df['goldPred'] = df['priceRise_gold'].shift(-1)
df['tkrPred'] = df['tkrPred']*100
df['goldPred'] = df['goldPred']*100
df = df.dropna()

Обратите внимание, что вы масштабируете значения в столбцах tkrPred и goldPred до реальных процентов, а не реальных чисел в диапазоне от -1,0 до 1,0.

Теперь вам нужно преобразовать df DataFrame с функциями и целевыми переменными в соответствующие массивы NumPy, которые будут использоваться для обучения и оценки модели:

features = df[['priceRise_tkr','volumeRise_tkr','priceRise_idx','volumeRise_idx','priceRise_gold']].to_numpy()
features = np.around(features, decimals=2) 
target = df[['tkrPred','goldPred']].to_numpy()

Настройка модели

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

from keras.models import Sequential
from keras.layers import Dense

Вы получаете модель в отдельной функции:

def get_model(n_inputs, n_outputs):
  model = Sequential()
  model.add(Dense(n_inputs, input_dim=n_inputs, activation='relu'))
  model.add(Dense(100, kernel_initializer='he_uniform', activation='relu'))
  model.add(Dense(n_outputs))
  model.compile(loss='mae', optimizer='adam')
  return model

Как видите, модель имеет три уровня: входной, скрытый и выходной. Вы определяете mae как функцию потерь и оптимизатор adam.

Обучение и оценка модели

Здесь вы тренируете и оцениваете модель с помощью повторяющегося кросс-валидатора K-кратного пересечения, который возвращает разные результаты для каждого вызова разделения:

from sklearn.model_selection import RepeatedKFold
n_inputs, n_outputs = features.shape[1], target.shape[1]
cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1)
for train_ix, test_ix in cv.split(features):
  X_train, X_test = features[train_ix], features[test_ix]
  y_train, y_test = target[train_ix], target[test_ix]
  model = get_model(n_inputs, n_outputs)
  model.fit(X_train, y_train, verbose=0, epochs=20)
  mae = model.evaluate(X_test, y_test, verbose=0)
  print('>%.3f' % mae)

Вот как может выглядеть результат:

>1.540
>1.527
>1.551
>1.606
>1.481
>1.495
>1.731
>1.380
…