ビットコイン自動売買botのバックテスト実装(移動平均線の交差を用いたアルゴリズムトレード)


こんにちは!スナフキンです.

ずっとやりたかったことの1つに,ビットコインの自動売買botのバックテスト実装があります.バックテストというのは,過去の価格データを使って自分の売買ロジックの検証を行うことです.

相場は価格以外にも,板の厚さやイナゴの状況によって,注文の執行コストなどが異なるため,バックテストで確認できたパフォーマンス通りの結果が出ることはないのですが,最低でも理想的な環境(注文が必ず一定の価格で約定する,など)でのバックテストでプラスの損益を出すBotでなければ,実際の相場で利益を出すのは難しいですし,利益が出たとしてもそれは単に「運がよかった」だけの可能性があります.

僕自身は,pythonを始めたばかりでこれまでバックテストの実装ができる技術がなかったこともあり,仕方なくbotをBitflyerの最小取引枚数である,0.001枚で実戦投入してその期待値を測っていました.(バックテストができるようになっても,少ない枚数で実践投入することは意味があります.上述の通り,バックテストと実際の相場での損益は異なるからです.)

ということで今日は,大学が春休みに入ったこともあり比較的時間もできたのでバックテストの実装を行ってみました.今回はとりあえず,非常によく知られている「移動平均線のゴールデンクロスとデッドクロス」によるトレードを,バックテストで検証してみようと思います.

図の緑の線(短期移動平均)が赤の線(中期移動平均)を追い越しているところがいわゆる「ゴールデンクロス」.買いシグナルと言われている.

僕自身バックテストについては知っていましたが,過去の価格データを使ってテストするというのは,一体どうやってやればよいのかまったく見当がつかず放置していましたので,同じように困っている方がいれば参考にしてみてください.

バックテストでやることを明確に理解する

まず大前提として,何らかの動作をプログラムに組み込むためには,その動作が何をしているのかを明確に理解する必要があります.何が言いたいかというと,「バックテスト」はどういう工程から成り立っているかを知る必要があるということです.ぼくたち人間は,「移動平均線が交差したらトレード」と言われればそれだけで何をやるか理解できますが,コンピュータの場合はもっと明確に何をするか指示する必要があります.

それを踏まえてバックテストで行う工程は,以下のように分けられます.

  1. 時系列データの一点一点における売り,買い,あるいは待機の判断.
  2. それらの判断を踏まえて売買を行った場合の損益計算.

まだやや抽象的なので,具体例を挙げてみます.以下は2/2の1分足データの一部で,実際にバックテストに使ったデータの一部です.OHLCデータはCryptowatchから毎時間自動収集するプログラムを作り取得しています.移動平均は終値から計算しました.(実際のプログラム内では,テクニカル指標計算ライブラリに計算させればよいです.)

この表内のデータでは,売買シグナルが出ていないため,バックテスト内で注文は行いません.しかし,表内の売買判断のところが「買い」あるいは「売り」になったときにはバックテスト内で注文を行います.では,バックテスト内で「注文を行う」とはどういうことかと言えば単純に,i番目のデータで買いの判断をしたときのビットコイン価格,買い枚数を$$Pb_i, Sb_i$$と売りの判断をした時のビットコイン価格,売り枚数を$$Ps_i, Ss_i$$として,すべてのデータにおける$${Pb_i}{Sb_i}-{Ps_i}{Ss_i}$$の合計を求れば良いです.

つまり,バックテストを回した全期間における売買損益は,次の式で表されます.

$$\sum ({Pb_i}{Sb_i}-{Ps_i}{Ss_i})$$

日時 始値 高値 安値 終値 出来高 短期移動平均 中期移動平均 売買判断
2018/2/2 23:27 927337 933006 925830 930000 343.5786 938819.7 976762.9 待機
2018/2/2 23:28 930625 931500 921800 923122 471.2546 935634.1 976810.8 待機
2018/2/2 23:29 923871 933108 923122 930000 397.0662 934863.7 977652.2 待機
2018/2/2 23:30 930000 933108 926000 930000 300.6519 932623.6 977930.8 待機
2018/2/2 23:31 930000 945965 928000 945965 311.734 934277.4 979755 待機
2018/2/2 23:32 937759 945965 935000 941002 362.9392 933467.2 980208.5 待機
2018/2/2 23:33 940369 941002 930000 934000 288.1619 932809 979439.2 待機
2018/2/2 23:34 934000 936500 926000 929500 194.7687 932108.9 978670 待機
2018/2/2 23:35 927888 933978 926500 932131 246.4504 932785.1 977699.3 待機
2018/2/2 23:36 932131 932632 922160 925009 269.5918 931573.8 976090.4 待機
2018/2/2 23:37 928997 930000 924978 929886 194.9879 932737.9 975102.5 待機
2018/2/2 23:38 928000 932470 925110 926498 202.2256 932048.9 974110.2 待機
2018/2/2 23:39 926498 926498 917000 923499 494.4462 931098.9 972706.3 待機
2018/2/2 23:40 927876 928099 918100 925000 300.0257 929152.5 971965.4 待機
2018/2/2 23:41 922872 925972 912300 916160 372.6278 925784.3 970286.1 待機
2018/2/2 23:42 916883 918026 912126 913002 416.8435 923368.7 968818.2 待機
2018/2/2 23:43 913776 913964 903288 906670 386.3896 920452.5 967242.7 待機
2018/2/2 23:44 906709 916800 905252 912450 251.4067 919062.4 965943.9 待機
2018/2/2 23:45 914443 917020 910000 917020 309.2952 918720.5 964924.3 待機

価格データの準備,ロジックの実装

さて,バックテストの概要はこのぐらいにして,実際にコードを書いていきます.テクニカル指標計算用のライブラリとして,ta-libを使います.

まずはcsvから1分足データをロードします.使うのは終値だけですが,一応OHLC全てロードしています.次に指数平滑移動平均(EMA)をta.EMAで計算し,それによって売り(-1),買い(1),待機(0)を判断する関数を実装します.ここではゴールデンクロスなら買い,デッドクロスなら売りとしています.

バックテストを実装する

バックテストを実装します.日本円初期保有量は,資産曲線を描くために設定しましたが,今回は使用しなくてもokです.今回は,0.1ビットコインを先ほど実装した関数の判断結果に従って売買したときの利益を,最終的なtotal – capitalによって計算しました.シグナルの出現回数が奇数回だった場合,ポジションが決済されずに残ってしまうので,最後の足の終値で決済することにしました.

バックテストの結果

2/3の1分足で,このシグナルに従ってトレードした場合は損益がマイナスになってしまいました.つまり,単純な移動平均線の交差を用いたトレードは必ずしもワークしないということです.もちろん,もっと長い期間で検証しなければ断定はできませんが.今後は,バックテストの過程を可視化して,ロジックの問題点を探れるようにしていきたいと思います.

シェアする

  • このエントリーをはてなブックマークに追加

フォローする