3. 风险指标详解:波动率、下行波动率、VaR、CVaR、最大回撤期
风险度量,是因子投资的「刹车系统」。
很多人只看收益,觉得年化30%就是好策略。我见过太多这样的案例了——回测曲线漂亮得像教科书,实盘三个月就扛不住。为什么?因为风险指标没算明白。
这一章,我们把这五个核心指标掰开揉碎。波动率、下行波动率、VaR、CVaR、最大回撤期。每个我都会讲清楚:怎么算、怎么用、坑在哪。
核心观点: 风险不是波动本身,而是你无法承受的波动。
3.1 波动率:最基础的「心跳监测」
波动率,说白了就是收益率的「标准差」。它告诉你策略每天的涨跌幅度有多大。
计算公式:
σ = sqrt( Σ(ri - r̄)² / (n-1) )
其中 ri 是每日收益率,r̄ 是平均收益率,n 是样本数。
我个人习惯用年化波动率。日波动率乘以 sqrt(252) 就行。为什么是252?因为A股一年大概252个交易日。
我的经验: 年化波动率在15%-25%之间,算是比较舒服的区间。低于10%说明策略太保守,高于30%就要小心了——你晚上可能睡不着觉。
举个例子。两个策略,年化收益都是20%。策略A波动率15%,策略B波动率35%。你选哪个?
我选A。因为B可能在某个月亏掉20%,然后你心态崩了,割肉离场。收益再高,拿不住也是白搭。
3.2 下行波动率:只关心「坏」的波动
波动率有个问题——它把上涨和下跌一视同仁。但作为投资者,我们其实不介意上涨波动。跌的时候才难受。
下行波动率就是专门看「坏波动」的指标。
计算公式:
σ_down = sqrt( Σ(min(ri - rf, 0))² / (n-1) )
rf 是目标收益率,通常设为0或者无风险利率。
嗯,这里要注意。下行波动率只取低于目标的部分。如果某天赚了5%,它不参与计算。如果亏了3%,它就算进去。
关键区别: 波动率惩罚「涨跌都罚」,下行波动率只罚「跌」。这更符合实际投资心理。
我在项目中遇到过这样的情况:一个高频策略,波动率看着挺高,但下行波动率很低。为什么?因为它大部分波动来自上涨,下跌时反而很稳。这种策略,其实比表面看起来更安全。
3.3 VaR:在险价值,问「最坏能亏多少」
VaR,Value at Risk。翻译过来就是「在险价值」。它回答一个问题:在95%(或99%)的置信水平下,最大可能亏损是多少?
计算方法有三种:
- 参数法: 假设收益率服从正态分布,直接用均值和标准差算。简单,但假设太强。
- 历史模拟法: 直接取历史收益率的分位数。比如95% VaR,就是取倒数第5%的收益率。
- 蒙特卡洛法: 模拟大量路径,取分位数。计算量大,但更灵活。
我个人最常用历史模拟法。简单、直观、不需要假设分布。
import numpy as np
def calculate_var(returns, confidence=0.95):
"""历史模拟法计算VaR"""
sorted_returns = np.sort(returns)
index = int((1 - confidence) * len(sorted_returns))
return sorted_returns[index]
# 示例
daily_returns = np.random.normal(0.001, 0.02, 1000)
var_95 = calculate_var(daily_returns, 0.95)
print(f"95% VaR: {var_95:.4f}") # 输出类似 -0.0321
避坑指南: 我曾经犯过一个错误——直接用VaR作为最大亏损上限。结果某天市场暴跌,VaR显示最多亏2%,实际亏了5%。为什么?因为VaR只保证「95%的情况下不超过」,那5%的极端情况它不管。这就是VaR的致命缺陷。
3.4 CVaR:VaR的「升级版」
CVaR,Conditional VaR,也叫Expected Shortfall。它解决了VaR的「尾部风险」问题。
VaR只告诉你「95%分位点的亏损是多少」,CVaR告诉你「如果亏损超过了VaR,平均会亏多少」。
计算公式:
CVaR = E[ r | r ≤ VaR ]
说白了,就是取所有比VaR更差的收益率的平均值。
你想想看,两个策略的95% VaR都是-3%。但策略A的CVaR是-4%,策略B的CVaR是-8%。这说明策略B一旦出事,后果严重得多。
我的建议: 做因子评价时,VaR和CVaR一起看。VaR看「大概率下的风险」,CVaR看「极端情况下的风险」。两个都低,才算真正安全。
def calculate_cvar(returns, confidence=0.95):
"""计算CVaR"""
sorted_returns = np.sort(returns)
index = int((1 - confidence) * len(sorted_returns))
tail_returns = sorted_returns[:index]
return np.mean(tail_returns)
cvar_95 = calculate_cvar(daily_returns, 0.95)
print(f"95% CVaR: {cvar_95:.4f}") # 比VaR更负
3.5 最大回撤期:你「扛」了多久?
最大回撤,大家都很熟悉——从最高点到最低点的最大跌幅。但最大回撤期,很多人会忽略。
它衡量的是:从最高点跌下来,到重新创出新高,一共花了多长时间。
为什么这个指标重要?
因为时间会消磨意志。一个策略最大回撤20%,但只用了2个月就回来了,你还能扛。如果最大回撤20%,花了2年才回来……嗯,大部分人早就割肉了。
我记得有个量化团队,策略年化收益25%,最大回撤只有15%。看起来很不错对吧?但最大回撤期是18个月。也就是说,你买入后要等一年半才能回本。这期间,客户早就骂娘了。
实战经验: 我个人对最大回撤期的容忍度是6个月。超过6个月,策略再优秀也要重新评估。因为市场环境变化太快,18个月后,当初的逻辑可能已经失效了。
计算方式:
def max_drawdown_period(equity_curve):
"""计算最大回撤期(天数)"""
peak = equity_curve[0]
peak_date = 0
max_dd_days = 0
for i, value in enumerate(equity_curve):
if value > peak:
peak = value
peak_date = i
else:
dd_days = i - peak_date
if dd_days > max_dd_days:
max_dd_days = dd_days
return max_dd_days
3.6 五个指标怎么用?一张表说清楚
| 指标 | 衡量什么 | 适用场景 | 我的阈值 |
|---|---|---|---|
| 波动率 | 整体波动幅度 | 初步筛选 | 年化 < 25% |
| 下行波动率 | 下跌时的波动 | 风险厌恶型投资者 | 年化 < 15% |
| VaR (95%) | 大概率下的最大亏损 | 日常风控 | 日 < -2% |
| CVaR (95%) | 极端情况下的平均亏损 | 压力测试 | 日 < -3% |
| 最大回撤期 | 从亏损到回本的时间 | 投资者心理评估 | < 6个月 |
这五个指标,从不同角度刻画风险。波动率看整体,下行波动率看下跌,VaR看大概率,CVaR看极端,最大回撤期看时间。缺一不可。
最后说一句: 风险指标不是越多越好,而是越「对」越好。选对指标,比堆砌指标重要得多。我个人做因子评价时,必看的就是这五个。看完这五个,心里基本有数了。