在线 EWMA 方差:偏重近期的波动率追踪器
Online EWMA Variance — Recency-Weighted Volatility Tracker
开始编码实现 solution(x: list[float], alpha: float) -> list[float]。给定长度为 N 的逐期观测序列 x(带符号浮点,可能为空)以及位于 [0.0, 1.0] 的逐步学习率 alpha,在确定性零 warm-start 下维护单流 West 风格 EWMA 方差,并在每个观测后发出更新后的方差。第 k 步(1 起)的递推为
delta = x_k - mean_old
mean_new = (1 - alpha) * mean_old + alpha * x_k
var_new = (1 - alpha) * (var_old + alpha * delta * delta)其中 mean_0 = 0.0、var_0 = 0.0。顺序很关键:delta 用的是 mean_old,不是 mean_new;并且 (1 - alpha) 因子乘的是整个 (var_old + alpha * delta * delta) 括号,而不是只乘新增项。每个观测发出一次 var_new。输出是长度 N 的非负浮点列表;len(x) == 0 返回 []。没有错误返回路径。
例
solution([2.0, -1.0, 0.5], 0.5) 返回 [1.0, 1.5, 0.8125]。在 alpha=0.5、(1-alpha)=0.5 下手算:k=1 时 mean_old=0, delta=2.0, mean_new=0.5*0+0.5*2.0=1.0, var_new=0.5*(0+0.5*4.0)=1.0;k=2 时 mean_old=1.0, delta=-1-1=-2.0, mean_new=0.5*1+0.5*(-1)=0.0, var_new=0.5*(1.0+0.5*4.0)=0.5*3.0=1.5;k=3 时 mean_old=0.0, delta=0.5, mean_new=0+0.5*0.5=0.25, var_new=0.5*(1.5+0.5*0.25)=0.5*1.625=0.8125。方差在 k=2(与均值差距最大)达到峰值,然后被 (1-alpha) 因子部分衰减。
一次线性扫描配两个标量给出 O(N) 时间与 O(N) 输出空间;评判使用绝对浮点容差 1e-9。
参见 stubs/stub.py 的函数骨架。
实践背景
一个风控仪表盘需要为逐期收益流给出偏重近期的波动率读数——慢到忽略单 tick 噪声,又快到不让昨日尖峰主导下周数值。单流 EWMA 方差递推是标准的生产捷径:每流两个标量,每 tick 一次更新,无需维护任何历史窗口。alpha 旋钮在响应度与稳定性之间权衡——alpha 偏小则贴近长期均值,alpha 偏大则追逐最新观测。本契约采用确定性零 warm-start(而不是首样本种子),是因为它能与同样在启动时假设零状态的 EWMA 风险价值下游管道干净地组合,并且让早期步输出仅是 alpha 与观测幅度的清洁函数。隐藏契约陷阱在于更新顺序:delta 必须以前一步的均值度量,并且 (1-alpha) 因子乘的是整个 (var_old + alpha*delta*delta) 括号——拆分 bug (1-alpha)*var_old + alpha*delta*delta 与用更新后均值算 delta 的 bug,都会让每个估计悄悄偏移,并只在下游波动率读数神秘走偏时才被发现。
约束条件
- 0 <= len(x) <= 5000;每个 x[i] 为有限浮点,绝对值不超过 1e6
- 0.0 <= alpha <= 1.0(两端闭区间,包含 alpha=0 即冻结状态、alpha=1 即每步将 var 坍缩到零)
- warm-start 为确定性零初始化:mean_0 = 0.0、var_0 = 0.0(不是首样本种子)
- 更新顺序固定:先用 mean_old 计算 delta = x_k - mean_old;再 mean_new = (1-alpha)*mean_old + alpha*x_k;再 var_new = (1-alpha)*(var_old + alpha*delta*delta);最后发出 var_new
- 输出始终是长度 N 的非负浮点列表;len(x)=0 返回 []。不存在错误或哨兵返回路径
样例
Case 1 · statement-example: x=[2.0, -1.0, 0.5] at alpha=0.5 — variance grows then partially decays
输入: [[2,-1,0.5],0.5]
期望: [1,1.5,0.8125]
alpha=0.5。逐步: k=1 delta=2 → var=0.5*(0+0.5*4)=1.0; k=2 mean=1, delta=-2 → var=0.5*(1+0.5*4)=1.5; k=3 mean=0, delta=0.5 → var=0.5*(1.5+0.5*0.25)=0.8125。从零冷启动后,第二步偏差最大,随后被 (1-alpha) 因子衰减。
Case 2 · statement-example: empty observation stream returns [] regardless of alpha
输入: [[],0.5]
期望: []
空输入直接返回空列表,与 alpha 取值无关。
Case 3 · statement-example: single observation x=[0.5] at alpha=0.4 — var = (1-alpha)*alpha*x^2 = 0.06
输入: [[0.5],0.4]
期望: [0.06]
第一步从 warm-start 起步: delta=0.5, var=(1-0.4)*(0+0.4*0.25)=0.6*0.1=0.06。warm-up 偏置在单步后明显(远小于 x^2=0.25)。
最近提交
还没有提交记录。
编码区
实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。
默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。
Case 1 · statement-example: x=[2.0, -1.0, 0.5] at alpha=0.5 — variance grows then partially decays
输入: [[2,-1,0.5],0.5]
期望: [1,1.5,0.8125]
alpha=0.5。逐步: k=1 delta=2 → var=0.5*(0+0.5*4)=1.0; k=2 mean=1, delta=-2 → var=0.5*(1+0.5*4)=1.5; k=3 mean=0, delta=0.5 → var=0.5*(1.5+0.5*0.25)=0.8125。从零冷启动后,第二步偏差最大,随后被 (1-alpha) 因子衰减。
Case 2 · statement-example: empty observation stream returns [] regardless of alpha
输入: [[],0.5]
期望: []
空输入直接返回空列表,与 alpha 取值无关。
Case 3 · statement-example: single observation x=[0.5] at alpha=0.4 — var = (1-alpha)*alpha*x^2 = 0.06
输入: [[0.5],0.4]
期望: [0.06]
第一步从 warm-start 起步: delta=0.5, var=(1-0.4)*(0+0.4*0.25)=0.6*0.1=0.06。warm-up 偏置在单步后明显(远小于 x^2=0.25)。