イベント駆動バックテスト Python - Part IV

作者: リン・ハーン優しさ作成日:2019年3月25日 14:24:46 更新日:

イベント駆動バックテストの実装の議論は,以前にイベントループ,イベントクラス階層,データ処理コンポーネントを考慮した.この記事では戦略クラス階層が概説される.戦略オブジェクトは市場データを入力として取り,取引信号イベントを出力として生成する.

戦略オブジェクトは,ポートフォリオオブジェクトにアドバイザリー信号を生成する市場データに関するすべての計算をカプセル化します.イベント駆動バックテスト開発のこの段階では,技術取引で見られるような指標またはフィルターの概念はありません.これらはクラス階層を作成するための良い候補でもありますが,この記事の範囲を超えています.

戦略階層は,SignalEventオブジェクトを生成するための単一の純粋仮想方法を持つ抽象的なベースクラスで構成されているため,比較的シンプルです. 戦略階層を作成するには,NumPy,panda,Queueオブジェクト,抽象的なベースクラスツール,SignalEventをインポートする必要があります.

# strategy.py

import datetime
import numpy as np
import pandas as pd
import Queue

abcから輸入 ABCMeta,抽象方法

イベントインポートから SignalEvent Strategy 抽象ベースクラスは,純粋な仮想calculate_signals メソッドを定義するだけです.派生クラスでは,これは市場データ更新に基づいて SignalEvent オブジェクトの生成を処理するために使用されます:

# strategy.py

class Strategy(object):
    """
    Strategy is an abstract base class providing an interface for
    all subsequent (inherited) strategy handling objects.

    The goal of a (derived) Strategy object is to generate Signal
    objects for particular symbols based on the inputs of Bars 
    (OLHCVI) generated by a DataHandler object.

    This is designed to work both with historic and live data as
    the Strategy object is agnostic to the data source,
    since it obtains the bar tuples from a queue object.
    """

    __metaclass__ = ABCMeta

    @abstractmethod
    def calculate_signals(self):
        """
        Provides the mechanisms to calculate the list of signals.
        """
        raise NotImplementedError("Should implement calculate_signals()")

ストラテジー ABCの定義は単純です. ストラテジー オブジェクトをサブクラス化する最初の例は,BuyAndHoldStrategyクラスを作成するために買いと保持戦略を使用します.これは,特定の日付で特定の証券に長い時間をかけて,ポートフォリオ内に保持します.したがって,各証券に1つの信号のみ生成されます.

製造者 (init) は,バー市場データ処理とイベントイベントキューオブジェクトを要求します.

# strategy.py

class BuyAndHoldStrategy(Strategy):
    """
    This is an extremely simple strategy that goes LONG all of the 
    symbols as soon as a bar is received. It will never exit a position.

    It is primarily used as a testing mechanism for the Strategy class
    as well as a benchmark upon which to compare other strategies.
    """

    def __init__(self, bars, events):
        """
        Initialises the buy and hold strategy.

        Parameters:
        bars - The DataHandler object that provides bar information
        events - The Event Queue object.
        """
        self.bars = bars
        self.symbol_list = self.bars.symbol_list
        self.events = events

        # Once buy & hold signal is given, these are set to True
        self.bought = self._calculate_initial_bought()

BuyAndHoldStrategyを初期化すると,購入した辞書メンバーは,すべてのシンボルのキーのセットをfalseに設定しています.資産がlongedされた場合,これはtrueに設定されます.本質的には,これはStrategyが,市場にあるかどうかを知ることができます.

# strategy.py

    def _calculate_initial_bought(self):
        """
        Adds keys to the bought dictionary for all symbols
        and sets them to False.
        """
        bought = {}
        for s in self.symbol_list:
            bought[s] = False
        return bought

このクラスでは,純粋仮想メソッドである calculate_signals が具体的には実装されています. このメソッドは,シンボルリストのすべてのシンボルをループして,バーデータハンドラーから最新のバーを取得します. そのシンボルが買われたかどうかを確認します (つまり,このシンボルのために市場にいるかどうか) もしそうでない場合は,単一の SignalEvent オブジェクトを作成します. これは,イベントキューに配置され,購入した辞書はこの特定のシンボルキーに対して正しく True に更新されます:

# strategy.py

    def calculate_signals(self, event):
        """
        For "Buy and Hold" we generate a single signal per symbol
        and then no additional signals. This means we are 
        constantly long the market from the date of strategy
        initialisation.

        Parameters
        event - A MarketEvent object. 
        """
        if event.type == 'MARKET':
            for s in self.symbol_list:
                bars = self.bars.get_latest_bars(s, N=1)
                if bars is not None and bars != []:
                    if self.bought[s] == False:
                        # (Symbol, Datetime, Type = LONG, SHORT or EXIT)
                        signal = SignalEvent(bars[0][0], bars[0][1], 'LONG')
                        self.events.put(signal)
                        self.bought[s] = True

これは明らかに単純な戦略ですが,イベント主導の戦略階層の性質を示すのに十分です.次の記事では,ペア取引などのより洗練された戦略を検討します.次の記事では,利益と損失 (PnL) を伴うポジションを追跡するポートフォリオ階層を作成する方法について検討します.


もっと