我有一个考试题,我必须使用布莱克和斯科尔公式来计算看跌期权和看涨期权的差额。
我找到了一个为我完成此任务的网站http://www.deltaquants.com/calc-test,所以我进入代码并找到了此功能:
getDelta: function(spot, strike, volatility, riskfree, dividendy) {
var self = this;
var d1 = self.getD1(spot, strike, volatility, riskfree, dividendy);
var Nd1 = phi(d1);
// Interesting line
var result = Math.exp( - dividendy * self.expiry) * (self.type !== 'put') ? Nd1 : (Nd1 - 1);
return result.toFixed(6);
}
我在Python中复制了它:
def delta(q, t, nd1, put: bool):
return np.exp(- q * t) * (nd1 - 1 * put)
print(delta(.02, .25, .5279031701805211, True)) # -0.46974223705768553
print(delta(.02, .25, .5279031701805211, False)) # 0.5252702421349968
[具有相同的输入(Nd1 = nd1,除数= q,self.expiry = t),JS代码为看跌期权返回-0.472097
,为看涨期权返回0.527903
。
我重写了他们的JS代码,以便可以在控制台中对其进行测试:
const delta = (q, t, nd1, type) => Math.exp(-q * t) * (type !== "put") ? nd1 : (nd1 - 1);
如果您以与在python中相同的方式重写JS:
const delta2 = (q, t, nd1, put) => Math.exp(-q * t) * (nd1 - 1 * put);
// Where put is a boolean
您得到与我的python代码相同的结果,似乎Mat.exp
部分始终在其代码中被忽略。你知道为什么吗?
问题是三元运算符(... ? ... : ...
)的运算符优先级比乘法的优先级低,因此,如果您有表达式A * B ? C : D
,它将被解析为好像是(A * B) ? C : D
而不是A * (B ? C : D)
。
如果添加括号以强调表达式的解析方式,则最终会这样:
var result = (Math.exp( - dividendy * self.expiry) * (self.type !== 'put')) ? Nd1 : (Nd1 - 1);
// ^-------------------- added parentheses ---------------------^
[您在这里看到涉及Math.exp
的表达式处于三元运算符的条件下,因此result
的值将为Nd1
或Nd1 - 1
。
[我怀疑预期的计算是
var result = Math.exp( - dividendy * self.expiry) * ((self.type !== 'put') ? Nd1 : (Nd1 - 1));
// ^---------- added parentheses ----------^