VaR 突破率的 Wilson Score 二项置信区间
Wilson Score Binomial CI for VaR Exceedance Rate
开始编码实现 solution(exceedance_count: int, total_obs: int, z_critical: float) -> list[float]。某风险台每日 VaR 回溯检验看板会在 Kupiec POF 似然比检验旁边给出实现突破率的置信区间。给定观测到的突破次数 exceedance_count(= N)、回溯窗口长度 total_obs(= T)、高斯临界值 z_critical(= z,例如 1.96 对应 95% 双侧 CI),返回 Wilson (1927) score 区间
p_hat = N / T
denom = 1 + z**2 / T
center = (p_hat + z**2 / (2*T)) / denom
margin = (z / denom) * sqrt(p_hat * (1 - p_hat) / T + z**2 / (4 * T**2))
[lower, upper] = [center - margin, center + margin]作为长度为 2 的 list[float] 返回。Wilson 是流行病学、质量控制和 VaR 回溯检验中标准的二项比例 CI——在 T 较小或 p_hat 极端时优于朴素的 Wald 区间 p_hat ± z*sqrt(p_hat*(1-p_hat)/T),因为 Wilson 在 0 和 1 边界附近覆盖率正确,而 Wald 在边界处坍缩为零宽。
实现是常数时间的:一次除法得 p_hat、一次平方、一次 sqrt,加上少量算术运算。难点不在算法复杂度,而在于把公式抄对(中心和半宽都要除 denom;sqrt 内有两项)。
算例
solution(3, 250, 1.96) 返回 [0.004089245839774543, 0.03468138907585788]。逐步:p_hat = 3/250 = 0.012;z**2 = 3.8416;denom = 1 + 3.8416/250 = 1.0153664。中心 = (0.012 + 3.8416/500) / 1.0153664 ≈ 0.01938。半宽 = (1.96/1.0153664) * sqrt(0.012*0.988/250 + 3.8416/(4*250**2)) ≈ 1.9305 * 0.007925 ≈ 0.01530。下界 ≈ 0.00409,上界 ≈ 0.03468。期望突破率 p = 0.01 落在区间内,95% 置信度下与模型一致。
三个易错点
第一,Wilson 不是 Wald。Wald 区间 p_hat ± z*sqrt(p_hat*(1-p_hat)/T) 以 p_hat 为中心、无分母、在 p_hat=0 处坍缩为 [0, 0]、在 p_hat=1 处坍缩为 [1, 1]。Wilson 以 (p_hat + z**2/(2T)) / denom 为中心、整体除以 denom、在 sqrt 内加 z**2/(4T**2)——正是这点让区间在边界处不退化。写 Wald 公式的作者得到一个不同、性质更差的区间,会在 N=0 和 N=T 边界测试上明显失败。
第二,**分母 1 + z**2/T。Wilson 中心和半宽都**要除以 denom = 1 + z**2/T。z=1.96、T=100 时该分母约为 1.0384,漏除会把区间放大几个百分点——小到让走 Wald 路线的作者以为可行,但足以在每个典型测试上踩 rel_tol=1e-9 比较器。
第三,sqrt 含两项。Wilson 半宽的 sqrt 是 sqrt(p_hat*(1-p_hat)/T + z**2/(4*T**2)),不是 sqrt(p_hat*(1-p_hat)/T)。z**2/(4T**2) 项在大 T 下很小(z=1.96、T=100 时约 4e-5),但正是这一项防止边界处坍缩——p_hat=0 时 sqrt 内第一项为 0,只剩第二项托住区间。漏掉第二项就退化回 Wald 的 sqrt,会在 N=0/N=T 边界测试上崩。
哨兵与边界
T = 0 在合约下不可达(total_obs >= 1),但参考解防御性地对该输入返回 [float('nan'), float('nan')]。
z = 0(无置信度)给出退化为 p_hat 处的零宽 CI,例如 solution(5, 100, 0.0) == [0.05, 0.05]。约束允许这一角点,因为它偶尔用作健全性检查(z=0 时中心公式必须退化为 p_hat;若不退化,说明 denom != 1 被错用)。N=0, z=0 时返回 [0, 0];N=T, z=0 时返回 [1, 1]。
p_hat = 0(N=0):下界恰为 0(在 abs_tol=1e-9 的浮点噪声内——参考解可能给出约 -5.55e-17 的极小负数);上界为 (z**2/T) / (1 + z**2/T) > 0。这是 Wilson 胜过 Wald 最干净的演示:z≈2 下经验法则 upper ≈ 3/T(rule of three)正是从此公式落出。
p_hat = 1(N=T):上一情形的镜像——下界为 1 / (1 + z**2/T) < 1,上界恰为 1。
p_hat = 0.5(N = T/2):Wilson 区间关于 0.5 严格对称(仅此一点严格对称——其他位置 Wilson 不对称,与构造上对称的 Wald 不同)。
大 T:T -> infinity 时 Wilson 收敛到 Wald,因为 z**2/T -> 0 且 z**2/(4T**2) -> 0。T=10000 时两者相差约 z**2/T ≈ 4e-4。
实践背景
Wilson score 区间是二项比例的标准频率派置信区间。在 VaR 回溯检验看板上它回答:“给定观测到的突破次数,真实突破率的合理范围是什么?”——与 Kupiec POF 检验“观测率与模型率统计上是否一致?”是姊妹问题。两者相关:5% 显著性水平下 Kupiec 拒绝大致对应模型率 p = 1 - alpha 落在 95% Wilson CI 之外。同一看板上的其他视角包括 Basel 红绿灯分区分类器(按计数分类的分区)、突破集群计数统计量(最长连续突破游程)、以及 Christoffersen 的独立性与条件覆盖性 LR 检验(联合覆盖与独立性)。Wilson 占据“突破率的区间估计”这一格——区别于检验统计量,也区别于评估突破*严重性*而非*频次*的量级损失 / pinball / ES 比率回溯检验。
约束条件
- 1 <= total_obs <= 10000(T >= 1)
- 0 <= exceedance_count <= total_obs(N ∈ [0, T])
- 0.0 <= z_critical <= 5.0(典型高斯临界值)
- 输出:长度为 2 的 list[float]——`[lower_bound, upper_bound]`;元素位于 `[0, 1]` 内(abs_tol=1e-9 容差下含浮点噪声);比较器 rel_tol=1e-9、abs_tol=1e-9、ordered=true;T==0 返回 `[NaN, NaN]`(防御性哨兵——合约下不可达)
样例
Case 1 · statement-example: T=250 N=3 z=1.96 (99% VaR daily, 95% CI)
输入: [3,250,1.96]
期望: [0.004089245839774543,0.03468138907585788]
p_hat = 3/250 = 0.012(略高于 1% 期望)。Wilson 95% CI ≈ [0.00409, 0.03468]。期望突破率 p = 0.01 落在区间内,95% 置信度下与模型一致。
Case 2 · visible: N=0 boundary, Wilson upper > 0 (Wald gives 0)
输入: [0,250,1.96]
期望: [0,0.015133847249623387]
零突破时 p_hat = 0;Wilson 下界 = 0,上界 = z**2/T / (1 + z**2/T) ≈ 0.01513。Wald 区间会(错误地)给出 [0, 0] —— Wilson 在 sqrt 中加的 z**2/(4T**2) 项保证上界非零。
Case 3 · visible: N=T boundary, Wilson lower < 1 (Wald gives 1)
输入: [250,250,1.96]
期望: [0.9848661527503766,1]
全部突破;p_hat = 1。Wilson 下界 ≈ 0.9849,上界 = 1。Wald 在边界处给出 [1, 1](零宽)——Wilson 因 z**2/(4T**2) 项保持有信息。
Case 4 · visible: N=T/2 symmetric around 0.5
输入: [125,250,1.96]
期望: [0.4384901486556353,0.5615098513443647]
p_hat = 0.5 时 Wilson 区间关于 0.5 严格对称(只有此处严格对称)。半宽 ≈ 0.06151。
Case 5 · visible: T=100 N=10 small T (Wilson != Wald)
输入: [10,100,1.96]
期望: [0.05522854161313613,0.1743673043676654]
p_hat = 0.10、T=100、z=1.96。Wilson 95% CI ≈ [0.0552, 0.1744];中心 ≈ 0.1148(比 0.10 上移 z**2/(2T)/denom)。Wald 给出 [0.0412, 0.1588](中心 0.10)——明显不同。
最近提交
还没有提交记录。
编码区
实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。
默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。
Case 1 · statement-example: T=250 N=3 z=1.96 (99% VaR daily, 95% CI)
输入: [3,250,1.96]
期望: [0.004089245839774543,0.03468138907585788]
p_hat = 3/250 = 0.012(略高于 1% 期望)。Wilson 95% CI ≈ [0.00409, 0.03468]。期望突破率 p = 0.01 落在区间内,95% 置信度下与模型一致。
Case 2 · visible: N=0 boundary, Wilson upper > 0 (Wald gives 0)
输入: [0,250,1.96]
期望: [0,0.015133847249623387]
零突破时 p_hat = 0;Wilson 下界 = 0,上界 = z**2/T / (1 + z**2/T) ≈ 0.01513。Wald 区间会(错误地)给出 [0, 0] —— Wilson 在 sqrt 中加的 z**2/(4T**2) 项保证上界非零。
Case 3 · visible: N=T boundary, Wilson lower < 1 (Wald gives 1)
输入: [250,250,1.96]
期望: [0.9848661527503766,1]
全部突破;p_hat = 1。Wilson 下界 ≈ 0.9849,上界 = 1。Wald 在边界处给出 [1, 1](零宽)——Wilson 因 z**2/(4T**2) 项保持有信息。
Case 4 · visible: N=T/2 symmetric around 0.5
输入: [125,250,1.96]
期望: [0.4384901486556353,0.5615098513443647]
p_hat = 0.5 时 Wilson 区间关于 0.5 严格对称(只有此处严格对称)。半宽 ≈ 0.06151。
Case 5 · visible: T=100 N=10 small T (Wilson != Wald)
输入: [10,100,1.96]
期望: [0.05522854161313613,0.1743673043676654]
p_hat = 0.10、T=100、z=1.96。Wilson 95% CI ≈ [0.0552, 0.1744];中心 ≈ 0.1148(比 0.10 上移 z**2/(2T)/denom)。Wald 给出 [0.0412, 0.1588](中心 0.10)——明显不同。