第 7 章 · 01 市场隐含收益


文档摘要

第 7 章 · 01 市场隐含收益 本节摘要:均值-方差优化的输入是「期望收益向量 μ」,而历史均值估计噪声极大、对样本极度敏感,稍有调整权重就剧烈变化。Black-Litterman 模型的第一块基石是「先验(prior)」:用市场当前市值反推出「市场自身隐含的收益预期」——市场是个庞大的加权 consensus,它的定价本身就包含了对未来收益的最佳猜测。本节讲清 PyPortfolioOpt 里的两个工具函数: (从市值 + 协方差 + 风险厌恶推隐含收益 Π = δΣw)和 (从市场指数价推 δ)。读完本节,你能从一组市值和协方差算出市场隐含的先验收益。 内容来源:原项目源码 、文档 ,汉化并套用体系化模板。 学习目标 阅读完本节,你应当能够: 说清为什么历史均值收益不是好的先验。

第 7 章 · 01 市场隐含收益

本节摘要:均值-方差优化的输入是「期望收益向量 μ」,而历史均值估计噪声极大、对样本极度敏感,稍有调整权重就剧烈变化。Black-Litterman 模型的第一块基石是「先验(prior)」:用市场当前市值反推出「市场自身隐含的收益预期」——市场是个庞大的加权 consensus,它的定价本身就包含了对未来收益的最佳猜测。本节讲清 PyPortfolioOpt 里的两个工具函数:market_implied_prior_returns(从市值 + 协方差 + 风险厌恶推隐含收益 Π = δΣw)和 market_implied_risk_aversion(从市场指数价推 δ)。读完本节,你能从一组市值和协方差算出市场隐含的先验收益。

内容来源:原项目源码 pypfopt/black_litterman.py、文档 docs/BlackLitterman.rst,汉化并套用体系化模板。

学习目标

阅读完本节,你应当能够:

  1. 说清为什么历史均值收益不是好的先验。
  2. market_implied_risk_aversion 从市场指数价推 δ。
  3. market_implied_prior_returns 从市值推隐含收益 Π。
  4. 解释 Π = δΣw_mkt 公式的金融含义。
  5. 知道市值权重 w_mkt 是怎么从市值归一化得到的。

一、为什么需要市场隐含收益:历史估计的痛

均值-方差优化的痛点集中在「期望收益」这一输入:

  • 历史均值噪声大:几年的日数据算出的年化均值,标准差可能比均值本身还大。
  • 对样本极敏感:多加半年数据,权重可能完全翻转。
  • 未考虑市场 consensus:历史忽略了「市场当前已经定价」的信息。

Black-Litterman 的洞见是:与其从噪声历史猜,不如从市场当前定价反推。市场本身就是无数投资者交易出的加权 consensus,市值大的资产就是市场集体认为「该重仓」的资产。把这个共识解析出来,就是先验。

💡 核心心法:市场是个大算盘——成千上万投资者用真金白银定价出来的市值权重,本身就隐含了对未来收益的预期。把这个预期反解出来,比硬算历史均值靠谱得多。

二、风险厌恶系数 δ:market_implied_risk_aversion

要算隐含收益,先估「市场风险厌恶系数 δ」。源码定义:

δ = (R_market - R_f) / σ²_market

即市场超额收益除以市场方差。源码 market_implied_risk_aversion:

def market_implied_risk_aversion(market_prices, frequency=252, risk_free_rate=0.0): if not isinstance(market_prices, (pd.Series, pd.DataFrame)): raise TypeError("Please format market_prices as a pd.Series") market_prices = market_prices.squeeze() rets = market_prices.pct_change().dropna() r = rets.mean() * frequency # 年化收益 var = rets.var() * frequency # 年化方差 return (r - risk_free_rate) / var

用法很直接,通常用 SPY(标普 500 ETF)作为市场代理:

from pypfopt import black_litterman market_prices = ... # pd.Series,如 yfinance 拉 SPY 收盘价 delta = black_litterman.market_implied_risk_aversion(market_prices) # 典型值 2 ~ 4,比如 2.5

⚠️ 频率对齐:frequency=252 默认按日线年化。如果你的 market_prices 是月线,要改 frequency=12,否则 δ 会差一个数量级。

δ 的金融含义是「投资者每承受一单位方差,要求多少超额收益补偿」。比如 δ=2.5,意味着「方差增加 1%,要求超额收益增加 2.5%」。这就是市场的「风险价格」。

三、市值权重 w_mkt 与 Π = δΣw_mkt

给定 δ、协方差 Σ、市值 mcaps,可以反推每个资产的隐含收益。核心公式:

Π = δΣw_mkt

其中 w_mkt 是市值归一化的权重。源码:

def market_implied_prior_returns(market_caps, risk_aversion, cov_matrix, risk_free_rate=0.0): mcaps = pd.Series(market_caps) mkt_weights = mcaps / mcaps.sum() # 归一化市值权重 return risk_aversion * cov_matrix.dot(mkt_weights) + risk_free_rate

逻辑解读:

  1. w_mkt = mcaps / Σmcaps:每个资产市值占总市值的比例。
  2. Σ·w_mkt:每个资产对市场组合风险的边际贡献。
  3. δ·(Σ·w_mkt):每个资产按市场风险价格 δ 应得的风险补偿——这就是隐含超额收益。
  4. 加上无风险利率,得到完整隐含收益。

💡 公式背后的直觉:如果 AAPL 市值占市场 5%,它在市场组合里贡献的风险是 Σ·w_aapl;按市场风险价格 δ 定价,这些风险「应该」换来 δ·Σ·w_aapl 的超额收益。这就是「从市场反推」的全部魔法。

四、完整示例:推一组隐含先验

import pandas as pd from pypfopt import black_litterman, risk_models # 假设已有: # prices: 资产价格 DataFrame,列是 ticker # market_prices: 市场指数(SP500/SPY)价格 Series # mcaps: 市值字典 {"AAPL": 2.7e12, "MSFT": 2.5e12, ...} S = risk_models.CovarianceShrinkage(prices).ledoit_wolf() delta = black_litterman.market_implied_risk_aversion(market_prices) prior = black_litterman.market_implied_prior_returns(mcaps, delta, S) print(f"风险厌恶 δ = {delta:.2f}") print(prior) # AAPL 0.10 # MSFT 0.12 # XOM 0.05 # ...

⚠️ 协方差必须对齐:cov_matrix 的列/索引要与 mcaps 的键一致。如果 cov_matrix 不是 DataFrame,源码会发警告:If cov_matrix is not a dataframe, market cap index must be aligned to cov_matrix。建议始终用 DataFrame。

五、市值数据怎么来

mcaps 是个 {ticker: 市值} 字典。常见来源:

  • yfinance:yf.Ticker(t).info["marketCap"](cookbook 4 的做法)。
  • 公开 API:FMP、Alpha Vantage、Financial Modeling Prep。
  • 静态数据:手动填(适合教学)。

cookbook 4 的写法:

mcaps = {} for t in tickers: mcaps[t] = yf.Ticker(t).info["marketCap"]

⚠️ 市值要同步:市值是「当下快照」,不同日期拉的市值可能差异巨大(尤其经过拆股、并购)。批量拉取时尽量用同一天的快照,避免不一致污染 w_mkt。

六、与历史均值的对比

输入来源 优点 缺点
历史均值 简单、纯数据驱动 噪声大、对样本敏感、忽略 consensus
市场隐含(先验) 稳定、含市场共识、直觉清晰 依赖市值的准确性、依赖 δ 估计

历史均值不是不能用,但 Black-Litterman 把它降级为「可选的先验之一」——你可以 pi= 喂历史均值或等权先验,但市场隐含是默认推荐

# 等权先验(每个资产相同) bl = BlackLittermanModel(S, pi="equal", absolute_views=viewdict) # 历史均值作先验 bl = BlackLittermanModel(S, pi=mu_historical, absolute_views=viewdict) # 市场隐含(默认推荐) bl = BlackLittermanModel(S, pi="market", market_caps=mcaps, absolute_views=viewdict)

本节要点回顾

  1. 历史均值是糟糕的先验:噪声大、对样本敏感、忽略市场共识。
  2. market_implied_risk_aversionδ=(R-R_f)/σ² 从市场指数价算风险厌恶,典型值 2~4,默认 frequency=252。
  3. market_implied_prior_returnsΠ=δΣw_mkt+R_f 从市值反推隐含收益,w_mkt 是市值归一化。
  4. 公式直觉:每个资产按「风险贡献 × 市场风险价格」获得的风险补偿,就是市场对未来收益的预期。
  5. 数据要求:协方差必须与 mcaps 对齐(用 DataFrame);mcaps 尽量是同日快照。
  6. 先验的灵活性:pi= 可以是 array / Series / "market" / "equal" / None,市场隐含是默认推荐。

下一节,我们引入主观观点——把「你对 AAPL 涨 20% 的判断」融合进先验,得到贝叶斯后验。


发布者: 作者: 灏天文库 转发
评论区 (0)
U