【Python】MT4ヒストリカルデータからAIで次の終値を予測する

スポンサーリンク

AIで為替の予想なんで出来たらいいですよね。ネットでいろいろ調べてみると、日足のヒストリカルデータから次の日足をAIで予測することをやっている人はいます。

1分足とか細かい足で予測したい!リアルタイムで予測したい!

他にも調べてみるとOANDAのAPIを使って予測している人もいました。

でも2021年5月22日現在はOANDAのAPIはプロコースかつゴールド会員じゃないと使えない!私はゴールド会員ですがベーシックコースなので使えません。

そこで目標は

PythonでAIを使ってFXDDのデモトレードMT4の最新ヒストリカルデータから1分後の終値を予測する!

です。

目標

PythonでAIを使ってFXDDのデモトレードMT4の最新ヒストリカルデータから1分後の終値を予測する。

参考にしたサイト

  1. Yahooファイナンスの日足データからAIで予測する方法。ディープラーニングの説明もあり、とても分かりやすいです。
【2時間で完成】為替(FX)を予想する深層学習AIをPythonで無料作成
こういった想いを持つ方に向けて記事を書いていきます。 これまで機械学習やデータ分析の経験がなくても、 Pythonを使ったことさえあれば動かすことができるコードを作成していきます。ちなみに最後の「FX取引の注文を発注する」という部分にはOA...
  1. MT4のヒストリカルデータをHST形式からCSV形式にする。
    MT4のヒストリカルデータはHST形式で、メモ帳で開いても文字化けしているような感じで何が何だかわかりません。このサイトのおかげでHSTデータを時刻と始値、高値、安値、終値に変換することが出来ました。

準備

  • MT4を使える環境
    取引業者はFXDDじゃなくてもいいです。デモ口座、本番口座はどちらでもいいです。
  • Pythonを使える環境
    AnacondaをインストールしてAnaconda Promptを使いました。
    Google Colaboratoryでやろうと思いましたが上手くいきませんでした。
  • フォルダの準備
    Pythonコードとヒストリカルデータを同じフォルダに入れる必要があります。
    私の場合:
    Desktop > FX_AI > 「FX_AI.py」「USDJPY15.hst」
  • ヒストリカルデータの場所
    私の場合:
    OS(C:) > ユーザー > ユーザー名 > AppData > Roaming > MetaQuotes > Terminal > (英数字のながーい羅列) > history > FXDD-MT4 Demo Server > 「USDJPY15.hst」

    「AppData」フォルダが見当たらない場合は上の表示タブから「隠しファイル」にチェックを入れてください。

コードの全容

コードの全容を貼ります。所々無駄な行があったりしますが、目を瞑ってください。

今回は15分足で分析したので「USDJPY15.hst」を開いています。

import os # ディレクトリ作成、パス結合、ファイル削除
import pandas as pd
import numpy as np

df=open("USDJPY15.hst",'rb')
#バイナリファイルを開く
ver = np.frombuffer(buffer=df.read(148)[:4], dtype='i4')
print(ver)
dtype=[
       ('DateTime','u8'),
       ('Open','f8'),
       ('Low','f8'),
       ('High','f8'),
       ('Close','f8'),
       ('Volume','f8'),
       ('Spread','i4'),
       ('RealVolume','i8')
]
df=pd.DataFrame(np.frombuffer(buffer=df.read(),dtype=dtype))
df=df.set_index(pd.to_datetime(df['DateTime'],unit='s')).drop('DateTime',axis=1)
print(df)
#df.to_csv(os.path.join(hst_dir,'USDJPY.csv'))

from tensorflow.keras.layers import Activation, Dense, Dropout
#機械学習ライブラリtensorflow
from tensorflow.keras.models import Sequential
from tensorflow.keras.optimizers import Adam
import matplotlib.pyplot as plt
import pandas_datareader.data as DataReader

def build_simple_model():
  simple_model=Sequential()
  simple_model.add(Dense(8,activation='relu',input_shape=(16,)))
  #中間層入力16出力8
  simple_model.add(Dense(8,activation='relu'))
  simple_model.add(Dense(8,activation='relu'))
  simple_model.add(Dense(1))
  #最終出力1

  return simple_model

forex_model=build_simple_model()
#print(forex_model.summary())
#深層学習モデルの形状を表示

forex_model.compile(loss='mse',optimizer=Adam(lr=0.001),metrics=['mae'])
#最適化の仕方を決める
#mse:mean_squared_error(平均二乗誤差)
#mae:mean_absolute_error(平均絶対誤差)

df['Close']=df['Close'].astype(float)

for i in range(16):
  df['Close-'+str(i+1)]=df['Close'].shift(i+1)

df=df.dropna(how='any')
#欠損値のある行を削除

train_x=df[['Close-'+str(i+1) for i in range(16)]].values
train_y=df['Close'].values

history=forex_model.fit(train_x,train_y,epochs=10,validation_split=0.2)
#epoch訓練データを何回繰り返して学習するか
#validation_split検証データとして使う割合

forex_model.save_weights('param.hdf5')

plt.plot(history.history['mae'],label='train mae')
plt.plot(history.history['val_mae'],label='val mae')
plt.xlabel('epoch')
plt.ylabel('mae')
plt.legend(loc='best')
plt.ylim([0,5])
#y軸の表示範囲を指定
plt.savefig('train.png')
#files.download('train.png')

input_data = np.array([[df['Close'].iloc[-(i+1)] for i in range(16)]])

prediction = forex_model.predict(input_data).flatten()
print('AIの予想値は',prediction)

出力結果

15分毎のデータになっていることが確認出来ました。

予想値が出力されましたが、今回は学習回数が10回だけなので全然信頼出来ないです笑。

次はコードの各パートの説明をします。説明不要の方はここで終わりです。

HSTファイルを開く

HSTファイルはメモ帳で開いてみると分かりますが、バイナリファイルといって、人が読めるものではありません。機械が読める形式のものです。

そこでHSTファイルであるヒストリカルデータを開くプロセスが下の部分です。

df=open("USDJPY15.hst",'rb')
#バイナリファイルを開く
  • open()に’rb’を付けることでバイナリファイルを開くことが出来ます。
  • USDJPY15.hstの「15」とは15分足のデータであることを表します。予測したい時間足に応じてヒストリカルデータのファイルを選択してください。開くファイルに応じてコードを修正してください。
ver = np.frombuffer(buffer=df.read(148)[:4], dtype='i4')
print(ver)
dtype=[
       ('DateTime','u8'),
       ('Open','f8'),
       ('Low','f8'),
       ('High','f8'),
       ('Close','f8'),
       ('Volume','f8'),
       ('Spread','i4'),
       ('RealVolume','i8')
]
df=pd.DataFrame(np.frombuffer(buffer=df.read(),dtype=dtype))
df=df.set_index(pd.to_datetime(df['DateTime'],unit='s')).drop('DateTime',axis=1)
print(df)
#df.to_csv(os.path.join(hst_dir,'USDJPY.csv'))
  • この操作ではバイナリファイルを人が読めるデータにし、時刻、始値、安値、高値、終値などに整列したデータに変換しています。
  • print(df)によって変換されたことが確認出来ます。
  • 「ver」というのは今回はバイナリデータのタイプを示すもので、print(ver)では[410]と表示されるはずです。難しいのでよく分かりませんでした笑。

深層学習するための準備

from tensorflow.keras.layers import Activation, Dense, Dropout
#機械学習ライブラリtensorflow
from tensorflow.keras.models import Sequential
from tensorflow.keras.optimizers import Adam
import matplotlib.pyplot as plt
import pandas_datareader.data as DataReader

  • 深層学習をするために必要なものをimportします。参考サイトで詳しく学んでください。
def build_simple_model():
  simple_model=Sequential()
  simple_model.add(Dense(8,activation='relu',input_shape=(16,)))
  #中間層入力16出力8
  simple_model.add(Dense(8,activation='relu'))
  simple_model.add(Dense(8,activation='relu'))
  simple_model.add(Dense(1))
  #最終出力1

  return simple_model

forex_model=build_simple_model()
#print(forex_model.summary())
#深層学習モデルの形状を表示

forex_model.compile(loss='mse',optimizer=Adam(lr=0.001),metrics=['mae'])
#最適化の仕方を決める
#mse:mean_squared_error(平均二乗誤差)
#mae:mean_absolute_error(平均絶対誤差)
  • 深層学習するためのモデルを設定します。ここでは中間層への入力数と中間層からの出力の数などを指定できます。
  • 最適化の仕方を決めることも出来ます。
df['Close']=df['Close'].astype(float)

for i in range(16):
  df['Close-'+str(i+1)]=df['Close'].shift(i+1)

df=df.dropna(how='any')
#欠損値のある行を削除

train_x=df[['Close-'+str(i+1) for i in range(16)]].values
train_y=df['Close'].values
  • 中間層への入力データの数は16なので、各時刻の終値の横の列に過去の直近の終値のデータ16個を並べます。
  • 最初の16個のデータは直近終値のデータが16個未満なので学習する時の対象外で、行もろとも削除します。

深層学習し予測結果を表示する

history=forex_model.fit(train_x,train_y,epochs=10,validation_split=0.2)
#epoch訓練データを何回繰り返して学習するか
#validation_split検証データとして使う割合
  • どのデータから何を予測するか、何回繰り返し学習するかなどを決めます。
  • 今回は「直近終値16個(train_x)」から「直後の終値(train_y)」を求めます。
  • 学習する繰り返しの回数はepochs=10回としていますが、通常は100回とはそれ以上みたいです。計算に時間かかるので10回だけで出力結果を表示しました。
forex_model.save_weights('param.hdf5')
  • 学習結果(パラメーターを保存、記憶する)
plt.plot(history.history['mae'],label='train mae')
plt.plot(history.history['val_mae'],label='val mae')
plt.xlabel('epoch')
plt.ylabel('mae')
plt.legend(loc='best')
plt.ylim([0,5])
#y軸の表示範囲を指定
plt.savefig('train.png')
#files.download('train.png')
  • 学習した時の学習回数が増えるたびにどのようなペースで最適化出来ているかのグラフを作ります。
  • Pythonファイルと同じフォルダに「train.png」が出来ると思います。これでepochsをどのくらいにするべきか分かるみたいです。
input_data = np.array([[df['Close'].iloc[-(i+1)] for i in range(16)]])
  • リアルタイムの直近16個の終値データを入力データに設定します。
prediction = forex_model.predict(input_data).flatten()
print('AIの予想値は',prediction)
  • 最適化した時のパラメーターを使って直近16個のデータから次の足の終値を予測します。
  • 予測値を表示します。

まとめ

PythonでAIを使ってMT4の最新ヒストリカルデータから15分後の終値を予測することが出来ました。

1分足で予測をしようとしましたが、計算に時間がかかり1分では間に合いませんでした。

課題

  • 計算に時間がかかり、15分足以上でないと予測が間に合わない
  • 精度が低い
  • 足が更新されるたびに「FX_AI」フォルダのヒストリカルデータを更新しなければならない
    これは、PythonをMetaQuotes > Terminal > (英数字のながーい羅列) > history > 「FXDD-MT4 Demo Server」フォルダ内で実行すれば解決するかもしれません。

未完成のプログラムなので各自で修正して使うことをオススメします!

コメント

タイトルとURLをコピーしました