冲击成本模型:永久冲击与暂时冲击
冲击成本这东西,说白了就是「你下单时对市场造成的扰动」。我刚开始做交易系统时,总觉得这是个理论概念,直到有一次实盘回测跑得漂亮,一上线就亏钱——嗯,就是没算冲击成本。
咱们今天把冲击成本拆开来看。它其实分两种:永久冲击和暂时冲击。理解这俩的区别,是构建成本模型的第一步。
永久冲击 vs 暂时冲击
先问个问题:你买100万股,股价涨了。等交易结束,股价会回到原来的位置吗?
答案是:不会完全回去。涨上去的那部分,有一部分是永久的,有一部分是暂时的。
- 永久冲击:你的交易改变了市场对这只股票的估值。比如你大量买入,市场认为「有大户看好」,于是均衡价格上移了。这部分冲击不会消失。
- 暂时冲击:纯粹是流动性摩擦。你吃掉了卖单,价格暂时被推高。等流动性恢复,价格会回落。这部分是暂时的。
我在项目中遇到过这样的情况:一个同事做算法交易,只考虑了暂时冲击,结果回测年化收益20%,实盘只有8%。为什么?因为永久冲击把成本吃掉了。你想想看,每次大单都推高买入成本,卖出时又压低价格,这中间的损失就是永久冲击。
核心公式:
总冲击成本 = 永久冲击 + 暂时冲击
永久冲击 ≈ 交易量 × 信息系数
暂时冲击 ≈ 交易量 × 流动性系数
冲击成本函数拟合
实际建模时,我们需要一个函数来描述冲击成本。常见的做法是:用交易量占日均成交量的比例作为自变量。
我个人的习惯是,先收集历史数据,然后做回归拟合。数据来源可以是逐笔成交数据,也可以是分钟级切片。拟合的目标是找到参数,让模型能预测「我下X%的量,会产生多少冲击」。
举个例子:
# 伪代码:冲击成本拟合
def fit_impact_model(trade_data):
# trade_data: 每笔交易的量、价格、时间
# 计算每笔交易的冲击 = 交易价格 - 基准价格
impact = trade_data['price'] - trade_data['benchmark']
# 计算交易量占比
volume_ratio = trade_data['volume'] / trade_data['avg_daily_volume']
# 回归:impact = a * volume_ratio + b * sqrt(volume_ratio)
# 或者用更复杂的非线性模型
params = regression(impact, volume_ratio)
return params
这里要注意:基准价格怎么选? 我建议用交易前一段时间的VWAP,或者用前收盘价。选错了基准,拟合出来的参数全是错的。
我曾经踩过的坑:用交易后的价格做基准。结果冲击成本算出来是负的——因为价格涨了,我以为自己「赚了冲击」。实际上那是市场本身的波动,不是冲击。基准一定要用交易前的价格。
线性冲击模型
线性模型是最简单的。它假设冲击成本与交易量成正比:
冲击成本 = α × 交易量占比
这个模型的好处是简单、可解释。α 可以理解为「每交易1%的日均成交量,产生的冲击基点」。
但说实话,线性模型在实盘中不太够用。为什么?因为市场在交易量大的时候,冲击会加速增长。你买1%的量,冲击是1个基点;买10%的量,冲击可能不是10个基点,而是20个基点。
我个人的经验是:线性模型只适合交易量占比小于1%的情况。超过这个阈值,误差会急剧增大。
| 交易量占比 | 线性模型预测 | 实际冲击 | 误差 |
|---|---|---|---|
| 0.5% | 0.5 bp | 0.6 bp | 0.1 bp |
| 2% | 2.0 bp | 3.2 bp | 1.2 bp |
| 5% | 5.0 bp | 12.0 bp | 7.0 bp |
你看,误差随着交易量增大而爆炸。所以实际系统中,我很少单独用线性模型。
平方根冲击模型
平方根模型是目前业界用得最多的。它的形式是:
冲击成本 = β × √(交易量占比)
为什么是平方根?这背后有理论支撑。简单说:市场深度不是线性的。你下单时,订单簿上的挂单量是随价格深度递增的。平方根模型正好能描述这种非线性。
我记得有一次做A股的高频策略,用平方根模型拟合出来的R²能达到0.85以上,而线性模型只有0.6。差距很明显。
实用技巧:平方根模型的参数 β 可以通过历史数据拟合得到。但要注意,不同股票的 β 差异很大。大盘蓝筹股的 β 可能只有0.5,小盘股的 β 可能到2.0。我建议按市值分组拟合,不要用统一参数。
实际应用中,我更喜欢用混合模型:
冲击成本 = α × 交易量占比 + β × √(交易量占比)
这样既能捕捉线性部分(小单的冲击),又能捕捉非线性部分(大单的加速冲击)。α 和 β 一起拟合,效果通常比单独用任何一个都好。
知识体系结构图
下面这张图展示了冲击成本模型的核心逻辑:
这张图把整个冲击成本模型串起来了。从永久冲击和暂时冲击出发,到两种主流模型,最后落到混合模型。我个人建议,实盘系统至少用平方根模型起步,等数据积累够了再升级到混合模型。
避坑指南
最后分享几个我踩过的坑:
- 数据频率太低:用日线数据拟合冲击模型,基本是瞎搞。冲击发生在秒级甚至毫秒级,至少要用分钟级数据。
- 忽略市场状态:牛市的冲击参数和熊市完全不同。我建议按市场状态分场景拟合,或者用滚动窗口。
- 过度拟合:模型参数太多,容易过拟合。我见过有人用10个参数的模型,回测完美,实盘一塌糊涂。简单模型往往更鲁棒。
我的建议:先跑一个简单的平方根模型,上线观察一个月。如果误差在可接受范围内,就别折腾了。交易成本模型追求的是「够用」,不是「完美」。
冲击成本模型就聊到这儿。记住:模型是工具,不是真理。再好的模型,也要用实盘数据不断校准。