4、回测系统搭建:回测框架选择、数据准备与事件驱动引擎设计
做市策略跟普通趋势策略不一样。普通策略你拿日线数据跑一跑,差不多能看出个七七八八。但做市策略不行——它吃的是微观结构里的那点利润,订单簿的每一次跳动、每一笔成交的先后顺序,都直接影响你的盈亏。所以回测系统这块,我花了不少时间折腾。
今天咱们就聊聊,怎么搭一个能用的做市策略回测系统。说白了,就三件事:选框架、准备数据、写引擎。
4.1 回测框架怎么选?
市面上常见的回测框架就那几个。我挨个说说我的看法。
Backtrader
这个我用得最多。社区活跃,文档也全。它自带了一个事件驱动的架构,你只需要继承它的策略类,写几个回调函数就行。我个人习惯用它来做快速验证。
缺点:对Tick级数据的处理效率一般,订单簿模拟需要自己扩展。
Zipline
Quantopian 留下的遗产。说实话,它更适合做因子研究和组合回测。做市策略里那些细碎的订单逻辑,Zipline 处理起来有点吃力。我试过一次,后来放弃了。
自建框架
嗯,这是我最推荐的方案。为什么?因为做市策略的很多细节,通用框架根本覆盖不到。比如订单簿的深度管理、部分成交的处理、撤单重发的时机——这些东西在通用框架里要么没有,要么实现得不够灵活。
我曾经在一个项目里,用 Backtrader 跑了一个做市策略的回测,结果发现它的成交逻辑跟实盘差了十万八千里。后来我花了两周时间,自己写了一个轻量级的事件驱动引擎。从那以后,我再也没回头用过通用框架做做市策略的回测。
4.2 数据准备:Tick级 vs 分钟级
数据是回测的命根子。做市策略对数据的要求,比普通策略高一个数量级。
Tick级数据
说白了,就是每一笔成交的记录。包括成交时间、价格、数量、买卖方向。有些交易所还会提供订单簿的快照数据。
我处理Tick级数据时,最头疼的是数据清洗。交易所的数据经常有缺失、重复、甚至时间戳错乱的情况。你想想看,如果时间戳错了,你的回测结果就全废了。
- 检查时间戳是否单调递增
- 去除明显的异常价格(比如零价格、负价格)
- 处理盘口数据的跳变(比如买卖价差突然拉大)
分钟级数据
如果你只是做初步的策略验证,分钟级数据也能凑合。但要注意,分钟级数据会丢失很多微观结构的信息。比如,你在分钟K线上看到的买卖价差,跟实际Tick级别的价差可能完全不一样。
我个人习惯是:先用分钟级数据跑一遍,看看策略逻辑有没有明显的问题。没问题了,再换Tick级数据做精细回测。
| 数据类型 | 适用场景 | 数据量 | 回测精度 |
|---|---|---|---|
| Tick级 | 高频做市、订单簿策略 | 大(每天几百万条) | 高 |
| 分钟级 | 初步验证、低频做市 | 小(每天几百条) | 中 |
4.3 事件驱动回测引擎设计
这是整个回测系统的核心。事件驱动,说白了就是:市场发生什么,引擎就处理什么。比如,来了一个新的Tick,引擎就更新订单簿,检查是否有订单可以成交,然后触发策略的逻辑。
我设计的引擎,核心就三个组件:
- 事件队列:按时间顺序存放所有事件(Tick、订单状态变化、定时器事件等)。
- 事件处理器:从队列里取出事件,分发给对应的模块处理。
- 策略模块:接收事件,做出决策,然后提交订单。
下面是一个简化版的引擎代码框架:
class EventDrivenEngine:
def __init__(self):
self.event_queue = []
self.strategy = None
self.order_book = OrderBook()
self.portfolio = Portfolio()
def run(self, data_feed):
for event in data_feed:
self.event_queue.append(event)
self._process_event()
def _process_event(self):
event = self.event_queue.pop(0)
if event.type == 'TICK':
self.order_book.update(event)
self.strategy.on_tick(event)
elif event.type == 'ORDER_FILL':
self.portfolio.update(event)
self.strategy.on_fill(event)
4.4 核心逻辑流程图
下面这张图,是我自己画的事件驱动引擎的核心流程。你可以看到,数据从左边进来,经过事件队列,然后分发给各个模块处理。
4.5 一些实战中的坑
最后,分享几个我踩过的坑,希望能帮你省点时间。
- 数据对齐问题:不同交易所的数据,时间戳可能不是同一个时区。我曾经因为这个,回测结果差了20%。
- 订单簿重建:如果你只有成交数据,没有订单簿快照,那重建订单簿是个大工程。我建议至少保存每秒钟的订单簿快照。
- 滑点模拟:做市策略的滑点影响特别大。别用固定滑点,最好根据订单簿的深度动态计算。
好了,回测系统搭建这块,咱们就聊到这儿。下一节咱们会深入聊聊策略逻辑的具体实现,包括报价算法和风险管理。到时候见。
公众号:蓝海资料掘金营,微信deep3321