← 返回编程题库
coding-first-day-cumulative-pnl-crosses-threshold简单免费版2000ms未尝试

累计 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) -> intcumulative_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 可见样例;服务端提交会运行可见样例和隐藏测试。

加载编辑器...
计时0:00

默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。

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。