当前位置:首页>python>使用Python进行事件驱动型量化回测(续3)

使用Python进行事件驱动型量化回测(续3)

  • 2026-08-25 07:10:50
使用Python进行事件驱动型量化回测(续3)

关于事件驱动回测系统的讨论,此前已涵盖事件循环、事件类层次结构以及数据处理组件等内容。本文将重点阐述策略类层次结构的设计。策略对象以市场数据作为输入,并输出交易信号事件。

一个策略对象封装了所有基于市场数据的计算逻辑,这些计算为投资组合对象生成建议信号。在事件驱动回测系统的当前开发阶段,尚未引入技术分析中常见的指标或过滤器概念。这些概念也适合构建独立的类层次结构,但本文暂不展开讨论。

策略类层次结构相对简单,主要包含一个抽象基类,该类具有生成信号事件SignalEvent对象的单一纯虚方法。为创建该层次结构,需要导入NumPy、pandas、队列对象、抽象基类工具以及信号事件类SignalEvent:

# strategy.pyimport datetimeimport numpy as npimport pandas as pdimport Queuefrom abc import ABCMeta, abstractmethodfrom event import SignalEvent
策略抽象基类仅定义了一个纯虚方法calculate_signals。在派生类中,该方法用于根据市场数据更新来生成信号事件对象:
# strategy.pyclass 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()")

策略抽象基类的定义非常简明扼要。我们首个策略子类的实例采用了买入并持有的策略来构建BuyAndHoldStrategy类。该策略在特定日期对某个证券建立多头仓位并长期持有,因此每个证券仅生成一次交易信号。该类的构造函数(__init__)需要接收市场数据处理器对象和事件队列对象作为参数:

# strategy.pyclass 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时,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
在此类中具体实现了calculate_signals这个纯虚方法。该方法会遍历代码列表中的所有交易品种,从数据处理器中获取每个品种的最新 K 线数据,然后检查该品种是否已被"买入"(即是否已对该品种建仓)。若尚未买入,则创建一个信号事件SignalEvent对象并将其放入事件events队列,同时将该品种在bought字典中的对应键值更新为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")。

最新文章

随机文章