风险管理是投资组合管理的核心。本文将介绍几种常用的风险指标及其 Python 实现。
常用风险指标概览
| 指标 | 含义 | 用途 |
|---|---|---|
| 波动率 | 收益率标准差 | 衡量价格波动程度 |
| VaR | 在险价值 | 估计潜在最大损失 |
| CVaR | 条件在险价值 | VaR 的改进版本 |
| 夏普比率 | 风险调整后收益 | 评估策略表现 |
| 最大回撤 | 历史最大损失 | 衡量极端风险 |
1. 波动率计算
历史波动率
import pandas as pd
import numpy as np
def calculate_volatility(returns, window=20, annualize=True):
volatility = returns.rolling(window=window).std()
if annualize:
volatility = volatility * np.sqrt(252)
return volatility
returns = df['close'].pct_change()
vol = calculate_volatility(returns, window=20)
print(f"当前波动率: {vol.iloc[-1]:.2%}")
EWMA 波动率
def ewma_volatility(returns, lambda_param=0.94):
variance = returns.var()
ewma_var = [variance]
for ret in returns[1:]:
variance = lambda_param * variance + (1 - lambda_param) * ret**2
ewma_var.append(variance)
ewma_vol = np.sqrt(np.array(ewma_var) * 252)
return ewma_vol
2. VaR (Value at Risk)
历史模拟法
def historical_var(returns, confidence_level=0.95):
var = np.percentile(returns, (1 - confidence_level) * 100)
return abs(var)
var_95 = historical_var(returns, 0.95)
print(f"95% VaR: {var_95:.2%}")
print(f"含义: 95%置信度下,单日最大损失不超过 {var_95:.2%}")
参数法(正态分布假设)
def parametric_var(returns, confidence_level=0.95):
from scipy import stats
mean = returns.mean()
std = returns.std()
z_score = stats.norm.ppf(1 - confidence_level)
var = -(mean + z_score * std)
return var
var_95_parametric = parametric_var(returns, 0.95)
print(f"95% VaR (参数法): {var_95_parametric:.2%}")
蒙特卡洛模拟法
def monte_carlo_var(returns, confidence_level=0.95, n_simulations=10000):
mean = returns.mean()
std = returns.std()
simulated_returns = np.random.normal(mean, std, n_simulations)
var = np.percentile(simulated_returns, (1 - confidence_level) * 100)
return abs(var)
3. CVaR (Conditional VaR)
def calculate_cvar(returns, confidence_level=0.95):
var = historical_var(returns, confidence_level)
tail_losses = returns[returns <= -var]
cvar = abs(tail_losses.mean())
return cvar
cvar_95 = calculate_cvar(returns, 0.95)
print(f"95% CVaR: {cvar_95:.2%}")
print(f"含义: 在最坏的 5% 情况下,平均损失为 {cvar_95:.2%}")
4. 夏普比率
def sharpe_ratio(returns, risk_free_rate=0.03, periods=252):
excess_returns = returns - risk_free_rate / periods
sharpe = excess_returns.mean() / excess_returns.std() * np.sqrt(periods)
return sharpe
sr = sharpe_ratio(returns)
print(f"夏普比率: {sr:.2f}")
5. 索提诺比率
def sortino_ratio(returns, risk_free_rate=0.03, periods=252):
excess_returns = returns - risk_free_rate / periods
downside_returns = excess_returns[excess_returns < 0]
downside_std = downside_returns.std()
sortino = excess_returns.mean() / downside_std * np.sqrt(periods)
return sortino
6. 最大回撤
def maximum_drawdown(returns):
cumulative = (1 + returns).cumprod()
running_max = cumulative.expanding().max()
drawdown = (cumulative - running_max) / running_max
max_dd = drawdown.min()
max_dd_date = drawdown.idxmin()
peak_date = cumulative[:max_dd_date].idxmax()
recovery_date = None
if cumulative[max_dd_date:].max() >= cumulative[peak_date]:
recovery_date = cumulative[max_dd_date:][
cumulative[max_dd_date:] >= cumulative[peak_date]
].index[0]
return {
'最大回撤': max_dd,
'高点日期': peak_date,
'最大回撤日期': max_dd_date,
'恢复日期': recovery_date,
'回撤持续天数': (max_dd_date - peak_date).days if recovery_date is None
else (recovery_date - peak_date).days
}
mdd_info = maximum_drawdown(returns)
print(f"最大回撤: {mdd_info['最大回撤']:.2%}")
print(f"回撤持续: {mdd_info['回撤持续天数']} 天")
7. 卡玛比率
def calmar_ratio(returns, periods=252):
annual_return = returns.mean() * periods
max_dd = abs(maximum_drawdown(returns)['最大回撤'])
calmar = annual_return / max_dd
return calmar
8. 综合风险报告
def risk_report(returns, initial_capital=100000):
print("=" * 60)
print("风险分析报告")
print("=" * 60)
print(f"\n【基础统计】")
print(f"样本数量: {len(returns)}")
print(f"平均日收益率: {returns.mean():.4%}")
print(f"年化收益率: {returns.mean() * 252:.2%}")
print(f"收益率标准差: {returns.std():.4%}")
print(f"年化波动率: {returns.std() * np.sqrt(252):.2%}")
print(f"\n【在险价值】")
var_95 = historical_var(returns, 0.95)
var_99 = historical_var(returns, 0.99)
cvar_95 = calculate_cvar(returns, 0.95)
cvar_99 = calculate_cvar(returns, 0.99)
print(f"95% VaR: {var_95:.2%} (约 ${initial_capital * var_95:,.0f})")
print(f"99% VaR: {var_99:.2%} (约 ${initial_capital * var_99:,.0f})")
print(f"95% CVaR: {cvar_95:.2%} (约 ${initial_capital * cvar_95:,.0f})")
print(f"99% CVaR: {cvar_99:.2%} (约 ${initial_capital * cvar_99:,.0f})")
print(f"\n【风险调整收益】")
sr = sharpe_ratio(returns)
sortino = sortino_ratio(returns)
calmar = calmar_ratio(returns)
print(f"夏普比率: {sr:.2f}")
print(f"索提诺比率: {sortino:.2f}")
print(f"卡玛比率: {calmar:.2f}")
print(f"\n【回撤分析】")
mdd_info = maximum_drawdown(returns)
print(f"最大回撤: {mdd_info['最大回撤']:.2%}")
print(f"高点日期: {mdd_info['高点日期'].strftime('%Y-%m-%d')}")
print(f"最大回撤日期: {mdd_info['最大回撤日期'].strftime('%Y-%m-%d')}")
print(f"持续天数: {mdd_info['回撤持续天数']} 天")
print(f"\n【交易统计】")
win_rate = len(returns[returns > 0]) / len(returns[returns != 0])
avg_win = returns[returns > 0].mean() if len(returns[returns > 0]) > 0 else 0
avg_loss = returns[returns < 0].mean() if len(returns[returns < 0]) > 0 else 0
print(f"胜率: {win_rate:.2%}")
print(f"平均盈利: {avg_win:.2%}")
print(f"平均亏损: {avg_loss:.2%}")
print(f"盈亏比: {abs(avg_win / avg_loss):.2f}" if avg_loss != 0 else "N/A")
print("=" * 60)
risk_report(returns, initial_capital=100000)
实战建议
-
选择合适的风险指标
- VaR:监管要求、风险预算
- 夏普比率:策略比较
- 最大回撤:客户沟通
-
注意指标局限性
- VaR 无法捕捉极端风险
- 夏普比率假设正态分布
- 历史数据不代表未来
-
多指标综合评估
- 不要依赖单一指标
- 结合定量和定性分析
- 考虑市场环境变化
-
定期更新计算
- 设置监控预警
- 滚动窗口计算
- 压力测试
总结
本文介绍了金融风险管理中的核心指标:
- 波动率:衡量市场风险
- VaR/CVaR:量化潜在损失
- 风险调整收益指标:评估策略质量
- 回撤分析:了解极端情况
掌握这些工具可以帮助你更好地理解和管理投资风险。
下一篇将介绍如何构建风险管理系统的实时监控面板。