查看全集:💎Quantopia量化分析56讲
根据资本资产定价模型(CAPM),股票收益可分解为:
其中:
风险分解公式:
其中左边为总风险的平方,右边第一项为系统性风险,第二项为非系统性风险
重要特性:
def 计算股票风险(β, 市场波动率, 特异波动率):
市场风险成分 = (β**2) * (市场波动率**2)
特异风险成分 = 特异波动率**2
总风险 = 市场风险成分 + 特异风险成分
市场风险占比 = 市场风险成分 / 总风险
return 总风险**0.5, 市场风险占比
# 示例:苹果公司(假设参数)
β_aapl = 1.2
市场波动率 = 0.18
特异波动率_aapl = 0.25
总风险, 市场占比 = 计算股票风险(β_aapl, 市场波动率, 特异波动率_aapl)
print(f"总风险:{总风险:.2%},市场风险占比:{市场占比:.1%}")
考虑等权组合():
组合风险公式:
其中:
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%,计算等权组合的市场风险占比。
构造对冲组合:
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%}")
使用Fama-French三因子模型:
其中:
对冲步骤:
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
常用分类体系:
# 获取行业分类示例
import yfinance as yf
tickers = ['AAPL', 'MSFT', 'TSLA', 'JPM', 'XOM']
sectors = []
for t in tickers:
info = yf.Ticker(t).info
sectors.append(info['sector'])
目标:各行业权重与基准一致
基准行业权重 = {'科技': 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%,如何调整至中性?
频率 | 优点 | 缺点 |
日内高频 | 风险控制精准 | 交易成本高 |
每日调仓 | 平衡成本与效果 | 隔夜风险留存 |
每周调仓 | 降低成本 | 风险敞口累积 |
其中:
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()
Kalman Filter动态贝塔估计的状态方程:
观测方程:
其中:
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)
使用机器学习捕捉复杂风险:
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只科技股数据:
提示:可从S&P500成分股中选取不同行业的股票进行测试,注意处理分红和拆股的影响。