3. 流动性度量指标(上):买卖价差、有效价差、实现价差
各位同学,咱们今天聊点实在的。
做跨品种套利,最怕什么?不是方向看错,是流动性枯竭。你算好了价差,挂单进去,结果发现根本成交不了——或者成交了,滑点吃掉你所有利润。我早年吃过这个亏,所以今天把这几个指标掰开揉碎讲清楚。
3.1 买卖价差(Bid-Ask Spread)
买卖价差,说白了就是市场上最优买价和最优卖价之间的差值。这是最直观的流动性指标。
公式:
绝对价差 = 卖一价 - 买一价
相对价差 = (卖一价 - 买一价) / 中间价 × 100%
举个例子。假设螺纹钢期货,买一价是3800,卖一价是3802。那绝对价差就是2个点。相对价差呢?中间价是3801,所以相对价差是2/3801 ≈ 0.053%。
我个人习惯看相对价差。为什么?因为不同品种价格差异太大。你拿螺纹钢和铜比绝对价差,没意义。但相对价差可以横向对比。
实战经验:
我一般把相对价差超过0.1%的品种列为“高摩擦成本”品种。做套利时,如果两个品种的相对价差都超过这个阈值,我会重新考虑策略——因为光进出场成本就可能吃掉一半利润。
3.2 有效价差(Effective Spread)
买卖价差有个问题——它只反映了最优报价,不代表你实际成交的成本。你想想看,你挂单不一定能成交在最优价上。尤其是大单,可能要吃好几档。
有效价差就是解决这个问题的。它衡量的是实际成交价格与中间价之间的偏差。
公式:
有效价差 = 2 × |成交价 - 中间价|
为什么乘以2?因为买卖价差本身是双向的。你买的时候偏离中间价一个方向,卖的时候又偏离另一个方向。有效价差把这两个方向都算进去了。
我记得有一次做豆粕和豆油的套利。看买卖价差只有0.03%,觉得流动性不错。结果一进去,实际成交的有效价差达到了0.12%。为什么?因为中间有大量程序化交易在抢单,我的订单被挤到了后面几档。这就是买卖价差“骗人”的地方。
避坑指南:
我曾经只盯着买卖价差做策略,结果回测漂亮,实盘一跑就亏。后来发现,有效价差才是真实成本。建议各位在回测时,至少用有效价差来模拟交易成本,别用买卖价差的一半——那太乐观了。
3.3 实现价差(Realized Spread)
实现价差,这个指标更狠。它不光看你成交时的成本,还看你平仓时的成本。说白了,它衡量的是“你进去再出来,到底被剥了多少皮”。
公式:
实现价差 = 2 × (成交价 - 平仓后的中间价)
这里有个关键点:平仓后的中间价。不是平仓时的中间价,而是你平仓之后,市场稳定下来的中间价。为什么?因为你的大单可能会暂时影响价格。实现价差要剔除这个暂时影响,只看真正的流动性成本。
嗯,这里要注意。实现价差和有效价差的区别,有点像“瞬时成本”和“全周期成本”。有效价差只管你进场那一瞬间,实现价差管你整个交易生命周期。
我做过一个统计,在股指期货和ETF的套利中,实现价差通常是有效价差的1.5到2倍。为什么?因为大单进去后,市场需要时间恢复。你如果做高频套利,这个恢复时间就是你的风险窗口。
3.4 三个指标的对比与选择
这三个指标,各有各的用处。我整理了一个表格,方便你对比:
| 指标 | 衡量什么 | 优点 | 缺点 |
|---|---|---|---|
| 买卖价差 | 最优报价的宽度 | 计算简单,实时性强 | 忽略实际成交成本 |
| 有效价差 | 实际成交成本 | 更贴近真实交易 | 需要成交数据 |
| 实现价差 | 全周期流动性成本 | 考虑市场冲击和恢复 | 计算复杂,需要事后数据 |
我个人建议:
- 做日内短线套利,重点看有效价差。因为你的持仓时间短,市场冲击影响小。
- 做中长线套利,重点看实现价差。因为你的单子大,市场恢复时间不可忽略。
- 买卖价差?我一般只用来做初步筛选。比如两个品种的买卖价差都很大,那直接跳过,不用浪费时间。
3.5 代码实现:计算三个价差
光说不练假把式。我给你一段Python代码,可以直接跑。这是我从一个实盘监控系统里抽出来的核心逻辑。
import pandas as pd
import numpy as np
def calculate_spreads(trade_data, quote_data):
"""
计算买卖价差、有效价差、实现价差
参数:
trade_data: DataFrame,包含成交价、成交量、时间戳
quote_data: DataFrame,包含买一价、卖一价、时间戳
"""
# 1. 买卖价差
quote_data['mid_price'] = (quote_data['bid_price'] + quote_data['ask_price']) / 2
quote_data['quoted_spread'] = quote_data['ask_price'] - quote_data['bid_price']
quote_data['relative_spread'] = quote_data['quoted_spread'] / quote_data['mid_price']
# 2. 有效价差
merged = pd.merge_asof(trade_data, quote_data, on='timestamp', direction='nearest')
merged['effective_spread'] = 2 * abs(merged['trade_price'] - merged['mid_price'])
# 3. 实现价差(需要事后5秒的中间价)
quote_data['future_mid'] = quote_data['mid_price'].shift(-5) # 5秒后的中间价
merged = pd.merge_asof(merged, quote_data[['timestamp', 'future_mid']],
on='timestamp', direction='nearest')
merged['realized_spread'] = 2 * (merged['trade_price'] - merged['future_mid'])
return merged[['timestamp', 'quoted_spread', 'effective_spread', 'realized_spread']]
# 使用示例
# spreads = calculate_spreads(trades, quotes)
# print(spreads.describe())
注意:
实现价差里的“事后中间价”取多少秒,取决于你的品种。我一般用5秒,但如果是国债期货这种流动性极好的品种,1秒就够了。如果是某些冷门商品,可能需要10秒甚至更长。你可以用回测来调这个参数。
3.6 知识体系图
下面这张图,把三个指标的关系和适用场景画清楚了。你可以保存下来,做策略时对照着看。
好了,这一节的内容就到这。三个指标,从简单到复杂,从表面到本质。你先把买卖价差和有效价差搞清楚,实现价差可以慢慢消化。下一节我们继续聊深度指标,比如Amihud非流动性比率和价格冲击系数——那些才是真正考验功力的东西。
公众号:蓝海资料掘金营,微信deep3321