← 返回编程题库
coding-ewma-weighted-historical-var中等免费版2000ms未尝试

EWMA 加权历史 VaR

EWMA-Weighted Historical VaR

开始编码

RiskMetrics 风格的时间衰减加权是对等权重历史 VaR 最经典的改写:每个观测都按它的「年龄」打上一个指数权重,让一个刚刚经历完波动率冲击的交易台在冲击还没从回看窗口里淡出之前,就能看到自己的 99% VaR 抬高。请实现 solution(pnl_samples: list[float], alpha: float, decay: float) -> float。输入是按时间排序的 PnL 序列(最旧的在索引 0、最新的在索引 n-1,带符号:正值=盈利)、VaR 置信度 alpha、每步衰减因子 decay。返回加权历史分位数 VaR,并以正的损失数值报告(序列为空时返回 float('nan'))。

参考算法分五步。(1) 构造原始权重 raw_w[i] = decay**(n - 1 - i)i0..n-1——raw_w[n-1] = 1(最新观测拿到最大权重)、raw_w[0] = decay**(n-1)(最旧观测拿到最小)。(2) 归一化:w[i] = raw_w[i] / sum(raw_w),让 sum(w) = 1。(3) 把每个 pnl_samples[i] 与对应的 w[i] 配对,按 pnl 升序排序。(4) 从最小 pnl 开始累积权重,找最小的 k 使得 cumulative_weight[k] >= (1 - alpha) - 1e-121e-12 epsilon 用来吸收加权和的 IEEE-754 漂移,与等权重历史 VaR 兄弟题口径一致)。(5) 阈值 pnl 就是 sorted_pairs[k][0];输出 -sorted_pairs[k][0],让尾部为亏损时输出正数。整体复杂度是排序 O(n log n) 加上权重构造和累积扫描的 O(n)。

solution([-0.05, 0.02, 0.01, -0.03, -0.02], 0.8, 0.9) 应返回 0.03n = 5decay = 0.9 时,从最旧到最新的原始权重是 [0.6561, 0.729, 0.81, 0.9, 1.0],求和得 4.0951;归一化后约为 [0.1602, 0.1780, 0.1978, 0.2198, 0.2442]。配对后按 pnl 升序排序得 (-0.05, 0.1602), (-0.03, 0.2198), (-0.02, 0.2442), (0.01, 0.1978), (0.02, 0.1780),累积权重为 0.1602, 0.3800, 0.6242, 0.8220, 1.0000alpha = 0.8 时阈值为 1 - 0.8 = 0.2k = 00.1602 < 0.2 不够,k = 10.3800 >= 0.2,所以阈值 pnl 是 -0.03,VaR 等于 0.03。注意,在同一份数据上 *等权重* 历史 VaR(decay = 1.0)是 0.05,因为最差的那笔观测(索引 0 处的 -0.05)是最旧的——时间衰减加权对它打了折扣,加权 VaR 因此变小。

实践背景

四个常见正确性陷阱。第一,*权重索引方向*:最新观测在索引 n-1,要拿到最大权重(decay**0 = 1)。如果写成 raw_w[i] = decay**i,时间衰减方向就翻转了;在波动率抬升的窗口里,这个指标会偏低,因为新出现的波动反而被当成了远古样本。第二,*必须归一化*:cum_w[k] >= 1 - alpha 这条阈值规则只有在总权重等于 1 时才有意义;归一化的分母就是等比数列和 (1 - decay**n) / (1 - decay)decay != 1 时)。第三,*排序方向*:pnl 必须升序排列——尾部是最左侧的累积切片。降序排序后再从顶部读取 (1 - alpha) 累积分位,得到的是上方尾部的「VaR」,方向反了。第四,1e-12 *epsilon 兜底* 与等权重历史 VaR 兄弟题保持一致:在精确相等的边界,sum(decay**k * pnl_weight) 的 IEEE-754 漂移会让累积值略小于 1 - alpha,让答案下标多走一位;少了 epsilon,教科书答案 k 会被误判成 k+1

两个 decay 退化情形顺手当作 sanity check。decay = 0.0 时除最新观测外所有原始权重都是 0(任何正数的 0 次方等于 1,0**正数 = 0),累积权重检查会在最新观测对应的排序位置就达标,结果是 -pnl_samples[-1],与 alpha 无关。decay = 1.0 时所有原始权重都是 1,归一化后是 1/n,问题退化为标准等权重历史 VaR——和兄弟题给出的阈值完全一致。等值 PnL 的并列也无碍:年龄不同但 PnL 相同的观测之间排序不确定,但它们权重之和与排序顺序无关,因此累积权重阈值是良定的(在并列簇内取任一下标都对应同一个 pnl 值);Python 的稳定升序排序会取最小的那个 k

约束条件

  • 0 ≤ len(pnl_samples) ≤ 1500。当列表为空时返回 `float('nan')` 作为「无观测」哨兵。
  • |pnl_samples[i]| ≤ 1e6,均为有限浮点数。最新观测位于索引 `n - 1`。
  • 0.5 ≤ alpha < 1.0(常见 VaR 置信度:0.5、0.9、0.95、0.99、0.999)。
  • 0.0 ≤ decay ≤ 1.0。decay = 0.94 是 RiskMetrics 日频的标准取值(半衰期约 11 天)。
  • 阈值规则:按 pnl 升序排序后,从最小 pnl 累积归一化权重,取最小的 `k` 满足 `cumulative_weight[k] >= (1 - alpha) - 1e-12`。
  • VaR 以正的损失数值输出(若阈值 pnl 仍然盈利则为负)。
  • 浮点容忍:rel_tol=1e-9,abs_tol=1e-9。

样例

Case 1 · statement-example, n=5 alpha=0.8 decay=0.9

输入: [[-0.05,0.02,0.01,-0.03,-0.02],0.8,0.9]

期望: 0.03

n=5、decay=0.9,原始权重从最旧到最新为 [0.6561, 0.729, 0.81, 0.9, 1.0]、归一化后约 [0.1602, 0.178, 0.1978, 0.2198, 0.2442]。按 pnl 升序排序得 (-0.05,0.1602),(-0.03,0.2198),(-0.02,0.2442),(0.01,0.1978),(0.02,0.178);累积 0.1602, 0.38, 0.6242, 0.822, 1.0。alpha=0.8 -> 阈值 0.2,第一个满足的下标 k=1 对应 pnl=-0.03,VaR=0.03。同一份数据下等权重 VaR 是 0.05,时间衰减把最旧那笔 -0.05 的影响打了折扣。

Case 2 · visible, n=4 alpha=0.95 decay=1.0 collapses to equal-weighted

输入: [[-0.04,-0.02,0.01,0.005],0.95,1]

期望: 0.04

decay=1.0 时所有归一化权重都是 1/4=0.25。排序后累积 0.25, 0.5, 0.75, 1.0;alpha=0.95、阈值=0.05,第一个 k=0 满足,对应 pnl=-0.04,VaR=0.04。

Case 3 · visible, n=3 alpha=0.95 decay=0.0 only most-recent counts

输入: [[-0.1,-0.05,0.02],0.95,0]

期望: -0.02

decay=0.0 退化为「只有最新观测」:raw_w=[0,0,1]、阈值无论多大都落在最新观测的排序位置上,VaR = -pnl_samples[-1] = -0.02 = -0.02(实际为负数,因为最新一笔是盈利)。

最近提交

还没有提交记录。

编码区

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

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

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

Case 1 · statement-example, n=5 alpha=0.8 decay=0.9

输入: [[-0.05,0.02,0.01,-0.03,-0.02],0.8,0.9]

期望: 0.03

n=5、decay=0.9,原始权重从最旧到最新为 [0.6561, 0.729, 0.81, 0.9, 1.0]、归一化后约 [0.1602, 0.178, 0.1978, 0.2198, 0.2442]。按 pnl 升序排序得 (-0.05,0.1602),(-0.03,0.2198),(-0.02,0.2442),(0.01,0.1978),(0.02,0.178);累积 0.1602, 0.38, 0.6242, 0.822, 1.0。alpha=0.8 -> 阈值 0.2,第一个满足的下标 k=1 对应 pnl=-0.03,VaR=0.03。同一份数据下等权重 VaR 是 0.05,时间衰减把最旧那笔 -0.05 的影响打了折扣。

Case 2 · visible, n=4 alpha=0.95 decay=1.0 collapses to equal-weighted

输入: [[-0.04,-0.02,0.01,0.005],0.95,1]

期望: 0.04

decay=1.0 时所有归一化权重都是 1/4=0.25。排序后累积 0.25, 0.5, 0.75, 1.0;alpha=0.95、阈值=0.05,第一个 k=0 满足,对应 pnl=-0.04,VaR=0.04。

Case 3 · visible, n=3 alpha=0.95 decay=0.0 only most-recent counts

输入: [[-0.1,-0.05,0.02],0.95,0]

期望: -0.02

decay=0.0 退化为「只有最新观测」:raw_w=[0,0,1]、阈值无论多大都落在最新观测的排序位置上,VaR = -pnl_samples[-1] = -0.02 = -0.02(实际为负数,因为最新一笔是盈利)。