第1章:风险因子体系构建
做量化投资这些年,我越来越觉得——风险管理不是事后补救,而是事前设计。你想想看,如果连风险来自哪里都说不清楚,那还谈什么控制?
这一章,我们就来聊聊风险因子体系的构建。说白了,就是把市场风险、信用风险、流动性风险、操作风险这四座大山,用数学语言给它量化出来。
1.1 市场风险:最熟悉的陌生人
市场风险,大家都不陌生。股票涨了跌了,债券收益率上上下下,这都是市场风险。但怎么量化它?我个人习惯用三个维度来刻画。
1.1.1 因子暴露度
公募基金持仓那么多股票,不可能一个个盯。我们得用因子模型来降维。比如经典的Barra模型,把市场风险拆解成:
- 市场因子:大盘涨跌带来的系统性风险
- 规模因子:大小盘风格切换的风险
- 价值因子:估值回归的风险
- 动量因子:趋势延续或反转的风险
- 波动率因子:市场情绪波动的风险
我在项目中遇到过一只量化基金,明明持仓很分散,但回撤比指数还大。一查因子暴露,好家伙,在规模因子上暴露了2.3个标准差。说白了,就是偷偷押注了小盘股,市场风格一转,直接被打回原形。
1.1.2 VaR与CVaR
VaR(在险价值)是市场风险量化的标配。但我要提醒你一句:VaR只看分位数,不管尾部有多肥。我建议用CVaR,也就是条件在险价值,它告诉你一旦亏钱,平均会亏多少。
核心公式:
VaR_α = inf{ l ∈ R : P(L > l) ≤ 1-α }
CVaR_α = E[ L | L > VaR_α ]
举个例子,95% VaR是100万,意思是只有5%的概率亏损超过100万。但CVaR可能是150万,意味着一旦触发尾部风险,平均亏损是150万。嗯,这里要注意,很多新手只看VaR,结果被尾部风险坑惨了。
1.1.3 压力测试场景
历史数据再长,也覆盖不了所有极端情况。我习惯构建几个经典压力场景:
- 2008年金融危机模式:股市暴跌+流动性枯竭
- 2020年疫情模式:V型反转+行业分化
- 利率急升模式:债券市场踩踏
我曾经用2008年的数据回测一个策略,表现还不错。结果2020年3月,流动性一收缩,策略直接崩了。为什么?因为历史回测没考虑到流动性分层的问题。
1.2 信用风险:债券基金的命门
公募基金里,信用风险主要来自债券持仓。尤其是信用债,一旦踩雷,净值可能直接腰斩。
1.2.1 信用利差分解
信用风险的核心是信用利差。我一般把它拆成两部分:
| 成分 | 含义 | 量化方式 |
|---|---|---|
| 违约风险溢价 | 发行人可能违约的补偿 | 信用评级+违约概率模型 |
| 流动性溢价 | 债券流动性不足的补偿 | 买卖价差+交易量指标 |
你看,信用利差不光是违约风险,还有流动性因素。很多新手只看评级,忽略了流动性溢价,结果遇到市场波动,想卖都卖不掉。
1.2.2 违约概率估算
违约概率怎么算?我推荐用Merton模型的结构化方法。核心逻辑很简单:公司资产价值低于负债时,就会违约。
# 简化的Merton模型实现
import numpy as np
from scipy.stats import norm
def merton_pd(equity, debt, volatility, risk_free_rate, time_to_maturity):
# 资产价值 = 股权价值 + 债务价值
asset_value = equity + debt
# 违约距离
distance_to_default = (np.log(asset_value / debt) +
(risk_free_rate - 0.5 * volatility**2) * time_to_maturity) / \
(volatility * np.sqrt(time_to_maturity))
# 违约概率
pd = norm.cdf(-distance_to_default)
return pd
# 举个例子
pd = merton_pd(equity=100, debt=80, volatility=0.3,
risk_free_rate=0.03, time_to_maturity=1)
print(f"违约概率: {pd:.2%}")
避坑指南:我曾经用Merton模型估算一只地产债的违约概率,结果模型显示只有2%,但实际违约了。后来发现,模型假设资产价值连续变化,但现实中公司可能因为流动性危机突然暴雷。所以,信用风险模型一定要结合基本面分析。
1.3 流动性风险:看不见的杀手
流动性风险,说白了就是你想卖的时候卖不掉,或者只能打折卖。公募基金每天开放赎回,流动性管理是头等大事。
1.3.1 流动性指标
我常用的流动性量化指标有三个:
- Amihud非流动性指标:日收益率绝对值 / 日成交额,越大说明流动性越差
- 买卖价差:直接反映交易成本
- 换手率:成交股数 / 流通股数,反映交易活跃度
你想想看,如果一只股票Amihud指标突然飙升,说明什么?说明市场深度不够,大单进出会引发价格剧烈波动。我在2021年就遇到过,一只小盘股持仓占比不到3%,但流动性枯竭时,硬是花了5天才清完仓,还多亏了2%的冲击成本。
1.3.2 流动性压力测试
光看静态指标不够,还得做压力测试。我习惯模拟三种场景:
- 正常市场:按日均成交量的10%卖出
- 压力市场:按日均成交量的5%卖出
- 极端市场:按日均成交量的1%卖出
然后计算每种场景下的清仓天数。如果极端市场下清仓天数超过5天,那这个持仓就得警惕了。
注意:流动性风险有传染性。一只股票流动性枯竭,可能引发整个板块的流动性危机。2020年3月的美债市场就是典型例子——连最安全的国债都出现了流动性问题。
1.4 操作风险:人总会犯错
操作风险,说白了就是人祸。交易员输错单、系统宕机、风控参数设错……这些事我见过太多了。
1.4.1 操作风险分类
我一般把操作风险分成四类:
| 类型 | 例子 | 量化方式 |
|---|---|---|
| 人为失误 | 交易员输错数量 | 历史失误频率 × 平均损失 |
| 系统故障 | 交易系统宕机 | 系统可用率 × 故障恢复时间 |
| 流程缺陷 | 风控审批流程缺失 | 流程合规率 |
| 外部欺诈 | 交易对手违约 | 信用评级 + 历史违约率 |
1.4.2 操作风险资本计量
巴塞尔协议给了三种方法,我推荐用高级计量法(AMA)。核心思路是:
# 操作风险资本计量(简化版)
def operational_risk_capital(loss_data, confidence_level=0.999):
# 损失数据:历史操作风险损失
# 使用损失分布法(LDA)
frequency = len(loss_data) # 年化频率
severity = np.mean(loss_data) # 平均损失严重度
# 预期损失
expected_loss = frequency * severity
# 非预期损失(用VaR近似)
unexpected_loss = np.percentile(loss_data, confidence_level * 100) - expected_loss
return expected_loss + unexpected_loss
我的经验:操作风险最难量化,因为历史数据太少。我建议用情景分析法补充——找业务部门的人一起头脑风暴,列出可能发生的操作风险事件,然后估算概率和损失。虽然主观,但总比没有强。
1.5 风险因子体系总览
说了这么多,我们来画一张图,把整个风险因子体系串起来。
这张图把四大风险因子和它们的量化维度串在了一起。你想想看,一个完整的风险管理系统,就是要把这四个维度都覆盖到,缺一不可。
好了,这一章我们聊了风险因子体系的构建。从市场风险的因子暴露和VaR,到信用风险的利差分解和违约概率,再到流动性风险的Amihud指标和清仓天数,最后是操作风险的分类和资本计量。每个风险都有它独特的量化方式,但核心思路是一样的——把模糊的风险变成可度量的数字。
下一章,我们会深入聊聊这些风险因子在公募基金组合中如何实时监控和预警。嗯,到时候我会分享一些实战中的踩坑经验,保证让你少走弯路。