今回はディープラーニングを使った人工知能でビットコインの自動売買を行う方法を解説します。
最終的に実際に購入を自動で行えるコードまで公開します。
この記事に書いてあること
・ディープラーニング(深層学習)の仕組み ・AIを学習させる為のPythonコード
・AIの予測した価格が現状の価格よりも高ければ、自動で買い注文を入れるコード
コードの仕様
・日足データを基に学習、予測を行う・過去16時点のビットコイン価格を入力すると、次の1時点のビットコイン予想価格を出力する
・ビットコイン予想価格が現在の価格よりも高ければ買い注文を行う
目次
深層学習(ディープラーニング)とは
まずは今回使用するディープラーニングモデルについて簡単におさらいしておきます。基本事項のみをさらっと復習していく感じなので機械学習やニューラルネットワークに詳しい人は読み飛ばしてもらってOKです。
今回使うのは全結合層のみのモデル
はじめに概要を説明しておきます。今回使用するモデルは、以下のような構造になっています。
これは数あるディープラーニングモデルの中でも全結合層のみを使ったモデルになります。
人間のニューロンの構造をシンプルにパクったモデルですね。
(図ではニューロン同士の結合をかなり省略していますが、実際には前後の層でニューロンがフルに結合しています)
このモデルの動きは大体こんな感じです。
①まず、はじめの入力層に過去のビットコインの価格データ(P_t-4など)を放り込みます。
(図では4つしか書かれていませんが、実際には今回使用することで16個の価格データを入力します)
②次に、それぞれの入力データを中間層に流していきます。
例えば今、中間層の一番上のユニット(ニューロン)には例として22400と表記してありますね。
これは例えば
o.8×P_t-4 + 1.3×P_t-3 + (-0.9)×P_t-2 + 0.1×P_t-1 = 22400
となっているということです。このように、ディープラーニングモデルでは前の層の値にそれぞれ重みをかけて次の層へと次々とデータを流していきます。
こうして層をどんどん経る内に、データの本質的な特徴が抽出できるというわけですね。
そして最終的な出力層にたどり着いた値を、ビットコインの予想価格だと判断します。
当然この予想価格は、現実のものとはズレがあります。
そもそもP_t-4に掛けた0.8などの値(=重み)には何の根拠もありませんでしたからね。
そこで膨大な学習用のデータを使って、より最終的な出力が正解に近づくように重みを最適化していくという仕組みです。
例えば
P_t-4 = 1000000
P_t-3 = 1200000
P_t-2 = 1100000
P_t-1 = 1000000
であったとします。
さらに、次の価格の正解が
P_t = 1200000
であったとしましょう。
これにも関わらず、
P_t = 1100000
などと予測してしまっていたら、P_tの予測がもっと大きくなるように重みを少し変更するというわけですね。
特にDeep Learningでは、誤差逆伝播法という方法で重みをどんどん更新していきます。
これを学習用のデータを使いまくって何度も何度も行なっていきます。P_t-4 = 1000000
P_t-3 = 1200000
P_t-2 = 1100000
P_t-1 = 1000000
であったとします。
さらに、次の価格の正解が
P_t = 1200000
であったとしましょう。
これにも関わらず、
P_t = 1100000
などと予測してしまっていたら、P_tの予測がもっと大きくなるように重みを少し変更するというわけですね。
特にDeep Learningでは、誤差逆伝播法という方法で重みをどんどん更新していきます。
この最適化していくステップのことをよく、AIに学習させるなんて呼んだりします。 こう書くと、
ディープラーニングってそんなものか
実際に深層学習とはいっても特別なことをするわけではありません。
その本質は大量のデータを使って大量のパラメーターをゴリ押しで最適化していく作業に他なりません。
実際の画像認識コンペに使われるような本格的なモデルだと何十層もの中間層を持ち、存在するパラメーターは億を超えることもあります。
今回の記事で使用するモデルでは中間層はひとつしかないので、普通の家庭用のパソコンでも十分を扱うことができます。
ただし、モデルをどんどん大きくして性能を追求していくとGPUを使用しないと、計算時間的にどんどんきつくなっていきます。
※GPUとは簡単に言うと CPU のパワーが増強されたバージョンです(下の Amazon リンクなど参照)。
また使用時間制限などがあって多少不便ですが、Google Colaboratoryを使うのも手です。
これはGoogle のGPUをクラウドで無料で使えるサービスです。
なお、今回のビットコイン価格の変化のような時系列データを扱うのに適したモデルは色々と開発されています。
興味がある人は
・RNN
・LSTM
等のモデルも学んでみると良いでしょう。
(参考リンク:RNNとLSTMを解説)
※話がややこしくなりすぎるのでこの辺のモデルは今回は触れません。
今回扱っている全結合層のモデルは、非常に分かりやすく入門に最適です。
その内容は、名著『ゼロから作る Deep Learning』(下記)を読めば完全理解できます。 Pythonの文法(「if文とは」など)から解説してくれているので初心者に非常にお勧めの本です。
なお上のモデルの図を見て、実装が大変そうだなと感じた人もいるかもしれません。興味がある人は
・RNN
・LSTM
等のモデルも学んでみると良いでしょう。
(参考リンク:RNNとLSTMを解説)
※話がややこしくなりすぎるのでこの辺のモデルは今回は触れません。
今回扱っている全結合層のモデルは、非常に分かりやすく入門に最適です。
その内容は、名著『ゼロから作る Deep Learning』(下記)を読めば完全理解できます。 Pythonの文法(「if文とは」など)から解説してくれているので初心者に非常にお勧めの本です。
しかし Python ではこの手のディープラーニングモデルを超楽に実装するためのフレームワークが準備されています。
なので、驚くほど少ないコードで実装が可能です。
しかも、今回は初心者でも使いやすいKerasを使用します。
安心してください。
上の図では省略しましたが、今回のモデルにおいて活性化関数という関数やランダムノイズも重要な役割を果たしています。
興味がある人は上で紹介した書籍を参考にしてみてください。
興味がある人は上で紹介した書籍を参考にしてみてください。
【準備】必要なPythonライブラリのインストール等
実際のコードを動かす前にまず必要な準備をしておきましょう。準備が正常に完了すると、下の四つのファイルが同じディレクトリ内に存在している状態になります。
準備完了した状態
・model.py(後述のコードをコピペしたもの)・train.py(後述のコードをコピペしたもの)
・auto-trade.py(後述のコードをコピペしたもの)
・price-data.csv(作成方法は後述)
学習用データを用意
まずは学習用のデータを用意します。どこから取ってきてもいいのですが、僕はInvesting.com(下記URL)からデータを入手しました。
https://jp.investing.com/crypto/bitcoin/btc-jpy-historical-data
本格運用時はもっと膨大なデータが必要になるわけですが、とりあえず約半年分の価格データを入手しました。
「データをダウンロードする」というボタンから、ダウンロードすることもできるっぽいですが会員登録するのがめんどくさかったので、
データをブラウザ上でコピーして CSV ファイルに貼り付けることにしました(下記画像参照)。
データを手動で選択して右クリックコピーするだけです。
後は適当にスプレッドシートなりエクセルなりにペーストして、csvファイルとして保存します。
名前はprice-data.csvとしておいてください。
最終的に 下画像のような CSV ファイルができていれば OK です。
後でコードを動かす分には、「終値」というカラムにビットコイン価格が並んでいれば OK です。
なお、1日単位ではなく1時間単位1分単位で学習予測を行う AI を改めて作りたいときは、「終値」の列にそれぞれの時間足のデータが並ぶようにすればOKです。
※画像の通り日付に関して降順になっていますが、これはコード内で処理する時に逆に並べ替えています。
※自動売買自体はコインチェックを使うのですが、このサイトにコインチェックのデータが無かったので、やむなくbitflyerを選択しました。
※自動売買自体はコインチェックを使うのですが、このサイトにコインチェックのデータが無かったので、やむなくbitflyerを選択しました。
tensorflowを導入
次に必要なライブラリをインストールします。今回は、扱いやすい機械学習フレームワークであるKerasを使います。
pipでインストールできるので非常に簡単です。
pip3 install tensorflow
Kerasを使うのに何故tensorflowをインストールするの?と思った方もいるでしょう。
以前はKerasとtensorflowは別々のフレームワークという色合いが強かったのですが、最近ではkerasはほとんどtensorflowに吸収されたような形になっています。
その他、matplotlibなどのライブラリもまだ入っていなければインストールして行きます。以前はKerasとtensorflowは別々のフレームワークという色合いが強かったのですが、最近ではkerasはほとんどtensorflowに吸収されたような形になっています。
pip3 install matplotlib
これらは次の「口座開設と API キー発行」セクションで紹介する記事の中でも紹介しているので、まだ入っていない人はこちらの記事を参考にしてインストールしてください。
どのライブラリも簡単にインストールできるので安心してください。
口座開設とAPIキー発行
今回は、AIでの価格予測後の売買注文をコインチェック口座で行います。コインチェックの口座開設と API キーの発行がまだの人はこれも行う必要があります。
コインチェックの口座開設は下のリンクから行うと簡単です。
無料でコインチェックに口座を開設する
APIキーの発行手順は、下の記事で説明している部分と全く同じです。
(そもそもAPIキーって何やねん?という話もごく簡単に触れています)
画像付きで解説しているので、是非参考にしてみてください。
コード本体と実行方法
さて、次にコードの本体を公開します。 それぞれのコードをコピペして、・model.py
・train.py
・auto-trade.py
という名前で保存してください。・train.py
・auto-trade.py
from tensorflow.keras.layers import Activation, Dense
from tensorflow.keras.models import Sequential
def create_model():
model=Sequential()
model.add(Dense(16,activation="relu",input_shape=(16,)))
model.add(Dense(16,activation="relu"))
#色々modelの構造をいじってみて実験すると良い。下のコメントを外すだけでもまた形状が変化する。
# model.add(Dense(64,activation="relu"))
model.add(Dense(1))
return model
from model import create_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
#モデルの作成
model = create_model()
#Deep Learning モデルの形状を表示
#print(model.summary())
#modelをコンパイル(最小化しようとする損失関数--ここでは自乗誤差--などを指定)する
model.compile(loss='mse', optimizer=Adam(lr=0.001), metrics=['mae'])
#学習用データ
df = pd.read_csv("price-data.csv")
#後のコードが書きやすいように訓練データを加工
#よくわからない時はdfをprintで見てみると良い
#まず現状だと日付の降順にデータが並んでいるので、逆にする
df = df.sort_index(axis='index',ascending=False)
#同じ行に過去16時点の価格(予想に使う説明変数)と今の価格(目的変数)が並ぶようにする
for i in range(16):
df["終値-"+str(i+1)]=df["終値"].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[["終値-"+str(i+1) for i in range(16)]].values
train_y=df["終値"].values
# print(train_x.shape)
# print(train_y.shape)
# print(train_x)
# print(train_y)
#注意)今回はコードの簡単さを重視して正規化などは無し
#リターンの時系列などにする、といった工夫もなし
# 学習の実行
history = model.fit(train_x, train_y, epochs=400, validation_split=0.2)
#学習結果をファイルに保存
#成功するとディレクトリ内にparam.hdf5というファイルが生成される
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,1000000])
plt.savefig("train-result.png")
from model import create_model
import pandas as pd
import numpy as np
from coincheck import market,order,account
#モデルの読み込み
model = create_model()
#学習した重みを読み込み
#先にtrain.pyを実行していないと、param.hdf5が存在しないのでエラーになる
model.load_weights('param.hdf5')
#学習したデータを使って今日の終値予測
#予測に使うデータを準備
df = pd.read_csv("price-data.csv")
#現状だと日付の降順にデータが並んでいるので、逆にする
df = df.sort_index(axis='index',ascending=False)
#入力データ
input_data = np.array([[df["終値"].iloc[-(i+1)] for i in range(16)]])
#推論値
prediction = model.predict(input_data).flatten()
print("AIが予測するBTC価格は以下です。")
print(prediction)
#直近のBTC価格をコインチェックから取得
m1=market.Market()
price_now = m1.ticker()["last"]
print("コインチェックでのBTC取引価格は以下です。")
print(price_now)
if prediction>price_now:
print("予測値が現在価格より高いので、買い注文を出します。")
#注文を出すには認証が必要
access_key=input("APIのアクセスキーを入力してください")
secret_key=input("APIのシークレットキーを入力してください")
print("買い注文を実行します。")
o1 = order.Order(secret_key=secret_key,access_key=access_key)
print(o1.buy_btc_jpy(rate=str(price_now),amount=0.005))
else:
print("買いチャンスとは判断出来なかったので、何もしません。")
後はコードを実行するだけで、学習から予測まで行うことができます。
学習を行う
まずは用意しておいた学習データを使って AI を学習させてみましょう。python3 train.py
①はじめにmodel.pyから僕が作っておいたモデルを読み込みます。
②その後学習データを入力しやすいように整形しています。
学習自体は
history = model.fit(train_x, train_y, epochs=400, validation_split=0.2)
これは、学習途中の予測結果と実際の価格データのズレを評価する値(損失関数と呼ばれる)などをその都度表示しているものです。
パソコンのスペックにもよりますが、今回は小規模なので学習はだいたい1分くらいで完了するはずです。
(本格的なデータセットとモデルを使った学習だとGPUを使って何週間もかかることもあります)
学習が終了すると param.hdf5 というファイルが同じディレクトリ内に保存されているはずです。
これが最適化された後の重みの情報を格納したファイルです。
(予測時にはこれを読み込んで使います)
また損失関数などの推移がどうなっていたかを記録したtrain-result.pngという画像ファイルも生成されていることでしょう(下画像参照)。
AIの予測に基づいてビットコインを自動で注文
次に、学習させた AI にビットコインの価格予想をさせてみましょう。やり方は簡単です。 auto-trade.pyを実行してください。
python3 auto-trade.py
①このコードはまず、先ほど準備したprice-data.csvから最新の価格データ16個を学習済みのAIに流し込みます。
成功すると、こんな感じの出力がされると思います。 ②そして吐き出された価格予想と、コインチェックの API を通じて取得した最新のビットコイン価格を比較します。
③もし予想価格の方が最新のビットコイン価格よりも高ければ、そのままビットコインの購入注文をコインチェックに発注する
という仕組みです。
(購入注文を行う場合はAPIキーの入力を求められます。端末上で入力してください。)
僕が実行した時点でBTC価格は597万円くらいでしたが、今回作ったAIはすぐに600万円に達するという予想を出してきました。
オリジナルモデルのカスタマイズ方法
自分でオリジナルのモデルを色々試してみたい時は、model.pyをいじります。例えばコメントアウトしてある部分を復活させるだけで、 中間層が1層から2層になります。
ディープラーニングの名前にふさわしいように、層を深くしてみるのも面白いかもしれません。
(ただしあまりパラメーターが増えすぎると普通の PC では計算量的に扱えなるので注意)
めちゃめちゃいいAIができた人は、こっそり教えてくださいね笑
こんにちは。
タケダです。
毎度記事を参考にさせて頂いています。
ありがとうございます。
今回の記事にあまり関係ないのですが、移動平均線の値やボリジャーバンドなど毎回計算していると大変でかつ取得期間を更新していかなければならず、効率が悪いと感じています。他のサイトからこれら値を引っ張ってくることできないのでしょうか?
ご確認お願いします。
お初にお目にかかります。
素敵な記事ありがとうございます。
当方、アナコンダのスパイダーでこちらのコードを実装したところ
学習の実行の段階でUnimplementedError: Cast string to float is not supportedと表示され
param.hdf5が出力されません。
解決策をご教示いただけたら幸いです。
何行目でエラーが出ているのか分かりませんが、
おそらくエクセル等に貼り付けた価格データが、数値(float)ではなく文字(string)として認識されているのではないかと思います。
df = pd.read_csv(“price-data.csv”)
の直後に下の一行を追加してみてください。
df[“終値”] = df[‘終値’].astype(float)
言葉が足らず申し訳ありません。エラーが発生している行は50行目
history = model.fit(train_x, train_y, epochs=400, validation_split=0.2)
です。エラーの内容は『tensorflow.python.framework.errors_impl.UnimplementedError: Cast string to float is not supported』です。
ご教示いただいたdf[“終値”] = df[‘終値’].astype(float)を追加したところ
先程と同じエラーと追加部分にて『SyntaxError: invalid character in identifier』になります。
何度もすみません。
すみません!なぜかクオーテーションマークが変な文字になっていました、、
df[“終値”] = df[“終値”].astype(float)
でやり直してみてください。
(「””」をこのコメント欄に入力すると、正常に反映されないのかもしれません、、)
通常のPythonの文字列用のクオーテーションマーク(””もしくは”)で「終値」を囲えば問題ないはず…!
解決しました!
過去データをエクセルにコピペしたときに、すべての数値にカンマが含まれていて、それが原因でした。
(エクセルの設定上、通貨と認識された場合はカンマが自動的に挿入される仕様になっているようです)
データを整形してカンマを除くと、元のプログラムのままで実行できました。
お手数をおかけしました。ありがとうございます。
お初にお目にかかります。
このような素晴らしい記事を書いていただきありがとうございます。
いくつか疑問点があるので質問させてください。
まず、買うときの指標として終値を学習させて予測値を出して予測値を元に買うかどうかを判定しておりますが
終値を使用している理由は何かありますか。
安値の値を学習させて現在の価格が安値の予測値より安かったら買うとかはどうでしょうか。あまり安値を指標として使うのはよくなかったりしますか。
また、売る際の指標は何が良いでしょうか。
自分が思いつくのは
1.現在の価格が終値の予測値を超えたら買う。
2.高値を学習させて現在の価格が高値の予測値を超えたら買う
ですがどうでしょうか。
ご考えをお聞かせいただければ幸いです。
コメント有難うございます。
>終値を使用している理由は何かありますか。
「金融データ分析で伝統的に終値が重視されるから」以外の理由はありません。
半ばフィーリングです。記事の目的は実装のサンプルを示すことなのでご容赦を笑
>あまり安値を指標として使うのはよくなかったりしますか。
そんなことはありません。実際に実装してみて、パフォーマンスが良ければそれが良いモデルです。
売る時の指標についてです。
1.2.共に「予測値を超えたら売る」ということでしょうか。
これも同様に、「実際に実装してみてパフォーマンスが良いものが良い」という結論になります。
この手のテクニカル系の分析には「これこれこうやったら駄目!」みたいなセオリー自体あんまないんですよね。
稼いげる物が正義だと思ってます笑
ご返信いただきありがとうございます。
私自身仮想通貨や金融データ等に詳しくなく
色々質問させていただきました。
記事を参考にして実際に試してみたいと思います。
ありがとうございました。
初めまして。
とてもいい記事でした。
質問なのですが、こちらのコードをbitflyerで実行するにはどこをいじればいいのでしょうか。
コメントありがとうございます。
auto-trade.pyの
冒頭のimport部分と
#直近のBTC価格をコインチェックから取得
のコメント以下を全体的にいじる必要があります。
これとは別のプログラムですがbitFlyerを使ったbotをいくつかこのブログで公開しています。
ブログ内検索で出てくるはずなので、よかったらそちらも参考にしてみてください。
はじめまして。月と申します。
最近pythonの勉強を始めたばかりの初心者です。
上記の記事のコードを使用させていただき、学習を行わせることはできました。
なのですがいざ、python3 auto-trade.pyを実行したら下記のようなエラーが発生してしまいました。
C:\Users\*****\OneDrive\デスクトップ\PythonBitcoin>python3 auto-trade.py
2021-10-24 04:22:58.819392: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library ‘cudart64_110.dll’; dlerror: cudart64_110.dll not found
2021-10-24 04:22:58.819602: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.
Traceback (most recent call last):
File “auto-trade.py”, line 11, in
from coincheck import market,order,account
ModuleNotFoundError: No module named ‘coincheck’
原因わかりますでしょうか。無知ですみません。。
コードを実行する前にコマンドプロンプトで
pip3 install coincheck
としてみてください。
できました!
教えていただきありがとうございました!