イベント駆動バックテストの実装の議論は,以前にイベントループ,イベントクラス階層,データ処理コンポーネントを考慮した.この記事では戦略クラス階層が概説される.戦略オブジェクトは市場データを入力として取り,取引信号イベントを出力として生成する.
戦略オブジェクトは,ポートフォリオオブジェクトにアドバイザリー信号を生成する市場データに関するすべての計算をカプセル化します.イベント駆動バックテスト開発のこの段階では,技術取引で見られるような指標またはフィルターの概念はありません.これらはクラス階層を作成するための良い候補でもありますが,この記事の範囲を超えています.
戦略階層は,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に設定しています.資産が
# 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 が具体的には実装されています. このメソッドは,シンボルリストのすべてのシンボルをループして,バーデータハンドラーから最新のバーを取得します. そのシンボルが
# 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
これは明らかに単純な戦略ですが,イベント主導の戦略階層の性質を示すのに十分です.次の記事では,ペア取引などのより洗練された戦略を検討します.次の記事では,利益と損失 (