累计 PnL 首次突破阈值的交易日
First Day Cumulative PnL Crosses Threshold
开始编码某只持仓策略每天结算一次 PnL,运营把每日的累计 PnL(即开仓以来的总收益)按时间顺序写进一个数组 cumulative_pnl。
风控同事关心的是一个反复出现的问题:「策略的累计 PnL 第一次达到 T 美元是哪一天?」
这个问题的答案直接决定何时触发分批止盈、何时把利润转出至次日的可用保证金、何时给上层基金经理发「目标已达成」的通报。
由于这只策略采用了严格的止损保护机制,使得历史回测中累计 PnL 始终单调不减——也就是说累计曲线只升不降。
利用这个单调性,可以把「首次达标」的查询从 O(n) 扫描压成 O(log n) 二分。
请实现 solution(cumulative_pnl: list[float], T: float) -> int。
cumulative_pnl[i] 是第 i 天收盘后的累计 PnL(美元),数组单调不减;
T 是目标阈值(美元)。
返回**最小的下标 i**,使得 cumulative_pnl[i] >= T;
如果整个数组都没达到 T,返回 -1。
浮点比较使用 1e-12 的绝对容忍:只要 cumulative_pnl[i] >= T - 1e-12 就视为达标,避免双精度尾差错判。
例如 solution([-50.0, -10.0, 0.0, 25.0, 80.0, 80.0, 150.0], 50.0) 应返回 4:
前四天的累计 PnL 分别是 -50, -10, 0, 25,都没到 50;第 4 天(下标从 0 开始)累计 80 ≥ 50,是首次达标的那一天。
再如 solution([1.0, 2.0, 3.0], 100.0) 应返回 -1:累计 PnL 始终低于阈值。
当 T 恰好等于某天的累计值,例如 solution([10.0, 20.0, 30.0], 20.0),应返回 1——因为 20 ≥ 20,第 1 天就已达标。
朴素的从前往后线性扫描在 n = 200000 的输入下是可以跑完的,但风控面板每秒可能对成千上万条策略并发查询,每条都做 O(n) 扫描会把 CPU 烤干。 利用「单调不减」这一关键事实,二分查找把每次查询压到 O(log n),整体性能差距将近一万倍。
约束条件
- 0 ≤ len(cumulative_pnl) ≤ 200000
- `cumulative_pnl` 单调不减(题目保证):cumulative_pnl[i] ≤ cumulative_pnl[i+1]
- -1e9 ≤ cumulative_pnl[i] ≤ 1e9(PnL 以美元计;可正可负)
- -1e9 ≤ T ≤ 1e9
- 返回 `int`:满足 `cumulative_pnl[i] >= T` 的最小下标 `i`;若不存在,返回 -1
- 比较使用 1e-12 的绝对容忍:当 `cumulative_pnl[i] >= T - 1e-12` 时视为达标
- 若 `cumulative_pnl` 为空,返回 -1
样例
Case 1 · statement example
输入: [[-50,-10,0,25,80,80,150],50]
期望: 4
前四天累计 PnL 分别是 -50, -10, 0, 25,都没到 50;第 4 天累计 80 ≥ 50,是首次达标。注意第 5 天也是 80(出现了重复值),但题目要的是「最小下标」,所以答案是 4 而不是 5。
Case 2 · threshold exactly hits a value
输入: [[10,20,30],20]
期望: 1
T = 20.0 恰好等于第 1 天的累计值 20.0。判断条件是 `>= T`,所以下标 1 已经达标——而不是要严格大于 T 跳到下标 2。
Case 3 · threshold never reached
输入: [[1,2,3],100]
期望: -1
整段累计 PnL 最大值才 3.0,远低于阈值 100.0。所有下标都不满足,按约定返回 -1。
最近提交
还没有提交记录。
编码区
实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。
默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。
Case 1 · statement example
输入: [[-50,-10,0,25,80,80,150],50]
期望: 4
前四天累计 PnL 分别是 -50, -10, 0, 25,都没到 50;第 4 天累计 80 ≥ 50,是首次达标。注意第 5 天也是 80(出现了重复值),但题目要的是「最小下标」,所以答案是 4 而不是 5。
Case 2 · threshold exactly hits a value
输入: [[10,20,30],20]
期望: 1
T = 20.0 恰好等于第 1 天的累计值 20.0。判断条件是 `>= T`,所以下标 1 已经达标——而不是要严格大于 T 跳到下标 2。
Case 3 · threshold never reached
输入: [[1,2,3],100]
期望: -1
整段累计 PnL 最大值才 3.0,远低于阈值 100.0。所有下标都不满足,按约定返回 -1。