【2時間で完成】為替(FX)を予想する深層学習AIをPythonで無料作成

・Deep Learning を使って 為替相場(FX)の予想をしてみたい
・自動で FX 取引をしてくれる bot をPythonで作りたい
こういった想いを持つ方に向けて記事を書いていきます。
この記事で作るコードの動き
・yahooファイナンスからドル円のデータを取得する
・取得したデータを使ってに深層学習 AI を学習させる
・学習した AI を使って未来のドル円の価格を予想する
・価格予想に従い FX 取引の注文を発注する
これまで機械学習やデータ分析の経験がなくても、 Pythonを使ったことさえあれば動かすことができるコードを作成していきます。
ちなみに最後の「FX取引の注文を発注する」という部分にはOANDA Japanの口座開設が必要ですが、それ以外のコードを動かす分には必要ありません。
【2021年8月24日追記】

現在、この記事に掲載しているget_data_and_train.pyを実行すると、

pandas_datareader._utils.RemoteDataError: Unable to read URL: https://finance.yahoo.com/quote/…….

といったエラーが出るようになっています。
どうやらYahoo financeがデータのスクレイピングを禁止してしまったようです。そのため、データ収集は手動で行う必要があります(今後もしかしたら修正版に更新するかもしれません)。

為替予想の人工知能の仕組み

はじめに今回作成するAIモデルの概要を説明しておきます。
仮想通貨の価格予想をディープランニングで行うで使ったモデルと基本的には一緒です。
過去のドル円の価格データをそのままモデルに流し込んで、最終的な出力として将来の価格予想を得ます。
今回もCPU環境での使用を想定していることもあり、中間層が3つだけ(全て全結合層)のシンプルなモデル(さっきの図では中間層は1つだけ描かれています)を作成します。

※なお全く機械学習に馴染みがなく、「全結合層ってなんぞ?」という方は下記書籍を参考にするとdeep learningの基礎が分かっていい感じになります。 今回予測するのは日足(1日ごと)のドル円の値です。
過去の1日毎の終値データ(を16個セットで)を深層学習モデルに流し込んで、その翌日の終値を予想させます。

学習時には、予測誤差が少なくなるようにどんどんモデルのパラメータを更新していきます(後述するコード中のmodel.fit()でやっています)。
前回は学習用のデータの取得を手動に頼っていましたが、今回はそこも Pythonプログラムでやってしまいます。

実装の前に必要なもの

コードを提示する前に、初めに必要なライブラリなどをインストールしておきましょう。

必要ライブラリ

今回使用するライブラリは全てpipでインストールすることができます。
楽チンですね。
まだ入っていないものがあれば、適宜インストールしてください。
pip3 install pandas
pip3 install pandas-datareader
pip3 install tensorflow
pip3 install matplotlib
ちなみにこちらは、為替の予想だけでなく自動売買まで動かしたい方向けのライブラリです。
OANDAのAPIを我々の Python プログラムから操作することが出来るラッパーだと解釈しています。
pip3 install oandapyV20
AI による為替予想だけを行えれば良くて、自動売買までは考えていないという方は最後のものはインストールしなくても OK です。

学習用の為替データセット

機械学習には、基本的に膨大なデータセットが必要になります。
仮想通貨編では、手動でデータをエクセルにコピペしてきましたが、その辺が原因でエラーが出てしまったという報告もありました。
なので今回はデータの取得もPythonでやってしまいましょう。
pandas-datareaderを使えば日足データならすぐに取得できるので、楽チンです。
(というか、日足データに対して動作するモデルを例として提示したのは、データ取得が簡単だったからという大人の事情があります笑)

AI作成Pythonコード公開

早速、コードを公開します。
get_data_and_train.py
predict.py
simple_model.py
という名前で下の三つのPythonファイルを同じディレクトリにコピペしてください。
from simple_model import build_simple_model
from tensorflow.keras.layers import Activation, Dense, Dropout
from tensorflow.keras.models import Sequential
from tensorflow.keras.optimizers import Adam
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import pandas_datareader.data as DataReader

start_day = "2016-10-1"

#start_dayから今日までのデータをダウンロードし、学習データとする。
df=DataReader.get_data_yahoo("JPY=X",start=start_day)

#ドル円データをcsvにして保存しておく
df.to_csv("USDJPY.csv")

#モデルの作成
forex_model = build_simple_model()

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

#modelをコンパイル(最小化しようとする損失関数--ここでは自乗誤差--などを指定)する
forex_model.compile(loss='mse', optimizer=Adam(lr=0.001), metrics=['mae'])

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

#後のコードが書きやすいように訓練データを加工
#よくわからない時はdfをprintで見てみると良い

#同じ行に過去16時点の価格(予想に使う説明変数)と今の価格(目的変数)が並ぶようにする
for i in range(16):
    df["Close-"+str(i+1)]=df["Close"].shift(i+1)

df = df.dropna(how="any")

# print(df.head())
# print(df.tail())
# print(df.columns)

#dfをnumpy配列に変換
#訓練データ(train_x)は 過去16時点までの価格*行数 となっている
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=400, validation_split=0.2)

#学習結果をファイルに保存
#成功するとディレクトリ内にparam.hdf5というファイルが生成される
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])
plt.savefig("train.png")
import pandas as pd
from simple_model import build_simple_model
import numpy as np

#モデルの読み込み
model = build_simple_model()

#学習した重みを読み込み
#先にget_data_and_train.pyを実行していないと、param.hdf5が存在しないのでエラーになる
model.load_weights('param.hdf5')

#学習したデータを使って今日の終値予測

#予測に使うデータを準備
df = pd.read_csv("USDJPY.csv")

#入力データ
input_data = np.array([[df["Close"].iloc[-(i+1)] for i in range(16)]])

#推論値
prediction = model.predict(input_data).flatten()
print("AIが予測する次のUSDJPYの終値は以下です。")
print(prediction)
from tensorflow.keras.layers import Activation, Dense
from tensorflow.keras.models import Sequential

def build_simple_model():

    simple_model=Sequential()
    simple_model.add(Dense(8,activation="relu",input_shape=(16,)))
    simple_model.add(Dense(8,activation="relu"))
    simple_model.add(Dense(8,activation="relu"))
    #modelの構造をいじり、実験するのも良い。
    # model.add(Dense(16,activation="relu"))
    simple_model.add(Dense(1))

    return simple_model

データの取得と学習

データの取得とモデルの学習は、get_data_and_train.pyを実行すれば完了します。
python3 get_data_and_train.py
これを実行すると、 次のような処理が実行されます。
データ取得と学習の流れ
①Yahoo ファイナンスから為替のデータを取得
②取得したデータをcsvファイルに保存(予測時に再利用)
③データをモデルに流し込むために整形
④学習
今回使っているkerasというフレームワークが親切設計であるために、コレだけの処理がごく簡単なコードでできてしまいます。
(損失関数などの設定は適宜コードの中のパラメーターを見てください。)

学習が完了すると、学習結果の重みファイルである”param.hdf5”が同じディレクトリ内に吐き出されます。
予測時はこれを読み込んで将来の為替相場(ドル円の値)を予測していくわけですね。

なお、どのように学習が進んだのかを示す “train.png”という画像データも同時に生成されているはずです。
この画像の中の二本の曲線(訓練データとバリデーションデータを示す)が二本とも右肩下がりになっていれば安心です(正確には右肩下がりになっていなければ何かが間違っていると疑った方が良いでしょう)。
ちなみに僕がやってみたところ、下のようになっていました。
最後の方はちゃんと学習が進んでいるのか、若干微妙ですね。
まあ細かい検証はまたの機会に譲って、とりあえず先に進みましょう。

将来のドル円の予想

次に先ほど学習したモデルを使って、将来のドル円の値を予想してみましょう。
「将来の」と言いましたが正確に言うと日足の次の終値(今日もしくは次の営業日)です。
やり方は簡単で、predict.pyを実行するだけです。
python3 predict.py
学習用のコードを実行した時に保存された為替データと重みファイルを使って予想します。
僕が実行した時は直近のドル円の終値が108.5円程度の状況下で107.8円といった予想を出してきました。
AIは円高を予想していますが、果たしてどうなる事やらですね。
これを書いてる時は、アメリカの長期金利の上昇が懸念されており一時はドル円が109円にも届いていました。
ここから107円台突入というのは、そこそこ大胆な予想だなという感想です。

深層学習モデルのカスタマイズ方法

さて今までは、僕が取り敢えず作っておいた簡易モデルを動かしているに過ぎませんでした。
モデルを独自にカスタマイズしたいと感じた方もいるでしょう。
そういった方はsimple_model.pyをいじれば OK です。

(当然のことながらモデルを変えるごとに、新たに学習し直す必要があります。)
なお今回のコードには著作権もクソもありません。
なので、良いAIが出来れば各自のブログなどで自由に公開してもらっても結構です(この記事にリンクさえ貼ってもらえれば)。
何かあった時の責任は負えませんが商用利用も自由です。

ついでに自動売買AIボットも動かしてみる

以上が為替価格の予想を行う深層学習AIの作成でした。
ここからは、これを基に FX 取引所で自動売買を行う方法もちょろっと解説していきます。

まずPythonコードをターミナルで動かして自動売買を行うにはOANDA japanのアカウントが必要です。
まずは下のリンクから Oandaの口座開設を行ってください。
(2021年現在、デモ口座のみの利用ではAPIの利用が不可になっているので、本番口座開設の必要があります。)

>>無料でOANDAの口座を開設する
DMM FXで既に口座を持っているから、DMMでやる方法を知りたい
等の感想を持った方もいるでしょう。
しかし残念ながら、OANDA以外の日本人向けの取引所ではREST APIが公開されていないため、あまり現実的ではありません。
詳しくはこちらの記事を参照してください。

Pythonで自動FX取引をするのが難しい理由

なお、ここまでで作成したコードの流用は難しくなりますが
・Python にこだわらない
・他人が作ったプログラムを使えればそれで良い
といった方はMT5(もしくはMT4)の利用でもFX自動売買自体は可能です。
詳しくは以下の記事を参照してください。

MT5を使ってFX自動取引を行う方法

取引所APIキー発行

さて口座開設が済んだら、次は API キーを発行しましょう。
注意点としては、以下の2条件に該当しない場合はAPI利用ができません。(2021年3月18日現在)

プロコース選択
・ゴールド会員(前月の取引額が50万USD相当以上)
・口座残高25万円以上

プロコースへの変更は、マイページにログインし、画面中央下の「取引コースの変更」から可能です。
※プロコースは最大発注量が大きい代わりにスプレッドも少し大きいというコースです(月額料金などはありません)。
準備が整ったらマイページの中央下の「APIアクセスの管理」からAPIキーを発行しておきます。

ディープラーニングAI+自動売買のコード

さて、では先ほど学習したAIを使用して取引まで行なってしまうサンプルコードを紹介します。
と言ってもやることは簡単で、予測値が現在価格よりも上であればドル円をロングし、下であればショートするだけです。
ポジションを閉じるときも自動では行わず、手動でやる必要があります。
あまり複雑な動きはせずに、最低限の部分だけ参考としてお見せできればといった感じですね。
import pandas as pd
from simple_model import build_simple_model
import numpy as np
from oandapyV20 import API
import oandapyV20.endpoints.instruments as instruments
import oandapyV20.endpoints.accounts as accounts #アカウント情報取得
import requests
from oandapyV20.endpoints.orders import OrderCreate
import json

#モデルの読み込み
model = build_simple_model()

#学習した重みを読み込み
#先にget_data_and_train.pyを実行していないと、param.hdf5が存在しないのでエラーになる
model.load_weights('param.hdf5')

#学習したデータを使って今日の終値予測

#予測に使うデータを準備
df = pd.read_csv("USDJPY.csv")

#入力データ
input_data = np.array([[df["Close"].iloc[-(i+1)] for i in range(16)]])

#推論値
prediction = model.predict(input_data).flatten()
print("AIが予測する次のUSDJPYの終値(日足)は以下です。")
print(prediction)

print("ここからFX自動売買取引所用の処理に入ります")

accountID = input("口座IDを入力してください")
access_token = input("アクセストークンを入力してください")

oanda = API(access_token=access_token, environment="live")
print(oanda)

#5秒足の終値を現在価格として使用する
params = {
    "count":1,
    "granularity":"S5"
}
#過去為替データを取得
r = instruments.InstrumentsCandles(instrument="USD_JPY", params=params)

#現在価格
price_now = float(r.response['candles'][1]['mid']["c"])

#円高に振れると予想されているならドル円ショート
# 注文方法:成行
# 取引通貨:USD/JPY
# 売買:売
# 数量:10000

if price_now > prediction:
    data = {
    "order": {
    "instrument": "USD_JPY",
    "units": -10000,
    "type": "MARKET",
    "positionFill": "DEFAULT"
    }
    }
    ep = OrderCreate(accountID=accountID, data=data)
    rsp = oanda.request(ep)
    print(json.dumps(rsp, indent=2))

#円安読みの時はドル円ロング
# 注文方法:成行
# 取引通貨:USD/JPY
# 売買:買
# 数量:10000

elif price_now < prediction:
    data = {
        "order": {
            "instrument": "USD_JPY",
            "units": 10000,
            "type": "MARKET",
            "positionFill": "DEFAULT"
        }
    }

    ep = OrderCreate(accountID=accountID, data=data)
    rsp = oanda.request(ep)
    print(json.dumps(rsp, indent=2))

このコードを先ほどから使っているディレクトリ上で trade.pyという名前のファイルにコピーして実行してください(本番環境で注文がでるので注意)。
 python3 trade.py
今回は単発の注文を出すことでしたが、if文やfor文、while文とうまいこと組み合わせることで、ずっと相場を監視して取引を行なってくれる bot を作成することができます。
もしカスタマイズした為替botで利益を上げることができたら、こっそり教えてくださいね笑

>>無料でOANDAの口座を開設する

【初心者向け】FX・仮想通貨の自動売買用のVPSサーバーのオススメはコレ!

2021年3月20日
スポンサーリンク

SNSシェアお願いします!

3 件のコメント

  • 機械学習初心者にはすごく為になる記事でした。
    1点気になったので質問させてください。
    get_data_and_train.pyを実行し、その後predict.pyを実行したら結果、115.068886と出ました。再度predict.pyを実行しても結果は同じでした。ですが、get_data_and_train.pyを再実行し、predict.pyを実行したら114.80327となりました。入力元のcsvも同じでパラメータも一切触っていないにも関わらず学習結果が変わってしまってるのですが、機械学習ってこういうものなのでしょうか?

    • 一部の工程(学習開始時のパラメーター初期化など)で乱数が使用されるので毎回結果が変わるのはありえることです。

      • なるほど、見えない所で乱数が使われてるのですね。理解できました。
        ありがとうございました。

  • コメントを残す

    メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

    CAPTCHA