SA-CCR 交易对手 EAD:抵押品折减后 RC 加跨资产类别 PFE 乘 Alpha
SA-CCR Counterparty EAD: Collateral-Adjusted RC plus Aggregated PFE with Alpha
开始编码实现 solution(current_mtm: float, collateral: float, pfe_per_asset_class: list[float], alpha_factor: float) -> float。某衍生品交易台的交易对手信用风险组每个交易日为每位交易对手的轧差组合(netting set)按 Basel III SA-CCR 框架计算违约时敞口(EAD)。给定四项标量/列表输入:current_mtm 是该轧差组合的有符号净 MtM(美元、为正表示对手方欠我们、为负表示我们欠对手方);collateral 是对手方为该轧差组合质押的流动抵押品的美元价值;pfe_per_asset_class 是按 Basel 资产类别分项的潜在未来敞口列表(典型为五大类:利率、汇率、权益、信用、商品——但函数接受长度 K 在 0 到 20 之间的任何列表);alpha_factor 是 Basel 监管乘数 alpha(标准值 1.4)。
把交易对手 EAD 算成 alpha_factor 乘上两项之和:重置成本 RC = max(0.0, current_mtm - collateral)(抵押品抵扣 MtM 索赔、且 RC 在零处截断、所以超额抵押不会产生负敞口),以及聚合潜在未来敞口 PFE_total = sum(pfe_per_asset_class)(简化版 SA-CCR 跨资产类别加和聚合)。闭式为 EAD = alpha_factor * (RC + PFE_total)。**Alpha 乘的是 (RC + PFE_total) 这个整体、不是只乘 PFE**——写成 EAD = RC + alpha * PFE_total 会在 RC 上少收 (alpha - 1) 倍。抵押品从 MtM 中减去、不加——它是对手方押给我们做担保的标的。PFE 跨资产类别加和、不是取最大。EAD 永远非负。
例
solution(2000000.0, 500000.0, [100000.0, 200000.0, 50000.0, 30000.0, 20000.0], 1.4) 返回 2660000.0。逐式拆解:RC = max(0.0, 2_000_000 - 500_000) = 1_500_000(轧差组合的 MtM 是 $2M 偏向我们、对手方质押了 $500K 抵押品、故实际重置成本为 $1.5M)。PFE_total = 100_000 + 200_000 + 50_000 + 30_000 + 20_000 = 400_000(五大 Basel 资产类别的加和)。EAD = 1.4 * (1_500_000 + 400_000) = 1.4 * 1_900_000 = 2_660_000.0。Alpha 乘整个括号——若改写成 EAD = RC + alpha * PFE_total = 1_500_000 + 1.4 * 400_000 = 2_060_000,等于在 RC 上少收 0.4 * 1_500_000 = $600K;这是 SA-CCR EAD 实现里最常见的 bug。
超额抵押情形的正本清源:current_mtm = 1_000_000、collateral = 1_500_000 已超额抵押。RC = max(0.0, 1_000_000 - 1_500_000) = max(0.0, -500_000) = 0.0、不是 -500_000。配合 pfe = [200_000]、alpha = 1.4 得 EAD = 1.4 * (0.0 + 200_000) = 280_000.0。漏掉 max(0, ...) 截断的作者会算成 EAD = 1.4 * (-500_000 + 200_000) = -420_000.0——一个负敞口、毫无意义:即便我方索赔已被抵押品全额覆盖、未来交易漂移仍可能伤我们、EAD 的下界是 alpha * PFE_total。
需要明确的边界:K == 0(空 pfe_per_asset_class)给出 PFE_total = 0 且 EAD = alpha_factor * RC。collateral > current_mtm(超额抵押)给出 RC = 0 且 EAD = alpha_factor * PFE_total。alpha_factor == 0 给出 EAD = 0、与 RC、PFE 无关。所有 pfe_per_asset_class[k] == 0 且 collateral >= current_mtm 同时成立给出 EAD = 0。输出恒为非负 float——因为 RC >= 0、PFE_total >= 0 且 alpha_factor >= 0。
期望算法:O(K) 把 PFE 列表加和、O(1) 做 RC 截断和 alpha 乘——除遍历 PFE 列表外都是常数工作量。本函数不抛异常——调用方保证 collateral >= 0、每个 pfe_per_asset_class[k] >= 0 且 alpha_factor >= 0。
实现细节由 stubs/stub.py 提供。
实践背景
每个交易日,衍生品交易台的交易对手信用风险组都会重跑 Basel III SA-CCR EAD 流水线、为每位交易对手的轧差组合算一次:拉取该轧差组合内所有交易的最新 MtM、对手方最新质押抵押品余额、监管引擎给出的按资产类别分项的 PFE 加项、以及监管 alpha(2017 标准 SA-CCR 锁定为 1.4)。输出 EAD = alpha * (RC + PFE_total) 进入两条下游:监管资本引擎把 EAD 折成风险加权资产与资本占用,以及内部交易对手限额监控、判断该对手方的总敞口是否突破交易台风险限额。公式里的三个正确性陷阱——RC 对 0 截断、抵押品减而非加、alpha 乘整个括号——正是每位 SA-CCR 验证审查员最先核对的项目,因为这些是该实现里高杠杆的资本影响 bug。
约束条件
- -1e9 <= current_mtm <= 1e9(净轧差组合的有符号净 MtM、美元)
- 0.0 <= collateral <= 1e9(交易对手对该轧差组合质押的抵押品价值、美元、视为流动)
- 0 <= len(pfe_per_asset_class) <= 20(按 Basel 资产类别分项的 PFE 列表、可为空)
- 0.0 <= pfe_per_asset_class[k] <= 1e9(每个资产类别的 PFE 项均为非负)
- 0.0 <= alpha_factor <= 5.0(Basel 监管乘数、SA-CCR 标准值为 1.4)
- 输出为单个 float——非负 EAD、美元;按 rel_tol=1e-9、abs_tol=1e-9 比对
样例
Case 1 · statement-example: 5-asset-class PFE with positive RC and alpha=1.4
输入: [2000000,500000,[100000,200000,50000,30000,20000],1.4]
期望: 2660000
RC = max(0, 2e6 - 5e5) = 1.5e6;PFE_total = 1e5 + 2e5 + 5e4 + 3e4 + 2e4 = 4e5;EAD = 1.4 * (1.5e6 + 4e5) = 1.4 * 1.9e6 = 2.66e6。
Case 2 · visible: over-collateralised - collateral exceeds MtM, RC floored at 0
输入: [1000000,1500000,[200000],1.4]
期望: 280000
超额抵押:current_mtm=1e6 < collateral=1.5e6;RC = max(0, -5e5) = 0;EAD = 1.4 * (0 + 2e5) = 2.8e5。漏 max(0,...) 会得 -4.2e5。
Case 3 · visible: empty PFE list - EAD reduces to alpha * RC
输入: [500000,100000,[],1.4]
期望: 560000
K=0:PFE_total = 0;RC = max(0, 5e5 - 1e5) = 4e5;EAD = 1.4 * (4e5 + 0) = 5.6e5。
最近提交
还没有提交记录。
编码区
实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。
默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。
Case 1 · statement-example: 5-asset-class PFE with positive RC and alpha=1.4
输入: [2000000,500000,[100000,200000,50000,30000,20000],1.4]
期望: 2660000
RC = max(0, 2e6 - 5e5) = 1.5e6;PFE_total = 1e5 + 2e5 + 5e4 + 3e4 + 2e4 = 4e5;EAD = 1.4 * (1.5e6 + 4e5) = 1.4 * 1.9e6 = 2.66e6。
Case 2 · visible: over-collateralised - collateral exceeds MtM, RC floored at 0
输入: [1000000,1500000,[200000],1.4]
期望: 280000
超额抵押:current_mtm=1e6 < collateral=1.5e6;RC = max(0, -5e5) = 0;EAD = 1.4 * (0 + 2e5) = 2.8e5。漏 max(0,...) 会得 -4.2e5。
Case 3 · visible: empty PFE list - EAD reduces to alpha * RC
输入: [500000,100000,[],1.4]
期望: 560000
K=0:PFE_total = 0;RC = max(0, 5e5 - 1e5) = 4e5;EAD = 1.4 * (4e5 + 0) = 5.6e5。