26、订单流与量化平台:在VN.PY、Backtrader中集成订单流数据
说实话,很多做订单流的朋友都问过我一个问题:
“我手工看订单流图表挺顺手的,但怎么把它弄到我的量化策略里?”
嗯,这是个好问题。你想想看,订单流数据本身是高频的、逐笔的,而传统的量化框架比如VN.PY、Backtrader,它们默认处理的是K线数据。这两者之间,存在一个“数据鸿沟”。
今天我就带你亲手填上这个坑。
为什么要在量化平台里集成订单流?
我个人习惯把订单流数据看作是“市场的CT扫描”。普通K线只能看到价格和成交量,但订单流能告诉你:
- 谁在主动买?谁在主动卖?
- 在关键价位上,有多少挂单在防守?
- 大单是吃货还是砸盘?
把这些信息量化成指标,再塞进策略里,效果往往比单纯用均线、MACD好得多。我在项目中遇到过好几次,用订单流数据过滤掉假突破,胜率直接提升了十几个点。
数据格式的“翻译”工作
首先得明确一点:订单流数据不是标准OHLCV。它通常是这样的:
# 原始订单流数据(逐笔成交)
timestamp, price, volume, side, ask_price, bid_price
09:30:01.123, 100.50, 200, BUY, 100.51, 100.49
09:30:01.456, 100.49, 150, SELL, 100.50, 100.48
...
而量化平台要的是这样的:
# 标准K线数据
datetime, open, high, low, close, volume
2024-01-01 09:30:00, 100.50, 100.55, 100.48, 100.52, 350
所以,第一步就是“聚合”。把逐笔数据按时间切片(比如1分钟、5分钟),同时计算出订单流特有的指标:
- Delta:主动买量 - 主动卖量
- Cumulative Delta:累计Delta
- POC:成交量最大价位
- VAH/VAL:价值区域上下沿
在VN.PY中集成订单流
VN.PY本身是事件驱动的,它的核心是BaseData和BarGenerator。我的做法是:
- 自定义一个TickData扩展,加上
delta、ask_volume、bid_volume字段。 - 重写BarGenerator,在生成1分钟K线时,同时计算Delta、POC等。
- 把订单流指标作为新的K线字段,比如
bar.delta、bar.cum_delta。
代码大概长这样:
class OrderFlowBarGenerator(BarGenerator):
def update_tick(self, tick: TickData):
# 原有的K线生成逻辑
super().update_tick(tick)
# 额外计算Delta
if tick.last_price >= tick.ask_price_1:
self.delta += tick.volume # 主动买
elif tick.last_price <= tick.bid_price_1:
self.delta -= tick.volume # 主动卖
# 当K线完成时,把delta赋值给bar
if self.bar_completed:
self.bar.delta = self.delta
self.delta = 0
self.on_bar(self.bar)
这样,你的策略里就能直接调用bar.delta了。我曾经用这个框架做过一个策略:当Delta连续3根K线为负且价格没跌,就做多。效果出奇的好。
在Backtrader中集成订单流
Backtrader的思路不太一样。它更偏向于“数据馈送”和“指标计算”。
我的做法是:
- 自定义一个DataFeed,继承
bt.feeds.PandasData,把订单流指标作为额外的lines。 - 在策略中直接使用这些lines。
举个例子:
class OrderFlowData(bt.feeds.PandasData):
# 定义额外的数据列
lines = ('delta', 'cum_delta', 'poc', 'vah', 'val')
# 映射到CSV或DataFrame的列名
params = (
('delta', 'delta'),
('cum_delta', 'cum_delta'),
('poc', 'poc'),
('vah', 'vah'),
('val', 'val'),
)
# 使用
data = OrderFlowData(dataname=df) # df里包含delta等列
cerebro.adddata(data)
然后在策略里:
class MyStrategy(bt.Strategy):
def next(self):
if self.data.delta[0] > 1000 and self.data.close[0] > self.data.poc[0]:
self.buy()
嗯,这里要注意:Backtrader的next()是按bar触发的,所以你的订单流数据必须提前聚合好。我建议在数据预处理阶段就把这些指标算好,存到DataFrame里,再喂给Backtrader。
避坑指南
我曾经踩过的坑:
- 时间对齐问题:订单流数据是微秒级的,而K线是秒级的。聚合时一定要处理好时间戳的舍入,否则数据会错位。
- 数据量爆炸:全量订单流数据一天可能几百万条。建议只保留聚合后的1分钟或5分钟数据,否则回放速度会慢到让你怀疑人生。
- Delta的计算口径:不同交易所对“主动买/主动卖”的定义略有不同。记得先做小样本测试,确认你的Delta计算逻辑和交易所一致。
核心逻辑流程图
下面这张图,是我自己总结的“订单流数据集成量化平台”的标准流程。你照着这个走,基本不会出错:
实战建议
我个人给你的建议:
- 刚开始别贪多。先只集成Delta和Cumulative Delta这两个指标,跑通了再慢慢加POC、VAH这些。
- 回测时一定要用“逐笔回放”模式,别用“跳跃式回放”。订单流策略对微观结构敏感,跳跃式回放会失真。
- 数据源方面,我推荐用DolphinDB或者ClickHouse来存原始订单流数据,查询和聚合速度都很快。
好了,关于在VN.PY和Backtrader里集成订单流数据,核心要点就这些。说白了,就是“聚合数据 -> 封装成平台能识别的格式 -> 在策略里调用”。你动手试一次,就会发现其实没那么复杂。