跳到主内容
研究主线因子策略、对冲与尾部风险 · 第37–42讲5/6模块导览 →
讲义

第41讲:为什么要对贝塔和行业暴露进行对冲 II (Why Hedge Beta and Sector Exposures II)

从单股和组合方差分解出发设计 Beta 与行业对冲,展示权重求解、风险贡献及压力情景下的限制。

完成状态保存在当前浏览器,可随时取消。

一、风险分解基础#

1.1 单只股票的风险构成#

根据资本资产定价模型(CAPM),股票收益可分解为:

Ri=αi+βiRm+ϵiR_i = \alpha_i + \beta_i R_m + \epsilon_i

其中:

  • RiR_i 为股票i的收益

  • βi\beta_i 为股票i对市场的敏感度系数

  • RmR_m 为市场组合收益

  • ϵi\epsilon_i 为特异性收益部分

风险分解公式

(σtotal)2=(βiσm)2+σϵi2(\sigma_{total})^2 = (\beta_i \sigma_m)^2 + \sigma_{\epsilon_i}^2

其中左边为总风险的平方,右边第一项为系统性风险,第二项为非系统性风险

重要特性

  • 市场风险随β线性增长

  • 特异性风险可通过组合分散

code
def 计算股票风险(β, 市场波动率, 特异波动率):
    市场风险成分 =**2) * (市场波动率**2)
    特异风险成分 = 特异波动率**2
    总风险 = 市场风险成分 + 特异风险成分
    市场风险占比 = 市场风险成分 / 总风险
    return 总风险**0.5, 市场风险占比

# 示例:苹果公司(假设参数)
β_aapl = 1.2
市场波动率 = 0.18
特异波动率_aapl = 0.25

总风险, 市场占比 = 计算股票风险(β_aapl, 市场波动率, 特异波动率_aapl)
print(f"总风险:{总风险:.2%},市场风险占比:{市场占比:.1%}")

1.2 两股票组合分析#

考虑等权组合(w1=w2=0.5w_1=w_2=0.5):

组合风险公式

σp2=w12(β12σm2+σϵ12)+w22(β22σm2+σϵ22)+2w1w2β1β2σm2\sigma_p^2 = w_1^2(\beta_1^2\sigma_m^2 + \sigma_{\epsilon_1}^2) + w_2^2(\beta_2^2\sigma_m^2 + \sigma_{\epsilon_2}^2) + 2w_1w_2\beta_1\beta_2\sigma_m^2

其中:

  • w1w_1w2w_2 为各股票权重(均为0.5)

  • β1\beta_1β2\beta_2 为各股票的贝塔系数

  • σm2\sigma_m^2 为市场收益率方差

  • σϵ12\sigma_{\epsilon_1}^2σϵ22\sigma_{\epsilon_2}^2 为各股票的特异性风险

code
import yfinance as yf

# 获取真实市场数据示例
start = '2020-01-01'
end = '2021-01-01'
data = yf.download(['AAPL', 'MSFT'], start=start, end=end)['Close']
returns = data.pct_change().dropna()

# 计算实际β值
cov_matrix = returns.cov()
市场方差 = returns['AAPL'].var()  # 以AAPL作为市场代理
β_msft = cov_matrix.loc['AAPL', 'MSFT'] / 市场方差

练习:假设两只股票β分别为1.3和0.8,特异波动率分别为18%和22%,计算等权组合的市场风险占比。

二、风险对冲实战#

2.1 Beta对冲原理#

构造对冲组合:

w2=w1β1β2w_2 = -w_1 \frac{\beta_1}{\beta_2}
code
def 计算对冲权重(β1, β2):
    w1 = 1
    w2 = -β1 / β2
    总权重 = w1 + abs(w2)
    return w1/总权重, w2/总权重  # 标准化为100%投资

w1, w2 = 计算对冲权重(1.2, 0.9)
print(f"对冲组合权重:股票1={w1:.1%}, 股票2={w2:.1%}")

2.2 多股票组合对冲#

使用Fama-French三因子模型:

Ri=α+βmktRmkt+βSMBSMB+βHMLHML+ϵiR_i = \alpha + \beta_{mkt}R_{mkt} + \beta_{SMB}SMB + \beta_{HML}HML + \epsilon_i

其中:

  • RiR_i 为股票i的超额收益

  • α\alpha为截距项

  • βmkt\beta_{mkt}为市场因子敏感度

  • βSMB\beta_{SMB} 为规模因子敏感度

  • βHML\beta_{HML}为价值因子敏感度

  • RmktR_{mkt}为市场超额收益

  • SMBSMB 为规模因子收益

  • HMLHML 为价值因子收益

  • ϵi\epsilon_i 为残差项

对冲步骤

  1. 通过多元回归估计各因子β

  2. 构建组合使各因子β之和为0

  3. 优化权重最小化组合波动

code
from sklearn.linear_model import LinearRegression

# 示例:三因子对冲
factors = get_factor_returns()  # 假设获取因子数据
stock_returns = get_stock_returns()

model = LinearRegression()
model.fit(factors, stock_returns)
betas = model.coef_

# 构建对冲组合
def 对冲组合(betas):
    n = betas.shape[1]
    A = np.vstack([betas.T, np.ones(n)])
    b = np.zeros(betas.shape[0] + 1)
    b[-1] = 1  # 权重和为1
    weights = np.linalg.lstsq(A.T, b, rcond=None)[0]
    return weights

三、行业风险对冲#

3.1 行业分类方法#

常用分类体系:

  • GICS(11个一级行业)

  • ICB(10个行业)

  • 自定义分类

code
# 获取行业分类示例
import yfinance as yf

tickers = ['AAPL', 'MSFT', 'TSLA', 'JPM', 'XOM']
sectors = []
for t in tickers:
    info = yf.Ticker(t).info
    sectors.append(info['sector'])

3.2 行业中性组合构建#

目标:各行业权重与基准一致

code
基准行业权重 = {'科技': 0.3, '金融': 0.2, ...}  # 自定义基准

def 行业中性调整(当前权重, 行业映射):
    行业敞口 = defaultdict(float)
    for ticker, w in 当前权重.items():
        行业 = 行业映射[ticker]
        行业敞口[行业] += w

    调整因子 = {行业: 基准权重/当前敞口 for 行业 in 行业敞口}

    新权重 = {}
    for ticker in 当前权重:
        行业 = 行业映射[ticker]
        新权重[ticker] = 当前权重[ticker] * 调整因子[行业]

    return 新权重

练习:假设组合中科技股权重超配10%,金融股低配5%,如何调整至中性?

四、策略实践建议#

4.1 对冲频率选择#

频率优点缺点
日内高频风险控制精准交易成本高
每日调仓平衡成本与效果隔夜风险留存
每周调仓降低成本风险敞口累积

4.2 绩效评估指标#

  1. 信息比率:
IR=E[RpRb]σpbIR = \frac{E[R_p - R_b]}{\sigma_{p-b}}

其中:

  • E[RpRb]E[R_p - R_b] 为组合相对基准的超额收益期望

  • σpb\sigma_{p-b}为超额收益的标准差

  • 该指标用于衡量单位主动风险下的超额收益水平

  1. 最大回撤

  2. Beta暴露时序图

  3. 行业集中度

code
def 绘制风险暴露(策略收益, 基准收益):
    plt.figure(figsize=(10,4))
    plt.subplot(121)
    rolling_beta = 策略收益.rolling(60).cov(基准收益) / 基准收益.rolling(60).var()
    rolling_beta.plot(title='滚动60日Beta暴露')

    plt.subplot(122)
    sector_exposure.plot(kind='bar', title='行业暴露')
    plt.tight_layout()

五、进阶思考#

5.1 动态对冲策略#

Kalman Filter动态贝塔估计的状态方程:

βt=βt1+wt\beta_t = \beta_{t-1} + w_t

观测方程:

rt=βtrm,t+ϵtr_t = \beta_t r_{m,t} + \epsilon_t

其中:

  • βt\beta_t为t时刻的贝塔值

  • wtw_t为状态噪声项

  • rtr_t 为资产收益率

  • rm,tr_{m,t}为市场收益率

  • ϵt\epsilon_t 为观测噪声项

code
from pykalman import KalmanFilter

kf = KalmanFilter(transition_matrices=[1],
                  observation_matrices=market_returns[:, None],
                  initial_state_mean=1,
                  initial_state_covariance=1)

beta_estimates, _ = kf.filter(stock_returns)

5.2 非线性风险建模#

使用机器学习捕捉复杂风险:

code
from sklearn.ensemble import GradientBoostingRegressor

model = GradientBoostingRegressor()
model.fit(X_train[['market_return', 'sector_return', 'interest_rate']],
          stock_returns_train)
predicted_risk = model.predict(X_test)

实战练习

使用yfinance获取5只科技股数据:

  1. 计算各股过去1年的Beta值

  2. 构建市场中性组合

  3. 分析组合的行业暴露变化

  4. 比较对冲前后的夏普比率变化

提示:可从S&P500成分股中选取不同行业的股票进行测试,注意处理分红和拆股的影响。