【Python】トレード戦略をバックテストして有効性を検証する

前回までのあらすじ

前回はビットコインの価格データをCoingeckoからAPIを使って取得しました。

今回はこの価格データからトレードシュミレーションを行い、戦略の有効性をバックテストを引き続きPythonを使って行っていきたいと思います。

トレード戦略・バックテストとは何か?

ライブラリの読み込み

まずはバックテストで使うライブラリをインポートします。

################ここから始める##############

#ライブラリの読み込み
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
import pandas as pd
import time
import datetime
import requests
import json

#ビットコインの価格データを取得する
def get_btcprice(ticker,max): 
    url=('https://api.coingecko.com/api/v3/coins/')+ticker+('/market_chart?vs_currency=jpy&days=')+max
    r=requests.get(url)
    r2 = json.loads(r.text) 
    return r2

#ビットコインの全期間の価格データを取得する
r2=get_btcprice('bitcoin','max')


#取得した価格データを整形する
#ライブラリの読み込み
from datetime import datetime
import pandas as pd

#jsonから価格データだけをPandasに変換して抽出する
def get_price(r2):
    s=pd.DataFrame(r2['prices'])
    s.columns=['date','price']
    date=[]
    for i in s['date']:
        tsdate=int(i/1000)
        loc =datetime.utcfromtimestamp(tsdate)
        date.append(loc)
    s.index=date
    del s['date']
    return s

btc=get_price(r2)
btc

<実行結果>

使用するのライブラリはPythonでデータ分析をする上でよく使うライブラリですし、前回の記事なので特に問題はないと思います。

データを可視化する

データが読み込めたら、まずは可視化してみましょう。

#データを可視化する
btc.plot()

すると↓のようなグラフが表示されます。

中々壮大なチャートになっています。。。

変化率から累積リターンを計算する

データの概要が掴めたところで次は変化率から累積リターンを計算します。基本的にトレードのリターンは変化率の合計で考えます。

変化率の計算は普通にfor文で計算することもできますが、Pythonであればpandasの関数pct_change()で一発で計算できます。

#変化率を計算する
change=btc['price'].pct_change()
change

<実行結果>

そして、この変化率から累積変化率を計算します。累積変化率の計算には対数化などが必要ですが、pandasのcumprod()で一発で計算できます。Python超便利ですね。

#変化率からトータルリターン(累積変化率)を計算する
trade_return=(change+1).cumprod()
trade_return[0]=1
trade_return=trade_return*10000
print(trade_return.head(),trade_return[-5:])

<実行結果>

この累積変化率が意味するものは、2013年4月28日から毎日ビットコインを1万円分購入して、次の日に売るということを繰り返していれば2019年6月23日には87万8,669円になっていたという計算になります。取らぬ狸の皮算用とはいえスゴイリターンですね。

ちなみにこのビットコインの価格データは毎日更新されていきますので、コードを実行する日によって累積リターンは変わります。

トレード戦略を考えバックテストで累積リターンを計算する

さてここからが本題なわけで次は適当なトレード戦略を考えて、その戦略に従って取引した場合の累積トレードリターンをPythonで計算してみます。

今回はとりあえず単純移動平均線を使ってみましょう。移動平均はtalibがなくてもPandasの関数.rolling().mean()で簡単に計算することができます。

#移動平均を計算する
EMA5=btc['price'].rolling(5).mean()
EMA25=btc['price'].rolling(25).mean()

このトレード戦略となる売買基準のことを一般的に『シグナル』といいます。トレード戦略のバックテストを行う際はまずこのシグナルの数値を計算し、そこからif文でシグナルに沿って『トレードシグナル』を計算します。

トレードシグナルとは、要は買いか、売りかのサインのことで、買いは1売りは-1とします。今回のシグナルは5日移動平均が25日移動平均より上ならば買い、下ならば売りとします。

この戦略によるトレードシグナルをPythonで計算する場合は↓のように記述します。

#トレード戦略から売買シグナルを計算する
signal=[]
for i in range(len(btc['price'])): 
    #5日平均が25日平均より上なら買い=1とする 
    if EMA5[i]>EMA25[i]: 
        signal.append(1) 
    #5日平均が25日平均より下なら売り=-1とする 
    elif EMA5[i]<EMA25[i]: 
        signal.append(-1) 
    else: signal.append(0) 
signal

実行すると0と1と-1が格納されたsignalリストが生成されます。これがトレードシグナルです。

バックテストでトレード戦略の累積リターンの計算する方法は、『価格の変化率×トレードシグナル』が一般的です。またn日のトレードシグナルからn+1日目に買いor売りを実行するので、シグナルと変化率はずらして計算する必要があります。そのまま計算すると、完璧な未来予知なのでトンデモリターンになります。

バックテストによる累積リターンの計算と計算結果の視覚化をPythonでは↓ように実装できます。

#プロット用ライブラリの読み込み
from pylab import rcParams
import matplotlib as mpl

#日本語フォントの読み込み
font = {"family":"Noto Sans CJK JP"}
mpl.rc('font', **font)


#キャンバスのサイズを大きくする
rcParams['figure.figsize'] = 10,5


#日次変化率×トレードシグナルの累積変化率で
#トレード戦略に従ってトレードした累積リターンを算出する
backtest_return=((change[1:-1]*signal[0:-2])+1).cumprod() 
x=btc.index[0:-2] 

#matplotlibでリターンの推移を可視化
plt.title('トレードリターンの比較') 
plt.plot(x,returns[0:-2],'b',label='ホールドした場合のリターン',alpha=0.3,linewidth=0.5) 
plt.plot(x,backtest_return,'orange',label='移動平均で取引した場合のリターン',alpha=1,linewidth=1.5) 
plt.grid(which='both') 
plt.legend()
plt.show()

<実行結果>

ちなみにMatplotlibに日本語入れたい場合は↓の記事を参照すれば簡単に日本語化が可能です。既にほかの方法で日本語化している人はフォントして云々くだりは無視して普通にプロットしてください。

【python】Matplotlibで日本語化して文字化けを無くす

<おまけ>

# 出力した画像を保存する 
plt.savefig('backtest_return.png')

バックテストを有効性検証する指標の計算

バックテストでトレード戦略の有効性を検証する際は、累積リターン以外にも色々あり、ここではそのいくつか紹介していきたいと思います。

・最大ドローダウン

累積リターンが最大の時点からどれくらい減少したか、トレード戦略の安定性を測るもの最大ドローダウンが低いほどリターンが安定しているということを意味する

・勝率

計算方法・勝ちトレード数÷全トレード数

・ペイオフレシオ

計算方法:勝ちトレードの平均利益額÷負けトレードの平均損失額

・プロフィットファクター

計算方法:純利益÷純損失

これらのトレード戦略指標をPythonで実装するコードはここで記述すると、記事が長くなってしまうので、別の記事に書いています。

終わり

以上が簡単なトレードシュミーションを行った場合の累積トレードリターンの計算方法と有効性の検証方法です。こういう計算が簡単にできるのがプログラミング言語の強みですね。特にこういったデータ分析系の処理ではPythonがホント便利です。

また移動平均以外のテクニカル指標を計算する関数はPandasにはないので、自分で計算する必要がありますが、Pythonには『talib』というライブラリがあり、それをインストールすれば、関数1つで簡単に計算することができます。talibのインストールと使い方については↓の記事で解説しています。

次は実際にビットコイン取引所のAPIを使って残高の確認や注文の発注を行っていきます。これらの知識を合わせるとビットコインの自動取引botを作ることができます。

Pythonで自動売買Botを作る①~システムトレードの流れを把握する

ビットコインの「ブロックチェーン技術」を超わかりやすく説明してみる

大学生に超オススメな格安プログラミングスクール「クリプテックアカデミア」の評判・レビュー

プログラミングの独学はとても難しい


プログラミングは小学校の義務教育にも導入され始めており、これから社会人として生きていく上でプログラミングはもはや出来て当たり前、出来なれば論外というエクセルレベルの必須スキルになりつつあります。そしてそういう話を聞いて参考書なりを購入して独学でプログラミング勉強しようと思っている人も少なくないでしょう。しかしプログラミングを独学で勉強し始めようと思うものの



・「分からない箇所で詰まって挫折してしまった」

・「勉強する時間が足りない」

・「ネットの記事だと情報が断片的でよくわからない」

・「コードのエラーの原因が分からない」



という壁にぶち当たって、プログラミングの勉強を止めてしまう方が少なくありません。独学でプログラミングを勉強してる時間のほとんどはつまづいている時間です。実際僕も最初のころ独学でプログラミングを勉強していた頃はエラーの原因が分からず丸1日を不意にしてしまった・・・そんな苦い経験がありました。



それで僕は一度はプログラミングの学習を諦めてしまいましたが、就活で現実を知る中で「プログラミングを勉強して、いずれフリーランスとして自由な生き方がしたい」「エンジニアとして若いうちから高収入を得たい」という気持ちから一念発起して「侍エンジニアのwebサービスコース」に申し込み、プロのエンジニアの方に対面でマンツーマンでPythonによるWebサービス作り方とWeb技術の基本を教えてもらい、ようやくプログラミングが理解でき、今ではエンジニアとしてそこそこの暮らしができるようになりました。





侍エンジニアでは、とりあえずプログラミングやインターネットの基本を知っておきたい人から、HTML・cssなどでWebサイトやWebアプリを作ってみたい人やPythonを勉強してデータサイエンティストやAIエンジニアになりたい人まで幅広いニーズに応えた様々なコースが用意されています。



IT業界と言ってもエンジニアの仕事はプログラミング言語次第でサーバーから機械学習・ディープラーニングまで多種多様ですし、侍エンジニアの無料レッスン(カウンセリング)を受けてみて、自分のやりたいITの仕事は何なのか?を見つけるのがエンジニアへの第一歩になります。ちなみに今侍エンジニアの無料レッスンを受けると1000円分のAmazonギフト券がもらえるので、試しに受けてみるだけもお得です。


自分は半端に独学やオンラインスクールで勉強して金と時間を無駄にするくらいなら、リアルのプログラミングスクールに通ってしっかりプログラミングを勉強した方がいいと思います。ちなみに今、侍エンジニアに申し込むと、25歳以下の学生の方であれば、受講料が20%OFFになるので超お得です。


そして、プログラミングは大勢で授業を受けたり漫然とオンライン学習をするよりも自分が分からない箇所をピンポイントでプロの講師に直接質問して、ちゃんと納得するというスタイルの方がお金は確かに少し掛かりますが、独学で学ぶよりも絶対にモノになります。


シェアする

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

フォローする