近期国内商品期货期权仿真交易开始, 不同于股票期权, 期货期权类型为美式. 本来想申请一个个人专栏来写点定价方面的东西, 目的也是为了巩固所学. 但由于某些原因被知乎暂停开设个人专栏的权利(原因下面有). 美式常用定价模型有:
1, 最小二乘蒙特卡洛模拟(LSM);
2, BAW;
3, 二叉树.
二叉树从精度上来讲是最好的, 理论本身也十分简单明了, 而且同递归算法天然匹配, 但计算速度太慢, 简直是暴力求解了(再次表明, 暴力model不可取). 大连商品交易所采取的是BAW模型, 这里就主要讲讲此模型.
BAW把美式期权价格表示为:
其中S为标的价格, T为距离到期时间, w(S, T)为early exercise premium.
由于美式和欧式期权价格都满足Black-Scholes偏微方程
其中b为标的的cost of carry, r为无风险利率.
故w亦满足BS方程, BAW模型把w作如下表示
这个表示很关键, 因子
的来源可以这样理解: T时间后得到1元, 现值只值
元, 假设我们要求立马兑现这1元钱, 那么此时有
的early exercise premium.
在分离出
这个因子后, w所满足BS偏微分方程近似成了一个常微分方程. 实际上, 当期权标的的cost of carry为0时, 我们甚至可对w作分离变量处理, 令
, 这样做的理由是当标的没有持有成本时, early exercise premium的时间因子部分完全可由现金流贬值来刻画! 为了说明这点我们回过头来看BAW模型, 其把w表示为
通过取
, BAW模型中把BS方程近似为
其中N为依赖cost of carry的常数, M则是与cost of carry无关的常数. 若我们假设cost of carry为0, 则N=0, 设
, 此时BS方程为
若我们在N等于0时直接代入方程(1), 并令方程(1)与方程(2)相同, 即
此时可以发现
恰为这个微分方程的解.
言归正传! 从常微分方程中得到f的形式解后, 需利用边界条件来确定唯一解, 实际上, BAW模型中该解唯一依赖的未知量是美式期权行权时刻标的资产价格
,我们知道美式的行权时间为停时, 即应该在美式期权价值第一次等于内在价值时行权, 也就是American(S, T)与max(S - StrikePrice, 0)相切的点执行. 自然, 我们就可选择牛顿迭代法来数值计算这个点. 至此, 整个BAW模型就讲完了.
最后Talk is cheap. Show me the code. 我用C++来实现这个算法, 当作一个小小的练习. 建立两个头文件, 一个是关于定价和计算波动率用到的数学工具, 一个是定价模型本身. C++知识点主要用了三个(言必称三):
1, lambda表达式和template, 此处运用只为形式上简洁一些;
2, namespace, 为的是防止命名冲突;
3, function object, 不使用函数而使用函数对象一是为了代码表现得更像C++而不是C, 更重要的是BAW模型有一些临时变量的计算很繁琐, 并且有共同变量, 故可用函数对象直接封装起来.
头文件norm_distribution.h
[code]#pragma once#ifndef LIUTING_NORM_DISTTRIBUTION_H#define LIUTING_NORM_DISTTRIBUTION_H#include #include namespace AmurTiger { const double PI = 3.141592653589793238462643; auto NormDensity = [](const double& d) { return (1.0 / sqrt(2.0 * PI)) * exp(-0.5 * d * d); }; double NormDist(const double& d) { if (d > 6.0) { return 1.0; }; if (d |