逐笔累计成交量加权均价
Cumulative VWAP at Each Tick
开始编码VWAP(成交量加权平均价,Volume-Weighted Average Price)是算法交易里最常被引用的母单基准之一:经纪商承诺执行价不差于当日 VWAP,研究员用它衡量自家执行算法的质量,做市台拿它做盘中风险敞口的快速估值。问题在于,VWAP 是一个滚动量——每来一笔新的撮合成交,它都需要被立刻刷新一次。回测引擎在重放一整天 tick 流时,可能要在 20 万笔成交后逐笔输出当前累计 VWAP,把这串数列喂给下游的 slippage 监控、母单进度条、以及实时图表。
请实现 solution(trades: list[tuple[float, int]]) -> list[float]。trades 是一段按时间到达顺序排列的成交流,每条形如 (price, qty),分别为成交价和成交量。返回一个等长的 list[float]:第 i 项是**截至第 i 笔成交(含本笔)为止的累计 VWAP**,即 (p_0*q_0 + p_1*q_1 + ... + p_i*q_i) / (q_0 + q_1 + ... + q_i)。题目保证每笔 qty >= 1,因此分母永不为 0;当 trades 为空时返回 []。
例如 solution([(100.0, 10), (101.0, 5), (99.5, 20)]) 应返回 [100.0, 100.333..., 99.857...]。第一笔后只有一笔成交,VWAP 即 100.0;第二笔后分子为 100*10 + 101*5 = 1505、分母为 15,得 100.3333...;第三笔后分子追加 99.5*20 = 1990,累计 3495,分母累计 35,得 99.8571...。注意第三笔虽然价格走低,但成交量更大,所以把整体 VWAP 拉了下来——这正是「成交量加权」相比简单算术均价的本质区别。
朴素做法是每输出一项就重新求和前缀,复杂度 O(n²);在 n = 200000 的规模下会跑成 4 × 10¹⁰ 次操作,明显超时。正确做法是维护两个运行累加量——累计名义金额 cum_notional 和累计成交量 cum_volume,每笔成交先更新它们再输出比值,整体一次顺序扫描,复杂度 O(n)。
约束条件
- 0 ≤ len(trades) ≤ 200000
- 每条 trade 是 `(price: float, qty: int)`
- 0 < price ≤ 10⁶(成交价为正浮点数)
- 1 ≤ qty ≤ 10⁶(每笔成交量为正整数,分母不会为 0)
- 返回 `list[float]`,长度等于 `len(trades)`,第 i 项是「截至第 i 笔成交(含)为止的 VWAP」
- 比较使用浮点容忍:`rel_tol=1e-9`
- 若 `trades` 为空,返回空列表 `[]`
样例
Case 1 · statement-style example with falling final tick
输入: [[[100,1],[101,1],[99.5,2]]]
期望: [100,100.5,100]
第一笔 VWAP 即 100.0;第二笔分子 100·1 + 101·1 = 201,分母 2,得 100.5;第三笔分子 201 + 99.5·2 = 400,分母 4,得 100.0——尾笔虽然价格走低但成交量是前两笔之和,把整体 VWAP 拉回了 100。
Case 2 · binary volumes with mixed prices stay bit-exact
输入: [[[10,1],[20,1],[10,2],[20,4]]]
期望: [10,15,12.5,16.25]
分母依次是 1、2、4、8,分子依次是 10、30、50、130;逐项除得 10.0、15.0、12.5、16.25。每一步成交量翻倍意味着新一笔的权重等于此前所有成交之和,所以 VWAP 向新一笔的价格快速靠拢。
最近提交
还没有提交记录。
编码区
实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。
默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。
Case 1 · statement-style example with falling final tick
输入: [[[100,1],[101,1],[99.5,2]]]
期望: [100,100.5,100]
第一笔 VWAP 即 100.0;第二笔分子 100·1 + 101·1 = 201,分母 2,得 100.5;第三笔分子 201 + 99.5·2 = 400,分母 4,得 100.0——尾笔虽然价格走低但成交量是前两笔之和,把整体 VWAP 拉回了 100。
Case 2 · binary volumes with mixed prices stay bit-exact
输入: [[[10,1],[20,1],[10,2],[20,4]]]
期望: [10,15,12.5,16.25]
分母依次是 1、2、4、8,分子依次是 10、30、50、130;逐项除得 10.0、15.0、12.5、16.25。每一步成交量翻倍意味着新一笔的权重等于此前所有成交之和,所以 VWAP 向新一笔的价格快速靠拢。