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

分制度条件历史 VaR

Regime-Conditional Historical VaR

开始编码

当一个交易台已经把自己看成是在两种明显不同的制度下运行(例如低波动的 calm 和高波动的 stressed,由上游制度分类器打标),它会按制度分别报 VaR,让今天 PnL 比对的阈值正好对应今天的制度。请实现 solution(pnl_samples: list[float], regime_indicator: list[int], alpha: float) -> list[float]。输入是按时间排序的 PnL 序列(带符号:正值=盈利)、等长的制度标签序列(每位严格是 0=calm 或 1=stressed)和 VaR 置信度 alpha。返回 [var_calm, var_stressed]:每个制度的历史 VaR,按 -sorted_r[k - 1] 计算(通常是正的损失数;如果该制度选中的尾部观测本身仍盈利,结果可能为负数——不要钳到零);如果某个制度没有样本,对应位返回 float('nan')

参考算法分三步。(1) *按制度分桶*:同步遍历 pnl_samplesregime_indicatorregime_indicator[t] == 0 时把 pnl_samples[t] 追加到 pnl_calm,否则追加到 pnl_stressed。(2) *逐制度计算 VaR*:每条桶若为空返回 float('nan');否则升序排序、按 k = max(1, ceil(N_r * (1 - alpha) - 1e-12)) 取尾部下标(N_r 是该制度样本数)、读取 -sorted_r[k - 1]。(3) 按 [var_calm, var_stressed] 的固定顺序返回。整体复杂度是分桶的 O(T) 加上每个制度排序的 O(N_r log N_r)。

solution([-0.05, 0.02, -0.03, 0.01, -0.04, -0.02, 0.005, -0.06], [0, 0, 0, 0, 1, 1, 1, 1], 0.95) 应返回 [0.05, 0.06]。calm 桶(制度 0)收集 [-0.05, 0.02, -0.03, 0.01],升序排序为 [-0.05, -0.03, 0.01, 0.02]N_0 = 4alpha = 0.95k = max(1, ceil(4 * 0.05 - 1e-12)) = max(1, 1) = 1,所以 var_calm = -sorted[0] = -(-0.05) = 0.05。stressed 桶(制度 1)收集 [-0.04, -0.02, 0.005, -0.06],升序排序为 [-0.06, -0.04, -0.02, 0.005]N_1 = 4alpha = 0.95k = 1,所以 var_stressed = -(-0.06) = 0.06。本例两个制度样本数相同,但 stressed 这边的最深回撤更大,因此 stressed 的 VaR 也更大——这正是分制度条件化想要凸显的差异。

实践背景

六个正确性陷阱。第一,*排序前先按制度分桶*:排序必须在每个制度自己的桶内独立做。先对联合序列排序再按制度切片,等于已经把制度标签丢了,得到的数没有统计意义。第二,*k 公式里要用每制度的 N_r,不能用全局 T*:alpha = 0.95 时一个 20 样本的制度 k = max(1, ceil(20 * 0.05 - 1e-12)) = 1,而 100 样本的联合分布会用 k = 5;混用这两个尺度是最常见的暗坑。第三,*VaR 是尾部那笔的相反数*(-sorted_r[k - 1]);直接报 sorted_r[k - 1] 在亏损时会得到负数,符号约定就反了。第四,*空制度返回 NaN*,既不是 0、也不能跳过:下游归因面板按固定下标读取,少一位或写成 0 都会让本来「没样本」的制度被误读成「没风险」。第五,*输出严格是长度 2 的列表*,顺序是 [var_calm, var_stressed];返回 dict、单一值、或者把两制度反过来都会破坏契约。第六,k 公式里的 1e-12 *epsilon 兜底* 与所有历史 VaR 兄弟题保持一致:没有它的话,ceil(20 * (1 - 0.95)) 在不同机器上可能得到 ceil(0.9999999999999998) = 1ceil(1.0000000000000002) = 2(乘法的舍入路径不同),有 epsilon 才能把两条路径都钳到 k = 1。

本题是历史 VaR 家族里的「分制度条件化」兄弟题,与多 alpha(同一组样本不同 alpha)、滚动 K 窗(无制度的滑窗)、EWMA 加权(按时间衰减不按制度)、滤波历史模拟(按波动率重标)、自定义权重(任意逐样本权重)、Cornish-Fisher(带偏度峰度的参数尾)等兄弟题分属不同切面。共同骨架是「单桶排序、读第 k 个尾部值、取负号」;区分点在于「桶」如何定义。

约束条件

  • 0 ≤ len(pnl_samples) == len(regime_indicator) ≤ 1500。两个列表长度必须一致(指示器给每笔 PnL 打标签)。
  • regime_indicator[t] 严格只能是 0(calm)或 1(stressed),不接受其他值。
  • |pnl_samples[t]| ≤ 1e6,均为有限浮点数。
  • 0.5 ≤ alpha < 1.0(常见 VaR 置信度:0.5、0.9、0.95、0.99、0.999)。
  • 每个制度的尾部下标:`k = max(1, ceil(N_r * (1 - alpha) - 1e-12))`,N_r 是该制度的样本数——不是全局 T。
  • 输出长度严格为 2:`[var_calm, var_stressed]`。每个条目是 `-sorted_r[k - 1]`(通常是正的损失数,但当该制度尾部观测仍然盈利时可能为负数——不要在 0 处截断),或 `float('nan')`(该制度无样本时)。
  • 浮点容忍:rel_tol=1e-9,abs_tol=1e-9。

样例

Case 1 · statement-example, T=8 alpha=0.95 split 4/4

输入: [[-0.05,0.02,-0.03,0.01,-0.04,-0.02,0.005,-0.06],[0,0,0,0,1,1,1,1],0.95]

期望: [0.05,0.06]

calm=[-0.05,0.02,-0.03,0.01] 升序 [-0.05,-0.03,0.01,0.02],N=4、k=ceil(4*0.05)=1,VaR_calm=0.05;stressed=[-0.04,-0.02,0.005,-0.06] 升序 [-0.06,-0.04,-0.02,0.005],k=1,VaR_stressed=0.06。

Case 2 · visible, T=8 alpha=0.5 mid-quantile

输入: [[-0.05,0.02,-0.03,0.01,-0.04,-0.02,0.005,-0.06],[0,0,0,0,1,1,1,1],0.5]

期望: [0.03,0.04]

alpha=0.5、N=4、k=ceil(2)=2。calm 排序后第 2 项 -0.03,VaR_calm=0.03;stressed 排序后第 2 项 -0.04,VaR_stressed=0.04。

Case 3 · visible, all-calm regime returns NaN for stressed

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

期望: [0.1,"NaN"]

stressed 无样本 -> NaN。calm N=3、alpha=0.9、k=1,升序 [-0.10,-0.02,0.05],VaR_calm=0.10。

最近提交

还没有提交记录。

编码区

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

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

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

Case 1 · statement-example, T=8 alpha=0.95 split 4/4

输入: [[-0.05,0.02,-0.03,0.01,-0.04,-0.02,0.005,-0.06],[0,0,0,0,1,1,1,1],0.95]

期望: [0.05,0.06]

calm=[-0.05,0.02,-0.03,0.01] 升序 [-0.05,-0.03,0.01,0.02],N=4、k=ceil(4*0.05)=1,VaR_calm=0.05;stressed=[-0.04,-0.02,0.005,-0.06] 升序 [-0.06,-0.04,-0.02,0.005],k=1,VaR_stressed=0.06。

Case 2 · visible, T=8 alpha=0.5 mid-quantile

输入: [[-0.05,0.02,-0.03,0.01,-0.04,-0.02,0.005,-0.06],[0,0,0,0,1,1,1,1],0.5]

期望: [0.03,0.04]

alpha=0.5、N=4、k=ceil(2)=2。calm 排序后第 2 项 -0.03,VaR_calm=0.03;stressed 排序后第 2 项 -0.04,VaR_stressed=0.04。

Case 3 · visible, all-calm regime returns NaN for stressed

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

期望: [0.1,"NaN"]

stressed 无样本 -> NaN。calm N=3、alpha=0.9、k=1,升序 [-0.10,-0.02,0.05],VaR_calm=0.10。