在线 EWMA 配对协方差:跨资产对冲比建模基石
Online EWMA Covariance Pair — Cross-Asset Hedge-Ratio Building Block
开始编码实现 solution(a: list[float], b: list[float], lam: float) -> list[float]。给定两条等长的逐期收益流 a、b 与 EWMA 衰减参数 lam(0 < lam < 1),维护三个在线 EWMA——两条单流的均值各一个、交叉积 a[i] * b[i] 一个——并对每个新对输出 EWMA 协方差估计 cov[i] = m_ab[i] − m_a[i] · m_b[i]。三个标量的递推都是标准的 EWMA m ← lam · m + (1 − lam) · x,独立进行。warm-up 约定为 m_a[−1] = m_b[−1] = m_ab[−1] = 0。每步顺序:先把三个标量都更新一拍,再用更新后的均值发出协方差——这是合约的一部分,"单流 EWMA 用上一拍、但 m_ab 用当前一拍"是另一种常见错法,会在小 i 的 adversarial 用例上给出可分辨的不同序列。长度不一致抛 ValueError;空输入返回 [],与 lam 无关。
例
solution([0.01, -0.02, 0.015, -0.005, 0.03], [0.02, -0.01, 0.018, -0.008, 0.025], 0.9) 返回大约 [1.8e-05, 3.888e-05, 5.99148e-05, 5.9140188e-05, 0.000116849]。手工演算:第 0 步 lam=0.9, (1−lam)=0.1,m_a = 0.1·0.01 = 0.001,m_b = 0.1·0.02 = 0.002,m_ab = 0.1·(0.01·0.02) = 2e-05,所以 cov[0] = 2e-05 − 0.001·0.002 = 1.8e-05。warm-up 偏置在 i=0 一目了然:cov[0] 大致为 lam·(1−lam)·a[0]·b[0] = 0.9·0.1·0.0002 = 1.8e-05,远小于 a[0]·b[0] = 2e-04。随着 EWMA 吸收更多对、均值落到联合走势上,协方差幅度逐步上行。
复杂度上:一次线性扫描、三个标量、O(N) 时间 / O(N) 输出空间;判分采用浮点容差比对。
函数骨架见 stubs/stub.py。
实践背景
配对交易台(pairs trading)需要随条件漂移在线重新估计跨资产协方差以更新对冲比,但每个 tick 都重做整段窗口在产线上代价过高。三标量 EWMA 是这一岗位的标准捷径:每 tick 一拍更新即可给出平滑衰减的协方差估计,下游 beta/相关性任务按需读取。lam 这个旋钮在响应度与稳定度之间切换——lam 接近 1 容忍短期噪声、给出慢速对冲比;lam 接近 0 紧贴最新的对子、几乎让协方差等同于即时积,多数台子认为这种估计在仓位测算上太抖。隐藏的合约陷阱是更新-发出的时序:常见 bug 把单流均值的"上一拍"和交叉项均值的"更新一拍"混搭,每个协方差估计都会被静默偏移,下游对冲比莫名其妙跑偏才暴露。另一个常见 bug 是把 lam 平方,混淆成 EWMA-of-EWMA——本题三个标量的递推都用 lam,不是 lam²。
约束条件
- 0 <= len(a) == len(b) <= 5000;每个元素为有限浮点数,绝对值不超过 100
- lam 为浮点数,严格满足 0 < lam < 1(端点开)
- warm-up 约定为 m_a[-1] = m_b[-1] = m_ab[-1] = 0;故 cov[0] 因 (1-lam) 因子被压向 0,并不等于 a[0]*b[0]
- 更新顺序固定:第 i 步先更新三个 EWMA,再用更新后的均值输出 cov[i] = m_ab[i] - m_a[i] * m_b[i]
- 长度不一致抛 ValueError;空输入返回空列表,与 lam 无关
样例
Case 1 · statement-example: paired return streams at lam=0.9 — covariance settles toward positive co-movement
输入: [[0.01,-0.02,0.015,-0.005,0.03],[0.02,-0.01,0.018,-0.008,0.025],0.9]
期望: [0.000017999999999999997,0.00003887999999999999,0.000059914799999999984,0.00005914018799999999,0.00011684940227999997]
lam=0.9 慢速 EWMA。每步先更新三个标量 m_a, m_b, m_ab,再用 cov_i = m_ab_i - m_a_i * m_b_i 输出。两条流大体同向,所以协方差为正且随时间累积。
Case 2 · statement-example: empty inputs at any lam yield []
输入: [[],[],0.5]
期望: []
空输入直接返回空列表,与 lam 无关。
Case 3 · statement-example: single pair, warm-up convention m=0 makes early cov heavily biased
输入: [[0.1],[0.2],0.9]
期望: [0.0018000000000000002]
单步:m_a=0.01, m_b=0.02, m_ab=0.002, cov=0.002-0.01*0.02=0.0018。warm-up 偏置在第一步明显(接近 (1-lam)*ab 量级,而非 ab 本身)。
最近提交
还没有提交记录。
编码区
实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。
默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。
Case 1 · statement-example: paired return streams at lam=0.9 — covariance settles toward positive co-movement
输入: [[0.01,-0.02,0.015,-0.005,0.03],[0.02,-0.01,0.018,-0.008,0.025],0.9]
期望: [0.000017999999999999997,0.00003887999999999999,0.000059914799999999984,0.00005914018799999999,0.00011684940227999997]
lam=0.9 慢速 EWMA。每步先更新三个标量 m_a, m_b, m_ab,再用 cov_i = m_ab_i - m_a_i * m_b_i 输出。两条流大体同向,所以协方差为正且随时间累积。
Case 2 · statement-example: empty inputs at any lam yield []
输入: [[],[],0.5]
期望: []
空输入直接返回空列表,与 lam 无关。
Case 3 · statement-example: single pair, warm-up convention m=0 makes early cov heavily biased
输入: [[0.1],[0.2],0.9]
期望: [0.0018000000000000002]
单步:m_a=0.01, m_b=0.02, m_ab=0.002, cov=0.002-0.01*0.02=0.0018。warm-up 偏置在第一步明显(接近 (1-lam)*ab 量级,而非 ab 本身)。