4. 滑点度量方法:实现价差、滑点百分比、滑点统计分布、滑点成本计算
滑点这东西,说白了就是「你以为能成交的价格」和「实际成交价格」之间的差距。我做了这么多年量化,见过太多策略在回测里跑得漂亮,一上实盘就亏钱——十有八九是滑点没算对。
今天咱们就把滑点度量这件事彻底讲透。我会从最基础的价差开始,一步步带你搭建完整的滑点度量体系。
4.1 价差:滑点的最底层构成
先问个问题:滑点从哪来?
最直接的来源就是买卖价差(Bid-Ask Spread)。你想买入,市场最优卖价是10.00,最优买价是9.98,这0.02的差距就是价差。如果你市价买入,至少要吃这0.02的亏。
我个人习惯把价差分为两类:
- 静态价差:某一时刻的买卖价差绝对值
- 动态价差:考虑订单簿深度后的加权价差
代码实现很简单:
def calc_spread(best_ask, best_bid):
"""计算绝对价差和相对价差"""
spread_abs = best_ask - best_bid
spread_pct = spread_abs / ((best_ask + best_bid) / 2)
return spread_abs, spread_pct
嗯,这里要注意:价差不是固定的。我在项目中遇到过,开盘前和收盘前价差能放大3-5倍。所以千万别用一个固定值去估算滑点。
4.2 滑点百分比:更直观的度量
绝对价差有个问题——不同价格的股票没法比。茅台2000块,价差2块才0.1%;某低价股5块,价差0.1块就2%了。所以我们需要滑点百分比。
滑点百分比的计算公式:
滑点百分比 = (实际成交价 - 预期成交价) / 预期成交价 × 100%
举个例子:
| 场景 | 预期价格 | 实际成交 | 滑点百分比 |
|---|---|---|---|
| 买入 | 10.00 | 10.05 | +0.5% |
| 卖出 | 10.00 | 9.95 | -0.5% |
你想想看,如果一个策略年化收益才10%,单笔滑点就吃掉0.5%,那交易频率稍微高点,利润全给滑点打工了。
4.3 滑点统计分布:别只看平均值
很多人算滑点就取个平均值完事。这其实是个坑。
我曾经吃过这个亏。有个策略回测时按平均滑点0.1%算,实盘前三个月确实没问题。结果第四个月遇到一次流动性危机,单笔滑点直接飙到0.8%,一天亏掉之前一个月的利润。
所以我们要看滑点的统计分布:
import numpy as np
import matplotlib.pyplot as plt
def slippage_distribution(slippages):
"""计算滑点统计分布"""
stats = {
'mean': np.mean(slippages),
'median': np.median(slippages),
'std': np.std(slippages),
'p95': np.percentile(slippages, 95),
'p99': np.percentile(slippages, 99),
'max': np.max(slippages)
}
return stats
重点关注两个指标:
- P95滑点:95%的情况下滑点不会超过这个值
- P99滑点:极端情况下的滑点上限
我个人习惯用P95作为日常成本估算,用P99做压力测试。如果P99滑点超过策略止损线的一半,这个策略就需要重新审视了。
4.4 滑点成本计算:把账算清楚
最后一步,把滑点换算成真金白银的成本。
滑点成本 = 滑点百分比 × 成交金额
但这里有个细节——不同订单类型,滑点成本算法不一样:
| 订单类型 | 滑点成本计算方式 | 说明 |
|---|---|---|
| 市价单 | 成交价 - 下单时中间价 | 最直接,但成本最高 |
| 限价单 | 成交价 - 限价 | 可能为负(吃到更好的价格) |
| TWAP/VWAP | 实际均价 - 目标均价 | 算法交易的基准 |
完整实现:
def calc_slippage_cost(order_type, fill_price, benchmark_price, volume):
"""
计算滑点成本
order_type: 'market', 'limit', 'twap'
"""
if order_type == 'market':
slippage = fill_price - benchmark_price
elif order_type == 'limit':
slippage = fill_price - benchmark_price # 限价单可能负滑点
elif order_type == 'twap':
slippage = fill_price - benchmark_price
cost = slippage * volume
cost_pct = (slippage / benchmark_price) * 100
return {
'slippage_abs': round(slippage, 4),
'slippage_pct': round(cost_pct, 4),
'total_cost': round(cost, 2)
}
4.5 本章小结
滑点度量这件事,说白了就是四个层次:
- 价差:最基础的度量,看买卖双方的博弈
- 滑点百分比:标准化度量,方便不同品种对比
- 统计分布:看极端情况,别被平均值骗了
- 成本计算:把滑点换算成钱,算清楚每笔交易的真实成本
我建议你从今天开始,在回测系统里加上滑点统计模块。哪怕只是记录每天的滑点分布,一个月后你就能看到很多有意思的规律——比如哪些时间段滑点最小,哪些股票流动性最好。这些经验,比任何理论都值钱。