GPU Gems 2 · Chapter 45. Options Pricing on the GPU

用 GPU 并行计算 Black-Scholes 和 binomial lattice:理解期权输入契约、CND 多项式向量化、反向动态规划,以及运算密集型金融计算的映射边界。

学习目标

  • 能解释期权的 spot、strike、maturity、risk-free rate 和 volatility 输入,并区分 call 与 put 的 payoff
  • 能用 Black-Scholes 的 d₁、d₂ 和 CND 近似计算 European call,并说明它为什么适合批量 GPU 计算
  • 能把 binomial lattice 的到期 payoff 逆向推进到根节点,解释单棵树的依赖与多份期权之间的并行
  • 能通过实验切换模型和输入参数,判断价格变化来自模型、波动率还是 lattice 步数

投资工具的“公平价值”不是一个画出来的形状,而是一组输入假设经过数值计算后的结果。GPU 适合这类工作,前提是我们把每份期权的输入放在对应位置,让同一个程序对许多位置重复执行。

本章比较两条路线:Black-Scholes 用一组解析表达式直接得到 European option 价格;binomial lattice 把未来价格离散成树,再从到期日逐层向后回推。前者每个像素几乎独立,后者单棵树有时间依赖,但许多独立期权仍然可以并行。

1. 先定义期权输入和 payoff

的价值来自 underlying asset。最小输入契约包括 spot price S、strike price X、maturity T、risk-free rate r 和 volatility σ。本章先讨论 European call:只允许在到期日执行,payoff 是 max(S − X, 0)

Black–Scholes:一份输入对应一个价格asset Sstrike Xtime Trate rvolatility σfragment programd₁, d₂ → CND(d)S × CND(d₁)− X e⁻ʳᵀ × CND(d₂)call priceV(S,X,T)运算密集、选项之间独立,适合批量并行和少量 uniform 共享
每个像素承载一份期权输入,fragment program 独立输出一份价格。

S 高于 X 时,call 的内在价值为正;T 越长或 σ 越大,未来 spot 的不确定范围通常越宽,期权价值也会受到影响。r 用连续复利把未来的 payoff 折算到今天。这里的“通常”很重要:它描述模型的敏感性,不代表真实市场中每个变量都独立或稳定。

2. Black-Scholes:解析模型的 GPU 映射

对 European call 的核心形式是 V = S × CND(d₁) − X × e⁻ʳᵀ × CND(d₂),其中 d₁d₂SXTrσ 共同决定,且 d₂ = d₁ − σ√T

一份期权的计算只读取自己的五个输入和共享的 r,不会依赖旁边像素的结果。GPU 可以把四张二维输入数组放在相同坐标:exercise price、asset price、time to expiration 和 volatility;在每个像素运行 fragment program,输出一张同尺寸的 price texture。

float BlackScholesCall(float S, float X, float T, float r, float v) {
    float d1 = (log(S / X) + (r + v * v * 0.5f) * T) / (v * sqrt(T));
    float d2 = d1 - v * sqrt(T);
    return S * CND(d1) - X * exp(-r * T) * CND(d2);
}

这段代码的重点不是旧 API,而是数据流:五个标量输入 → 一个价格输出。只要后续计算也留在 GPU,CPU↔GPU 通信就不会成为每份 option 都要支付的固定成本。

3. CND 和算术强度

没有简单的闭式表达式,因此 GPU 版本使用多项式近似。先计算 K = 1 / (1 + a|x|) 和它的幂次,再把系数与幂次组成四路向量,用 dot(float4, float4) 合并多项式项。

CND:把多项式近似改写成四路向量操作输入 xL = |x| × 常数K = 1 / (1 + aL)float4 KK, K², K³, K⁴dot(coefficients, powers)+ K⁵ 与 exp 项CND(x)概率值一次调用内部有较多浮点运算,算术强度高于 CPU↔GPU 往返成本
CND 没有简单闭式表达式;把幂次和系数排成 float4,可利用 GPU 四路向量算术。

高是 Black-Scholes 适合 GPU 的原因之一:一次输入取样会触发 log、除法、sqrt、exp、CND 多项式和组合运算,输出却只有一个 float。原章还利用 GPU 的四路向量硬件预计算幂次;这不是改变数学模型,而是改变同一数学表达式的执行形状。

为什么 Black–Scholes 适合 GPU:算术强度高输入带宽S, X, T, σr uniform输出 V计算密度log / divsqrt / expCND polynomialdot(float4)把更多后续金融计算留在 GPU,可摊薄 CPU↔GPU 通信成本
GPU 的优势来自单位数据搬运对应更多计算,而不是简单把 CPU 代码搬到显卡。

需要谨慎处理输入边界。Tσ 为零时,d₁ 的分母会退化;SX 必须为正;CND 近似要在正负输入两侧保持一致。生产实现应把这些条件作为数据清洗和 shader 分支契约,而不是让 NaN 传遍整张价格纹理。

4. Binomial lattice:用动态规划处理更灵活的 exercise

把 maturity T 切成 N 个时间步。每一步的资产价格向上乘 u,向下乘 d;到期叶子先计算 payoff,再用上、下节点的期望值乘折现因子得到当前层的值。

Binomial lattice:依赖关系沿时间向后收缩t₀uduuuddd到期 payoffmax(S − X, 0) 或 put payoff反向动态规划期望值 × 折现因子 → 根节点
lattice 把到期日的 payoff 放在叶子上,再沿时间反向折现回当前价格。

它本质上是 <Term def="把复杂问题拆成相邻子问题,并从已知的终点状态逐步回推当前状态的算法方法">dynamic programming</Term>:同一节点的价值由下一列两个节点决定。European option 只需要 continuation value;American option 还要在每个节点比较“继续持有”和“立即执行”的较大值,因此 lattice 比 Black-Scholes 更适合表达提前执行约束。

dt = T / N
u  = exp(σ * sqrt(dt))
d  = 1 / u
V  = payoff at maturity
for time = N - 1 down to 0:
    V[j] = discount * (Pu * V[j + 1] + Pd * V[j])

一棵树内部的列必须按顺序从右到左推进;但要同时定价数百或数千份相互独立的 option,就可以把不同树放到不同线程或纹理位置,让 GPU 保持高 occupancy。

GPU lattice:列级同步,期权级并行option Aoption B每一列一个 kernel读右侧两个节点写左侧一个节点多份 option 同时推进单棵树依赖顺序;一千份独立树提供横向并行度
单个 lattice 有反向依赖;同时运行许多独立期权,才能让 GPU 保持足够多的线程。

5. 动手实验:比较两个模型的实际输出

先预测:把模型从 Black-Scholes 切换到 binomial lattice,增加 steps 会不会让价格稳定地靠近解析结果?把 volatility 拖高,价格曲线的哪一段变化最明显?

GPU Gems 2 · Chapter 45

期权定价:同一输入批量映射到 GPU

切换解析模型和 lattice 模型,改变 spot、volatility、steps,观察实际计算出的 call price 与价格敏感曲线。

▷ 可交互
当前模型价格10.45European call · X=100 · T=1spot → price 敏感曲线60140lattice 预览(四步)001100220011350002249
这是教学计算,不是投资建议;价格只是给定模型和输入假设下的数值输出。

实验固定 X = 100T = 1r = 0.05,使用实际的 CND 近似和 binomial backward induction 计算 European call。敏感曲线不是预先写入的分数,而是对一组 spot 值重新调用当前模型得到的价格;lattice 预览则显示四步树的 payoff 节点。

6. 正确性、吞吐与边界

Black-Scholes 的每份输入几乎独立,适合把大量像素作为并行 work items;lattice 的单棵树有列依赖,适合通过多份期权扩大并行规模。两者都应该比较同一输入下的 CPU 参考值和 GPU 输出,并检查浮点误差、CND 尾部、lattice 步数和边界 payoff。

GPU 速度也不能脱离数据搬运来讨论。若每次只把少量数据送上 GPU、只做一条短公式、再立刻把结果读回 CPU,PCI Express 往返会吞掉收益。把后续组合计算、风险指标或批量筛选继续放在 GPU 上,才能让高 arithmetic intensity 真正摊薄通信成本。

本章只讨论模型实现,不提供投资建议。真实使用还需要校准波动率、利率、股息、流动性、交易成本和 exercise 规则,并由合规的金融系统验证假设;GPU 只负责在给定模型下高吞吐地计算。

小结

  • option 价格是输入契约与模型假设下的数值,不是市场保证。
  • Black-Scholes 对 European call 给出独立、运算密集的像素级计算。
  • CND 多项式可以通过幂次预计算和 float4 dot 提高 GPU 利用率。
  • lattice 用反向动态规划表达更灵活的 exercise,但单棵树有顺序依赖。
  • 多份独立 option、足够的算术强度和留在 GPU 的后续计算决定吞吐收益。

练习

问题 1|输入契约 当 S = XT = 1r = 0.05σ = 0.2 时,若把 σ 提高到 0.4,为什么 call price 通常会上升?这能否推出市场价格一定会上升?

问题 2|改写 Demo 给实验增加 put payoff,并让模型切换到 put 时显示 max(X − S, 0)。为什么不能只把 call 的结果乘一个负号?

问题 3|并行边界 为什么 GPU 可以同时计算一千份 lattice,却不能无同步地同时更新同一棵树的所有时间列?如果要支持 American option,需要在哪一步加判断?

名词解释

本章出现的专业名词,用大白话再讲一遍。

option
价值依赖另一项资产的衍生合约,call 和 put 分别给予买入或卖出权利。
Black-Scholes model
在特定分布和无套利假设下计算 European option 理论价格的解析模型。
cumulative normal distribution
累计标准正态分布函数,输入一个标准化值并返回它左侧的概率。
arithmetic intensity
每搬运一份数据所做的浮点运算量,用来判断计算还是带宽更可能成为瓶颈。
lattice model
把未来资产价格离散成树,并从到期 payoff 反向回推当前价值的模型。
dynamic programming
复用相邻子问题结果、从已知终点逐步求出当前状态的算法方法。

资料与写作方式声明

本章以GPU Gems 系列权威目录界定学习范围,并结合正文列出的技术资料独立重写;不宣称复现原书正文,也不沿用原作表述。

原作版权归作者与出版社所有;本站原创教学结构与表述仅供学习交流。

讨论

评论区加载中…