オブザーバーを理解するためのクオンツフレームワークバックトレーダーに関する記事

導入

Backtrader オブザーバーは、主に、資金、売買ポイントなど、戦略の運用中にさまざまなステータス指標を観察するために使用されます。 cerebro.plot() を呼び出した後、以下に示すように、ステータス指標の変化を簡単に視覚化できます。以下の図は、Broker、Trades、BuySell の 3 人のオブザーバーを使用して、バックテスト プロセス中の現金と時価総額、取引損益、売買ポイントの変化を表示することができます。

説明書

  1. 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) を通じてデフォルト以外の表示を制御できます。

  1. オブザーバー オブザーバー実行時間: オブザーバー オブザーバーは、すべてのインジケーターとストラテジーの next メソッドが実行された後に実行され、データを収集します。したがって、ストラテジー next メソッドで読み取られるオブザーバー [0] の最新データは、next の現在時刻よりも遅くなります。バー

  2. オブザーバーからデータを読み取る方法

  • オブザーバーはライン オブジェクトに属しており、過去のバックテスト データが保存され、マーケット ライン オブジェクトと同様に操作できます。オブザーバーには、ポリシー属性 self.stats を通じてアクセスできます。

class MyStrategy(bt.Strategy):
    def next(self):
        # 当前时点的前一天的可用现金
        self.stats.broker.cash[0]
        self.stats.broker.value[0]
        # 获取当前时刻前一天的收益
        self.stats.timereturn.line[0]
  1. オブザーバーにデータを保存する方法

現在、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」をフォローしてください。同時に、投資交流グループやクオンツ投資セミナー グループへの招待も受け取ることができます。そこでは、多くの投資愛好家、クオンツ実務家、テクノロジー専門家とコミュニケーションやディスカッションを行うことができ、投資レベルを迅速に向上させることができます。

記事を書くのは簡単ではありませんが、この記事が参考になったと思ったらクリックして読んでください。

参考

おすすめ

転載: blog.csdn.net/richardzhutalk/article/details/125456719