『 Backtrader 』というバックテスト/システムトレード向けのPythonフレームワークが気になったので触れてみることに。
本記事では、環境構築~簡易サンプルコード実行までを(備忘録用に)まとめました。
私の環境は下記の通りです。
Windows 10
Python 3.10.0
Jupyter Notebook
準備
本記事のサンプルコードを動かすためのライブラリをインストールしていきます。
Backtrader DocumentationのQuickstart Guideのサンプルコードを一通り動かす場合は、backtrader githubページ記載の手順に従えばOKです。
Download ZIPで『datas』フォルダのデータをローカルに持ってくることもお忘れなく。
backtrader
このフレームワークを利用することによって、バックテスト/トレーディングのためのインフラ構築を簡単に行うことができます。
端末で下記いずれかのコマンドを実行し、インストールします。
pip install backtrader
pip install backtrader[plotting] # matplotlib 未インストールの場合
plotするには matplotlib のバージョンは最低 1.4.1 は必要みたいです。`
yfinance
Yahoo!Financeからマーケット情報をダウンロードするために使用します。
yfinance githubページにも記載されている通り、Yahoo, Inc.公認のAPIではないため、注意して扱う必要がありそうです。
pip install yfinance
yfinence を使用するためには、他に Pandas , Numpy , requests , lxml が必要になります。
各ライブラリの必要なバージョン等については、上記リンクよりご確認ください。
動作確認
今回はできるだけシンプルに、コードが機能するかを確かめます。
従って、取引戦略を凝ったり、手数料を考慮する等、細かいロジックは実装しません。
データ取得
まずは yfinance を使ってデータを取りに行きましょう。
今回の対象は米国ETFの VTI とします。
import yfinance as yf
data = yf.download('VTI', start='2022-04-01', end='2022-05-01')
data
''' 実行結果 -> '''
Open High Low Close Adj Close Volume
Date
2022-03-31 230.679993 231.320007 227.610001 227.669998 227.669998 4087000
2022-04-01 228.660004 228.750000 226.630005 228.580002 228.580002 3455900
2022-04-04 228.860001 230.539993 228.380005 230.520004 230.520004 3241100
... ... ... ... ... ... ...
2022-04-27 209.850006 212.399994 208.550003 209.660004 209.660004 4955900
2022-04-28 211.880005 215.750000 209.449997 214.770004 214.770004 3767700
2022-04-29 212.899994 214.309998 206.710007 206.880005 206.880005 7326200
日毎の始値や終値などの情報が入っていますね。
ちなみに、データの型はDataFrameです。
type(data)
''' 実行結果 -> '''
pandas.core.frame.DataFrame
Backtraderについて
サンプル全体を動かす前に、backtraderの基礎を一度おさえておきます。
基本的な構成は以下のようになります。
- 1. Strategyの構築
- 調整するパラメータを決定したうえで、マーケットへのEntry/Exitのロジックを記述します。 必要となる指標があればStrategy内でインスタンス化します。
- 2. Cerebro Engineの作成
- データ入力やStrategyの実行、データ監視をまとめて行ってくれます。バックテスト/データ供給/トレーディングの核を担う部分になります。
- 3. Cerebro Engineの実行
- データのロードと入力を行い(cerebro.adddata)、実行(cerebro.run())します。cerebro.plot()で結果を図示できます。
import backtrader as bt
# Strategyの構築
class MyStrategy(bt.Strategy):
''' 処理を記載 '''
# Cerebro Engineの作成
cerebro = bt.Cerebro()
# データロード/入力
data = ''' データを取ってくる '''
cerebro.adddata(data)
# 実行
cerebro.run()
自作したMyStrategyクラスはbt.Strategyクラスを継承しているため、特定のメソッドを記述するだけで、Cerebro Engineの方で良い感じに実行してくれます。
サンプルコードの実行
それでは、VTI のData FeedをCerebro Engineに渡して、動かしてみましょう。
サンプルコード
import backtrader as bt
import yfinance as yf
class MyStrategy(bt.Strategy):
# 実行記録
def log(self, txt, dt=None):
dt = dt or self.datas[0].datetime.date(0)
print('%s, %s' % (dt.isoformat(), txt))
# コンストラクタ
def __init__(self):
self.dataclose = self.datas[0].close
self.order = None
# 処理通知部
def notify_order(self, order):
if order.status in [order.Submitted, order.Accepted]:
return
# 取引内容を通知
if order.status in [order.Completed]:
if order.isbuy():
self.log('BUY EXECUTED, %.2f' % order.executed.price)
elif order.issell():
self.log('SELL EXECUTED, %.2f' % order.executed.price)
self.bar_executed = len(self)
elif order.status in [order.Canceled, order.Margin, order.Rejected]:
self.log('Order Canceled/Margin/Rejected')
self.order = None
# 売買処理部
def next(self):
self.log('Close, %.2f' % self.dataclose[0])
if self.order:
return
# マーケットにいるかチェック
if not self.position:
# 3セクション連続下落で購入
if self.dataclose[0] < self.dataclose[-1]:
if self.dataclose[-1] < self.dataclose[-2]:
self.log('BUY CREATE, %.2f' % self.dataclose[0])
self.order = self.buy()
else:
# 5セクション経過で良かれ悪かれ売却
if len(self) >= (self.bar_executed + 5):
self.log('SELL CREATE, %.2f' % self.dataclose[0])
self.order = self.sell()
# ETF:VTIのデータをダウンロード
yf_data = yf.download('VTI', start='2022-04-01', end='2022-05-01')
# データをCerebro Engine用のフォーマットに変換
data = bt.feeds.PandasData(dataname=yf_data)
# Cerebro Engineの作成
cerebro = bt.Cerebro()
# Strategyの読み込み
cerebro.addstrategy(MyStrategy)
# データ入力
cerebro.adddata(data)
# ターゲット資産の設定
cerebro.broker.setcash(400)
# 実行
cerebro.run()
# 最終結果を表示
print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
実行結果
[*********************100%***********************] 1 of 1 completed
2022-03-31, Close, 227.67
2022-04-01, Close, 228.58
2022-04-04, Close, 230.52
2022-04-05, Close, 227.15
2022-04-06, Close, 224.54
2022-04-06, BUY CREATE, 224.54
2022-04-07, BUY EXECUTED, 224.20
2022-04-07, Close, 225.39
2022-04-08, Close, 224.69
2022-04-11, Close, 221.18
2022-04-12, Close, 220.50
2022-04-13, Close, 223.39
2022-04-14, Close, 220.67
2022-04-14, SELL CREATE, 220.67
2022-04-18, SELL EXECUTED, 220.41
2022-04-18, Close, 220.29
2022-04-18, BUY CREATE, 220.29
2022-04-19, BUY EXECUTED, 220.23
2022-04-19, Close, 224.17
2022-04-20, Close, 223.88
2022-04-21, Close, 220.22
2022-04-22, Close, 214.22
2022-04-25, Close, 215.39
2022-04-26, Close, 209.25
2022-04-26, SELL CREATE, 209.25
2022-04-27, SELL EXECUTED, 209.85
2022-04-27, Close, 209.66
2022-04-28, Close, 214.77
2022-04-29, Close, 206.88
Final Portfolio Value: 385.83
Strategyの売買ロジックとしては、
3セクション連続で基準価格(終値)が下落した場合に買い注文(成行)を実施し、
5セクション経過で売り注文を実施しています。
ただし、まだマーケットに出ていない場合は、買い注文のみの実行となっています。
注意点として、売買の判断材料は対象銘柄の終値となっているため、売買が実行されるのは 翌営業日 になっています。
2022-04-26, SELL CREATE, 209.25
2022-04-27, SELL EXECUTED, 209.85
ターゲット資産400.00 [dol] に対し、このStrategyを適用すると、資産が385.83 [dol] まで減ってしまいました。
利益を上げるには、Strategyをしっかり練る必要がありそうです。
今回の目的である「 backtrader の動作確認」は達成しましたので、本記事の内容としては以上になります。