花了好几天终于把Broadie and Detemple(1996)这篇论文里的美式期权定价算法给写出来了,找bug累死了。。。
这个算法的思想就是计算出美式期权的价格上限和价格下限,然后根据给上下限取一个权重,就可以得出美式期权的价格,至于最优权重取多少需要对历史数据做回归。
原文里期权价格的计算可以分为只根据价格下限(Lower Bound,即LBA)和同时根据上下限(Lower and Upper Bound,即LUBA)。
该算法的精确性可以做到非常高,具体对比在ju and zhong(1999)论文里有,甚至仅次于二叉树模型。
还有一点感触就是在求一个非线性方程的解时Newton法和Secant法并不好用,得出的解是错误的,所以这里有一块还是用了二分法。
class BroadieDetemple
{
//S:标的资产现价
//X:执行价
//r:无风险利率
//q:连续分红率,Cost of Carry = r-q
//sigma:波动率
//t:距离到期时间
//lamda:权重
//PutCall:Call/Put
//Type:LBA/LUBA
public enum EPutCall
{
Call,
Put,
}
public EPutCall PutCall
{
get;
set;
}
public enum EType
{
LBA,
LUBA,
}
public EType Type
{
get;
set;
}
public double GetOptionValue(double S, double X, double q, double r, double sigma,
double t, double lamda, EPutCall PutCall, EType Type)
{
if(r==0)
r = r+1e-10;
if(q==0)
q = q+1e-10;
switch(PutCall)
{
case EPutCall.Call:
return CallValue(S, X, q, r, sigma, t, lamda, Type);
case EPutCall.Put:
return CallValue(X, S, r, q, sigma, t, lamda, Type);
default:
return 0.0;
}
}
private double CallValue(double S, double X, double q, double r, double sigma,
double t, double lamda, EType Type)
{
switch(Type)
{
case EType.LBA:
return lamda*CallLow(S, X, q, r, sigma, t);
case EType.LUBA:
return lamda*CallLow(S, X, q, r, sig