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

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

逐步比较未对冲、市场 Beta 对冲和行业对冲后的残差相关性,并用有效广度刻画相关结构变化。

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

数据准备与工具:

code
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import yfinance as yf
from sklearn.covariance import LedoitWolf
import seaborn as sns
import statsmodels.api as sm

# 数据获取函数
def get_stock_data(tickers, start, end):
    data = yf.download(tickers, start=start, end=end)
    return data['Close']  # 仅使用收盘价

一、系统性风险与对冲的必要性#

在构建交易策略时,系统性风险是需要重点管理的对象。这类风险无法通过分散投资消除,需要通过构建对冲来降低影响。本文将通过三个逐步优化的案例,展示如何通过Beta对冲和行业对冲来降低资产间的相关性,提升策略的有效性。

关键概念:

  • Beta系数:衡量资产对市场波动的敏感度

  • 残差收益:资产收益中无法被市场或行业因素解释的部分 计算公式: 市场对冲残差 = 资产收益 - Beta * 市场收益 行业对冲残差 = 市场残差 - 行业Beta * 行业收益

二、对冲策略案例#

2.1 案例1:无对冲策略#

  1. 获取股票历史数据

  2. 计算收益率

  3. 分析相关性

code
tickers = ['WFC', 'JPM', 'USB', 'XOM', 'BHI', 'SLB']
start = '2015-01-01'
end = '2017-02-22'

# 获取数据
prices = get_stock_data(tickers, start, end)
returns = prices.pct_change().dropna()

# 计算协方差矩阵
lw = LedoitWolf().fit(returns)
cov_matrix = lw.covariance_

# 转换为相关系数
def cov_to_corr(cov):
    d = np.sqrt(np.diag(cov))
    return cov / np.outer(d, d)

corr_matrix = cov_to_corr(cov_matrix)

# 可视化
plt.figure(figsize=(12,6))
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm',
            xticklabels=tickers, yticklabels=tickers)
plt.title('无对冲策略相关系数矩阵(平均相关系数:0.56)')

现象观察:金融股(WFC、JPM、USB)与能源股(XOM、BHI、SLB)形成明显聚类,组内相关性高达0.7-0.8

2.2 案例2:Beta对冲策略#

  1. 加入市场基准(SPY)

  2. 对每只股票进行市场回归

  3. 提取残差收益

code
tickers += ['SPY']
prices = get_stock_data(tickers, start, end)
returns = prices.pct_change().dropna()

# 分离市场收益
market_returns = returns['SPY']
stock_returns = returns.drop('SPY', axis=1)

# 计算市场Beta残差
residuals = pd.DataFrame()
for stock in stock_returns:
    model = sm.OLS(stock_returns[stock], sm.add_constant(market_returns))
    results = model.fit()
    residuals[stock] = results.resid

# 计算对冲后相关系数
lw = LedoitWolf().fit(residuals)
corr_matrix_beta = cov_to_corr(lw.covariance_)

# 可视化对比
fig, axes = plt.subplots(1,2, figsize=(16,6))
sns.heatmap(corr_matrix, ax=axes[0], cmap='coolwarm',
           annot=True, vmin=-1, vmax=1)
sns.heatmap(corr_matrix_beta, ax=axes[1], cmap='coolwarm',
           annot=True, vmin=-1, vmax=1)

关键改进

  • 平均相关系数从0.56降至0.22

  • 跨行业相关性显著降低(如金融与能源股相关性降至0.1-0.3)

2.3 案例3:行业对冲策略#

  1. 加入行业ETF(XLF金融/XLE能源)

  2. 分行业进行二次对冲

code
sector_etf = {'金融': 'XLF', '能源': 'XLE'}
tickers = ['WFC', 'JPM', 'USB', 'XOM', 'BHI', 'SLB', 'SPY', 'XLF', 'XLE']

prices = get_stock_data(tickers, start, end)
returns = prices.pct_change().dropna()

# 市场对冲
market_ret = returns['SPY']
sector_rets = {
    '金融': returns['XLF'] - market_ret * sm.OLS(returns['XLF'], sm.add_constant(market_ret)).fit().params[1],
    '能源': returns['XLE'] - market_ret * sm.OLS(returns['XLE'], sm.add_constant(market_ret)).fit().params[1]
}

# 分行业二次对冲
final_residuals = pd.DataFrame()
for sector in ['金融', '能源']:
    sector_stocks = ['WFC','JPM','USB'] if sector == '金融' else ['XOM','BHI','SLB']
    sector_ret = sector_rets[sector]

    for stock in sector_stocks:
        # 市场对冲
        model_mkt = sm.OLS(returns[stock], sm.add_constant(market_ret))
        res_mkt = model_mkt.fit().resid

        # 行业对冲
        model_sector = sm.OLS(res_mkt, sm.add_constant(sector_ret))
        final_residuals[stock] = model_sector.fit().resid

# 计算最终相关系数
lw = LedoitWolf().fit(final_residuals)
corr_matrix_full_hedge = cov_to_corr(lw.covariance_)

效果呈现

  • 金融组内部相关性降至0.05以下

  • 跨行业相关性接近零

  • 平均相关系数降至0.028

三、有效广度计算#

Buckle公式

N1+ρ(N1)\frac{N}{1 + \rho(N-1)}

其中N为资产数量,ρ为平均相关系数

code
def effective_breadth(N, rho):
    return N / (1 + rho*(N-1))

cases = [
    ('无对冲', 0.56),
    ('Beta对冲', 0.22),
    ('行业对冲', 0.028)
]

plt.figure(figsize=(10,6))
x = np.linspace(0, 1, 100)
for label, rho in cases:
    plt.plot(x, effective_breadth(6, x),
             label=f'{label} (实际ρ={rho})' if label else None)
plt.legend()
plt.title('不同对冲策略的有效广度对比')
plt.xlabel('平均相关系数ρ')
plt.ylabel('有效广度BR');

结论

  1. 无对冲:BR ≈ 2

  2. Beta对冲:BR ≈ 3.2

  3. 全对冲:BR ≈ 5.8

小练习#

  1. 尝试使用不同行业组合(如科技+医疗)复现对冲过程

  2. 修改Buckle公式计算函数,验证当ρ=0时BR=N

  3. 计算苹果(AAPL)与微软(MSFT)在不同对冲阶段的相关性变化

code
# 练习参考答案
# 1. 更换行业ETF代码为XLK(科技)和XLV(医疗)
# 2. 验证函数:
assert np.isclose(effective_breadth(10, 0), 10)
# 3. 苹果微软对冲分析:
tickers = ['AAPL', 'MSFT', 'SPY', 'XLK']
# ...重复上述对冲步骤...

下节预告#

在(下)篇中,我们将深入探讨:

  • 多因子风险模型的应用

  • 动态对冲策略的构建

  • 实盘交易中的对冲成本优化

通过本教程,我们验证了系统性风险对冲对提升策略有效性的重要作用。在实际操作中,建议在策略研发初期就纳入风险管理模块,而非事后补救。有效降低资产间相关性可以显著提升策略的夏普比率,为获取alpha收益创造更有利的条件。