Цель

Торговля алгоритмами - самая противоречивая тема во всем мире. Исследователи и эксперты по инвестициям прилагают все усилия, чтобы уловить тенденции цен и получить маржинальную прибыль. Как энтузиаст данных, меня интересует, насколько точной может быть модель прогнозирования, и поэтому в этой статье я буду использовать один из фундаментальных механизмов нейронной сети «LSTM» для прогнозирования цен на несколько криптовалют.

Импорт данных

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

Анализ данных о ценах на криптовалюту за 1 минуту (Python)

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

Все коды и данные загружены на мой GitHub. Вы можете проверить и народное это репо для дальнейшего изучения модели. =)

В этой статье я начну с импорта подготовленного файла cryptocurrency_df.csv.

import pandas as pd
cryptocurrency_df = pd.read_csv('cryptocurrency_df.csv')
cryptocurrency_df['Datetime'] = pd.to_datetime(cryptocurrency_df['Datetime'])
cryptocurrency_raw_df = cryptocurrency_df.copy()
coindesk20_list = list(cryptocurrency_df.columns)[1:]

Визуализация данных

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

Индивидуальное ценообразование на криптовалюту

import matplotlib.pyplot as plt
coin = coindesk20_list[0]
plt.figure(figsize=(16,8))
plt.plot(cryptocurrency_df['Datetime'], cryptocurrency_df[coin])
plt.ylabel('Price (USD)')
plt.xlabel('Date')
plt.title(coin + ' Price from ' + str(min(cryptocurrency_df['Datetime']))[:10] + ' to ' + str(max(cryptocurrency_df['Datetime']))[:10])
plt.show()

Стоимость нескольких криптовалют

import matplotlib.pyplot as plt
fig = plt.figure(figsize=(18,16))
fig.suptitle('The CoinDesk 20 Prices (Original)', fontsize=16, y = 0.92)
for i in range(len(coindesk20_list)):
    coin = coindesk20_list[i]
    plt.subplot(5, 4, i+1)
    plt.plot(cryptocurrency_df['Datetime'], cryptocurrency_df[coin], color = 'C1')
    plt.title(coin)
    plt.xticks([])
plt.show()

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

Параметры

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

  1. x_window: сколько прошлых ценовых данных вы будете использовать для прогнозирования цены?
  2. time_shift: какой момент времени вы хотите предсказать на основе прошлых данных?
  3. testing_window: как долго вы хотите тестировать модель?

Позвольте мне объяснить концепцию графическим способом. Обратите внимание, что в наборе данных мы используем данные за 1 минуту, но здесь, я думаю, легче понять концепции, используя ежедневные данные. Учитывая, что теперь у вас есть данные о ценах за 10 дней, вы хотите использовать данные за 3 дня, чтобы спрогнозировать цену через 2 дня. Другими словами, вы будете использовать цены понедельника, вторника и среды, чтобы предсказать цену пятницы. В этом случае для x_window будет установлено значение 3, поскольку используются данные только за 3 дня, а time_shift будет равно 2, поскольку вы прогнозируете цену через 2 дня. И последнее, но не менее важное: для проверки модели мы хотели бы использовать данные за последние 4 дня для ее тестирования, и поэтому для testing_window будет установлено значение 4.

В этом руководстве мы будем использовать данные за 3 часа, чтобы спрогнозировать цену следующей минуты на 1 день в качестве примера. (x_window: 180, time_shift = 1, testing_window: 1440)

testing_window = 1440      # 1 day
x_window = 180             # 3 hours
time_shift = 1             # 1 minute

Предварительная обработка данных

Нетрудно обнаружить, что разные криптовалюты могут иметь совершенно разные величины. Например, BTC колеблется от 30 000 до 42 500 долларов США, а EOS - от 3 до 4 долларов США. Одним из способов повышения производительности модели и более быстрой сходимости является масштабирование данных посредством стандартизации.

from sklearn.preprocessing import StandardScaler
train_idx = int((len(cryptocurrency_df) - testing_window - x_window)*0.8) + x_window
sc = StandardScaler().fit(cryptocurrency_df.iloc[:train_idx, 1:])
cryptocurrency_df.iloc[:, 1:] = sc.transform(cryptocurrency_df.iloc[:, 1:])

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

Подготовка данных

В этом руководстве мы будем использовать данные за 3 часа, чтобы спрогнозировать цену следующей минуты на 1 день в качестве примера. (x_window: 180, time_shift = 1, testing_window: 1440) Изучив методику, вы можете установить другую комбинацию, чтобы настроить ваши потребности, например, использование данных за 1 месяц для прогнозирования цены в следующем месяце.

Шаг 1. Преобразуйте данные в X и Y

datetime_list = cryptocurrency_df['Datetime']
cryptocurrency_df = cryptocurrency_df.iloc[:, 1:]
import numpy as np

X = np.zeros((len(cryptocurrency_df)-x_window-time_shift+1, len(cryptocurrency_df.columns), x_window))
Y = np.zeros((len(cryptocurrency_df)-x_window-time_shift+1, len(cryptocurrency_df.columns), 1))
for i in range(X.shape[0]):
    X[i] = np.array(cryptocurrency_df.iloc[i:i+x_window]).T
    Y[i] = np.array(cryptocurrency_df.loc[i+x_window+time_shift-1])[:,np.newaxis]

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

Шаг 2. Разделите данные на наборы для обучения, проверки и тестирования

X_train = X[:-testing_window]
Y_train = Y[:-testing_window]
X_test = X[-testing_window:]
Y_test = Y[-testing_window:]
val_idx = int(X_train.shape[0]*0.8)
X_val = X_train[val_idx:]
Y_val = Y_train[val_idx:]
X_train = X_train[:val_idx]
Y_train = Y_train[:val_idx]

Модель LSTM

LSTM означает долгую краткосрочную память. Это известная архитектура нейронной сети, используемая для последовательных данных, таких как данные о продольных ценах.

from tensorflow import keras
from tensorflow.keras import layers
model = keras.Sequential([
    layers.LSTM(64, input_shape=X.shape[1:], activation="relu", return_sequences=True),
    layers.Dense(1),])
opt = keras.optimizers.SGD(learning_rate=0.01, momentum=0.01, nesterov=True)
model.compile(loss='mean_squared_error', optimizer=opt)
callback = keras.callbacks.EarlyStopping(monitor='val_loss', patience=30)
history = model.fit(X_train, Y_train, epochs=1000, validation_data=(X_val, Y_val), shuffle=True, batch_size=8, verbose=1, callbacks=[callback])

Чтобы обучить нейронную сеть, вы можете выполнить следующие шаги.

1. Определите архитектуру модели.

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

2. Определите функцию потерь и соответствующий оптимизатор.

После настройки архитектуры модели мы должны решить, какую функцию потерь использовать. В нашем случае, поскольку мы прогнозируем числовые цены crptocurrencies, можно рассмотреть «mean_sequared_error». Здесь используется оптимизатор «SGD» (стохастический градиентный спуск), который представляет собой простой, но известный подход к обучению модели.

3. Начните подгонку модели.

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

  • shuffle: если для параметра shuffle установлено значение TRUE, обучающие образцы будут иметь случайный порядок вместо последовательного. Это может каким-то образом помочь предотвратить чрезмерное изучение модели.
  • batch_size: это количество выборок, использованных в 1 итерации.
  • callback: ранняя остановка обратного вызова может избежать переобучения и сократить время обучения, когда нет улучшений с точки зрения val_loss.

Прогнозирование модели

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

Y_pred = model.predict(X_test)[:, :, 0]
pred_df = pd.DataFrame(sc.inverse_transform(Y_pred), columns=coindesk20_list, index=list(datetime_list[-len(Y_pred):]))
pred_df = pred_df.rename_axis('Datetime').reset_index()
pred_df.head()

Здесь вы можете заметить, что после предсказания я использую sc.inverse_tranform в направлении Y_pred. Это потому, что в самом начале статьи я стандартизировал цены на криптовалюты. Следовательно, inverse_transform - это преобразование их обратно в соответствующем масштабе.

Чтобы визуализировать результат прогноза, вы можете использовать приведенные ниже коды.

Индивидуальное ценообразование на криптовалюту

import matplotlib.pyplot as plt
coin = coindesk20_list[0]
plt.figure(figsize=(16,8))
temp_df = cryptocurrency_raw_df.iloc[-1440*7:]
plt.plot(temp_df['Datetime'], temp_df[coin])
plt.plot(pred_df['Datetime'], pred_df[coin], alpha = 0.6)
# add verticle reference line
plt.axvline(x=min(pred_df['Datetime']), color='k', linestyle=(0, (5, 5)))
plt.ylabel('Price (USD)')
plt.xlabel('Date')
plt.title(coin + ' Predicted Price from ' + str(min(temp_df['Datetime']))[:10] + ' to ' + str(max(temp_df['Datetime']))[:10])
plt.show()

Стоимость нескольких криптовалют

import matplotlib.pyplot as plt
temp_df = cryptocurrency_raw_df.iloc[-1440*7:]
fig = plt.figure(figsize=(18,16))
fig.suptitle('The CoinDesk 20 Predicted Prices', fontsize=16, y = 0.92)
for i in range(len(coindesk20_list)):
    coin = coindesk20_list[i]
    plt.subplot(5, 4, i+1)    
    plt.plot(temp_df['Datetime'], temp_df[coin], color = 'k', alpha = 0.3)
    plt.plot(pred_df['Datetime'], pred_df[coin], alpha = 0.5)
    plt.axvline(x=min(pred_df['Datetime']), color='k', linestyle=(0, (5, 5)))
    plt.title(coin)
    plt.xticks([])
plt.show()

Резюме

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

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