一、风险分解基础#
1.1 单只股票的风险构成#
根据资本资产定价模型(CAPM),股票收益可分解为:
其中:
-
为股票i的收益
-
为股票i对市场的敏感度系数
-
为市场组合收益
-
为特异性收益部分
风险分解公式:
其中左边为总风险的平方,右边第一项为系统性风险,第二项为非系统性风险
重要特性:
-
市场风险随β线性增长
-
特异性风险可通过组合分散
def 计算股票风险(β, 市场波动率, 特异波动率):
市场风险成分 = (β**2) * (市场波动率**2)
特异风险成分 = 特异波动率**2
总风险 = 市场风险成分 + 特异风险成分
市场风险占比 = 市场风险成分 / 总风险
return 总风险**0.5, 市场风险占比
# 示例:苹果公司(假设参数)
β_aapl = 1.2
市场波动率 = 0.18
特异波动率_aapl = 0.25
总风险, 市场占比 = 计算股票风险(β_aapl, 市场波动率, 特异波动率_aapl)
print(f"总风险:{总风险:.2%},市场风险占比:{市场占比:.1%}")1.2 两股票组合分析#
考虑等权组合():
组合风险公式:
其中:
-
和 为各股票权重(均为0.5)
-
和 为各股票的贝塔系数
-
为市场收益率方差
-
和 为各股票的特异性风险
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对冲原理#
构造对冲组合:
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三因子模型:
其中:
-
为股票i的超额收益
-
为截距项
-
为市场因子敏感度
-
为规模因子敏感度
-
为价值因子敏感度
-
为市场超额收益
-
为规模因子收益
-
为价值因子收益
-
为残差项
对冲步骤:
-
通过多元回归估计各因子β
-
构建组合使各因子β之和为0
-
优化权重最小化组合波动
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个行业)
-
自定义分类
# 获取行业分类示例
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 行业中性组合构建#
目标:各行业权重与基准一致
基准行业权重 = {'科技': 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 绩效评估指标#
- 信息比率:
其中:
-
为组合相对基准的超额收益期望
-
为超额收益的标准差
-
该指标用于衡量单位主动风险下的超额收益水平
-
最大回撤
-
Beta暴露时序图
-
行业集中度
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时刻的贝塔值
-
为状态噪声项
-
为资产收益率
-
为市场收益率
-
为观测噪声项
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 非线性风险建模#
使用机器学习捕捉复杂风险:
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年的Beta值
-
构建市场中性组合
-
分析组合的行业暴露变化
-
比较对冲前后的夏普比率变化
提示:可从S&P500成分股中选取不同行业的股票进行测试,注意处理分红和拆股的影响。