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
↡价值依赖另一项资产的衍生合约;call 给予买入权利,put 给予卖出权利,但都不是必须执行 的价值来自 underlying asset。最小输入契约包括 spot price S、strike price X、maturity T、risk-free rate r 和 volatility σ。本章先讨论 European call:只允许在到期日执行,payoff 是 max(S − X, 0)。
S 高于 X 时,call 的内在价值为正;T 越长或 σ 越大,未来 spot 的不确定范围通常越宽,期权价值也会受到影响。r 用连续复利把未来的 payoff 折算到今天。这里的“通常”很重要:它描述模型的敏感性,不代表真实市场中每个变量都独立或稳定。
2. Black-Scholes:解析模型的 GPU 映射
↡在一组连续分布和无套利假设下,用 d₁、d₂ 和标准正态分布计算 European option 理论价格的解析模型 对 European call 的核心形式是 V = S × CND(d₁) − X × e⁻ʳᵀ × CND(d₂),其中 d₁ 和 d₂ 由 S、X、T、r 和 σ 共同决定,且 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) 合并多项式项。
↡每搬运一单位数据所执行的浮点运算数量;越高通常越能摊薄带宽和通信成本 高是 Black-Scholes 适合 GPU 的原因之一:一次输入取样会触发 log、除法、sqrt、exp、CND 多项式和组合运算,输出却只有一个 float。原章还利用 GPU 的四路向量硬件预计算幂次;这不是改变数学模型,而是改变同一数学表达式的执行形状。
需要谨慎处理输入边界。T 或 σ 为零时,d₁ 的分母会退化;S 和 X 必须为正;CND 近似要在正负输入两侧保持一致。生产实现应把这些条件作为数据清洗和 shader 分支契约,而不是让 NaN 传遍整张价格纹理。
4. Binomial lattice:用动态规划处理更灵活的 exercise
↡把到期日的 payoff 放在二叉价格树上,再按风险中性概率和折现因子逐层向后计算当前价值的离散模型 把 maturity T 切成 N 个时间步。每一步的资产价格向上乘 u,向下乘 d;到期叶子先计算 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。
5. 动手实验:比较两个模型的实际输出
先预测:把模型从 Black-Scholes 切换到 binomial lattice,增加 steps 会不会让价格稳定地靠近解析结果?把 volatility 拖高,价格曲线的哪一段变化最明显?
GPU Gems 2 · Chapter 45
期权定价:同一输入批量映射到 GPU
切换解析模型和 lattice 模型,改变 spot、volatility、steps,观察实际计算出的 call price 与价格敏感曲线。
实验固定 X = 100、T = 1、r = 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 = X、T = 1、r = 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
- 复用相邻子问题结果、从已知终点逐步求出当前状态的算法方法。