查看全集:💎Quantopia量化分析56讲
VaR(风险价值):在给定置信水平α下,未来一段时间内投资组合可能承受的最大损失。例如α=95%的VaR为-10万元,表示未来有95%的概率损失不超过10万元。
CVaR(条件风险价值):当损失超过VaR时,这些极端损失的平均值。反映尾部风险,比VaR更能体现危机情境。
正态分布VaR计算公式:
其中:
历史模拟法VaR计算公式:
其中:
条件风险价值(CVaR)计算公式:
其中:
import numpy as np
import pandas as pd
import yfinance as yf
from scipy.stats import norm
# 生成10个正态分布的虚拟资产收益率
np.random.seed(42)
returns = np.random.normal(0.01, 0.1, (1000, 10))
returns = pd.DataFrame(returns, columns=[f'Asset_{i}' for i in range(10)])
# 生成等权重组合
weights = np.ones(10) / 10
plt.figure(figsize=(10,4))
plt.bar(range(10), weights)
plt.title('等权重投资组合分配')
plt.xlabel('资产编号')
plt.ylabel('权重比例');
def historical_var(returns, weights, alpha=0.95, value=1e6):
port_returns = returns.dot(weights)
var = np.percentile(port_returns, 100*(1-alpha)) * value
return var
print(f"95% VaR: {historical_var(returns, weights):,.2f} 元")
输出示例:95% VaR: -42,567.89 元
# 获取苹果、微软历史数据
tickers = ['AAPL', 'MSFT']
data = yf.download(tickers, start='2015-01-01', end='2020-01-01')['Close']
# 计算收益率
returns = data.pct_change().dropna()
returns.plot.hist(bins=50, alpha=0.6, figsize=(10,4))
plt.title('苹果与微软历史收益率分布');
# 生成随机权重
np.random.seed(42)
weights = np.random.random(len(tickers))
weights /= weights.sum()
# 计算滚动VaR
window = 252 # 1年交易天数
var_series = returns.rolling(window).apply(
lambda x: np.percentile(x.dot(weights), 5)*1e6)
plt.figure(figsize=(10,4))
var_series.plot()
plt.title('滚动一年期95% VaR')
plt.ylabel('风险价值(万元)');
def normal_var(mu, sigma, alpha=0.95):
return norm.ppf(1-alpha, mu, sigma)
mu = returns.mean().dot(weights)
sigma = np.sqrt(weights.T @ returns.cov() @ weights)
print(f"正态法VaR: {normal_var(mu, sigma)*1e6:,.2f} 元")
print(f"历史法VaR: {historical_var(returns, weights)*1e6:,.2f} 元")
def conditional_var(returns, weights, alpha=0.95, value=1e6):
port_returns = returns.dot(weights)
var = np.percentile(port_returns, 100*(1-alpha))
cvar = port_returns[port_returns <= var].mean() * value
return cvar
print(f"CVaR: {conditional_var(returns, weights):,.2f} 元")
# 分布对比可视化
plt.figure(figsize=(10,4))
plt.hist(returns.dot(weights), bins=50, density=True, alpha=0.6)
x = np.linspace(-0.1, 0.1, 100)
plt.plot(x, norm.pdf(x, mu, sigma), 'r-')
plt.legend(['正态分布', '实际收益'])
plt.title('收益分布对比');
提示:债券数据可使用TLT(20年以上美国国债ETF)