Préface
La dernière fois, j'ai présenté une stratégie de trading quantitative simple et j'ai reçu de nombreux messages privés me demandant comment utiliser le modèle de série chronologique d'apprentissage en profondeur. Permettez-moi de partager quelques idées sur la façon dont le modèle LSTM prédit les prix de demain.
Modèle LSTM
La mémoire à long terme (LSTM) est un réseau neuronal séquentiel spécial. Une unité LSTM ordinaire se compose d'une "unité" , d'une "porte d'entrée" , d'une "porte de sortie" et d'une "porte d'oubli" .
![19751ed4f093394a335b145df84eda75.png](https://img-blog.csdnimg.cn/img_convert/19751ed4f093394a335b145df84eda75.png)
Pour faire simple, le modèle de série chronologique utilise une période continue de données dans l'historique pour prédire les données futures. Nous connectons les flux de données d'entrée de manière cyclique à l'aide du module LSTM, comme le montre la figure ci-dessous.
![b7f246dd2e2e4a6d4e40ac71c132f5ce.png](https://img-blog.csdnimg.cn/img_convert/b7f246dd2e2e4a6d4e40ac71c132f5ce.png)
Préparation environnementale
Nous ouvrons d'abord un nouveau Notebook sur Jukuan. N'oubliez pas d'utiliser la version python3, sur laquelle Tensorflow est préinstallé.
❝Sinon, installez-le manuellement
❞
!pip install tensorflow
import math
import numpy as np
import pandas as pd
import tensorflow as tf
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import Dense, LSTM
import matplotlib.pyplot as plt
plt.style.use('fivethirtyeight')
Vérifiez d'abord la version tensorflow, 1.12, keras 2.2.4, le modèle simple est fondamentalement suffisant.
import keras
print('tensorflow:',tf.__version__) # 1.12.2
print('keras:',keras.__version__) # 2.2.4
préparation des données
En prenant comme exemple le « Fonds indiciel CSI 300 », les données des 60 premiers jours sont un intervalle de série chronologique et nous obtenons toutes les « données de clôture » depuis 2015 sous forme d'ensemble de données.
security = '510300.XSHG'
his_period = 60 # 历史时间
df = get_price(security, start_date="2015-01-05", end_date="2021-12-31", frequency='daily')
df[:3]
![6975f2f7be834ff9829bab75613cb9b1.png](https://img-blog.csdnimg.cn/img_convert/6975f2f7be834ff9829bab75613cb9b1.png)
Il y a 1705 éléments de données au total. Visualisons-les d’abord.
plt.figure(figsize=(16,8))
plt.title('Close Price History')
plt.plot(df['close'])
plt.xlabel('Date', fontsize=18)
plt.ylabel('Close Price', fontsize=18)
plt.show()
![dcb7b3a38ad128b23a4a272ef8435394.png](https://img-blog.csdnimg.cn/img_convert/dcb7b3a38ad128b23a4a272ef8435394.png)
Divisez l'ensemble de formation
Filtrez les données de clôture et divisez d'abord 80 % de celles-ci dans un ensemble de formation contenant 1 364 enregistrements.
data = df.filter(['close'])
dataset = data.values
training_data_len = math.ceil( len(dataset) * .8 )
Normalisez les données et mettez-les à l'échelle à (0,1) pour faciliter la formation
scaler = MinMaxScaler(feature_range=(0, 1))
scaled_data = scaler.fit_transform(dataset)
![b1b1e2fee668e81fc04fb850387470d9.png](https://img-blog.csdnimg.cn/img_convert/b1b1e2fee668e81fc04fb850387470d9.png)
Toutes les 60 données historiques sont utilisées comme ensemble de formation, et des données d'étiquette sont attribuées pour générer un ensemble de formation.
train_data = scaled_data[0:training_data_len, :]
x_train = []
y_train = []
for i in range(his_period, len(train_data)):
x_train.append(train_data[i-his_period:i, 0])
y_train.append(train_data[i, 0])
x_train, y_train = np.array(x_train), np.array(y_train)
x_train = np.reshape(x_train, (x_train.shape[0], x_train.shape[1], 1))
x_train.shape
Après l'avoir converti en tableau numpy, les dimensions sont (1304, 60, 1).
La modélisation
Nous utilisons le modèle séquentiel keras pour construire le réseau neuronal, utilisons d'abord un LSTM à 2 couches de 50 unités pour extraire les fonctionnalités, puis utilisons une couche entièrement connectée pour générer les résultats. L'optimiseur utilise Adam et la fonction de perte utilise MSE.
model = Sequential()
model.add(LSTM(50, return_sequences=True, input_shape=(x_train.shape[1], 1)))
model.add(LSTM(50, return_sequences=False))
model.add(Dense(25))
model.add(Dense(1))
model.compile(optimizer='adam', loss='mean_squared_error')
Modèle de formation
Définissez la taille du lot sur 1 et entraînez-vous d'abord pendant 5 époques.
model.fit(x_train, y_train, batch_size=1, epochs=5)
![d455bfd13ef38cb4a6780af0701f4dfa.png](https://img-blog.csdnimg.cn/img_convert/d455bfd13ef38cb4a6780af0701f4dfa.png)
Bon, tout est prêt, la prochaine étape consiste à préparer une tasse de café et à attendre patiemment. . .
Valider le modèle
Nous divisons les 20 % restants des données dans l'ensemble de test, qui est également converti en données numpy, avec des dimensions de (341, 60, 1).
test_data = scaled_data[training_data_len - his_period:, :]
x_test = []
y_test = dataset[training_data_len:, :]
for i in range(his_period, len(test_data)):
x_test.append(test_data[i-his_period:i, 0])
x_test = np.array(x_test)
x_test = np.reshape(x_test, (x_test.shape[0], x_test.shape[1], 1))
x_test.shape
Pour prédire une vague, calculez d’abord la rmse.
predictions = model.predict(x_test)
predictions = scaler.inverse_transform(predictions)
rmse=np.sqrt(((predictions - y_test) ** 2).mean())
rmse
![6debec02a393975861063c6ec2fd91ee.png](https://img-blog.csdnimg.cn/img_convert/6debec02a393975861063c6ec2fd91ee.png)
Visualisez l'effet
train = data[:training_data_len]
valid = data[training_data_len:]
valid['Predictions'] = predictions
plt.figure(figsize=(16, 8))
plt.title('Model')
plt.xlabel('Data', fontsize=18)
plt.ylabel('Close Price', fontsize=18)
plt.plot(train['close'])
plt.plot(valid[['close', 'Predictions']])
plt.legend(['Train', 'Val', 'Predictions'], loc='lower right')
plt.show()
![9ec4ce938c329ec13495c8afc2b2de86.png](https://img-blog.csdnimg.cn/img_convert/9ec4ce938c329ec13495c8afc2b2de86.png)
Dans l’ensemble, la tendance est fondamentalement prévue et le prix prévu est conservateur. Il peut y avoir des facteurs tels que des époques de modèle insuffisantes, ou il se peut que l'indice soit à un niveau relativement élevé au cours des deux dernières années et que le modèle n'ait pas vu le monde.
Les amis intéressés peuvent modifier certains paramètres ou introduire plus de fonctionnalités et les affiner.
Combat réel
Ré-acquérir l'ensemble de données, toutes les données de 2015 à hier.
new_df = get_price(security, start_date="2015-01-05", end_date="2022-1-4", frequency='daily')
new_df.tail()
![cec54f5eb176eb410858a8b009c18f47.png](https://img-blog.csdnimg.cn/img_convert/cec54f5eb176eb410858a8b009c18f47.png)
Prédisons le cours de clôture de demain
last_days = new_df.filter(['close'])[-his_period:].values
last_days_scaled = scaler.transform(last_days)
X_test = []
X_test.append(last_days_scaled)
X_test = np.array(X_test)
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))
pred_price = model.predict(X_test)
pred_price = scaler.inverse_transform(pred_price)
print(pred_price)
[[4.901391]]
N'oubliez pas de jeter un œil au prix réel après la fermeture du marché demain ?
get_price(security, start_date="2022-1-5", end_date="2022-1-5", frequency='daily').filter(['close'])
D'accord, je vous ai dit le code de la richesse, cela dépend simplement de l'exactitude du cours de clôture de demain.
![94f3152075318638ec629e97f478350f.png](https://img-blog.csdnimg.cn/img_convert/94f3152075318638ec629e97f478350f.png)
Enfin, je voudrais mentionner qu’il existe des risques à entrer sur le marché et que l’investissement doit donc être prudent.
Téléchargement du code source
![b25564a43ca8a17b4d13d84d348defd6.png](https://img-blog.csdnimg.cn/img_convert/b25564a43ca8a17b4d13d84d348defd6.png)
Les documents et informations pertinents pour ce problème peuvent être trouvés sur le compte public « Deep Awakening » et répondre : « trade01 » en arrière-plan pour obtenir le lien de téléchargement.