← 返回编程题库
coding-vasicek-conditional-pd-given-systematic-factor中等免费版1000ms未尝试

在已实现系统因子下的 Vasicek 单因子条件 PD

Vasicek Single-Factor Conditional PD Given a Realized Systematic Factor

开始编码

实现 solution(z_unconditional: float, asset_correlation: float, systematic_factor_z: float) -> float。信贷风险团队对每个对手方、每个已实现宏观态都调用一次此函数,把对手方的无条件违约阈值与银行选定的资产相关性,转换成在已实现系统因子 M 下的条件违约概率。这是 Vasicek 单因子原语,也是监管 IRB 资本和大多数解析与 Monte Carlo 组合信贷损失引擎的核心。

输入:

  • z_unconditional —— 对手方的标准化违约触发阈值,等于 Phi^-1(unconditional_pd)。调用方已经对无条件 PD 做过反正态变换;本函数只消费这个标量阈值(带符号;低 PD 时为负)。
  • asset_correlation —— 参数 R,落在 [0.0, 1.0]:对手方资产收益与系统因子之间的相关系数的平方。R 越大,对手方违约触发对宏观态越敏感。R = 1.0 是退化端点,由下面的 NaN 哨兵处理。
  • systematic_factor_z —— 已实现的系统因子 M,一个标准正态抽样(带符号)。负的 M 是不利宏观态;正的 M 是有利宏观态。

输出由如下可观测公式定义:

  1. 参数arg = (z_unconditional - sqrt(asset_correlation) * systematic_factor_z) / sqrt(1 - asset_correlation)
  2. 标准正态 CDFconditional_pd = Phi(arg),其中 Phi(x) = 0.5 * (1 + erf(x / sqrt(2)))

退化模型的哨兵:

  • asset_correlation == 1.0,分母 sqrt(1 - R) 为零,条件 PD 数学上未定义。返回 float('nan')

只要 asset_correlation < 1.0,分母严格为正,除法良定义。输出是 [0, 1] 内的概率。

solution(-2.326347874040841, 0.20, 0.0) 返回约 0.004648489920910659。对手方的无条件 PD 是 Phi(-2.326...) = 1%;资产相关性是 R = 0.20;已实现的系统因子是中位 M = 0。参数为 (-2.326... - sqrt(0.20) * 0) / sqrt(0.80) = -2.326.../0.8944... = -2.601...Phi(-2.601...) ≈ 0.00465 = 46.5 bp。条件在中位宏观态上时,条件 PD 低于 1% 的无条件基准:把同一个负阈值除以 sqrt(1 - R) < 1 之后会变得更极端(更负),Phi 在更极端的负数上的取值更小。直观解释:M = 0 时"已知宏观处于平均",把半个标准差的宏观信息吸入后验后,对手方剩余的特异阈值要跨过更高的门槛才能违约。

应力态放大效应算例:solution(-2.326347874040841, 0.20, -2.0) 返回约 0.054695548310186026。同一对手方(PD = 1%)、同一资产相关性(R = 0.20),但应力宏观态 M = -2(两个标准差的不利冲击)。参数变成 (-2.326... - sqrt(0.20) * (-2)) / sqrt(0.80) = (-2.326 + 0.8944) / 0.8944 = -1.6011Phi(-1.6011) ≈ 5.47%。条件 PD 从 1%(无条件)跳到了约 5.5%——五倍之多。这就是 Vasicek 模型的核心信息:尾部宏观态通过资产相关性渠道把违约概率成倍放大。

有利态算例:solution(-2.326347874040841, 0.20, 2.0) 返回约 0.0001585368182744351。同样设置,但 M = +2(强劲的顺风宏观态)。参数为 (-2.326 - sqrt(0.20) * 2)/sqrt(0.80) = (-2.326 - 0.8944) / 0.8944 = -3.601Phi(-3.601) ≈ 0.000159 = 1.59 个基点。条件 PD 从 1% 塌缩到约 16 bp——与应力情形对称的有利镜像。

R = 1 哨兵算例:solution(-2.326347874040841, 1.0, 0.0) 返回 float('nan')。资产相关性达到了退化的上限;分母 sqrt(1 - 1) = 0,条件 PD 未定义。返回 NaN——不要返回 0.0不要抛异常。

R = 0 吸收边界算例:solution(-2.326347874040841, 0.0, -1.5) 返回约 0.01R = 0sqrt(R) * M = 0sqrt(1 - R) = 1,公式塌缩为 Phi(z_unconditional) = Phi(-2.326...) = 1%——也就是无条件 PD。系统因子完全不起作用,因为零资产相关性下对手方的资产收益与宏观因子独立。

边界asset_correlation == 1.0 返回 NaN(退化)。asset_correlation == 0.0 无论 systematic_factor_z 取多少都返回无条件 PD。systematic_factor_z = 0(中位宏观)在 R > 0z_unconditional < 0 时返回低于无条件 PD 的值(负阈值被除以 sqrt(1 - R) < 1 后变得更极端);z_unconditional > 0 时反之对称。z_unconditional 很负(低无条件 PD)时条件 PD 一直很小,除非 M 也强烈为负。本函数对约束区间内任何输入都不抛异常;NaN 哨兵是 R = 1 情形的合同输出。

实现细节由 stubs/stub.py 提供。

实践背景

Vasicek 单因子高斯 Copula 模型——由 Oldrich Vasicek 提出,被采纳为 Basel II/III IRB 资本框架的解析骨架——把每个对手方的标准化资产收益分解为系统成分 sqrt(R) * M 和特异成分 sqrt(1 - R) * eps_i,其中 Meps_i 是独立的标准正态。当资产收益跌破阈值 z_unconditional = Phi^-1(unconditional_pd) 时违约。在已实现系统因子 M = m 上做条件后,特异成分是仅剩的随机性,所以条件违约概率为 P(sqrt(R) * m + sqrt(1 - R) * eps_i < z_unconditional) = Phi((z_unconditional - sqrt(R) * m) / sqrt(1 - R))。这个条件 PD 是 IRB 渐近单一风险因子(ASRF)资本公式的输入:监管设 M = Phi^-1(0.001)(99.9 分位的不利宏观态,即 M ≈ -3.09)以得到最坏情况下的条件 PD,然后乘以 LGD 与有效到期调整,得到每单位敞口的资本要求。同一原语也喂给 Monte Carlo 组合信贷损失引擎(抽 M,对每个对手方算这个条件 PD,把二元违约相加)、大组合渐近损失分布(在无穷颗粒度下,条件 PD 曲线本身就是损失分布)以及压力测试引擎(把 M 设为目标分位读出条件违约率)。本原语刻意把以下几条实现陷阱显式化——分子是减 sqrt(R) * M(宏观应力的符号通过减去负数流入 PD)、分母是 sqrt(1 - R) 而非 sqrt(R)(特异标准差,不是系统)、输出是 Phi 而非 erf[0, 1] 内的概率,不是 [-1, 1] 内的值)、输入是反正态阈值而非 PD 本身——这些正是生产信贷风控回归测试反复抓到的方向性与维度错误。纯 O(1) 实现(两次开方、一次减法、一次除法、一次 erf、一次平移缩放)就是标准原语;面对几百个宏观抽样、几百万对手方的生产系统按同一递推式做向量广播,但每次调用的合同完全相同。

约束条件

  • -5.0 <= z_unconditional <= 5.0
  • 0.0 <= asset_correlation <= 1.0
  • -5.0 <= systematic_factor_z <= 5.0
  • 输出:float —— 条件 PD,落在 [0, 1],或当 asset_correlation == 1.0 时为 NaN
  • 浮点比较器使用 rel_tol=1e-9, abs_tol=1e-9, nan_equals_nan=true

样例

Case 1 · statement-example: median macro, 1% PD, R=0.20

输入: [-2.326347874040841,0.2,0]

期望: 0.004648489920910659

无条件 PD = 1%(z = Phi^-1(0.01) ≈ -2.326)。R = 0.20,M = 0,arg = -2.326/sqrt(0.80) ≈ -2.601,Phi(-2.601) ≈ 0.00465 = 46.5 bp——**低于** 1% 基准。负阈值除以 sqrt(1 - R) < 1 后变得更极端,Phi 取值更小。

Case 2 · statement-example: stressed macro M=-2, 1% PD, R=0.20

输入: [-2.326347874040841,0.2,-2]

期望: 0.054695548310186026

同一对手方,应力 M = -2。arg = (-2.326 + sqrt(0.20)*2)/sqrt(0.80) ≈ -1.601,Phi(-1.601) ≈ 5.47%。从无条件 1% 跳到五倍——Vasicek 尾部放大。

Case 3 · statement-example: R = 1 returns NaN sentinel

输入: [-2.326347874040841,1,0]

期望: "NaN"

asset_correlation = 1.0 -> 分母 sqrt(1 - R) = 0,模型退化,条件 PD 未定义 -> NaN。

Case 4 · typical: benign macro M=+2, 1% PD, R=0.20

输入: [-2.326347874040841,0.2,2]

期望: 0.0001585368182744351

同一对手方,有利顺风 M = +2。arg ≈ -3.601,Phi ≈ 0.000159 = 1.59 bp。M = -2 应力情形的对称镜像。

Case 5 · typical: R = 0 absorbing, M has no effect (returns unconditional PD)

输入: [-2.326347874040841,0,-1.5]

期望: 0.010000000000000009

R = 0 -> sqrt(0)*M = 0 且 sqrt(1-0) = 1,因此 conditional_pd = Phi(z) = 1%,与 M 无关。系统因子通道关闭。

Case 6 · typical: severe stress M=-3.5, 1% PD, R=0.20

输入: [-2.326347874040841,0.2,-3.5]

期望: 0.19740245477544682

M = -3.5(比 99.9 分位还更不利)作用在 PD=1%、R=0.20 的对手方上。arg ≈ -0.851,Phi ≈ 19.74%。条件 PD 接近无条件基准的二十倍。

Case 7 · typical: 5% PD, R=0.15, median macro

输入: [-1.6448536269514722,0.15,0]

期望: 0.03720417559535216

z = Phi^-1(0.05) ≈ -1.645,R = 0.15,M = 0。arg = -1.645/sqrt(0.85) ≈ -1.784,Phi ≈ 3.72%。低于 5% 基准:负阈值除以 sqrt(1 - R) < 1 后变得更极端。

Case 8 · typical: 5% PD, R=0.15, M=-2 stress

输入: [-1.6448536269514722,0.15,-2]

期望: 0.1726036808645422

5% PD 对手方,R = 0.15,M = -2。arg ≈ -0.944,Phi ≈ 17.26%。条件 PD 相对 5% 无条件涨了三倍多。

Case 9 · typical: 5% PD, R=0.15, M=+2 benign

输入: [-1.6448536269514722,0.15,2]

期望: 0.004341844058280919

5% PD 对手方,R = 0.15,M = +2。arg ≈ -2.624,Phi ≈ 0.434%。条件 PD 压到约 43 bp。

Case 10 · typical: 0.1% PD high-grade obligor, R=0.30, M=0

输入: [-3.090232306167813,0.3,0]

期望: 0.00011057943536707526

投资级对手方:z = Phi^-1(0.001) ≈ -3.090,R = 0.30,M = 0。arg = -3.09/sqrt(0.70) ≈ -3.694,Phi ≈ 0.011%。条件 PD 略高于 1 bp。

Case 11 · typical: 0.1% PD, R=0.30, M=-2 stress

输入: [-3.090232306167813,0.3,-2]

期望: 0.008557527229073048

同一投资级对手方在 M = -2 应力下。arg = (-3.09 + sqrt(0.30)*2)/sqrt(0.70) ≈ -2.384,Phi ≈ 0.856%。条件 PD 相对 0.1% 基准跳了约 80 倍。

Case 12 · typical: 10% PD high-yield obligor, R=0.10, median macro

输入: [-1.2815515655446004,0.1,0]

期望: 0.08836790517422427

高收益对手方:z = Phi^-1(0.10) ≈ -1.282,R = 0.10,M = 0。arg = -1.282/sqrt(0.90) ≈ -1.351,Phi ≈ 8.84%。略低于 10% 基准。

Case 13 · typical: 10% PD, R=0.10, M=-1.5

输入: [-1.2815515655446004,0.1,-1.5]

期望: 0.19741968513641323

高收益对手方在中度应力 M = -1.5。arg = (-1.282 + sqrt(0.10)*1.5)/sqrt(0.90) ≈ -0.851,Phi ≈ 19.74%。约为基准两倍。

Case 14 · boundary: z=0 (PD=50%), R=0.5, M=0 returns 0.5

输入: [0,0.5,0]

期望: 0.5

z = 0 表示无条件 PD = 50%。M = 0 时 arg = 0/sqrt(0.5) = 0,Phi(0) = 0.5。条件 PD 恰为 50%。

Case 15 · boundary: z=0, R=0.5, M=-1 symmetric stress

输入: [0,0.5,-1]

期望: 0.8413447460685429

z = 0(PD = 50%),M = -1。arg = sqrt(0.5)/sqrt(0.5) = 1,Phi(1) ≈ 84.13%。条件 PD 在一倍标准差不利宏观下从 50% 跳到 84%。

Case 16 · boundary: z=0, R=0.5, M=+1 symmetric benign

输入: [0,0.5,1]

期望: 0.15865525393145707

M=-1 情形的镜像:arg = -1,Phi(-1) ≈ 15.87%。从 50% 对称塌缩到约 16%。

Case 17 · boundary: R=0 with M=+5 maximum systematic shock has no effect

输入: [0,0,5]

期望: 0.5

R = 0 完全吸收系统冲击。arg = 0/1 = 0,无论 M = +5 与否,conditional_pd = 0.5。

Case 18 · boundary: R=0 with M=-5 maximum systematic shock has no effect

输入: [0,0,-5]

期望: 0.5

R=0 与 M=+5 情形的镜像;conditional_pd = 0.5。

Case 19 · boundary: R=0.99 huge correlation, M=0 still gives 0.5

输入: [0,0.99,0]

期望: 0.5

R 非常大但 M = 0。arg = 0/sqrt(0.01) = 0,Phi(0) = 0.5。

最近提交

还没有提交记录。

编码区

实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。

加载编辑器...
计时0:00

默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。

Case 1 · statement-example: median macro, 1% PD, R=0.20

输入: [-2.326347874040841,0.2,0]

期望: 0.004648489920910659

无条件 PD = 1%(z = Phi^-1(0.01) ≈ -2.326)。R = 0.20,M = 0,arg = -2.326/sqrt(0.80) ≈ -2.601,Phi(-2.601) ≈ 0.00465 = 46.5 bp——**低于** 1% 基准。负阈值除以 sqrt(1 - R) < 1 后变得更极端,Phi 取值更小。

Case 2 · statement-example: stressed macro M=-2, 1% PD, R=0.20

输入: [-2.326347874040841,0.2,-2]

期望: 0.054695548310186026

同一对手方,应力 M = -2。arg = (-2.326 + sqrt(0.20)*2)/sqrt(0.80) ≈ -1.601,Phi(-1.601) ≈ 5.47%。从无条件 1% 跳到五倍——Vasicek 尾部放大。

Case 3 · statement-example: R = 1 returns NaN sentinel

输入: [-2.326347874040841,1,0]

期望: "NaN"

asset_correlation = 1.0 -> 分母 sqrt(1 - R) = 0,模型退化,条件 PD 未定义 -> NaN。

Case 4 · typical: benign macro M=+2, 1% PD, R=0.20

输入: [-2.326347874040841,0.2,2]

期望: 0.0001585368182744351

同一对手方,有利顺风 M = +2。arg ≈ -3.601,Phi ≈ 0.000159 = 1.59 bp。M = -2 应力情形的对称镜像。

Case 5 · typical: R = 0 absorbing, M has no effect (returns unconditional PD)

输入: [-2.326347874040841,0,-1.5]

期望: 0.010000000000000009

R = 0 -> sqrt(0)*M = 0 且 sqrt(1-0) = 1,因此 conditional_pd = Phi(z) = 1%,与 M 无关。系统因子通道关闭。

Case 6 · typical: severe stress M=-3.5, 1% PD, R=0.20

输入: [-2.326347874040841,0.2,-3.5]

期望: 0.19740245477544682

M = -3.5(比 99.9 分位还更不利)作用在 PD=1%、R=0.20 的对手方上。arg ≈ -0.851,Phi ≈ 19.74%。条件 PD 接近无条件基准的二十倍。

Case 7 · typical: 5% PD, R=0.15, median macro

输入: [-1.6448536269514722,0.15,0]

期望: 0.03720417559535216

z = Phi^-1(0.05) ≈ -1.645,R = 0.15,M = 0。arg = -1.645/sqrt(0.85) ≈ -1.784,Phi ≈ 3.72%。低于 5% 基准:负阈值除以 sqrt(1 - R) < 1 后变得更极端。

Case 8 · typical: 5% PD, R=0.15, M=-2 stress

输入: [-1.6448536269514722,0.15,-2]

期望: 0.1726036808645422

5% PD 对手方,R = 0.15,M = -2。arg ≈ -0.944,Phi ≈ 17.26%。条件 PD 相对 5% 无条件涨了三倍多。

Case 9 · typical: 5% PD, R=0.15, M=+2 benign

输入: [-1.6448536269514722,0.15,2]

期望: 0.004341844058280919

5% PD 对手方,R = 0.15,M = +2。arg ≈ -2.624,Phi ≈ 0.434%。条件 PD 压到约 43 bp。

Case 10 · typical: 0.1% PD high-grade obligor, R=0.30, M=0

输入: [-3.090232306167813,0.3,0]

期望: 0.00011057943536707526

投资级对手方:z = Phi^-1(0.001) ≈ -3.090,R = 0.30,M = 0。arg = -3.09/sqrt(0.70) ≈ -3.694,Phi ≈ 0.011%。条件 PD 略高于 1 bp。

Case 11 · typical: 0.1% PD, R=0.30, M=-2 stress

输入: [-3.090232306167813,0.3,-2]

期望: 0.008557527229073048

同一投资级对手方在 M = -2 应力下。arg = (-3.09 + sqrt(0.30)*2)/sqrt(0.70) ≈ -2.384,Phi ≈ 0.856%。条件 PD 相对 0.1% 基准跳了约 80 倍。

Case 12 · typical: 10% PD high-yield obligor, R=0.10, median macro

输入: [-1.2815515655446004,0.1,0]

期望: 0.08836790517422427

高收益对手方:z = Phi^-1(0.10) ≈ -1.282,R = 0.10,M = 0。arg = -1.282/sqrt(0.90) ≈ -1.351,Phi ≈ 8.84%。略低于 10% 基准。

Case 13 · typical: 10% PD, R=0.10, M=-1.5

输入: [-1.2815515655446004,0.1,-1.5]

期望: 0.19741968513641323

高收益对手方在中度应力 M = -1.5。arg = (-1.282 + sqrt(0.10)*1.5)/sqrt(0.90) ≈ -0.851,Phi ≈ 19.74%。约为基准两倍。

Case 14 · boundary: z=0 (PD=50%), R=0.5, M=0 returns 0.5

输入: [0,0.5,0]

期望: 0.5

z = 0 表示无条件 PD = 50%。M = 0 时 arg = 0/sqrt(0.5) = 0,Phi(0) = 0.5。条件 PD 恰为 50%。

Case 15 · boundary: z=0, R=0.5, M=-1 symmetric stress

输入: [0,0.5,-1]

期望: 0.8413447460685429

z = 0(PD = 50%),M = -1。arg = sqrt(0.5)/sqrt(0.5) = 1,Phi(1) ≈ 84.13%。条件 PD 在一倍标准差不利宏观下从 50% 跳到 84%。

Case 16 · boundary: z=0, R=0.5, M=+1 symmetric benign

输入: [0,0.5,1]

期望: 0.15865525393145707

M=-1 情形的镜像:arg = -1,Phi(-1) ≈ 15.87%。从 50% 对称塌缩到约 16%。

Case 17 · boundary: R=0 with M=+5 maximum systematic shock has no effect

输入: [0,0,5]

期望: 0.5

R = 0 完全吸收系统冲击。arg = 0/1 = 0,无论 M = +5 与否,conditional_pd = 0.5。

Case 18 · boundary: R=0 with M=-5 maximum systematic shock has no effect

输入: [0,0,-5]

期望: 0.5

R=0 与 M=+5 情形的镜像;conditional_pd = 0.5。

Case 19 · boundary: R=0.99 huge correlation, M=0 still gives 0.5

输入: [0,0.99,0]

期望: 0.5

R 非常大但 M = 0。arg = 0/sqrt(0.01) = 0,Phi(0) = 0.5。