Cross-Gamma 2D Shock-Grid PnL via Bilinear-Quadratic Taylor
Cross-Gamma 2D Shock-Grid PnL via Bilinear-Quadratic Taylor
开始编码某双因子压力测试引擎在二维冲击网格(如平行利率波动 × 隐含波动率位移)下对账本进行重估。引擎将每个头寸的灵敏度预聚合为五个账本级 greek:一阶 delta_x、delta_y,纯二阶 gamma_xx、gamma_yy,以及混合偏导 gamma_xy = d^2 P / (dx dy),再扫过一系列网格点 (sx_k, sy_k) 得到 PnL 曲面。交叉 gamma 项是本题独有的"联合曲率"刻画:一个 delta 平、对角 gamma 与交叉 gamma 都为正的账本,在 (+rate, -vol) 冲击下亏损与在 (+rate, +vol) 下盈利同量级——而仅看主轴的 Taylor 曲面会完全错过这一不对称。
请实现 solution(delta_x, delta_y, gamma_xx, gamma_yy, gamma_xy, shocks_x, shocks_y)。shocks_x 与 shocks_y 是两个长度均为 K 的并行列表,定义 K 个网格点(第 k 个点是 (shocks_x[k], shocks_y[k]),并非笛卡尔积)。对每个网格点返回二阶 Taylor PnL
其中 ,。
交叉 gamma 项前没有 。原因:在完整 Hessian 二次型 中,对称双重求和两次访问非对角对 与 ,再由 Schwarz 定理得 ,两次访问合并为 。两个对角项 gamma_xx、gamma_yy 各被访问一次,保留 。如果在每个二阶项前都统一写 ,会把交叉 gamma 多扣掉一半,是这道题最常见的错。
PnL 是带符号的。gamma_xy 为正时,同号联合冲击 让 PnL 增加,反号联合冲击 让 PnL 减少,幅值都是 。对角贡献 在 下不变,所以联合冲击的非对称性完全由交叉 gamma 项承担。纯 x 冲击()与纯 y 冲击()都会塌缩到该轴上的一维二阶 Taylor,交叉项消失。
Example
solution(2.0, -1.5, 0.04, 0.02, -0.01, [10.0, -10.0, 5.0, 0.0], [5.0, 5.0, -5.0, 10.0]) 返回 [14.25, -24.75, 18.5, -14.0]。以 k=0 的 (sx, sy) = (10, 5) 为例:线性部分 2*10 + (-1.5)*5 = 20 - 7.5 = 12.5;纯二次 0.5 * 0.04 * 100 + 0.5 * 0.02 * 25 = 2.0 + 0.25 = 2.25;交叉部分 (-0.01) * 10 * 5 = -0.5;合计 12.5 + 2.25 - 0.5 = 14.25。k=1 处 (-10, 5),线性与交叉部分相对 k=0 都翻号,但 sx 的纯二次项不变:-20 - 7.5 + 2.0 + 0.25 + 0.5 = -24.75。k=2 处 (5, -5),|sx|=|sy|=5 不变,但符号组合不同:10 + 7.5 + 0.5 + 0.25 + 0.25 = 18.5(注意交叉贡献 (-0.01) * 5 * (-5) = +0.25)。k=3 处 (0, 10),整个 x 通道清零,结果 -1.5 * 10 + 0.5 * 0.02 * 100 = -15 + 1 = -14。
参见 stubs/stub.py 中的函数骨架。
Practical context
这一原语比线性 delta 情景网格、单因子对角 gamma Taylor 高一档,是捕捉联合曲率最便宜的双因子重估方法。一支波动率/利率自营桌每天跑 (利率 -200bp..+200bp) × (IV -20%..+20%) 的交叉网格,每个交点上用的就是这条公式,其中五个 greek 由头寸级 Greek 每日预聚合而来。交叉 gamma 项区分了"delta 平、在 (+rate, -vol) 下亏损"的账本与"delta 平、在 (+rate, +vol) 下亏损"的账本——对角 gamma 一样,仅 gamma_xy 符号相反。一个常见的偷工减料做法——丢掉交叉 gamma 只压主轴——会系统性低估任何利率-波动耦合显著的账本(多数利率-波动率相对价值桌都属于此类)的联合压力。测试套件特别瞄准的两个坑:(1) 在 gamma_xy 前加 1/2(数学上差因子 2——Hessian 双重访问非对角元),(2) 反对称冲击下交叉贡献正负号搞反。两类 bug 都能在仅对角的测试上侥幸通过,只在真正的二维冲击下暴露——这也是隐藏测试集大量集中在反对称与不对称网格点上的原因。
Edge cases
K = 0:返回[]。- 某网格点上
sx = sy = 0:无论 greek 取何值,PnL 贡献恰为0.0。 - 纯 x 冲击(所有 k 都有
shocks_y[k] == 0):塌缩为 x 上的一维二阶 Taylor,交叉 gamma 不显式出现。 - 纯 y 冲击(所有 k 都有
shocks_x[k] == 0):塌缩为 y 上的一维二阶 Taylor,交叉 gamma 不显式出现。 - 反对称网格点(
sx = +a,sy = -a):交叉贡献为-gamma_xy * a^2,专门用来抓在交叉项前误加1/2或把符号弄反的实现。
约束条件
- 0 <= K <= 4000,其中 K = len(shocks_x) = len(shocks_y);调用方保证两并行数组长度相等
- `delta_x`、`delta_y`、`gamma_xx`、`gamma_yy`、`gamma_xy` 均为有限浮点数,绝对值不超过 1e6
- 每个 `shocks_x[k]`、`shocks_y[k]` 均为有限浮点数,绝对值不超过 1e3
- `gamma_xy` 直接就是混合偏导 d^2 P / (dx dy)——不要再除以 2。1/2 前因子只作用于纯对角项 `gamma_xx` 与 `gamma_yy`
- 输出为长度 K 的 `list[float]`,按网格点顺序排列;浮点比较容差 rel_tol = 1e-9,abs_tol = 1e-9
样例
Case 1 · statement-example four mixed grid points
输入: [2,-1.5,0.04,0.02,-0.01,[10,-10,5,0],[5,5,-5,10]]
期望: [14.25,-24.75,18.5,-14]
k=0: 2*10 + (-1.5)*5 + 0.5*0.04*100 + 0.5*0.02*25 + (-0.01)*10*5 = 14.25。k=1: -20 - 7.5 + 2.0 + 0.25 + 0.5 = -24.75。k=2: 10 + 7.5 + 0.5 + 0.25 + 0.25 = 18.5。k=3: 0 - 15 + 0 + 1.0 + 0 = -14.0。
Case 2 · visible empty grid returns empty list
输入: [1,2,3,4,5,[],[]]
期望: []
K=0:直接返回空列表,与 greek 取值无关。
最近提交
还没有提交记录。
编码区
实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。
默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。
Case 1 · statement-example four mixed grid points
输入: [2,-1.5,0.04,0.02,-0.01,[10,-10,5,0],[5,5,-5,10]]
期望: [14.25,-24.75,18.5,-14]
k=0: 2*10 + (-1.5)*5 + 0.5*0.04*100 + 0.5*0.02*25 + (-0.01)*10*5 = 14.25。k=1: -20 - 7.5 + 2.0 + 0.25 + 0.5 = -24.75。k=2: 10 + 7.5 + 0.5 + 0.25 + 0.25 = 18.5。k=3: 0 - 15 + 0 + 1.0 + 0 = -14.0。
Case 2 · visible empty grid returns empty list
输入: [1,2,3,4,5,[],[]]
期望: []
K=0:直接返回空列表,与 greek 取值无关。