ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

tf-quant-finance LSM 最小二乘蒙特卡洛算法:用 Longstaff-Schwartz 回归法为美式期权定价

tf-quant-finance LSM 最小二乘蒙特卡洛算法:用 Longstaff-Schwartz 回归法为美式期权定价 金融科技科学计算【免费下载链接】tf-quant-financeHigh-performance TensorFlow library for quantitative finance.项目地址https://gitcode.com/gh_mirrors/tf/tf-quant-finance点击查看免费下载导读本文围绕 tf-quant-finance 中tf_quant_finance.experimental.lsm_algorithm模块展开系统讲解基于 Longstaff Schwartz2001回归法的最小二乘蒙特卡洛LSM美式期权定价实现从 API 概览、least_square_mc与least_square_mc_v2两代定价入口的参数语义到多项式基函数、篮子看跌期权 payoff 构造再到与仓库源码、测试用例对照的算法原理纵深。读完本文你将能够用该模块完成模拟标的路径 → 构造 payoff 与基函数 → 回归求最优停时 → 折现均值的完整美式期权定价流程并理解 v2 版本为 XLA 兼容与批量估值所做的工程取舍。模块定位与整体 API 结构lsm_algorithm模块位于tf_quant_finance/experimental/下模块 docstring 概括为LSM algorithm methodsLSM 算法方法集。模块级索引文档 api_docs/tf_quant_finance/experimental/lsm_algorithm.md 列出了全部 5 个公开符号定义于 tf_quant_finance/experimental/lsm_algorithm/init.py公开 API来源文件作用least_square_mclsm.py用 LSM 算法为美式期权定价基础版least_square_mc_v2lsm_v2.py用 LSM 算法为美式期权定价XLA 兼容、支持 batch 与样本校准划分make_basket_put_payoffpayoff.py从样本构造简单篮子看跌期权的 payoff 可调用对象make_polynomial_basislsm.py构造用于回归的多项式基函数v1 版make_polynomial_basis_v2lsm_v2.py构造用于回归的多项式基函数v2 版带时间索引参数模块级导入后可通过tff.experimental.lsm_algorithm.least_square_mc等形式调用tff.experimental.__init__.py第 20 行将lsm_algorithm纳入公开子模块。在 Bazel 构建体系中BUILD 将其拆分为lsm、lsm_v2、payoff三个py_library并配套lsm_test、lsm_v2_test、payoff_test三个py_test目标。LSM 算法原理回顾least_square_mc的 docstring 对算法思想作了如下概括与 lsm.py 一致最小二乘蒙特卡洛LSM算法是一种估值美式期权的蒙特卡洛方法。利用标的资产的样本路径和用户提供的 payoff 函数它尝试为每条样本路径找到最优行权点在已知最优行权点后期权价值被定义为假设最优行权下的平均 payoff 并折现到现值。这一思想源自文献Longstaff, F.A. and Schwartz, E.S., 2001.Valuing American options by simulation: a simple least-squares approach. The review of financial studies, 14(1), pp.113–147。与普通蒙特卡洛只模拟到期 payoff 不同美式期权允许在到期前的任意可行时点行权因此核心难点在于估计每个时刻继续持有的期望价值continuation value。LSM 的巧妙之处在于从后往前在每个可行行权时点用该时点实值路径的样本做横截面回归以当前标的价格的函数为解释变量以未来已折现最优现金流为响应变量得到条件期望函数的近似再逐条路径比较立即行权收益与继续持有期望从而回溯出最优停时。least_square_mc基础版定价入口函数签名与参数语义tf_quant_finance.experimental.lsm_algorithm.least_square_mc( sample_paths, exercise_times, payoff_fn, basis_fn, discount_factorsNone, dtypeNone, nameNone )各参数含义详见 least_square_mc.mdsample_paths形状为[num_samples, num_times, dim]的Tensor即底层 Ito 过程在num_times个时间点上的dim维样本路径。exercise_times形状为[num_exercise_times]的int32Tensor元素必须是[0, ..., num_times - 1]的子集表示期权可行权的时点 tick。payoff_fn可调用对象输入形状[num_samples, num_times, dim]的样本与一个表示当前时间索引的整数标量输出形状[num_samples, payoff_dim]的Tensordtype 与样本一致表示在该时点立即行权的支付。payoff_dim允许在同一标的资产samples上并行估值多个期权。basis_fn可调用对象输入形状[num_samples, dim]的样本输出形状[basis_size, num_samples]的Tensor即用于回归持有价值的设计矩阵。discount_factors形状[num_exercise_times]或[num_samples, num_exercise_times]的Tensor第 k 个元素表示时间 tick k 处的折现因子。默认None映射为与样本同 dtype、形状[num_exercise_times]的全 1Tensor。dtype可选tf.float32或tf.float64指定输入输出Tensor的 dtype默认None时由 TensorFlow 推断。namePythonstr为函数创建的 Op 添加前缀默认None映射为least_square_mc。返回值形状[num_samples, payoff_dim]、与samples同 dtype 的Tensor。源码级执行流程从 lsm.py 的实现可以看到以下关键步骤输入规整sample_paths、exercise_times、discount_factors统一转为Tensor若discount_factors缺省则构造全 1 折现向量若其 rank 为 1则扩展为[1, num_exercise_times]第 204-205 行并在末尾concat一个值为 1 的前缀元素使discount_factors[0] 1代表 0 时刻的折现因子第 207-209 行。现金流初始化取最后一个可行权 tick调用payoff_fn得到到期 payoff形状[num_samples, payoff_dim]并在其后拼接num_times - 1个 0构成形状[num_samples, payoff_dim, num_exercise]的cashflow张量第 212-221 行。倒推循环通过tf.while_loop以LsmLoopVars(exercise_index, cashflow)为循环变量从num_times - 1递减到 0循环条件exercise_index 0见lsm_loop_cond第 236-239 行。循环体_lsm_loop_body第 354-380 行每个迭代执行计算当前 tick 的即时行权价值exercise_value payoff_fn(sample_paths, tick)用continuation_value_fn将当前索引右侧的现金流折现到当前时点得到继续持有的现值第 242-269 行折现比例由discount_factors[..., exercise_index 1:] / discount_factors[..., exercise_index]给出取sample_paths[:, tick, :]调用basis_fn构造回归设计矩阵调用expected_exercise_fn做最小二乘回归得到每条路径期望持有价值详见下文调用_updated_cashflow第 318-351 行更新现金流当exercise_value expected_continuation时判定该路径应提前行权写入新的现金流并将之后的现金流置零。定价输出循环结束后用continuation_value_fn(loop_value.cashflow, discount_factors, 0)将现金流折现到 0 时刻再对样本维度做reduce_mean第 231-233 行即得平均最优行权 payoff 的现值。回归核心expected_exercise_fn回归的数学本质在 lsm.py 的注释中交代得很清楚对于设计矩阵 X 与响应 y最优线性无偏估计系数 β 满足正规方程XX β Xy。实现细节包括仅在实值路径上回归mask cast(exercise_value 0, ...)将非实值路径的设计矩阵行清零第 297-300 行因为永远不会在该时点行权的样本不影响回归系数注释同时指出同一组样本路径在不同 payoff 下实值集合不同因此batch_design通过broadcast_to为每个 payoff 维复制一份设计矩阵。伪逆保证数值稳定lhs matmul(masked, masked, transpose_aTrue)后用tf.linalg.pinv(lhs)计算伪逆第 305-308 行避免病态矩阵导致的数值不稳定。结果截断最终返回tf.maximum(continuation, 0.0)第 315 行即期望持有价值不小于 0——这与继续持有期权不会带来负的期望价值的金融直觉一致。论文示例的测试验证lsm_test.py 直接复现了 Longstaff Schwartz 论文 Section 1 的经典 8 条路径、3 个行权时刻算例samples [[1.0, 1.09, 1.08, 1.34], [1.0, 1.16, 1.26, 1.54], [1.0, 1.22, 1.07, 1.03], [1.0, 0.93, 0.97, 0.92], [1.0, 1.11, 1.56, 1.52], [1.0, 0.76, 0.77, 0.90], [1.0, 0.92, 0.84, 1.01], [1.0, 0.88, 1.22, 1.34]] # 每两期之间的利率为 0.06对应折现因子 interest_rates [0.06, 0.06, 0.06] discount_factors np.exp(-np.cumsum(interest_rates))test_american_option_putlsm_test.py用make_polynomial_basis(2)与make_basket_put_payoff([1.1])在exercise_times[1, 2, 3]下得到美式看跌价格0.1144test_european_option_put仅在exercise_times[3]行权得到欧式价格0.0564与论文手算结果吻合。这组测试同时验证了算法在tf.float32/tf.float64两种精度下都稳定。make_basket_put_payoff篮子看跌 payoff 构造器tf_quant_finance.experimental.lsm_algorithm.make_basket_put_payoff( strike_price, dtypeNone, nameNone )strike_price与样本 dtype 一致的Tensor形状[num_samples, num_strikes]可同时为多个行权价构造 payoff。dtype/name语义同前name默认put_valuer。返回一个可调用对象输入形状[num_samples, num_exercise_times, dim]的样本与当前时间标量输出形状[num_samples, num_strikes]的 payoff。底层实现在 payoff.py 的_put_valuer中取出time_index处的切片样本对最后一维篮子成分维度dim求平均average reduce_mean(slice_sample_paths, axis-1)再返回tf.nn.relu(strike_price - average)即篮子平均价格低于行权价的差额不为负。它通过functools.partial把strike_price绑定进闭包形成可调用对象。值得注意该实现天然兼容 batch 输入rank 为 3 时自动expand_dims到[num_samples, 1, num_times, dim]rank 为 4 时转置为[num_samples, batch_size, num_times, dim]第 79-84 行。payoff_test.py 给出了可直接对拍的手算期望对 strike[1.1, 1.2]、末时刻样本第 3 条路径1.03的 payoff 为[0.07, 0.17]第 4 条路径0.92为[0.18, 0.28]第 6 条路径0.90为[0.2, 0.3]等。make_polynomial_basis回归用的多项式基函数tf_quant_finance.experimental.lsm_algorithm.make_polynomial_basis(degree)degreeint32标量期望的多项式次数若小于 0tf.debugging.assert_greater_equal会抛出断言docstring 声明为ValueError见 lsm.py。返回输入[num_samples, dim]、输出[degree * dim, num_samples]的可调用对象。核心逻辑lsm.py先做中心化Y X - mean(X, axis0)再构造次数从 0 到degree的完整单项式网格并做reduce_prod最后转置。docstring 中的示例degree2, dim2说明其展开包含1, X, X**2, Y, Y**2, X*Y, X**2*Y, X*Y**2等项。附带的数值示例basis make_polynomial_basis(2) x [1.0, 2.0, 3.0, 4.0] x tf.expand_dims(x, -1) basis(x) # Expected result: # [[ 1.0, 1.0, 1.0, 1.0], [-1.5, -0.5, 0.5, 1.5]]第一行是常数项 1第二行是中心化后的X - mean(X)均值为 2.5故为-1.5, -0.5, 0.5, 1.5。注意此处输出形状为[degree * dim, num_samples]与 v2 版本存在差异见下。least_square_mc_v2XLA 兼容的升级版签名差异tf_quant_finance.experimental.lsm_algorithm.least_square_mc_v2( sample_paths, exercise_times, payoff_fn, basis_fn, discount_factorsNone, num_calibration_samplesNone, dtypeNone, nameNone )与 v1 相比v2lsm_v2.py的核心变化体现在支持 batch 维度sample_paths可为[num_samples, num_times, dim]或[batch_size, num_samples, num_times, dim]batch_size允许并行估值多个期权通过 payoff 的多个标的或多组样本路径两种方式见 lsm_v2_test.py 中test_american_option_put_batch_samples与test_american_option_put_batch_payoff。相应地payoff_fn输出形状变为[num_samples, batch_size]basis_fn需接收完整样本路径与时间索引两个参数输出[batch_size, basis_size, num_samples]。新增num_calibration_samples可选整数不超过num_samples指定用于 LSM 回归步骤的路径条数注意定价时只用最后num_samples - num_calibration_samples条路径第 284-286 行即回归用前 N 条、定价用后 M 条以降低用同一批样本既做回归又做定价带来的偏差。默认None表示所有样本同时用于回归与定价。静态形状与 XLA 兼容文件头部 docstring第 15-26 行明确说明v2 是为XLA 兼容而设计——_continuation_value_fn、_expected_exercise_fn、_updated_cashflow内部所有张量均为静态形状用tf.where 固定形状掩码替代 v1 中的动态拼接代价是内存占用上升且某些情况下可能比不做 XLA 编译的旧版慢。make_polynomial_basis_v2输出的函数额外带time_index参数内部用tf.slice按索引切片避免动态形状张量这也是它与 v1 基函数的主要区别。折现因子 rank 3 支持discount_factors可为[num_exercise_times]或与[num_samples, batch_size, num_exercise_times]兼容的 rank 3 张量第 243-249 行用tf.pad前置 1。回归细节_expected_exercise_fn第 331-386 行在 v1 的实值掩码 伪逆基础上增加calibration_indices的tf.gather子采样输出用tf.nn.relu截断非负。v2 的回归基函数make_polynomial_basis_v2tf_quant_finance.experimental.lsm_algorithm.make_polynomial_basis_v2(degree)与 v1 的差异在于返回的可调用对象接收(sample_paths, time_index)两个参数内部先按time_index切片出当前时点的样本再中心化并做幂网格展开lsm_v2.py。输出形状为[batch_size, (degree 1)**dim, num_samples]——注意 v2 是完整的(degree 1)**dim个单项式含所有交叉项与常数项而 v1 docstring 写作[degree * dim, num_samples]并宣称展开含X*Y等交叉项两者展开的项数规则并不相同选用时需按形状断言核对。文档自带示例basis tff.experimental.lsm_algorithm.make_polynomial_basis_v2(2) x [[1.0], [2.0], [3.0], [4.0]] x tf.expand_dims(x, axis-1) basis(x, tf.constant(0, dtypenp.int32)) # Expected result: # [[ 1. , 1. , 1. , 1. ], [-1.5 , -0.5 , 0.5 , 1.5 ], # [ 2.25, 0.25, 0.25, 2.25]]即[常数项 1, 中心化一次项 X-2.5, 中心化二次项 (X-2.5)**2]。端到端实战欧式/美式看跌期权定价对照主文档least_square_mc与least_square_mc_v2均附有同一份完整示例lsm.py、lsm_v2.py下面给出修正笔误后的可运行版本原文档中lsm_price(...)应为least_square_mc(...)strikes应为strikeimport numpy as np import tensorflow as tf import tf_quant_finance as tff from tf_quant_finance.experimental.lsm_algorithm import ( least_square_mc, make_basket_put_payoff, make_polynomial_basis) # 标的为 Black-Scholes 过程dS_t / S_t rate dt sigma**2 dW_tS_0 1.0 # 其中 rate 0.1波动率 sigma 1.0。先定义 log(S_t) 的漂移与波动函数 rate 0.1 def drift_fn(_, x): return rate - tf.ones_like(x) / 2. def vol_fn(_, x): return tf.expand_dims(tf.ones_like(x), -1) # 用 Euler 格式将 100000 条路径向前推进 1 年 times np.linspace(0., 1, num50) num_samples 100000 log_paths tf.function(tff.models.euler_sampling.sample)( dim1, drift_fndrift_fn, volatility_fnvol_fn, random_typetff.math.random.RandomType.PSEUDO_ANTITHETIC, timestimes, num_samplesnum_samples, seed42, time_step0.01) # 取指数还原 S_t 样本 paths tf.math.exp(log_paths) # 行权价 1.1、期限 1 年的美式看跌期权 strike [1.1] exercise_times tf.range(times.shape[-1]) discount_factors tf.exp(-rate * times) payoff_fn make_basket_put_payoff(strike) basis_fn make_polynomial_basis(10) american_price least_square_mc(paths, exercise_times, payoff_fn, basis_fn, discount_factorsdiscount_factors) # 期望结果约 [0.397] # 对照同一标的的欧式看跌期权仅到期行权 european_price tff.black_scholes.option_price( volatilities[1], strikesstrike, expiries[1], spots[1.], discount_factorsdiscount_factors[-1], is_call_optionsFalse, dtypetf.float64) # 期望结果约 [0.379]该示例要点路径模拟复用 euler_sampling.sample随机数采用PSEUDO_ANTITHETIC对偶变量降低方差seed42保证可复现每条路径在 50 个时间点采样exercise_times tf.range(50)表示每个采样点都可行权美式价格约 0.397高于欧式价格约 0.379差值即为提前行权权利的价值——这是检验 LSM 定价合理性的直观判据。选型建议与注意事项v1 与 v2 的取舍v2 是为 XLA 编译设计的静态形状实现lsm_v2.py更契合tf.function/ XLA 加速场景v1 动态拼接在某些非 XLA 场景下可能更快、内存占用更低。若需并行估值多个期权或使用num_calibration_samples防过拟合应选 v2。基函数与 degree 选择degree过小如 1~2回归精度不足过大则设计矩阵膨胀、过拟合风险上升。论文示例与测试用degree2即可在 8 条路径上精确复现蒙特卡洛大样本场景常用 10 阶主文档示例但仍需结合标的维度权衡(degree1)**dim的爆炸式增长。仅实值路径参与回归expected_exercise_fn用exercise_value 0掩码lsm.py实值判定的直觉是虚值路径在当期必不行权这与 Longstaff-Schwartz 原始论文一致。dtype 一致性discount_factors、strike_price需与sample_pathsdtype 一致定价对精度敏感时建议显式传入tf.float64。回归稳定性实现使用tf.linalg.pinv伪逆求解正规方程v1/v2 相同对病态设计矩阵具有较好的容错性。与稳定版models.longstaff_schwartz的关系experimental.lsm_algorithm与 models/longstaff_schwartz 是同一算法在仓库中的两条演进线稳定版tff.models.longstaff_schwartz提供了least_square_mc、make_polynomial_basis、make_basket_put_payoff三个同名 API其签名含num_calibration_samples与 batch 支持与 experimental 下的 v2 版本一致实现在 models/longstaff_schwartz/lsm.py 中。从源码结构看experimental 版本更贴近算法原型与研究用途稳定版则对类型标注、docstring 与 API 规范做了收尾。生产环境建议优先使用models.longstaff_schwartz研究原型或需要对照两代实现差异时可参考experimental.lsm_algorithm的源码与测试lsm_test.py、lsm_v2_test.py。赞分享金融科技科学计算【免费下载链接】tf-quant-financeHigh-performance TensorFlow library for quantitative finance.项目地址https://gitcode.com/gh_mirrors/tf/tf-quant-finance点击查看免费下载相关推荐tf-quant-finance 中 Longstaff-Schwartz 最小二乘蒙特卡洛LSM美式期权定价least_square_mc 的用法、源码原理与测试验证tf quant finance 中 Longstaff Schwartz 最小二乘蒙特卡洛LSM美式期权定价least_square_mc 的用法、源码金融科技科学计算tf-quant-finance 中最小二乘蒙特卡洛LSM算法实战向量化定价美式期权tf quant finance 中最小二乘蒙特卡洛LSM算法实战向量化定价美式期权 本文围绕 tf_quant_finance.models.longs金融科技科学计算终极指南如何使用 TensorFlow 量化金融库实现最小二乘蒙特卡洛算法终极指南如何使用 TensorFlow 量化金融库实现最小二乘蒙特卡洛算法 最小二乘蒙特卡洛算法LSM是金融工程中用于美式期权定价的核心技术之一。tf q金融科技科学计算创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进