第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 知识体系总览

下面这张图是我自己画的,把本章的核心逻辑串起来了:

价格发现模型知识体系 价格发现 Hasbrouck IS模型 Gonzalo-Granger PT模型 核心:信息冲击的方差贡献 谁的信息冲击方差大,谁的信息份额高 核心:共同因子的权重贡献 谁对共同因子权重高,谁主导价格 共同基础:VECM模型 + 协整关系

这张图把逻辑串得很清楚:价格发现是目标,IS和PT是两种实现路径,但都离不开VECM这个基础工具。

1.6 实战中的坑与建议

最后,分享几个我在实战中踩过的坑:

  1. 数据频率要匹配:我曾经用日频数据跑IS模型,结果信息份额天天变,毫无规律。后来换成5分钟高频数据,结果就稳定了。高频数据才能捕捉到信息冲击的瞬时效应。
  2. 协整关系要检验:这是前提。没有协整关系,VECM就是错的,后面的IS和PT全是垃圾。我一般用Johansen检验,显著性水平设5%。
  3. 滞后阶数要选对:用AIC或BIC准则。我习惯用AIC,因为它对高频数据更敏感。
  4. 结果要交叉验证:IS和PT结果不一致时,别急着下结论。先检查数据质量,再考虑是不是市场结构有问题。

重要提醒:模型只是工具,不是真理。我见过有人把IS模型结果当圣旨,结果实盘亏得一塌糊涂。记住,任何模型都有假设条件,现实市场永远比模型复杂。

好了,这一章就到这里。代码可以直接复制到你的Jupyter Notebook里跑。有问题随时交流。

无相订单流研究社 微信Lucian808555