導入
Backtrader オブザーバーは、主に、資金、売買ポイントなど、戦略の運用中にさまざまなステータス指標を観察するために使用されます。 cerebro.plot() を呼び出した後、以下に示すように、ステータス指標の変化を簡単に視覚化できます。以下の図は、Broker、Trades、BuySell の 3 人のオブザーバーを使用して、バックテスト プロセス中の現金と時価総額、取引損益、売買ポイントの変化を表示することができます。
説明書
-
cerebro.addobserver() 経由でオブザーバーを追加
import backtrader as bt
# 查看收益序列
cerebro.addobserver(bt.observers.TimeReturn)
# 查看回撤序列
cerebro.addobserver(bt.observers.DrawDown)
-
addobserver(obscls, args, **kwargs): パラメーター obscls はオブザーバー Observer に対応し、 args、**kwargs はオブザーバーによってサポートされるパラメーターに対応します
cerebro = bt.Cerebro(stdstats=False)
cerebro.addobserver(bt.observers.Broker)
cerebro.addobserver(bt.observers.Trades)
cerebro.addobserver(bt.observers.BuySell)
-
Cerebro は、デフォルトで Broker (Cash & Value)、Trades、および BuySell 3 オブザーバーを追加します (stdstats=True)。cerebro をインスタンス化するときに、bt.Cerebro(stdstats=False) を通じてデフォルト以外の表示を制御できます。
-
オブザーバー オブザーバー実行時間: オブザーバー オブザーバーは、すべてのインジケーターとストラテジーの next メソッドが実行された後に実行され、データを収集します。したがって、ストラテジー next メソッドで読み取られるオブザーバー [0] の最新データは、next の現在時刻よりも遅くなります。バー
-
オブザーバーからデータを読み取る方法
-
オブザーバーはライン オブジェクトに属しており、過去のバックテスト データが保存され、マーケット ライン オブジェクトと同様に操作できます。オブザーバーには、ポリシー属性 self.stats を通じてアクセスできます。
class MyStrategy(bt.Strategy):
def next(self):
# 当前时点的前一天的可用现金
self.stats.broker.cash[0]
self.stats.broker.value[0]
# 获取当前时刻前一天的收益
self.stats.timereturn.line[0]
-
オブザーバーにデータを保存する方法
現在、Backtrader にはオブザーバー データをファイルに直接保存するメカニズムがないため、独自に実装する必要があります。バックトレーダーが推奨する実装方法は次のとおりです。
-
ポリシーのstartメソッドでファイルを開きます
-
ポリシーの next メソッドと stop メソッドに対応する値を書き込みます
DrawDown オブザーバー モードを例として、サンプル コードは次のとおりです。
class MyStrategy(bt.Strategy):
def start(self):
self.mystats = open('mystats.csv', 'wb')
self.mystats.write('datetime,drawdown, maxdrawdown\n')
def next(self):
self.mystats.write(self.data.datetime.date(-1).strftime('%Y-%m-%d'))
self.mystats.write(',%.2f' % self.stats.drawdown.drawdown[0])
self.mystats.write(',%.2f' % self.stats.drawdown.maxdrawdown[0])
self.mystats.write('\n')
def stop(self):
self.mystats.write(self.data.datetime.date(0).strftime('%Y-%m-%d'))
self.mystats.write(',%.2f' % self.stats.drawdown.drawdown[0])
self.mystats.write(',%.2f' % self.stats.drawdown.maxdrawdown[0])
self.mystats.write('\n')
バックトレーダーに付いてくるオブザーバー
組み込みのオブザーバーには次のものが含まれます。
-
ベンチマーク:パフォーマンス ベンチマークのリターン シーケンスを記録します。パフォーマンス ベンチマークのデータは、adddata、resampledata、replaydata およびその他の追加関数を通じて事前に cerebro に追加する必要があります。視覚化中に、戦略自体のリターン シーケンスと戦略のリターン カーブが記録されます。パフォーマンス ベンチマークも同時に描画されます。
-
ブローカー、現金、価値: ブローカー オブザーバーは、各時点でのブローカーの利用可能な資金と総資産を記録します。現金と価値の曲線は、視覚化中に同時に表示されます。現金と価値を別々に表示したい場合は、 、それぞれ backtrader.observers を呼び出すことができます。
-
BuySell:バックテスト プロセス中に売買シグナルを記録し、視覚化中に価格曲線上の売買ポイントをマークします。
-
DrawDown:バックテスト プロセスのリトレースメント シーケンスを記録し、視覚化中にリトレースメント カーブを描画します。
-
TimeReturn: バックテスト プロセス中の返品シーケンスを記録し、視覚化中に TimeReturn 返品曲線が描画されます。
-
取引: バックテスト プロセス中に各取引の損益を記録し、視覚化中に損益ポイントを描画します。
-
LogReturns:戦略のログリターンを記録します。
-
LogReturns2: 2 つのデータ、data0 と data1 をサポートする拡張 LogReturns
-
FundValue:バックテストプロセス中にファンドの価値を記録します。
-
FundShares:バックテストプロセス中のファンドシェアを記録します。
その中で、一般的に使用されるオブザーバーには、Broker、BuySell、Trades、TimeReturn、DrawDown、Benchmark などが含まれます。
新しいオブザーバーを作成する
Broker オブザーバーには、現金と価値という 2 つのライン オブジェクトがあります。その実装は次のようになります。
class Broker(Observer):
alias = ('CashValue',)
lines = ('cash', 'value')
plotinfo = dict(plot=True, subplot=True)
def next(self):
self.lines.cash[0] = self._owner.broker.getcash()
self.lines.value[0] = value = self._owner.broker.getvalue()
ご覧のとおり、オブザーバーをカスタマイズする手順は次のとおりです。
-
カスタム オブザーバーは bt.observer.Observer から継承しますが、他の既存のオブザーバーから継承することもできます。
-
必要な行とパラメータを宣言します。パラメータはオプションです。対応するデータを次のメソッドに格納します
-
cerebro.plot() で視覚的に表示するために、plotinfo 属性と plotlines 属性を宣言します。
-
オブザーバーを保持する戦略を示す自動属性 _owner があります。
さらに、OrderObserver をカスタマイズできます (公式 Web サイトを参照): 標準の BuySell オブザーバーは、実行された操作のみを考慮しますが、以下に示すように、注文の作成と有効期限のステータスを表示するオブザーバーを作成できます。
class OrderObserver(bt.observer.Observer):
lines = ('created', 'expired',)
plotinfo = dict(plot=True, subplot=True, plotlinelabels=True)
plotlines = dict(
created=dict(marker='*', markersize=8.0, color='lime', fillstyle='full'),
expired=dict(marker='s', markersize=8.0, color='red', fillstyle='full')
)
def next(self):
for order in self._owner._orderspending:
if order.data is not self.data:
continue
if not order.isbuy():
continue
# Only interested in "buy" orders, because the sell orders
# in the strategy are Market orders and will be immediately
# executed
if order.status in [bt.Order.Accepted, bt.Order.Submitted]:
self.lines.created[0] = order.created.price
elif order.status in [bt.Order.Expired]:
self.lines.expired[0] = order.created.price
もちろん、他の既存のオブザーバーから継承することもできます。参照コードは次のとおりです。
class MyBuySell(bt.observers.BuySell):
# 将barplot默认值改为True
params = (('barplot', True), ('bardist', 0.015))
# 将三角形改为箭头
plotlines = dict(
buy=dict(marker=r'$\Uparrow$', markersize=8.0, color='#d62728' ),
sell=dict(marker=r'$\Downarrow$', markersize=8.0, color='red')
)
結論とコミュニケーション
詳細なコンテンツについては、WeChat 公開アカウント「Zhuge Shuo Talk」をフォローしてください。同時に、投資交流グループやクオンツ投資セミナー グループへの招待も受け取ることができます。そこでは、多くの投資愛好家、クオンツ実務家、テクノロジー専門家とコミュニケーションやディスカッションを行うことができ、投資レベルを迅速に向上させることができます。
記事を書くのは簡単ではありませんが、この記事が参考になったと思ったらクリックして読んでください。