简单的代码来计算呼叫选项的“到期时间”是一个无限循环

我想通过使用下面的循环来计算呼叫选项的“到期时间”。 请注意, optionbidprice是电子表格上打印的一个数字,可以正确读取。 期权价格必须重新计算每个新的T ,因此也function0 。 此外,每次迭代都重新计算functionderived

 optionPrice = BSMOptPrice(opT, S, sigma, K, rf, q, T) functionDerived = (-1) * ((S * Nd1accent * sigma * Exp(-q * T)) / (2 * Sqr(T))) + (q * S * ND1 * Exp(-q * T)) - (rf * K * Exp(-rf * T) * ND2) Do Until function0 = 0.1 function0 = optionBidPrice - optionPrice Tnext = T - (function0 / functionDerived) T = Tnext Loop calculateOptionExpiration = Tnext 

我猜测0.1数字太不现实,并且循环找不到一个好的T值。

你怎么看?

而什么@EricJ。 回答是有效的,还有其他的方法来直接testing0.1的值…而不需要testing它周围的小范围。

其中之一是转换为十进制变体子types,它不会受到双精度,单精度或datetypes不精确的影响。

考虑这个过程。 它将永远不会完成,因为Double的不精确性:

 Sub Bad() Dim k As Double k = 0 Do Until k = 0.1 k = k + 0.001 DoEvents Loop MsgBox k End Sub 

现在考虑一下,它会立即结束:

 Sub Good() Dim k As Variant ' <-- look here k = CDec(0) ' <-- look here Do Until k = 0.1 k = k + 0.001 DoEvents Loop MsgBox k End Sub 

回答@ Jolien.A问题:

functionDerived定义为变体,并在等号右侧的expression式上使用CDec()。

这是一个更好的方法,尽pipe在OP的情况下它不起作用:

 Sub Better() Dim k As Double k = 0 Do Until k = 0.1@ ' <-- look here k = k + 0.001 DoEvents Loop MsgBox k End Sub 

这个更快,因为迭代器(k)保持为Double。 请注意At末尾的符号(@) Do Until k = 0.1@ At符号是十进制types字符,并将其用作文字数字值的后缀指示VBA编译器该数字为十进制,不是Double(这是分数字面数字的默认值。

额外细节

从MSDN: https : //msdn.microsoft.com/en-us/library/xtba3z33.aspx

十进制数据types:

  • 保存带符号的128位(16字节)值

  • 它最多支持29位有效数字

  • 它特别适用于计算,如财务,需要大量的数字,但不能容忍舍入误差。

  • 最大值是+/- 7.9228162514264337593543950335,最小的非零值是+/- 0.0000000000000000000000000001(+/- 1E-28)。

  • 十进制不是浮点数据types。 Decimal结构包含一个二进制整数值,以及一个符号位和一个整数比例因子,指定该值的哪一部分是小数部分。 正因为如此,十进制数字在浮点types(Single和Double)中的表示方式更精确。

  • 十进制数据types是所有数字types中最慢的。 在select数据types之前,您应该权衡精度对性能的重要性。

0.1的值不能完全使用浮点数来表示。 您将需要testing该值是在0.1左右的一个小范围内 。 请注意,对于任何浮点相等比较来说都是如此。

有关深入的解释,请参阅为什么0.1不存在于浮点中