← 返回编程题库
coding-reverse-stress-test-flag-loss-scenarios中等免费版2000ms未尝试

反向压力测试:标记触及亏损阈值的情景

Reverse Stress Test — Flag Scenarios That Hit a Loss Target

开始编码

反向压力测试把常规问题倒过来问。常规问题是「给定这个固定冲击向量,PnL 是多少?」;反向问题是「给定一个我们承受不起的目标亏损,哪些因子联动真的能造出这种亏损?」。风险团队会枚举一组合理的候选情景——历史回放、监管规定的冲击、专家手工搭出来的组合——并把每一个线性 Taylor PnL 跨过阈值的情景挑出来。被挑出的子集会上报给董事会评审,或进入下一步的非线性重估值。

请实现 solution(exposures, factor_shocks, target_loss_dollars)exposures 是长度 M 的组合层面一阶敏感度向量:exposures[m] 是因子 m 单位冲击下的美元 PnL(有符号,单位为因子的自然单位——例如「每 1bp 利率移动多少美元」)。factor_shocks 形状为 (S, M):factor_shocks[s][m] 是候选情景 s 下因子 m 的冲击大小。target_loss_dollars 是非负的亏损量级。

对每个情景 s,线性 Taylor PnL 为

pnl[s]  =  m=0M1exposures[m]factor_shocks[s][m] \text{pnl}[s] \;=\; \sum_{m=0}^{M-1} \text{exposures}[m] \cdot \text{factor\_shocks}[s][m]\text{。}

返回满足下式的情景索引列表

pnl[s]    target_loss_dollars, \text{pnl}[s] \;\le\; -\text{target\_loss\_dollars}\text{,}

按升序排列(即按情景索引顺序)。阈值用的是非严格不等号:PnL 恰好等于 -target_loss_dollars 的情景被标记。阈值本身是正的亏损量级——比较前要先取负,因为 PnL 是有符号的,亏损就是负的 PnL。如果没有情景触发阈值,输出是 [](空列表,绝不是哨兵值)。

这里的 PnL 模型是线性(delta-only)Taylor;gamma 与 cross-gamma 明确不在本原语范围内。更高阶的重估值是后续步骤,只对被标记的子集做。

solution([100.0, 50.0], [[1.0, 1.0], [-2.0, 1.0], [-2.0, -2.0], [0.0, 0.0]], 100.0) 返回 [1, 2]。组合敞口是 [+100, +50](每单位因子 0 +100,每单位因子1+100,每单位因子 1 +50)。四个情景的 PnL 分别是 100*1 + 50*1 = 150100*(-2) + 50*1 = -150100*(-2) + 50*(-2) = -300100*0 + 50*0 = 0。当 target_loss_dollars = 100 时,阈值是 pnl[s] <= -100。情景 1(PnL -150)与情景 2(PnL -300)满足;情景 0(盈利)与情景 3(盈亏平衡)不满足。输出 [1, 2] 按情景索引升序。

实现细节由 stubs/stub.py 提供。

实践背景

巴塞尔与多数本国银行监管都明确要求做反向压力测试,原因是常规压力测试在回答一个不太对的问题——真正危险的情景未必出现在交易台已有的标准菜单上。标准流程是:(1) 从机构无法承受的目标亏损出发(例如 CET1 资本的四分之一,或某个监管最低缓冲被击穿);(2) 枚举或采样一个较大的候选情景集;(3) 把每一个线性 Taylor PnL 跨阈值的候选挑出来;(4) 用全功能非线性定价器对挑出的子集重估值,按实际亏损排序;(5) 把剩下的清单交给模型风险与治理委员会。本题实现的是第 (3) 步——决定哪些情景值得做昂贵非线性重估值的廉价线性过滤器。不等号方向(<= 配上取负后的阈值)正是审计时会逐行复核的部分:严格 < 会悄无声息地把刚好踩在阈值上的情景从上报清单里漏掉;漏写取负则会把盈利情景而不是危险情景塞进清单。

约束条件

  • 0 <= M <= 12,M = len(exposures) 是风险因子数
  • 0 <= S <= 200,S = len(factor_shocks) 是候选情景数
  • 对非空输入,`factor_shocks` 每行长度都是 M(矩形矩阵)。参考解假设输入形状合法——形状不一致属于调用方前置条件违反,行为未定义
  • `exposures` 与 `factor_shocks` 每个分量都是有限浮点数,绝对值不超过 1e6
  • 0.0 <= target_loss_dollars <= 1e10(非负的亏损量级)
  • 输出是 `list[int]`,每个元素是位于 `[0, S)` 的情景索引,按升序排列,不允许重复

样例

Case 1 · statement-example two factors four scenarios

输入: [[100,50],[[1,1],[-2,1],[-2,-2],[0,0]],100]

期望: [1,2]

组合敞口 [100, 50]。四个情景 PnL = 150, -150, -300, 0。阈值 -100:情景 1 (-150 <= -100) 与情景 2 (-300 <= -100) 满足;情景 0 (+150) 与情景 3 (0) 不满足。按索引升序输出 [1, 2]。

Case 2 · visible single factor one losing scenario

输入: [[10],[[5],[-3],[-1]],20]

期望: [1]

PnL = [50, -30, -10]。阈值 -20:仅情景 1 (-30 <= -20) 满足;情景 2 (-10) 不满足;情景 0 (+50) 是盈利。

Case 3 · visible non-strict inequality at exact boundary

输入: [[2],[[10],[-50],[-100]],100]

期望: [1,2]

PnL = [20, -100, -200]。阈值 -100:情景 1 PnL=-100,因为 -100 <= -100 成立而被标记;情景 2 (-200 <= -100) 也满足;情景 0 (+20) 是盈利。

Case 4 · visible empty scenario list returns empty

输入: [[1,2,3],[],500]

期望: []

S=0,没有情景可评估,直接返回空列表。

Case 5 · visible target zero flags breakeven and losses

输入: [[1,1],[[1,1],[0,0],[-1,0],[1,-1]],0]

期望: [1,2,3]

PnL = [2, 0, -1, 0]。阈值 0:pnl <= 0 标记情景 1 (0)、2 (-1)、3 (0);情景 0 (+2) 不满足。

Case 6 · visible empty factors target zero flags all

输入: [[],[[],[],[]],0]

期望: [0,1,2]

M=0:每个情景在零个因子上求和得 PnL=0。阈值 0:0 <= 0 成立,全部标记。

最近提交

还没有提交记录。

编码区

实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。

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

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

Case 1 · statement-example two factors four scenarios

输入: [[100,50],[[1,1],[-2,1],[-2,-2],[0,0]],100]

期望: [1,2]

组合敞口 [100, 50]。四个情景 PnL = 150, -150, -300, 0。阈值 -100:情景 1 (-150 <= -100) 与情景 2 (-300 <= -100) 满足;情景 0 (+150) 与情景 3 (0) 不满足。按索引升序输出 [1, 2]。

Case 2 · visible single factor one losing scenario

输入: [[10],[[5],[-3],[-1]],20]

期望: [1]

PnL = [50, -30, -10]。阈值 -20:仅情景 1 (-30 <= -20) 满足;情景 2 (-10) 不满足;情景 0 (+50) 是盈利。

Case 3 · visible non-strict inequality at exact boundary

输入: [[2],[[10],[-50],[-100]],100]

期望: [1,2]

PnL = [20, -100, -200]。阈值 -100:情景 1 PnL=-100,因为 -100 <= -100 成立而被标记;情景 2 (-200 <= -100) 也满足;情景 0 (+20) 是盈利。

Case 4 · visible empty scenario list returns empty

输入: [[1,2,3],[],500]

期望: []

S=0,没有情景可评估,直接返回空列表。

Case 5 · visible target zero flags breakeven and losses

输入: [[1,1],[[1,1],[0,0],[-1,0],[1,-1]],0]

期望: [1,2,3]

PnL = [2, 0, -1, 0]。阈值 0:pnl <= 0 标记情景 1 (0)、2 (-1)、3 (0);情景 0 (+2) 不满足。

Case 6 · visible empty factors target zero flags all

输入: [[],[[],[],[]],0]

期望: [0,1,2]

M=0:每个情景在零个因子上求和得 PnL=0。阈值 0:0 <= 0 成立,全部标记。