22、订单流与量化交易入门:订单流数据的量化处理、用Python计算Delta和成交量分布、构建简单的订单流量化策略
订单流数据到底是什么?
说实话,很多做量化的朋友一开始都搞混一件事——他们以为订单流就是Tick数据。其实不是。
Tick数据记录的是每一笔成交的价格和数量。而订单流数据,记录的是每一笔订单的主动方向。说白了,就是谁先动手的。
我刚开始接触订单流时,也踩过这个坑。当时我拿了一堆Tick数据,以为能直接算Delta,结果算出来的东西完全不对。后来才明白,订单流的核心在于「主动买」和「主动卖」的区分。
举个例子:
- 当前盘口:买一100元,卖一101元
- 有人直接以101元买入——这是主动买,记为+1手
- 有人直接以100元卖出——这是主动卖,记为-1手
这个方向信息,就是订单流数据的灵魂。
Delta:订单流里最基础的指标
Delta的计算其实很简单:
Delta = 主动买入量 - 主动卖出量
但你别小看这个公式。我见过很多交易员,盯着Delta看了好几年,还是没搞明白它到底在说什么。
Delta的本质是什么?是资金博弈的瞬时力量对比。
如果Delta持续为正,说明买方在主动吃单。如果Delta突然转负,说明卖方开始发力了。嗯,这里要注意——Delta不是预测指标,它是确认指标。
核心认知:Delta告诉你「现在谁在主导市场」,而不是「接下来谁会主导」。
用Python计算Delta
假设我们有一份订单流数据,格式大概是这样的:
| 时间 | 价格 | 成交量 | 方向 |
|---|---|---|---|
| 09:30:01 | 100.50 | 200 | Buy |
| 09:30:02 | 100.48 | 150 | Sell |
| 09:30:03 | 100.52 | 300 | Buy |
用Python处理起来其实就几行代码:
import pandas as pd
# 加载数据
df = pd.read_csv('orderflow.csv')
# 计算Delta
df['Delta'] = df.apply(
lambda row: row['成交量'] if row['方向'] == 'Buy' else -row['成交量'],
axis=1
)
# 累计Delta
df['Cumulative_Delta'] = df['Delta'].cumsum()
# 按分钟聚合
minute_delta = df.resample('1min', on='时间')['Delta'].sum()
我个人习惯把Delta分成三个级别来看:
- 逐笔Delta:看每一笔的瞬时博弈
- 分钟Delta:看短周期的力量变化
- 累计Delta:看全天资金的净流向
我在项目中遇到过一个问题——如果只看累计Delta,很容易被大单干扰。比如某笔大单把Delta拉得很高,但后续全是小单在卖,累计Delta还在高位,实际上买方已经没劲了。所以,我建议你结合分钟Delta一起看。
成交量分布:找到市场的「价值区域」
成交量分布(Volume Profile)是另一个核心工具。它告诉你:在某个价格区间,成交了多少量。
为什么重要?因为市场在某个价格成交得越多,说明这个价格被「认可」的程度越高。说白了,这是市场的共识价格。
计算逻辑也不复杂:
# 假设df包含价格和成交量
price_bins = range(int(df['价格'].min()), int(df['价格'].max()) + 1, 1)
volume_profile = pd.cut(
df['价格'],
bins=price_bins
).value_counts().sort_index()
# 找到成交量最大的价格区间
poc = volume_profile.idxmax()
这里有个关键点——POC(Point of Control),也就是成交量最大的那个价格。我一般把它当作市场的「重心」。
实战技巧:当价格远离POC时,往往会有回归的倾向。但注意,这不是绝对的。我曾经在某个品种上看到价格偏离POC 3%还继续冲,结果追进去的人全被埋了。所以,成交量分布更适合做辅助判断,而不是单一入场依据。
构建一个简单的订单流量化策略
好了,理论讲完了,咱们来点实战的。下面这个策略,是我早期做订单流交易时用的一个原型,虽然简单,但逻辑很清晰。
策略逻辑:
- 计算过去5分钟的累计Delta
- 计算当前价格相对于POC的位置
- 如果累计Delta为正且价格在POC上方,做多
- 如果累计Delta为负且价格在POC下方,做空
- 止损设在POC的另一侧
import pandas as pd
import numpy as np
def orderflow_strategy(df, lookback=5):
# 计算分钟Delta
df['Minute_Delta'] = df.resample('1min', on='时间')['Delta'].sum()
# 计算累计Delta
df['Cum_Delta_5min'] = df['Minute_Delta'].rolling(lookback).sum()
# 计算成交量分布
price_bins = np.arange(df['价格'].min(), df['价格'].max(), 0.5)
volume_profile = pd.cut(df['价格'], bins=price_bins).value_counts()
poc = volume_profile.idxmax()
# 生成信号
df['Signal'] = 0
df.loc[(df['Cum_Delta_5min'] > 0) & (df['价格'] > poc), 'Signal'] = 1
df.loc[(df['Cum_Delta_5min'] < 0) & (df['价格'] < poc), 'Signal'] = -1
return df
注意:这个策略只是一个教学示例。实盘中,你需要考虑滑点、手续费、以及Delta的滞后性。我曾经用这个策略跑回测,看起来收益不错,但一上实盘就亏——因为回测用的是历史数据,而实盘中的Delta变化比回测快得多。
订单流与量化结合的核心逻辑
下面这张图,是我自己总结的订单流量化交易的知识框架:
你看,整个流程其实就四步:拿数据 → 算指标 → 定策略 → 执行。但每一步都有坑。
比如数据层,很多交易所的订单流数据是不完整的,你得自己拼接。我早期做的时候,就因为数据源的问题,算出来的Delta全是错的,白忙活了两周。
再比如策略层,你算出来的Delta和成交量分布,到底怎么用?是作为入场信号,还是作为过滤条件?我个人习惯是把它们当过滤条件——先有交易逻辑,再用订单流数据去验证。
避坑指南
最后,分享几个我踩过的坑:
- 别迷信Delta的绝对值:Delta的大小和合约的流动性有关。同一个Delta值,在螺纹钢和黄金上的意义完全不同。
- 成交量分布要动态更新:我见过有人用昨天的POC来交易今天的行情,结果亏得一塌糊涂。市场每天都在变,POC也要跟着变。
- 订单流不是万能的:在震荡行情里,订单流数据会频繁发出假信号。我建议你结合趋势指标一起用。
嗯,今天就先聊到这儿。订单流和量化的结合,其实还有很多可以深挖的地方。比如如何用机器学习处理订单流数据,如何构建多周期的Delta策略——这些我们后面再慢慢聊。