成交量加权中位数成交价
Size-Weighted Median Fill Price
开始编码实现 solution(fills: list[list]) -> float。给定一组成交记录,每笔形如 [price, size](size 为正整数),返回成交量加权中位数成交价。流程:按 price 升序排序,计算 total = sum(size),然后找出累计 size 首次达到 ceil(total / 2) 的最小价位,并返回该价位。空输入或总量为 0 返回 float("nan")。
例
solution([[100.0, 3], [101.0, 5], [99.5, 2]]) 返回 100.0。按价升序为 99.5(size=2), 100.0(size=3), 101.0(size=5)。总量 = 10,阈值 = ceil(10/2) = 5。累计 size: 2、5、10。第一个达到 5 的累计值出现在价位 100.0,因此成交量加权中位数为 100.0。
边界同价的情形——比如两笔同价同时贡献跨过阈值的那一步——按照"从低到高扫到第一笔触发即停"的规则,自然取较低的价位(左到右扫描,跨过即停,二者其实是同一条规则)。再注意:当某一笔成交本身就独占了总量的 50% 及以上(比如一笔大单),无论它周围有多少笔零碎成交,答案就是它的价位——这正是"成交量加权中位数"想刻画的鲁棒性所在。
最自然的实现:排序 O(N log N) + 累计扫描 O(N),总体 O(N log N) 时间、O(N) 空间。基于堆的部分排序也合法,但在这里没有渐近优势。注意区分:本题不是"按下标取排序中点"的计数式中位数——那种做法忽略 size,size 不均匀时会得到错的答案。
实现细节由 stubs/stub.py 提供。
实践背景
母单执行回顾报告想用一个具有代表性的成交价做总结。VWAP(成交量加权均值)是最常用的选择,但对长尾里少数异常成交较敏感——一笔被点错的最后成交就足以把整体指标拉偏。成交量加权中位数是它的鲁棒搭档:按定义,恰好一半的执行量落在它(含等于)下方、另一半在它上方,因此任何一笔异常成交对它的影响最多是 size/total 的权重,而不会像均值那样被 size*price 放大。实务上桌面会同时看两者:VWAP 用于对到达基准的滑点归因,成交量加权中位数用于回顾报告和 TCA 看板里"中枢成交价"的描述。同一个 solution(fills) 工具被早会概要和合规层面的最佳执行审计共同复用,所以契约是固定的,阈值语义(ceil、同价取低)也必须钉死。
约束条件
- 0 <= len(fills) <= 5000
- 每笔 fill 形如 `[price: float, size: int]`,`size >= 1`;price 可为任意有限 float(正、零或负);price 中不会出现正负无穷或 NaN
- 1 <= size <= 100000 per fill;sum of sizes 可放入 63-bit int
- 空输入 (`fills == []`) 返回 `float('nan')`;否则返回成交量加权中位数 price,类型为 `float`
- 浮点比对采用 `rel_tol=1e-9, abs_tol=1e-12`;checker 下 NaN 与 NaN 视为相等
样例
Case 1 · statement-example: simple three-fill log
输入: [[[100,3],[101,5],[99.5,2]]]
期望: 100
三笔成交按价升序为 99.5(2)、100.0(3)、101.0(5);总量 10,阈值 ceil(10/2)=5;累计 2、5、10,首次 >=5 在 100.0。
Case 2 · visible: empty fills returns NaN
输入: [[]]
期望: "NaN"
空输入按规范返回 NaN。
Case 3 · visible: single huge fill dominates total
输入: [[[10,1],[20,1],[50,100]]]
期望: 50
总量 102,阈值 51;按价升序累计 1、2、102,首次跨过 51 的是 50.0;50.0 一笔即占据全部权重的多数。
Case 4 · visible: tied prices consolidate at lower level
输入: [[[5,2],[5,3],[6,4]]]
期望: 5
两笔 5.0 合计 5、6.0 为 4;总量 9,阈值 ceil(9/2)=5;累计 2、5、9,首次 >=5 在第二笔 5.0 处,因此返回 5.0。
最近提交
还没有提交记录。
编码区
实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。
默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。
Case 1 · statement-example: simple three-fill log
输入: [[[100,3],[101,5],[99.5,2]]]
期望: 100
三笔成交按价升序为 99.5(2)、100.0(3)、101.0(5);总量 10,阈值 ceil(10/2)=5;累计 2、5、10,首次 >=5 在 100.0。
Case 2 · visible: empty fills returns NaN
输入: [[]]
期望: "NaN"
空输入按规范返回 NaN。
Case 3 · visible: single huge fill dominates total
输入: [[[10,1],[20,1],[50,100]]]
期望: 50
总量 102,阈值 51;按价升序累计 1、2、102,首次跨过 51 的是 50.0;50.0 一笔即占据全部权重的多数。
Case 4 · visible: tied prices consolidate at lower level
输入: [[[5,2],[5,3],[6,4]]]
期望: 5
两笔 5.0 合计 5、6.0 为 4;总量 9,阈值 ceil(9/2)=5;累计 2、5、9,首次 >=5 在第二笔 5.0 处,因此返回 5.0。