파이썬으로 이벤트 기반 백테스팅 - 4부

저자:선함, 2019-03-25 14:24:46, 업데이트:

이벤트 주도 백테스팅 구현에 대한 논의는 이전에 이벤트 루프, 이벤트 클래스 계층 및 데이터 처리 구성 요소를 고려했습니다. 이 기사에서는 전략 클래스 계층을 설명합니다. 전략 객체는 시장 데이터를 입력으로 받아 거래 신호 이벤트를 출력으로 생성합니다.

전략 객체는 포트폴리오 객체에 자문 신호를 생성하는 시장 데이터에 대한 모든 계산을 포괄합니다. 이벤트 기반 백테스터 개발의 이 단계에서 기술적 거래에서 발견되는 것과 같은 지표 또는 필터의 개념이 없습니다. 이것들은 또한 클래스 계층을 만드는 데 좋은 후보이지만이 문서의 범위를 초월합니다.

전략 계층은 시그널 에벤트 객체를 생성하기 위해 하나의 순수 가상 메소드로 추상적인 기본 클래스를 구성하기 때문에 상대적으로 간단합니다. 전략 계층을 생성하기 위해서는 NumPy, pandas, Queue 객체, 추상적인 기본 클래스 도구 및 SignalEvent를 수입해야합니다.

# strategy.py

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

abc에서 가져오기 ABCMeta, 추상 방법

이벤트 수입에서 SignalEvent 전략 추상 기본 클래스는 순수 가상 계산_신호 메소드를 정의합니다. 파생 클래스에서는 시장 데이터 업데이트를 기반으로 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 클래스를 만들기 위해 구매 및 보유 전략을 사용합니다. 이것은 특정 날짜에 특정 증권에 장기간에 걸쳐서 포트폴리오 내에서 유지됩니다. 따라서 각 증권당 하나의 신호만 생성됩니다.

제작자 (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()

바이 앤 홀드 전략의 초기화 시 구매 된 사전 멤버는 모든 기호에 대한 키 세트를 False로 설정합니다. 자산이 롱 된 후에는 True로 설정됩니다. 본질적으로 이것은 전략이 시장에 있는지 여부를 알 수있게합니다.

# 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

이 클래스에서는 calculated_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) 로 우리의 위치를 추적하는 포트폴리오 계층을 만드는 방법을 고려할 것입니다.


더 많은