2. 高频环境下的冲击成本建模:Almgren-Chriss模型、瞬时冲击与永久冲击、非线性冲击函数拟合
各位同学,咱们今天聊一个实打实的问题——冲击成本建模。
做高频TWAP策略,最怕什么?怕你刚把单子砸进去,价格就跑了。你想想看,本来算得好好的,按时间均匀切单,结果第一笔就把市场打穿了,后面几笔全在高位接盘。嗯,这就是冲击成本在作祟。
我在早期做高频策略时,就吃过这个亏。当时回测曲线漂亮得不行,一上实盘就亏钱。后来才发现,我压根没把冲击成本算进去。说白了,回测里的成交价是理想价,实盘里的成交价是血淋淋的现实价。
2.1 冲击成本的核心逻辑
冲击成本,简单讲就是你的订单对市场价格造成的影响。你买,价格涨;你卖,价格跌。这个影响分两种:
- 瞬时冲击:订单执行瞬间造成的价格偏离。单子吃完,价格会部分恢复。
- 永久冲击:订单执行后,价格回不来的那部分。市场认为你的交易包含了信息。
我习惯用一个比喻来理解:你往平静的湖面扔一块石头。水花溅起来那一下是瞬时冲击,水面最终上升的高度是永久冲击。石头沉底了,水不会完全恢复原状。
核心公式(Almgren-Chriss模型):
瞬时冲击 = α · σ · (Q/V)^β
永久冲击 = γ · σ · (Q/V)
其中:Q是你的订单量,V是市场成交量,σ是波动率,α、β、γ是待拟合参数
2.2 Almgren-Chriss模型实战拆解
Almgren-Chriss模型,说白了就是学术界给量化交易者的一把尺子。它把冲击成本拆成了两部分:瞬时部分和永久部分。
我个人习惯用这个模型做两件事:
- 事前预估:下单前算一下,这笔单子大概会造成多大的滑点。
- 事后归因:交易结束后,分析滑点中有多少是冲击造成的,多少是市场波动造成的。
我记得有一次做比特币的TWAP,流动性极差。用Almgren-Chriss模型一算,发现如果按原始方案切单,冲击成本能吃掉整个策略利润的30%。后来我调整了切单粒度,把大单拆成更小的碎片,才把冲击压下来。
避坑指南:
我曾经犯过一个低级错误——直接用日成交量V来计算冲击。在高频环境下,你应该用分钟级甚至秒级的成交量。日成交量会严重低估冲击,因为流动性在一天内分布极不均匀。
2.3 瞬时冲击与永久冲击的分离
为什么要区分瞬时和永久?因为它们的优化方向完全不同。
| 冲击类型 | 特征 | 优化方向 |
|---|---|---|
| 瞬时冲击 | 执行后价格快速恢复 | 降低单笔订单量,增加订单频率 |
| 永久冲击 | 执行后价格不恢复 | 拉长执行时间,隐藏交易意图 |
你想想看,如果市场里全是瞬时冲击,那好办——拆细单子就行。但如果有永久冲击,说明你的交易被市场嗅到了信息。这时候再拆细也没用,得换策略,比如用暗池或者冰山订单。
我在做A股高频策略时,就遇到过典型的永久冲击问题。某只小盘股,我每天只交易几千股,但价格硬是被我推高了0.2%。后来分析发现,是因为我的订单被做市商识别了,他们提前埋伏,等我买完再卖给我。嗯,这就是永久冲击的典型场景。
2.4 非线性冲击函数拟合
Almgren-Chriss模型假设冲击与订单量的关系是线性的(永久冲击)或幂律的(瞬时冲击)。但真实市场往往更复杂。
我建议你直接用历史数据做非线性拟合。具体做法:
import numpy as np
from scipy.optimize import curve_fit
# 定义非线性冲击函数
def impact_func(Q, alpha, beta, gamma):
# Q: 订单量占比 (Q/V)
# 返回: 冲击成本 (bps)
return alpha * (Q ** beta) + gamma * Q
# 历史数据: 订单量占比 vs 实际冲击
Q_data = np.array([0.001, 0.005, 0.01, 0.02, 0.05])
impact_data = np.array([0.5, 1.2, 2.1, 3.8, 8.5])
# 拟合参数
params, _ = curve_fit(impact_func, Q_data, impact_data)
alpha, beta, gamma = params
print(f"拟合结果: alpha={alpha:.3f}, beta={beta:.3f}, gamma={gamma:.3f}")
这段代码看着简单,但实际用起来有几个坑:
- 数据清洗:剔除异常值,比如大单砸盘后的极端冲击。
- 时间窗口:冲击的测量窗口要统一,我一般用1秒窗口。
- 市场状态:不同波动率下,冲击函数参数差异很大。建议分状态拟合。
注意:
非线性拟合的结果对初始值敏感。我建议先用线性模型跑一遍,把结果作为非线性拟合的初始值。否则容易陷入局部最优,拟合出来的参数完全不能用。
2.5 高频环境下的特殊考量
高频环境和传统环境不一样。有几个点你得特别注意:
- 订单簿微观结构:高频下,冲击不仅来自你的订单,还来自订单簿的深度变化。做市商看到你的订单后,可能会撤单或调整报价。
- 延迟影响:你的订单到达交易所时,市场可能已经变了。这个延迟本身就会产生冲击。
- 反身性:你的策略本身会影响市场,市场的变化又会反过来影响你的策略。这是个闭环。
我个人习惯在高频策略中引入一个「冲击缓冲系数」。比如,模型算出来冲击是2个bps,我实际按3个bps来算。多出来的1个bps就是给不确定性留的余量。这个习惯帮我避免了好几次实盘翻车。
2.6 本章知识体系
下面这张图是我自己整理的冲击成本建模知识体系,你可以对照着梳理思路:
这张图把整个知识体系串起来了。从Almgren-Chriss模型出发,分支出瞬时和永久冲击,再往下落到非线性拟合这个核心方法上。底部的实践要点,是我在实际项目中踩过坑后总结出来的。
好了,这一章的内容就到这里。冲击成本建模是个硬功夫,建议你拿到自己的历史数据跑一遍拟合,看看参数长什么样。每个市场的参数都不一样,别指望拿别人的参数直接用。
公众号:蓝海资料掘金营,微信deep3321