Forex Forecast Based on LSTM


This is first deep learning model I built. I just want to put it here to see it later for fun or whatever.

【為替データの扱い】
為替データの予測ということであるが、データは得られるだろうが、モデルを決めないといけない。LSTMで、EURUSDの予想をしてみた。2019年度の一年間のデータを取った。データはHistData.comから取る。最初から、最後まで自分でやるのは初めてだったか、かなり勉強になった。

import pandas as pd 
from sklearn.preprocessing import MinMaxScaler
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.layers import Dense, Flatten, Conv2D, Activation, Dropout
from tensorflow.keras import Model
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM
from keras import optimizers
from keras.optimizers import Adam
from keras import losses
from keras.layers import Dense, Activation
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np

data1= pd.read_csv('drive/My Drive/FX/1/DAT_MT_EURUSD_M1_2019.csv', names = ["date", "time", "open", "high", "low", "close", "volume"])
datetime1 = data1["date"] + "." + data1["time"]
data2 = pd.to_datetime(datetime1, format = "%Y.%m.%d.%H:%M")
data2
data1["datetime"] = data2
data1
timeindex1 = data1.set_index('datetime', inplace=True)
data2 = data1['open'].resample("30T").first()

1分ごとのデータを取ったが、リサンプリングより、30分毎のデータに変えた。またデータの前処理でnanの値のところは、前の値と同じになるようにした。時系列のデータは平均を取るより、このような扱いの方がいいと思う。その後、MinMaxScalerでスケーリングを行った。

#データの欠損値を前の値で埋める
data3 = pd.DataFrame(data2, columns = ["open"])
data4 = data3.fillna(method='ffill')

from sklearn.preprocessing import MinMaxScaler

y = np.array(data4['open'])
# 標準化
scaler = MinMaxScaler(feature_range=(0, 1))   
y1 = y.reshape(-1, 1)
y = scaler.fit_transform(y1)
x = np.arange(len(y))

input_len = 4
X, Y = [], []
for i, _ in enumerate(x):
    if (i+input_len+1 >= len(x)):
        break
    X.append(y[i:i+input_len])
    Y.append(y[i+input_len+1][0])

split_index = int(len(X)*0.7)
# 学習・テスト用データに分割
train_x = X[:split_index]
train_y = Y[:split_index]
test_x = X[split_index:]
test_y = Y[split_index:]

train_x = np.array(train_x).reshape(len(train_x), -1,1)
test_x = np.array(test_x).reshape(len(test_x), -1,1)
train_y = np.array(train_y).reshape(len(train_y),-1,1)
test_y = np.array(test_y).reshape(len(test_y),-1,1)

train_x = np.asarray(train_x)

train_y = np.asarray(train_y)
test_x = np.asarray(test_x)
test_y = np.asarray(test_y)
train_x = np.array(train_x).reshape(len(train_x), -1, 1)
test_x = np.array(test_x).reshape(len(test_x), -1, 1)
train_y = np.array(train_y).reshape(len(train_y))
test_y = np.array(test_y).reshape(len(test_y))

# RNNの初期化
model = tf.keras.Sequential()

# 最初のLSTMとDropoutの追加
model.add(LSTM(50, return_sequences = True))
model.add(Dropout(0.2))

# 二番目のLSTMとDropoutの追加
model.add(LSTM(50, return_sequences = True))
model.add(Dropout(0.2))

# 三番目のLSTMとDropoutの追加
model.add(LSTM(50, return_sequences = True))
model.add(Dropout(0.2))

# 四番目のLSTMとDropoutの追加
model.add(LSTM(50))
model.add(Dropout(0.2))

# 出力層の追加
model.add(Dense(1))

# 学習のためのRNNモデルを設定
model.compile(optimizer = 'adam', loss = 'mean_squared_error')

# RNNモデルを学習させる
model.fit(train_x, train_y, epochs = 10, batch_size = 32)
# モデルの評価
score = model.evaluate(test_x, test_y)
score

損失関数は回帰なので、MSEを使った。

# ラベルなどの設定
df = pd.DataFrame(data4.index.values, columns = ["datetime2"])
label_x = df.to_numpy()
label_x = label_x[len(y)-len(test_y):]

test_y = scaler.inverse_transform(np.array(test_y).reshape(-1,1))
test_y = test_y.reshape(len(test_y))

# 予測値の抽出
predict_y = model.predict(test_x)   
# 元の値に戻す
predict_y = scaler.inverse_transform(predict_y)     

fig, ax = plt.subplots()
ax.plot(label_x, predict_y, label="prediction", color="red")
ax.plot(label_x, test_y, label="raw data", color="blue")
plt.tick_params(axis='x', which='major', labelsize=6)
ax.legend()
plt.show()


赤が予測で、青が元々のデータである。うまく予想できているように思える。