第1章:价格发现模型(一)——Hasbrouck信息份额模型(IS)、永久-暂时模型(PT)
各位好,我是老张。今天咱们聊聊价格发现模型。说实话,这玩意儿我当年刚入行时也头疼过一阵子。后来在实盘项目中踩过坑、翻过车,才慢慢摸透了门道。今天我把这些经验掰开揉碎了讲给你听。
1.1 什么是价格发现?
价格发现,说白了就是市场怎么把信息变成价格的过程。你想想看,同一只股票在A股和港股同时交易,为什么两边价格不一样?哪个价格更「真实」?这就是价格发现要回答的问题。
我个人习惯把价格发现理解成「信息竞赛」——不同市场、不同交易者都在往价格里塞信息,谁塞得快、塞得准,谁就主导了价格走向。
核心观点:价格发现不是看价格涨跌,而是看价格如何吸收新信息。
1.2 Hasbrouck信息份额模型(IS)
Hasbrouck在1995年提出了这个模型。我记得第一次读他的论文时,被里面的数学推导绕得晕头转向。后来在实盘项目中用Python跑了一遍,才恍然大悟——原来就这么回事。
1.2.1 模型思想
IS模型的核心假设是:所有价格序列背后有一个共同的「隐含有效价格」。这个有效价格是随机游走的,而各个市场的观测价格,就是在这个有效价格基础上加上一些暂时性噪音。
用数学语言说:
p_t = m_t + s_t
其中:
p_t是观测价格向量(比如沪深300在A股和港股的价差)m_t是隐含有效价格(随机游走)s_t是暂时性成分(平稳过程)
嗯,这里要注意:有效价格的变化来自新信息冲击。谁的信息冲击贡献大,谁的信息份额就高。
1.2.2 模型推导
推导过程其实不复杂。我们先把价格序列写成向量误差修正模型(VECM):
Δp_t = αβ'p_{t-1} + Σ_{i=1}^{k} Γ_i Δp_{t-i} + ε_t
然后,Hasbrouck把误差修正项分解成信息份额。具体来说,他把协方差矩阵做Cholesky分解:
Ω = MM'
其中M是下三角矩阵。那么第j个市场的信息份额就是:
IS_j = ( [ψM]_j^2 ) / ( ψΩψ' )
这里ψ是永久冲击向量。说白了,就是看每个市场的冲击在总冲击里占多大比例。
实战技巧:我在项目中遇到过Cholesky分解对变量顺序敏感的问题。建议你多换几种顺序跑一遍,取平均值作为最终结果。这样更稳健。
1.2.3 Python实现
下面是我常用的实现代码。注意,这里用了statsmodels做VECM估计:
import numpy as np
import pandas as pd
from statsmodels.tsa.vector_ar.vecm import VECM
def hasbrouck_is(prices, k=1):
"""
计算Hasbrouck信息份额
prices: DataFrame, 列是不同市场的价格序列
k: 滞后阶数
"""
# 估计VECM
vecm = VECM(prices, k_ar_diff=k, coint_rank=1)
vecm_fit = vecm.fit()
# 提取永久冲击向量
alpha = vecm_fit.alpha
beta = vecm_fit.beta
psi = beta.T @ np.linalg.inv(alpha.T @ beta) @ alpha.T
# 残差协方差矩阵
resid = vecm_fit.resid
Omega = np.cov(resid, rowvar=False)
# Cholesky分解
M = np.linalg.cholesky(Omega)
# 计算信息份额
psi_M = psi @ M
total_var = psi @ Omega @ psi.T
IS = (psi_M ** 2) / total_var
return IS.flatten()
# 示例使用
# prices = pd.DataFrame({'A股': p_a, '港股': p_h})
# is_values = hasbrouck_is(prices)
# print(f"A股信息份额: {is_values[0]:.2%}")
避坑指南:我曾经因为没检查协整关系,直接跑VECM,结果出来的信息份额全是NaN。后来才意识到,必须先做Johansen检验确认协整阶数。这是新手最容易犯的错误。
1.3 永久-暂时模型(PT)
PT模型是Gonzalo和Granger在1995年提出的。和IS模型不同,PT模型关注的是「谁在驱动共同因子」,而不是「谁的信息贡献大」。
1.3.1 模型思想
PT模型把价格分解成两部分:
- 永久成分(Permanent): 共同因子,随机游走
- 暂时成分(Transitory): 偏离共同因子的部分,均值回归
你想想看,如果A股价格涨了1%,港股只涨了0.5%,那这0.5%的差异就是暂时成分,迟早要回归。
1.3.2 模型推导
PT模型的推导更直观。从VECM出发:
Δp_t = αβ'p_{t-1} + 滞后项 + ε_t
永久成分的权重向量由α的正交补决定:
α_⊥ = null(α')
那么共同因子就是:
f_t = α_⊥' p_t
每个市场对共同因子的贡献,就是α_⊥中对应元素的平方占比。
关键区别:IS模型看的是「信息冲击的方差贡献」,PT模型看的是「对共同因子的权重贡献」。两者角度不同,结果也可能不同。
1.3.3 Python实现
def gonzalo_pt(prices, k=1):
"""
计算Gonzalo-Granger永久-暂时模型
"""
vecm = VECM(prices, k_ar_diff=k, coint_rank=1)
vecm_fit = vecm.fit()
alpha = vecm_fit.alpha
# 计算α的正交补
# 使用SVD分解
U, S, Vt = np.linalg.svd(alpha.T)
alpha_perp = Vt[-1, :] # 取最后一个右奇异向量
# 计算贡献度
contributions = alpha_perp ** 2 / np.sum(alpha_perp ** 2)
return contributions
# 示例
# pt_values = gonzalo_pt(prices)
# print(f"A股对共同因子贡献: {pt_values[0]:.2%}")
1.4 IS模型 vs PT模型:怎么选?
这个问题我经常被问到。我的建议是:
| 场景 | 推荐模型 | 原因 |
|---|---|---|
| 你想知道哪个市场最先反映信息 | IS模型 | 它直接度量信息冲击的方差贡献 |
| 你想知道哪个市场主导价格走势 | PT模型 | 它度量对共同因子的权重 |
| 市场噪音很大 | PT模型 | 对噪音更稳健一些 |
| 你想做高频交易策略 | IS模型 | 能捕捉微观结构信息 |
我的习惯:两个模型都跑一遍。如果结果一致,那结论很可靠。如果不一致,反而值得深挖——说明市场结构有问题。
1.5 知识体系总览
下面这张图是我自己画的,把本章的核心逻辑串起来了:
这张图把逻辑串得很清楚:价格发现是目标,IS和PT是两种实现路径,但都离不开VECM这个基础工具。
1.6 实战中的坑与建议
最后,分享几个我在实战中踩过的坑:
- 数据频率要匹配:我曾经用日频数据跑IS模型,结果信息份额天天变,毫无规律。后来换成5分钟高频数据,结果就稳定了。高频数据才能捕捉到信息冲击的瞬时效应。
- 协整关系要检验:这是前提。没有协整关系,VECM就是错的,后面的IS和PT全是垃圾。我一般用Johansen检验,显著性水平设5%。
- 滞后阶数要选对:用AIC或BIC准则。我习惯用AIC,因为它对高频数据更敏感。
- 结果要交叉验证:IS和PT结果不一致时,别急着下结论。先检查数据质量,再考虑是不是市场结构有问题。
重要提醒:模型只是工具,不是真理。我见过有人把IS模型结果当圣旨,结果实盘亏得一塌糊涂。记住,任何模型都有假设条件,现实市场永远比模型复杂。
好了,这一章就到这里。代码可以直接复制到你的Jupyter Notebook里跑。有问题随时交流。