6、冲击成本参数估计:永久冲击系数估计、临时冲击系数估计、波动率估计

好,咱们进入第六章。这一章是实战手册里最「硬核」的部分之一。

前面我们讲了冲击成本模型长什么样,也讲了怎么用交易数据去拟合。但模型里的那些参数——永久冲击系数、临时冲击系数、波动率——到底怎么算出来?

说白了,参数估计不准,模型就是摆设。我见过不少团队,模型搭得漂漂亮亮,一上线就亏钱,回头一查,参数全是拍脑袋估的。

今天咱们就把这三个参数掰开揉碎,讲清楚。

6.1 永久冲击系数估计

永久冲击,指的是你的订单对市场造成的「不可逆」影响。比如你买了一大笔股票,把价格推高了,就算你买完了,价格也回不到原来的位置。

这个系数,我习惯用VWAP(成交量加权平均价)TWAP(时间加权平均价)的差值来估计。

核心思路:

永久冲击 = 订单执行期间的市场价格变化 - 临时冲击(可逆部分)

但在实际中,我们通常用回归模型直接分离两者。

具体做法是这样的:

  1. 收集历史交易数据,包括每笔订单的成交量订单方向(买/卖)、执行价格基准价格(比如订单到达前的市场价)。
  2. 计算每笔订单的价格冲击:冲击 = (执行价格 - 基准价格) / 基准价格。
  3. 用回归模型拟合:冲击 = α + β₁ × (成交量/市场总成交量) + β₂ × 订单方向 + ε。

这里的 β₁ 就是永久冲击系数。为什么?因为成交量占比越大,你的订单对市场的影响越持久。

我的经验:

我曾经在拟合一个高频股票时,发现永久冲击系数特别小,几乎为零。一开始我以为模型错了,后来才发现——那只股票流动性极好,几百万的订单打进去,价格纹丝不动。嗯,这就是流动性好的典型特征。

代码实现也不复杂,用 Python 的 statsmodels 库就能搞定:

import statsmodels.api as sm
import pandas as pd

# 假设 df 包含列:volume_ratio(成交量占比), direction(1买/-1卖), impact(价格冲击)
X = df[['volume_ratio', 'direction']]
X = sm.add_constant(X)
y = df['impact']

model = sm.OLS(y, X).fit()
permanent_coef = model.params['volume_ratio']
print(f"永久冲击系数: {permanent_coef:.6f}")

这里要注意一点:数据频率。我建议用分钟级数据,太细了噪声大,太粗了丢失信息。

6.2 临时冲击系数估计

临时冲击,说白了就是你的订单「吓到了」市场,但等交易结束,价格会慢慢恢复。

这个系数怎么估?我个人的习惯是看订单簿的恢复速度

具体来说:

  1. 找到那些大单成交后,价格在短时间内(比如1-5分钟)又回到原位的案例。
  2. 计算这些案例中,价格偏离的幅度和持续时间。
  3. 用回归模型拟合:临时冲击 = γ × (成交量/市场深度) + δ × 订单方向。

这里的 γ 就是临时冲击系数。市场深度越浅,临时冲击越大。

避坑指南:

我曾经犯过一个错误——把永久冲击和临时冲击混在一起回归。结果两个系数都估计不准。后来我改用两阶段回归:先估计永久冲击,把残差拿出来再估计临时冲击。效果好了很多。

两阶段回归的代码示例:

# 第一阶段:估计永久冲击
model_perm = sm.OLS(y, X).fit()
residuals = model_perm.resid  # 残差 = 临时冲击 + 噪声

# 第二阶段:估计临时冲击
# 假设临时冲击与订单规模、市场深度有关
X_temp = df[['order_size', 'market_depth']]
X_temp = sm.add_constant(X_temp)
model_temp = sm.OLS(residuals, X_temp).fit()
temporary_coef = model_temp.params['order_size']
print(f"临时冲击系数: {temporary_coef:.6f}")

你想想看,为什么临时冲击系数比永久冲击系数更难估?因为临时冲击的「恢复」过程,受太多因素影响——市场情绪、其他订单的到达、新闻事件……所以,我建议用高频数据(比如 tick 级数据)来估计,样本量越大越好。

6.3 波动率估计

波动率,是冲击成本模型里最基础的参数。没有波动率,你连订单的「风险」都算不清楚。

估计波动率的方法很多,我挑三个最实用的讲:

方法 适用场景 优点 缺点
历史波动率 低频交易、长期策略 简单、稳定 滞后、对突变不敏感
已实现波动率 高频交易、日内策略 实时、准确 需要高频数据
GARCH模型 波动率聚类明显的市场 能捕捉波动率变化 参数估计复杂

我个人最常用的是已实现波动率。为什么?因为它能反映「当下」的市场状态。你想想看,如果今天市场突然暴跌,你用过去30天的历史波动率,根本反应不过来。

已实现波动率的计算很简单:

import numpy as np

# 假设 prices 是分钟级价格序列
returns = np.diff(np.log(prices))
realized_vol = np.sqrt(np.sum(returns**2))
print(f"已实现波动率: {realized_vol:.6f}")

这里有个细节:采样频率。我建议用5分钟或10分钟的频率。太细了(比如1分钟),会受到微观结构噪声的干扰;太粗了(比如1小时),又会丢失日内波动信息。

我的一个小技巧:

在估计波动率时,我会同时计算上行波动率下行波动率。因为市场在上涨和下跌时,波动特征往往不同。比如,下跌时的波动率通常更大。这个差异,在冲击成本模型里能帮你更精准地控制风险。

知识体系总览

下面这张图,把本章的三个参数估计方法串起来了。你可以看到,永久冲击和临时冲击是「兄弟」,一个管长期影响,一个管短期扰动;而波动率是「地基」,所有估计都离不开它。

冲击成本参数估计知识体系 永久冲击系数 临时冲击系数 波动率估计 VWAP/TWAP差值回归 订单簿恢复速度回归 已实现波动率 两阶段回归 高频数据(tick级) 5分钟采样频率 三者相互独立,但波动率是冲击系数估计的基础

好了,这一章的内容就到这里。参数估计是个细活,急不来。我建议你拿到数据后,先画图看看分布,再动手跑回归。很多时候,数据里的异常值会直接把你的系数带偏。

嗯,下一章我们会聊怎么把这些参数用到实盘交易中。但今天,先把这三个系数估准了再说。


交易系统化学习资料 微信Strategy888888