昨年の今頃から一年間ぐらいBTCの値動きを機械学習で予測し一定の利益を上げることを目的として実験を繰り返してきたが、今回一定の安定した成果を上げられたのでその記録をここに残しておこうと思います。
STEP1.データの準備
PythonライブラリのyfinanceからBTCJPYの過去60日間5分足のデータを取得し、OHLCのデータのみに変換する。その後、特徴量をさらに6つ用意し、N*10サイズのデータを作る。
STEP2.ラベルの設計
予測の対象となるラベルを作成する。Cnを終値のデータ列、Rnをn番目のラベルだとすると、Rnは次のように定義される。
この変数は見ての通り前後20個の終値のデータの和の対数変化率に等しい。小口の個人投資家にとって最も大切となるのはトレンドを適切に読みそれに乗っかることであるが、この指標はまさにトレンドを定量化したものと言える。例えばRnがプラスということは、現時点から見て後ろの価格よりもこの先高くなる、ということになるのでロングと判断できる。(マイナスも然り)
気を付けて欲しいのは、このデータは「未来の」データを用いているため、少し前のトレンドについては確定的な情報を与えてくれるが、現在のことについては何も分からない。例えばずっと上昇している株があって、現時点がトレンドの転換点なのかまだ5合目なのか判断がつかないのと同じことである。そこで現在までのデータのみを用いてこのRnを予測すること、がテーマとなる。なお前後20個の比としているのは、これが長すぎるとほとんど1に収束してしまうし、短すぎるとノイズをキャンセルするという本来の目的が損なわれるので、なんとなく程よいと思われるところにしただけなのでもっといい期間があるかもしれない。
金融データの分析でいつも大きな問題となってくるのはS/N比が著しく低いこと、すなわち有効な情報に対してノイズが多すぎることなのですが、そこをうまく解決できているいい変数の取り方だと思います。なおこの変数の取り方はこちらの論文を参考にしました→Zihao Z., Stefan Z., & Stephen R.(2020) DeepLOB: Deep Convolutional Neural Networks for Limit Order Books ( https://arxiv.org/pdf/1808.03668.pdf )
(これは余談ですが、ネット上には機械学習で株価を予測してみた!みたいな記事が(I〇mediaなどに)結構あるのですが、実際にはどれも二点間の傾きなどの効果の薄いラベルを用いているようなものが多く、恐らく書いてある通りにやっても意味のある結果を全く出せないものばかりだったりします)
STEP3.モデルの設計
いつもの通り、LSTMモデルを用いた。以下のような感じになる。
STEP4.学習・予測
データを手動でtrainデータとtestデータに分けた。train_test_splitを使わなかったのは、古いデータで学習させてから新しいデータでテストしたかったこと、データの前後の繋がりを無視できなかったことが理由である。EarlyStoppingを用いた結果220epochs学習し、以下のようにlossが順調に減少した。
結果と収益
横軸を予測結果、縦軸を正解としてヒートマップを作成すると以下の表のようになる。0は上昇、1は中立、2は下落をそれぞれ意味する。全体として予測精度は約84%となった。また、実際にはプラスだったのをマイナス、マイナスだったのをプラスと予測したのは3544件のうち4件だけだった。
その一方、機械が無難にNeutralの予測を出しておけばいいだろ、と学習してしまったのか、0(上昇)と下落(2)の偽陰性がとても多い。ここを修正できればもっと収益を上げられるようになるので改良が必要かもしれない(個人的には、去年ぐらいに拾えるだけシグナルを拾うシステムでトレードしたら大損した経験があるので、これぐらいで安牌だと思っている)
テストデータについて収益の推移は以下のグラフのようになった。収益はプラスと予測したら現物のロング、マイナスでレバ1倍のショート、ニュートラルになったら手じまいするというルールで計算した。3544個分のデータ(即ち3544*5分=295時間、約12日)で42%の利益が出ているので結構うまく行ったと思う。なによりほとんど後退していないのがこの手法の一番推せるところかなと思います。(前の記事に書いたような手法ではかなり収益の増減が(主に下側に)ぶれた)
テストデータでうまく行ったものの、実証実験ではズタボロになり絵に描いた餅、、、という様な事をこの一年何回もやってきたので、今回も新しいデータについて2週間から一か月ほど実験し、うまくいくかどうかを検証する期間を設ける。今回は割と自信があるのでうまく行くといいなあ