← 返回编程题库
coding-var-hit-residual-lag1-autocorrelation中等免费版1000ms未尝试

VaR 命中残差的 Lag-1 自相关

Lag-1 Autocorrelation of VaR Hit Indicators

开始编码

实现 solution(realized_pnls: list[float], var_forecasts: list[float]) -> float。某风险台每日 VaR 回溯检验看板把这一例程与突破计数、Christoffersen LR_ind 统计量并列运行,作为 VaR 突破在时间上是否聚集的快速可视化诊断。给定长度 T 的每日 PnL 与对应的次日 VaR 预测(正损失数),构造命中指示序列

h[t] = 1   若  realized_pnls[t] < -var_forecasts[t]
h[t] = 0   否则

并返回标准样本 lag-1 自相关

acf_1 = sum_{t=1..T-1} (h[t] - h_bar) * (h[t-1] - h_bar)
        ----------------------------------------------------
              sum_{t=0..T-1} (h[t] - h_bar)^2

其中 h_bar = (1/T) * sum_t h[t] 是样本均值。acf_1 强正说明突破集中在被模型遗漏的波动率簇中;强负说明命中-未命中交替过度(常见于波动率预测在突破后一日才反应);接近 0 与 i.i.d. 突破一致。实现是三遍线性扫描(均值、分子交叉积、分母平方偏差);除指示数组外空间为 O(1)。

算例

solution([-60000.0, -55000.0, -70000.0, 8000.0, 4000.0, -52000.0, -58000.0, 5000.0], [50000.0, 50000.0, 50000.0, 50000.0, 50000.0, 50000.0, 50000.0, 50000.0]) 返回 0.058333...。逐日突破判定:第 0、1、2 日亏损超过 50000(命中);第 3、4 日盈利(未命中);第 5、6 日亏损超过 50000(命中);第 7 日盈利(未命中)。所以 h = [1, 1, 1, 0, 0, 1, 1, 0]h_bar = 5/8 = 0.625。中心化偏差在命中处为 +3/8、未命中处为 -5/8。7 个 lag-1 交叉积之和为 7/64;8 个平方偏差之和为 5*(3/8)^2 + 3*(5/8)^2 = 15/8。故 acf_1 = (7/64) / (15/8) = 7/120 ≈ 0.0583——轻度正自相关,与可见的两段短聚簇一致。

哨兵与边界

T < 2:连续配对为 0,lag-1 ACF 未定义;返回 float('nan')。覆盖空列表与任意单日窗口。

分母 == 0:平方偏差和归零的唯一可能是 h 为常数——窗口内全无突破(每项都是 0)或每日都突破(每项都是 1)。两种情形下中心化残差全为 0,公式是 0 / 0。返回 float('nan')——无方差可相关。漏掉该分支的写法在全未命中输入(平静期最常见)或全命中输入(合成压力测试中偶发)上除零崩溃。

「除单一翻转外为常数」的命中模式——如 [0, ..., 0, 1]——方差仍为正,ACF 良定义;不要把常数-h 哨兵扩展到真正的常数之外。

五个易错点

第一严格不等与非严格不等。命中条件为 realized_pnls[t] < -var_forecasts[t];损失恰好等于阈值是模型预测准确,不是命中。把 < 写成 <= 的作者多算的命中数恰为「相等日数」,并污染下游所有中心化偏差。判别测试在六日窗口里塞了三天精确相等——严格版返回 -7/12、非严格版返回 ≈ -0.033

第二,**var_forecasts 的符号约定。预测为正损失数**:var_forecasts[t] = 50000.0 意味着「明日亏损不超过 50000 的把握很高」,故突破判定为 realized_pnls[t] < -var_forecasts[t](注意一元负号)。把 var_forecasts[t] 当作有符号 PnL 下界、写成 realized_pnls[t] < var_forecasts[t] 的作者每天都判错。

第三标准样本 ACF 公式分子分母都要减去样本均值 h_bar:分子是 (h[t] - h_bar) * (h[t-1] - h_bar)、分母是 (h[t] - h_bar)^2。任意一边漏减 h_bar(例如以未中心化分子除以中心化分母)得到的偏值与教科书 ACF 不一致。

第四求和范围不对称。分子是 T-1 个 lag-1 交叉积(t = 1..T-1);分母是 T 个平方偏差(t = 0..T-1)。两边硬凑同一区间——例如把分母也从 t = 1 起算「对齐」分子——得到的是另一个(同样有偏)ACF,与标准约定不一致。

第五分母 == 0 哨兵。h 为常数(全 0 或全 1)时所有中心化偏差为 0、分母为 0。不要默默除以 0;返回 float('nan') 表示「无方差可相关」。形式与 Kupiec / Christoffersen 的稀疏数据 NaN 哨兵一致——VaR 回溯检验姊妹族在该处保持统一。

实践背景

正确标定的 VaR 模型下,命中指示序列应近似 i.i.d. Bernoulli——边际突破率匹配理论率(Kupiec POF)相邻命中相互独立(Christoffersen LR_ind)。lag-1 样本 ACF 是后者的最简标量诊断:正 ACF 表示命中在时间上聚集(被模型遗漏的波动率簇/regime);负 ACF 表示反聚集(常见于波动率预测在突破后一日才反应);零 ACF 与 i.i.d. 突破一致。LR_ind 不易在图上读出,但 ACF 在折线图上一眼可见,故被放在每日回溯检验看板的突破计数旁边,配合 LR_ind 完成正式卡方决断。

本题是题库的标量诊断姊妹——区别于 coding-christoffersen-independence-lr-test(同一性质的形式化卡方似然比检验)、coding-var-backtest-exceedance-cluster-count(数最长连续突破段,而非自相关)、coding-kupiec-pof-likelihood-ratio(无条件覆盖性、忽略时序结构)、coding-lopez-magnitude-loss-function-var-backtest(按损失幅度加权、非时序诊断)。

约束条件

  • 0 <= len(realized_pnls) == len(var_forecasts) <= 1500。两序列等长。
  • |realized_pnls[t]| <= 1e6;元素为有符号有限浮点数(正为利润、负为亏损)。
  • 0.0 <= var_forecasts[t] <= 1e6;VaR 预测为**正损失数**(非负)。
  • 输出:float —— lag-1 样本自相关 ∈ [-1, 1],或 `float('nan')`(T<2 或 h 为常数);rel_tol=1e-9、abs_tol=1e-9;NaN 与 NaN 视为相等。

样例

Case 1 · statement-example: clustered hits in 8-day window

输入: [[-60000,-55000,-70000,8000,4000,-52000,-58000,5000],[50000,50000,50000,50000,50000,50000,50000,50000]]

期望: 0.058333333333333334

八天窗口含两段连续突破。命中指示 h=[1,1,1,0,0,1,1,0],h_bar=5/8=0.625。中心化偏差在命中处为 3/8、未命中处为 -5/8。7 项交叉乘积之和为 7/64;8 项平方偏差之和为 5*(3/8)^2 + 3*(5/8)^2 = 15/8。ACF = (7/64)/(15/8) = 7/120 ≈ 0.0583。轻度正自相关,与可见的短聚簇一致。

Case 2 · visible: T=1 below minimum pair count

输入: [[-100],[50]]

期望: "NaN"

T=1 没有任何连续配对,lag-1 ACF 未定义。返回 float('nan')。空列表返回同样的 NaN。

Case 3 · visible: alternating hits give strong negative autocorrelation

输入: [[10,-200,10,-200,10,-200,10,-200,10,-200,10,-200,10,-200,10,-200,10,-200,10,-200],[100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100]]

期望: -0.95

严格交替的命中模式 h=[0,1,0,1,...] 长度 20(10 次命中、10 次未命中)。h_bar=0.5,所有偏差为 ±0.5。19 个 lag-1 交叉积都为 -0.25;分子 = -19*0.25 = -4.75。分母 = 20*0.25 = 5.0。ACF = -4.75/5.0 = -0.95——强负自相关,反聚簇的标志。

Case 4 · visible: 50-day window with no exceedances yields denominator=0

输入: [[10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10],[100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100]]

期望: "NaN"

50 天全部未突破,h 为恒为 0 的常数序列。样本均值 h_bar=0;每个偏差均为 0;分母平方偏差之和为 0;ACF 为 0/0。返回 float('nan')——表示「无方差可相关」。任意全突破输入同理。

最近提交

还没有提交记录。

编码区

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

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

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

Case 1 · statement-example: clustered hits in 8-day window

输入: [[-60000,-55000,-70000,8000,4000,-52000,-58000,5000],[50000,50000,50000,50000,50000,50000,50000,50000]]

期望: 0.058333333333333334

八天窗口含两段连续突破。命中指示 h=[1,1,1,0,0,1,1,0],h_bar=5/8=0.625。中心化偏差在命中处为 3/8、未命中处为 -5/8。7 项交叉乘积之和为 7/64;8 项平方偏差之和为 5*(3/8)^2 + 3*(5/8)^2 = 15/8。ACF = (7/64)/(15/8) = 7/120 ≈ 0.0583。轻度正自相关,与可见的短聚簇一致。

Case 2 · visible: T=1 below minimum pair count

输入: [[-100],[50]]

期望: "NaN"

T=1 没有任何连续配对,lag-1 ACF 未定义。返回 float('nan')。空列表返回同样的 NaN。

Case 3 · visible: alternating hits give strong negative autocorrelation

输入: [[10,-200,10,-200,10,-200,10,-200,10,-200,10,-200,10,-200,10,-200,10,-200,10,-200],[100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100]]

期望: -0.95

严格交替的命中模式 h=[0,1,0,1,...] 长度 20(10 次命中、10 次未命中)。h_bar=0.5,所有偏差为 ±0.5。19 个 lag-1 交叉积都为 -0.25;分子 = -19*0.25 = -4.75。分母 = 20*0.25 = 5.0。ACF = -4.75/5.0 = -0.95——强负自相关,反聚簇的标志。

Case 4 · visible: 50-day window with no exceedances yields denominator=0

输入: [[10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10],[100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100]]

期望: "NaN"

50 天全部未突破,h 为恒为 0 的常数序列。样本均值 h_bar=0;每个偏差均为 0;分母平方偏差之和为 0;ACF 为 0/0。返回 float('nan')——表示「无方差可相关」。任意全突破输入同理。