Learning
VOL. VII · NO. 73 · OTC Derivatives · 19 JUL 2026

Risk Management Framework

OTC 衍生品 · 19 JUL 2026 · 16 min read · 2,726 words
· · ·

ODTS 24 — 风险管理框架:安全网

业务问题

场外衍生品交易台承担风险。每笔交易都有风险。问题不是”我们有没有风险?“而是”我们知道自己的风险是什么吗?“风险管理是以下实践的循环:衡量风险(我们可能损失多少?)、设定限额(允许我们损失多少?)、监控风险(我们在限额内吗?)、缓释风险(对冲、保证金、提前终止)。

风险类型

风险类型含义衡量方式归属谁
市场风险 (Market Risk)市场波动的 P&L 影响Greeks, VaR, 压力测试交易台
交易对手风险 (Counterparty Risk)客户违约PFE, CVA, 信用限额信用风险
流动性风险 (Liquidity Risk)无法平仓买卖价差、持仓规模交易台
操作风险 (Operational Risk)系统故障、人为错误事故数、损失事件运营
模型风险 (Model Risk)错误的定价模型模型验证、储备金量化团队
法律风险 (Legal Risk)合同不可执行法律审查、ISDA 争议法律团队

对一个从事交易系统开发的人来说,理解这些风险类别很重要——因为你在 EOD 批处理中加一个字段,可能影响的是市场风险计量;你改一个结算逻辑,可能影响的是交易对手风险。

市场风险:Greeks

Greeks 是市场风险衡量的核心。每个希腊值是一个敏感度指标,告诉你当市场波动时 P&L 会发生什么。

对于一笔香草看涨期权——标的为贵州茅台 (600519.SH),名义本金 1000 万,行权价 200,期限 6 个月——EOD 快照可能显示:Delta 为 +45,230 元(茅台涨 1 元 → P&L 增加 4.5 万),Gamma 为 3,450 元(标的每波动 1 元,Delta 变化 3,450),Vega 为 1,200 元(波动率 +1% → P&L +1,200),Theta 为 -850 元(每天时间价值损耗 850 元),Rho 为 500 元(利率 +1% → P&L +500)。

Delta 对冲的实际操作: 交易员的持仓 Delta 为 +45,230(多头),为了对冲需要卖出价值 45,230 元的茅台股票,使净 Delta 归零。第二天,Gamma 使 Delta 变化了 +3,450,所以需要再卖出价值 3,450 元的茅台股票。每次再对冲都有交易费用(印花税、佣金)。高 Gamma 的交易需要频繁再对冲,这会侵蚀 P&L。这就是为什么交易员在报价时会把 Gamma 成本算进价格里。

头寸限额

交易台对每个标的有硬性限额。Delta 限额为每个标的 ±5000 万(超限必须立即对冲),Gamma 限额为 ±500 万(必须减少头寸),Vega 限额为 ±200 万(必须买入/卖出期权对冲),名义本金限额为每个交易对手 5 亿(不得有新交易),集中度限额为不超过日均成交量的 10%。

限额超限有分级协议:达到限额的 80% 时系统记录警告;90% 时系统邮件通知风险团队;100% 时通知首席交易员,必须在 1 小时内批准;120% 时该标的暂停交易。

代码中限额检查通过 RiskCheckThresholdLevel 枚举实现——四个级别(NORMAL, WARNING, BREACH, CRITICAL),每个级别关联对应的通知策略。检查引擎位于 eds-utility/src/.../risk/model/RiskCheckDetailResult.java,结果结构包含 thresholdLevelcheckStatus(通过/失败)、exceededAmountapprovedBy

VaR(风险价值)

VaR 回答”在 99% 置信水平下,我们一天内的最大可能损失是多少?“比如说,每日 VaR 为 500 万,意味着有 1% 的概率一天损失超过 500 万,相当于每年约 2.5 个交易日。

历史模拟法

系统的计算方式使用历史模拟法 (Historical Simulation):取过去 500 个交易日的市场数据(即期价格、波动率、利率、汇率的历史日变化),用每天的市场波动重新为整个投资组合定价,计算每个情景的 P&L。然后从最差到最好排序,取倒数第 5 差的结果(500 的 1% = 5)。这个过程在 hedging-as 的 EOD 风险批处理中执行,关键输入来自 EDS_CTRCONTRACTEOD 表(前一日的 Greeks 缓存)和每日市场快照。

历史模拟步骤:
  第 1 步:取每个风险因子过去 500 天的日收益率
  第 2 步:对每个风险因子,生成 500 个"明日情景"(当前值 × 历史收益率)
  第 3 步:对每个情景,用一阶近似重新估值组合:
           new_NPV ≈ old_NPV + Σ(Greek × Δrisk_factor)
  (注意:这里用了一阶近似,假设 Greeks 在市场小幅波动下近似线性)
  第 4 步:按 P&L 变化从小到大排序
  第 5 步:第 5 小的值 = 99% VaR

VaR 的统计噪声

VaR 的精度取决于历史窗口长度。窗口越长,样本代表性越好,但过长的窗口包含过时的市场制度。500 天是一个折中:

窗口长度    优点              缺点
─────────  ──────────────    ─────────────────────
250 天     反应快,捕捉新 regime   尾部事件不够
500 天     较好的尾部估计        可能包含过时 regime
1000 天    尾部最稳定            包含 4 年前的制度,可能已不适用

ODTS 选择的 500 天窗口意味着 2008 危机数据在 2010 年后已经被踢出窗口——但 2015 年股灾的影响会保留到 2017 年。

Expected Shortfall(期望损失)

VaR 有局限性:它告诉你第 99 百分位水平,但不告诉你那 1% 的尾部会发生什么。一个组合可能 VaR = 500 万且最大损失 = 600 万(尾部紧凑,安全),也可能 VaR = 500 万但最大损失 = 5000 万(肥尾,危险)。

系统也计算期望损失 (Expected Shortfall)——最差 1% 情景的平均值——来解决这个问题。如果最差 5 个情景的 P&L 分别是 -500 万、-520 万、-550 万、-600 万、-5000 万,VaR = 500 万,但 ES = (-500 + -520 + -550 + -600 + -5000)/5 = -1434 万。ES 比 VaR 大 3 倍,表明尾部存在极端风险——这本身就是个预警信号。

潜在未来敞口 (PFE)

PFE 估算”如果市场朝不利方向波动,这笔交易在未来某个日期可能值多少钱?“它通过 Monte Carlo 模拟生成 10,000 条价格路径,计算每条路径上的未来盯市价值 (MTM),取第 95 百分位值。PFE 决定信用额度使用(占用了客户多少信用额度)、初始保证金(最低抵押品要求)和资本占用(为该交易持有的监管资本)。

PFE 计算细节

PFE 计算流程:
  第 1 步:为每个风险因子(即期价格、利率、汇率)拟合几何布朗运动参数
           μ = 历史漂移率,σ = 历史波动率
  第 2 步:生成 10,000 条未来路径,每条路径向前模拟到交易到期日
  第 3 步:在每条路径上的每个未来估值日,重新定价交易
  第 4 步:对每个未来估值日,取 10,000 个 MTM 值的第 95 百分位
  第 5 步:整条 PFE 曲线 = 各估值日的第 95 百分位 MTM 值序列
           (通常在交易前半段上升,后半段下降——因为时间价值衰减)

PFE 曲线的业务解释

PFE 曲线形状:
  期限较短: 曲线陡峭上升、平缓下降——市场有足够时间移动但到期日又近
  期限较长: 曲线先升后降,峰值在约 1/3 到期处

  看涨期权 PFE: 峰值在约 30-40% 期限处,然后下降
  互换 PFE: 对称,峰值在约 40-50% 期限处
  TRS PFE: 持续上升(名义价值不变,但不确定性增加)

信用额度检查

每个交易对手有一个信用额度。代码中风险检查 (RiskCheckDetailResult) 在交易簿记时触发:

招行:额度 5 亿,当前占用 3.5 亿(占 70%),可用 1.5 亿

如果新交易 PFE = 8000 万:
  检查:3.5 亿 + 0.8 亿 = 4.3 亿 < 5 亿 → 通过 ✓

如果新交易 PFE = 2 亿:
  检查:3.5 亿 + 2 亿 = 5.5 亿 > 5 亿 → 拒绝 ✗
  可否覆盖?可以,首席交易员操作 override 并记录原因

2021 年发生过一笔交易簿记后超过了交易对手信用额度 5000 万的案例。系统没有阻止,因为系统在应用汇率转换之前检查了限额。新交易以美元计,限额以人民币计。7000 万美元按 6.8 汇率折合 4.76 亿人民币,但系统比较了 4.8 亿 + 7000 万 = 5.5 亿(把美元名义本金当作人民币),交易通过了检查并被簿记。结果信用额度超出 2600 万人民币,2 天后才被 EOD 风险报告发现。

根本原因: RiskCheckDetailResult 中的敞口计算没有对非本币交易进行汇率转换,限额比较在金额和货币之间不匹配时仍然通过了。

修复及后续: 这个 bug 在事后被标记为”关键修复”。解决方案不是简单的加汇率转换——因为限额检查是一个通用的 RiskCheckDetailResult 类,支持多种风险类别(Delta、Vega、信用额度等),而汇率转换只适用于信用额度检查。最终方案是在信用额度检查分支中增加 ExchangeRateUtil.convert(amount, fromCcy, toCcy) 调用,但这花了 3 周——因为需要确保不影响其他风险类别的检查逻辑。

ActiveMQ 延迟的实际后果

风险规则引擎通过 ActiveMQ 消息队列异步执行。正常情况下延迟 200-500ms,但在高峰时期(如 EOD 附近或市场大幅波动时),队列积压可能导致几分钟的延迟。

2022 年某事件:
  交易员在 14:55 簿记一笔大额 TRS(名义 2 亿)
  → ActiveMQ 消息发送到 RiskRuleNotification 队列
  → 队列积压(同期有 EOD 批处理消息也在队列中)
  → 风险检查在 15:03 才完成(8 分钟后!)
  → 检查结果:Delta 限额超限 1200 万
  
  问题:
    这 8 分钟里交易员认为"系统没报错,说明通过了"
    → 继续簿记了另一笔关联交易
    → 实际上这两笔交易加起来的 Delta 限额超了 2500 万
    → 等到 EOD 风险报告出来才发现

教训: 异步风险检查的延迟意味着”没报错”不等于”通过了”。交易员和运营需要理解这个架构约束——不能把 ActiveMQ 的沉默等同于风险通过的确认。

压力测试

交易台定期运行压力情景。ODTS 的压力测试通过 RiskRulePublisher 机制触发——一个 ActiveMQ 消息驱动的风险规则引擎:当市场数据变动超过阈值时,消息被发布到 RiskRuleNotification 队列,触发对应的风险规则评估。

标准压力情景

情景市场冲击适用场景
2008 危机股票 -50%,波动率 +300%,信用价差 +500bp系统性危机
2015 中国股灾股票 -30%,波动率 +200%,流动性半衰期 3 天中国市场危机
利率冲击利率 +2%,汇率 -5%,债券收益率 +150bp货币政策突变
信用事件指定交易对手违约,回收率 40%,剩余头寸价差 +100bp交易对手违约
相关性破裂所有相关性变为 1,分散化失效系统性风险
人民币贬值USDCNY +10%,离岸/在岸价差扩大至 500bp汇率危机

压力测试的计算过程

压力测试不是简单的因子冲击——它需要一致地重新定价整个投资组合。ODTS 的做法是:

步骤 1: 加载当前持仓的全部 Greeks(来自 EDS_CTRCONTRACTEOD)
步骤 2: 对每个情景,计算 Greeks × 市场冲击 = P&L 变化
步骤 3: 汇总所有交易得到组合级别的 P&L 影响
步骤 4: 将结果存入风险报表表

限制:一阶近似(Greeks 在压力情景下可能高度非线性,
      但完全重新定价数千笔交易在时间上不可行)

对于尾部风险较大的奇异期权,一阶近似可能严重低估损失。风险团队对这些产品维护额外的模型储备金 (model reserve),在压力测试结果之上扣减。

压力测试的频率

每日自动: 5 个标准情景全量运行
每周深度: 对奇异期权组合进行完全重新定价(非一阶近似)
每月附加: 中国证监会 (CSRC) 规定的情景
季度: 反向压力测试 — "什么场景会导致我们损失 1 亿?"

风险规则引擎

ODTS 的风险检查不是硬编码的,而是通过规则引擎实现的。eds-utility 中的 Drools 规则文件(如 Risky.drl)定义了风险规则:

规则文件路径:
  eds-utility/resources/rules/nqaGrossPrice/Risky.drl
  eds-utility/resources/rules/grossPrice/Risky.drl
  eds-utility/resources/rules/grossPrice/Risky_Hedge.drl

规则触发机制:
  交易簿记 → RiskRulePublisher 发送 ActiveMQ 消息 →
  RiskRuleNotification 被消费 → Drools 规则引擎评估 →
  RiskCheckDetailResult 记录检查结果

这里有一个架构上的权衡:规则引擎提供了灵活性(规则修改不需要重新部署代码),但也引入了延迟(ActiveMQ 消息传递意味着风险检查不是完全的实时——有一个几百毫秒的滞后)。对于大交易量时期,消息队列可能出现积压,风险检查结果延迟几分钟才出现。

VaR 的欺骗性——一个压力测试案例

VaR = 500 万听起来很安全——如果公司资本金是 50 亿,0.1% 的风险敞口。但 VaR 的欺骗性在于:它假设历史会重演

2022 年某真实情景:
  正常市场下 VaR = 500 万
  2022 年 3 月(俄乌冲突 + 美联储加息叠加):
    实际最大日损失 = 2300 万(VaR 的 4.6 倍!)
    
  为什么 VaR 这么不准?
    - 500 天历史窗口中大部分是 2021 年低波动的数据
    - 2022 年 3 月的波动率水平是历史均值的 3 倍
    - VaR 模型直到波动率数据进入窗口(约 3 个月后)才"学会"了新的波动率水平
    
  后来补充的压力测试显示(如果当时跑了"2008 危机"情景):
    压力损失 = 3500 万——更准确地反映了极端损失可能性
    但当天 EOD 风险报告中的 VaR = 500 万(基于历史模拟)

业务含义: VaR 是滞后指标——它反映的是过去 500 天的市场,而不是明天的市场。压力测试是前瞻性的,但只在管理团队查看时才有用。风险管理的最大危险不是 VaR 水平高,而是 VaR 看起来安全但实际风险已经变了。

首席交易员每天早上看到的风险报告

─────────────────────────────────────────
     每日风险报告 | Date: 2025-07-17
─────────────────────────────────────────
P&L 摘要:
  MTM P&L:                      +1,234,567.89
  已实现 P&L:                     -234,567.89
  未实现 P&L:                   +1,469,135.78

风险指标:
  VaR (99%, 1d):                  5,200,000.00
  期望损失:                        8,100,000.00
  压力损失 (2008):                12,300,000.00

希腊值敞口(前 5 大标的):
  600519.SH (茅台):    Δ=+2.3M  Γ=+0.5M  ν=+0.8M
  000858.SZ (五粮液):  Δ=-1.1M  Γ=+0.3M  ν=+0.4M
  300750.SZ (宁德时代): Δ=+0.8M  Γ=-0.2M  ν=+0.3M

限额检查:
  所有限额在容忍范围内 ✓

交易对手风险:
  信用额度使用率: 67%
  最大敞口: 招商银行 (120M)
  未付保证金催缴: 15M (今天到期)

关键文件

组件路径
风险检查结果模型eds-utility/src/.../risk/model/RiskCheckDetailResult.java
风险检查状态枚举eds-utility/src/.../risk/enums/PbMessageEnum.java(RiskCheckStatus, RiskCheckThresholdLevel)
风险规则类别eds-utility/src/.../risk/enums/RiskCategory.java
风险规则类型eds-utility/src/.../risk/enums/RiskRuleType.java
规则引擎 DRLeds-utility/resources/rules/grossPrice/Risky.drl
对冲规则eds-utility/resources/rules/grossPrice/Risky_Hedge.drl
ActiveMQ 风险规则发布eds-utility/src/.../activeMQ/RiskRule/RiskRulePublisher.java
风险规则通知eds-utility/src/.../activeMQ/RiskRule/RiskRuleNotification.java
风险常数eds-utility/src/.../risk/util/RiskConstant.java
VaR 计算hedging-as/.../risk/VarCalculationAction.java
风险计算入口hedging-as/.../risk/RiskAction.java
风险规则 DAOhedging-as/.../risk/dao/RiskRuleDaoImpl.java
EOD 风险快照表eds-web-app/db/EDS/V1.8/EDS20171107170003_CREATE_CTCONTRACTEOD.sql
限额配置视图eds-web-app/db/EDS/code/views/v_limit_config.sql

风险管理是一个由限额、VaR、PFE 和情景分析组成的系统,每天运行——它不能防止损失,但它确保交易台确切知道可能损失多少,并且永远不会超过公司愿意容忍的金额。代码中的风险规则引擎通过 ActiveMQ 消息驱动,这带来灵活性但也引入了风险检查的异步延迟——一个需要交易台公认的架构决策。