3. 模型风险识别:协整关系失效、参数估计偏差、模型过拟合与欠拟合
做价差回归交易,最怕什么?
不是行情突然反转,也不是滑点太大。我最怕的是——模型本身是错的,我还浑然不知。
模型风险,说白了就是你用一套看似完美的数学工具去抓市场规律,结果规律根本不存在,或者已经变了。我见过太多人把回测曲线做得漂漂亮亮,一上实盘就崩。嗯,今天咱们就聊聊这背后的三个核心风险点。
核心观点:模型风险是价差回归交易中最隐蔽的杀手。它不像市场风险那样直观,但一旦爆发,往往是系统性亏损。
3.1 协整关系失效:你以为的稳定,其实只是幻觉
协整,是价差回归交易的基石。两个品种的价格序列,如果存在协整关系,它们的线性组合就是平稳的。说白了,就是它们会「手拉手」一起走,走散了还会拉回来。
但问题是——协整关系是会变的。
我在2018年做过一个股指期货的配对交易。沪深300和中证500的价差,回测了3年,协整检验P值稳稳的0.01以下。结果2019年一开年,价差直接脱缰,一去不回头。后来复盘才发现,是因为市场风格切换,资金从大盘股流向小盘股,两个指数的「手」松开了。
⚠️ 协整失效的常见原因:
- 结构性变化:政策调整、行业变革、市场规则改变
- 流动性变化:某个品种的流动性骤降,导致价差扭曲
- 套利者退出:做这个配对的人少了,价差回归的动力就弱了
- 时间窗口:协整关系本身就有时效性,不是永恒的
怎么识别?我个人习惯用滚动协整检验。别只看全样本的检验结果,要定期重新跑一遍。比如每20个交易日,重新做一次Johansen检验。如果P值从0.01跳到了0.15,你就要警惕了。
# 滚动协整检验示例(Python伪代码)
import statsmodels.tsa.vector_ar.vecm as vecm
def rolling_coint_test(price1, price2, window=60):
results = []
for i in range(window, len(price1)):
sub1 = price1[i-window:i]
sub2 = price2[i-window:i]
# 做Johansen检验
result = vecm.coint_johansen(pd.concat([sub1, sub2], axis=1), 0, 1)
p_value = result.trace_stat_crit_vals[0][1] # 简化处理
results.append(p_value)
return results
💡 我的经验:协整关系失效前,往往有「预兆」。比如价差在回归区间内停留的时间越来越短,或者回归的幅度越来越小。别等到彻底脱缰才动手。
3.2 参数估计偏差:你的模型参数,可能只是「恰好」
做价差回归,免不了要估计参数。回归系数、均值回归速度、波动率……这些参数,你拿历史数据一跑就出来了。但问题是——这些参数真的稳定吗?
我见过最典型的坑:用过去3年的数据估计出回归系数β=1.2,然后直接拿来建仓。结果实盘跑了两个月,β变成了0.9。为什么?因为样本区间内恰好有一段极端行情,把系数「拉偏」了。
参数估计偏差,说白了就是你的样本不能代表总体。你想想看,如果样本里包含了一轮大牛市,那估计出来的均值回归速度肯定偏慢——因为牛市里价差确实不容易回归。
怎么解决?我建议做三件事:
- 滚动估计:别用固定样本,每期都重新估计参数。看看参数是不是稳定的。
- 敏感性分析:改变样本区间,看看参数变化大不大。如果β在0.8到1.5之间乱跳,那这个模型就别用了。
- 贝叶斯方法:给参数加个先验分布,别让极端值牵着鼻子走。
# 滚动回归系数估计
import numpy as np
from sklearn.linear_model import LinearRegression
def rolling_beta(price1, price2, window=60):
betas = []
for i in range(window, len(price1)):
x = price1[i-window:i].values.reshape(-1, 1)
y = price2[i-window:i].values
model = LinearRegression().fit(x, y)
betas.append(model.coef_[0])
return betas
# 如果betas序列的波动率超过0.3,我建议你重新审视模型
if np.std(betas) > 0.3:
print("⚠️ 参数不稳定,模型风险较高")
关键点:参数估计偏差不是「有没有」的问题,而是「有多大」的问题。你要做的是量化这个偏差,并把它纳入风控体系。
3.3 模型过拟合与欠拟合:两个极端,一样危险
过拟合和欠拟合,是机器学习里的老生常谈。但在价差回归交易里,它们有更具体的表现形式。
过拟合:你给模型加了太多「花里胡哨」的东西。比如,你发现价差回归速度跟成交量、波动率、甚至天气都有关系,于是你建了一个多因子模型。回测结果漂亮得不得了,夏普比率3.0。但一上实盘,直接变成-0.5。
为什么会这样?因为那些因子可能只是统计上的巧合。你想想看,如果你在100个因子里找,总能找到几个跟价差走势「恰好」相关的。但那是噪声,不是信号。
欠拟合:反过来,你只用了一个简单的线性回归,连滞后项都不加。结果价差的均值回归过程有明显的自相关性,你的模型根本抓不住。这种模型虽然稳健,但赚不到钱。
| 风险类型 | 表现 | 回测特征 | 实盘特征 |
|---|---|---|---|
| 过拟合 | 参数过多,因子复杂 | 夏普极高,回撤极小 | 直接崩盘,夏普转负 |
| 欠拟合 | 模型过于简单 | 夏普通常较低 | 表现稳定但收益低 |
怎么平衡?我个人习惯用交叉验证。把数据分成训练集和验证集,在训练集上调参数,在验证集上看效果。如果训练集上表现很好,验证集上一塌糊涂,那就是过拟合了。
💡 避坑指南:我曾经做过一个模型,加入了12个因子,回测夏普2.8。我总觉得哪里不对,就做了个简单的「随机化检验」——把价差序列打乱,再用同样的模型去跑。结果夏普还有2.0。这说明什么?模型根本就是在拟合噪声。从那以后,我每个模型都要过这一关。
3.4 知识体系总览
下面这张图,是我自己梳理的模型风险识别框架。你可以把它当成一个检查清单,每次建模型前都过一遍。
这张图的核心逻辑很简单:三大风险不是孤立的。协整关系失效会导致参数估计偏差,参数估计偏差又会加剧过拟合。所以,你不能只盯着一个点看,要系统性地审视整个模型。
⚠️ 最后提醒一句:模型风险识别不是一次性工作。市场在变,你的模型也要跟着变。我每个月都会重新审视一遍自己的模型,看看协整关系还在不在,参数有没有漂移,回测和实盘的差距大不大。这活儿不轻松,但值得。
公众号:蓝海资料掘金营,微信deep3321