第4讲:价差与信号计算
各位同学,今天我们来聊聊做市策略里最基础、也最要命的部分——价差和信号计算。说白了,你连买卖价差都算不明白,那后面的策略全是空中楼阁。我当年刚入行时,就吃过这个亏。
4.1 买卖价差计算
买卖价差(Bid-Ask Spread),就是最优卖价减去最优买价。公式很简单:
Spread = Ask_Price - Bid_Price
但实际项目中,我们通常用相对价差:
Relative_Spread = (Ask - Bid) / Mid_Price
为什么要用相对值?因为不同股票价格差太多。茅台2000块,价差2块才0.1%;某低价股2块钱,价差2分钱就是1%。你拿绝对值去比较,根本没法统一处理。
核心要点:价差是流动性的直接体现。价差越小,流动性越好。做市商赚的就是这个价差。
我在项目中遇到过一个问题:有些交易所的订单簿数据里,买一卖一可能同时为空。这时候价差怎么算?我的做法是:如果任意一侧为空,直接返回NaN,后续策略会跳过这个时间点。千万别自作聪明去补一个默认值,那会引入偏差。
4.2 加权中间价
中间价(Mid Price)大家都会算:
Mid = (Bid + Ask) / 2
但这里有个坑——如果买卖挂单量严重不平衡,这个中间价其实很虚。举个例子:
- 买一:100元,挂1000股
- 卖一:101元,挂10股
中间价是100.5元。但你想成交,大概率只能按100元卖,因为卖一那10股根本不够吃。这时候就需要加权中间价了。
加权中间价的计算方式有很多种,我个人比较常用的是按挂单量加权:
Weighted_Mid = (Bid_Price * Ask_Size + Ask_Price * Bid_Size) / (Bid_Size + Ask_Size)
为什么这么算?你想想看,如果卖一侧挂单很少,说明卖方力量弱,价格应该更偏向买方。这个公式正好反映了这个逻辑。
小技巧:我习惯同时计算普通中间价和加权中间价,两者的差值可以作为一个信号。差值越大,说明订单簿越不平衡,可能预示着价格即将变动。
4.3 成交量加权平均价(VWAP)
VWAP大家应该不陌生,公式是:
VWAP = Σ(Price_i * Volume_i) / Σ(Volume_i)
但在高频做市场景下,我们通常计算的是实时VWAP,也就是从当天开盘到当前时刻的累计加权平均价。这个指标用来衡量你的成交价格是否跑赢了市场平均水平。
我一般会维护两个VWAP:
- 全量VWAP:从开盘到现在的所有成交
- 滚动VWAP:最近N笔成交(比如最近100笔)
滚动VWAP对短期价格变化更敏感。我曾经用滚动VWAP作为做市策略的参考基准,效果比用全量VWAP好不少。
def calc_rolling_vwap(trades, window=100):
"""
计算滚动VWAP
trades: list of (price, volume)
"""
if len(trades) < window:
return None
recent = trades[-window:]
total_vol = sum(v for _, v in recent)
total_val = sum(p * v for p, v in recent)
return total_val / total_vol if total_vol > 0 else None
注意:VWAP对异常成交很敏感。比如一笔大单以极端价格成交,会严重拉偏VWAP。我建议在计算前先做一次价格过滤,剔除明显异常的单子。
4.4 订单簿不平衡指标
这个指标是我做策略时最依赖的信号之一。它衡量的是买卖双方的力量对比。
最简单的版本:
Imbalance = (Bid_Volume - Ask_Volume) / (Bid_Volume + Ask_Volume)
取值范围在-1到1之间。正值表示买方力量强,负值表示卖方力量强。
但实际项目中,只看买一卖一太片面了。我通常会用深度加权的不平衡指标:
def calc_depth_imbalance(order_book, levels=5):
"""
计算深度加权不平衡
order_book: 订单簿数据
levels: 考虑的档位数
"""
bid_vol = sum(order_book['bids'][i]['volume'] * (levels - i)
for i in range(min(levels, len(order_book['bids']))))
ask_vol = sum(order_book['asks'][i]['volume'] * (levels - i)
for i in range(min(levels, len(order_book['asks']))))
if bid_vol + ask_vol == 0:
return 0
return (bid_vol - ask_vol) / (bid_vol + ask_vol)
为什么要加权?因为越靠近最优价的挂单,对价格的影响力越大。我给近端挂单更高的权重,这样算出来的不平衡指标更灵敏。
实战经验:我曾经用这个指标做过一个简单的均值回归策略。当不平衡指标超过0.7时做空,低于-0.7时做多。回测效果不错,但实盘时要注意——极端不平衡往往伴随着大单冲击,滑点会吃掉大部分利润。
4.5 知识体系总览
下面这张图总结了本章的核心内容,我建议你保存下来,写代码时对照着看:
4.6 实战中的坑
最后分享几个我踩过的坑:
- 数据延迟问题:订单簿数据更新频率极高,你算出来的价差可能已经过时了。我一般会打一个时间戳,判断数据是否在可接受的时间窗口内。
- 零成交量处理:VWAP计算时如果成交量为0,直接除会报错。记得加个判断。
- 极端行情:涨跌停时,买卖价差会变得非常大,不平衡指标也会失效。这时候最好暂停策略。
- 交易所差异:不同交易所的订单簿数据结构不一样,有的用价格档位,有的用价格区间。写代码时一定要做一层抽象。
我的建议:刚开始做策略时,先把这四个指标算清楚,画成曲线图,盯着看几天。你会发现很多规律——比如价差在开盘和收盘时最大,中午最小;不平衡指标在重大消息发布前会剧烈波动。这些观察比任何理论都值钱。
好了,这一讲就到这里。记住一句话:信号的质量决定了策略的上限。把基础打牢,后面才能走远。