在线 EWMA 残差流:以"先前"指数加权均值衡量当期收益的意外度
Online EWMA Residual Stream — Surprise-vs-Prior Exponential-Weight Mean
开始编码实现 solution(returns: list[float], lam: float) -> list[float]。给定一段逐期收益序列 returns 与 EWMA 衰减参数 lam(0 < lam < 1),维护在线 EWMA 并对每个新观测 r_t 输出与"先前"EWMA 的残差 e_t = r_t − m_{t-1}。这里 m_{t-1} 仅累积 r_0..r_{t-1},不包含当期 r_t;warm-up 约定 m_{-1} = 0,因此 e_0 = r_0。EWMA 的递推为 m_t = lam · m_{t-1} + (1 − lam) · r_t,先输出残差再做更新——这是本题的核心区分点:用更新后的 m_t 当作基准会让当期观测自我解释,化简后得到的错误残差恰为正确值的 lam 倍(即 r_t − m_t = lam · (r_t − m_{t-1}))。
例:solution([0.01, -0.005, 0.012, 0.008, 0.05], 0.9) 返回大约 [0.01, -0.006, 0.0116, 0.00644, 0.047796]。手工演算:m_{-1}=0 → e_0=0.01;m_0=0.001 → e_1=-0.005-0.001=-0.006;m_1=0.0004 → e_2=0.012-0.0004=0.0116;m_2=0.00156 → e_3=0.008-0.00156=0.00644;m_3≈0.002204 → e_4=0.05-0.002204≈0.047796。终端的剧烈跳跃完整保留在最后一个残差里,这正是 EWMA 残差作为"惊讶度"指标的物理意义。
复杂度上一次线性扫描 O(N)、O(N) 输出空间即可;判分采用浮点容差比对。空 returns 返回空列表,与 lam 取值无关。
函数骨架见 stubs/stub.py。
实践背景
EWMA 残差是 quant 监控里最朴素也最高频被使用的"惊讶度"标量:风控仪表盘用它把每根 bar 的当期收益与近期均值做比对,超阈值即触发一次告警;执行台用它在分钟频跟踪 alpha 信号是否仍在其历史均值附近游走,一旦残差持续偏向一侧就开始怀疑信号衰减;做市与套利策略则把它作为最便宜的滤波层垫在更复杂的模型之前。这个标量看似简单,但"用先前 EWMA 还是更新后 EWMA"是一道隐藏的合约题:错用一拍会让残差被 lam 因子静默压缩(lam 越接近 0 压缩越严重,越接近 1 误差越小),下游阈值标定全部错位却不会报错——这正是工程化时最容易吃亏的地方。
约束条件
- 0 <= len(returns) <= 5000;每个元素为有限浮点数,绝对值不超过 100
- lam 为浮点数,严格满足 0 < lam < 1(端点开)
- warm-up EWMA 约定为 m_{-1} = 0;故 returns 非空时 e_0 = returns[0]
- 残差定义为 e_t = returns[t] - m_{t-1},其中 m_{t-1} 由 r_0..r_{t-1} 累计得到,不含 r_t
- 输出是与输入等长的浮点列表;空输入返回空列表
样例
Case 1 · statement-example: calm with a terminal jolt at lam=0.9 — late residual exposes the surprise
输入: [[0.01,-0.005,0.012,0.008,0.05],0.9]
期望: [0.01,-0.006,0.011600000000000001,0.00644,0.047796000000000005]
lam=0.9 慢速 EWMA:m_{-1}=0 -> e0=0.01;m0=0.001 -> e1=-0.006;m1=0.0004 -> e2=0.0116;m2=0.00156 -> e3=0.00644;m3≈0.002204 -> e4=0.047796。终端跳跃带来明显大残差。
Case 2 · statement-example: empty returns -> empty residuals
输入: [[],0.5]
期望: []
空输入直接返回空列表,与 lam 无关。
Case 3 · statement-example: single observation, residual equals the observation (warm-up EWMA = 0)
输入: [[0.025],0.94]
期望: [0.025]
只有一个观测:m_{-1}=0,故 e0 = 0.025 - 0 = 0.025。
最近提交
还没有提交记录。
编码区
实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。
默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。
Case 1 · statement-example: calm with a terminal jolt at lam=0.9 — late residual exposes the surprise
输入: [[0.01,-0.005,0.012,0.008,0.05],0.9]
期望: [0.01,-0.006,0.011600000000000001,0.00644,0.047796000000000005]
lam=0.9 慢速 EWMA:m_{-1}=0 -> e0=0.01;m0=0.001 -> e1=-0.006;m1=0.0004 -> e2=0.0116;m2=0.00156 -> e3=0.00644;m3≈0.002204 -> e4=0.047796。终端跳跃带来明显大残差。
Case 2 · statement-example: empty returns -> empty residuals
输入: [[],0.5]
期望: []
空输入直接返回空列表,与 lam 无关。
Case 3 · statement-example: single observation, residual equals the observation (warm-up EWMA = 0)
输入: [[0.025],0.94]
期望: [0.025]
只有一个观测:m_{-1}=0,故 e0 = 0.025 - 0 = 0.025。