PART6.Automated Trading
14.Event-Driven Trading Engine Implementation-事件驱动的交易引擎实现
本章提供了一个用Python编写的完全自包含的事件驱动的回测系统的实现。特别的是,这一章的写作是为了扩展那些在其他算法交易文本和论文中通常被忽略的细节。接下来的代码将允许您模拟关于预测、动量和均值回归领域在股票、外汇和期货市场的高频策略。
然而,大量的细节带来了复杂性。这里提供的回溯测试系统需要许多组件,每个组件本身都是综合实体。因此,第一步是概述什么是事件驱动的软件,然后描述回测的组件以及整个系统是如何配合在一起的。
事件驱动软件
在深入研究这样一个回测软件的开发之前,我们需要理解事件驱动系统的概念。视频游戏为事件驱动的软件提供了一个自然的用例,并提供了一个简单的示例供您探索。一个视频游戏有多个组件,在高帧率的实时设置中相互交互。这是通过在一个称为事件循环或游戏循环的“无限”循环中运行整个计算集来处理的。
在游戏循环的每一次循环中,都会调用一个函数来接收最新的事件,这些事件将由游戏中相应的先前动作生成。根据事件的性质(可能包括按键或鼠标单击),将执行一些后续操作,这些操作将终止循环或生成一些其他事件。这个过程将继续下去。
下面是一些伪代码的例子:
while True: # 永远运行循环
new_event = get_new_event() # 获取最新事件
# 基于事件类型,执行一个动作
if new_event.type == "LEFT_MOUSE_CLICK":
open_menu()
elif new_event.type == "ESCAPE_KEY_PRESS":
quit_game()
elif new_event.type == "UP_KEY_PRESS":
move_player_north()
# ... 以及更多的事件
redraw_screen() # 更新屏幕以提供动画
tick(50) # 等待50毫秒
代码不断地检查新事件,然后根据这些事件执行操作。特别是它允许实时响应处理的假象,因为代码不断被循环,事件被检查。随后更加清晰,这正是我们所需要的,以便进行高频交易模拟。
为什么要使用事件驱动的回测软件?-事件驱动系统比起矢量化方法有很多优势:
● 代码重用——通过设计,一个事件驱动的回测软件既可以用于历史的回溯测试,也可以用于最小程度的组件切换的实时交易。这对于矢量化的回测软件来说是不正确的,因为所有的数据必须同时可用来进行统计分析。
● 前向偏差——事件驱动的回测软件不存在前向偏差,因为市场数据接收被视为必须被执行的“事件”。因此,可以用市场数据“点滴供给”事件驱动的回测软件,复制订单管理和投资组合系统的行为方式。
● 现实主义——事件驱动的后台测试人员允许对订单的执行和交易成本的产生进行重要的定制。由于可以构造自定义的经纪商处理程序,因此处理基本市场和限价订单以及市场开放(MOO)和市场关闭(MOC)非常简单。
尽管事件驱动系统具有许多优点,但与更简单的矢量化系统相比,它们有两个主要缺点。首先,它们的实现和测试要复杂得多。有更多的“移动部件”导致更大的机会引入错误。为了缓和这种适当的软件测试方法,可以使用测试驱动开发。
其次,与矢量化系统相比,它们执行速度更慢。在进行数学计算时,无法使用最佳向量化操作。
组件对象
要将事件驱动方法应用到回溯测试系统中,需要定义我们的组件(或对象)来处理特定的任务:
● 事件-事件是事件驱动系统的基本类单元。它包含一个类型(如“MARKET”、“SIGNAL”、“ORDER”或“FILL”),该类型决定如何在事件循环中处理它。
● 事件队列——事件队列是内存中的Python队列对象,它存储由软件的其余部分生成的所有事件子类对象。
● 数据处理器——数据处理器是一个抽象基类(ABC),它提供了一个处理历史或实时市场数据的接口。这提供了很大的灵活性,因为策略和投资组合模块因此可以在两种方法之间重用。数据处理器会根据系统的每一次心跳生成一个新的市场事件(见下面)。
● 策略——策略也是一个抽象基类(ABC),它提供了获取市场数据并生成相应信号事件的接口,这些信号事件最终将被投资组合对象使用。信号事件包含一个股票代码、一个方向(长或短)和一个时间戳。
● 投资组合—这是一个类层次结构,用于处理与策略的当前和后续位置相关的订单管理。它还对整个投资组合进行风险管理,包括行业敞口和头寸规模。在更复杂的实现中,这可以委托给风险管理类。投资组合从队列中获取信号事件并生成添加到队列中的订单事件。
● 执行处理器—执行处理器模拟到经纪业务的连接。处理程序的工作是从队列中获取订单事件并执行它们,可以通过模拟方法,也可以通过到真实经纪商的实际连接。一旦订单被执行,处理程序就会创建填充事件,它描述实际交易的内容,包括费用、佣金和滑动(如果建模)。
● 回测—所有这些组件都封装在一个事件循环中,该事件循环正确处理所有事件类型,并将它们路由到适当的组件。
尽管组件数量众多,但这是一个相当基本的交易引擎模型。还有很大的扩展空间,特别是在如何使用投资组合方面。此外,不同的交易成本模型也可以抽象到它们自己的类层次结构中。
更多内容请关注公众号【火象】~