1

我正在尝试使用布莱克斯科尔斯公式http://en.wikipedia.org/wiki/Black%E2%80%93Scholes构建一个简单的程序来为看涨期权定价。我试图找出从正态分布中获取概率的最佳方法。例如,如果我要手动执行此操作,我得到的值为 d1=0.43,而不是在此表中查找 0.43 http://www.math.unb.ca/~knight/utility/NormTble.htm并得到值 0.6664。

我相信c或objective-c中没有函数可以找到正态分布。我也在考虑创建一个二维数组并循环遍历,直到找到所需的值。或者,也许我可以用相应的值定义 300 个双精度值并循环遍历这些值,直到得到适当的结果。关于最佳方法的任何想法?

4

1 回答 1

5

您需要更清楚地定义您正在寻找的内容。根据您发布的内容,您似乎正在寻找累积分布函数或 P(d < d1),其中 d1 以标准偏差测量,d 是正态分布:以您的示例为例,如果 d1 = 0.43 则 P(d < d1) = 0.6664。

您想要的函数称为误差函数erf(x),它有一些很好的近似值。

显然erf(x)math.hC 中标准的一部分。(不确定objective-c,但我认为它可能也包含它)。

erf(x)不完全是您需要的功能。一般形式 P(d < d1) 可以通过erf(x)以下公式计算:

P(d<d1) = f(d1,sigma) = (erf(x/sigma/sqrt(2))+1)/2

其中 sigma 是标准差。(在您的情况下,您可以使用 sigma = 1。)

您可以在Wolfram Alpha上对此进行测试,例如: f(0.43,1) = (erf(0.43/sqrt(2))+1)/2 = 0.666402 与您的表匹配。

还有两件事很重要:

  1. 如果您正在寻找 d1 较大的 P(d < d1)(绝对值大于大约 3.0 * sigma),那么您真的应该使用互补误差函数erfc(x) = 1-erf(x),它告诉您 P(d < d1) 与 0 的接近程度或 1 而不会遇到数字错误。对于 d1 < -3*sigma,P(d < d1) = (erf(d1/sigma/sqrt(2))+1)/2 = erfc(-d1/sigma/sqrt(2))/2,并且对于d1 > 3*sigma, P(d < d1) = (erf(d1/sigma/sqrt(2))+1)/2 = 1 - erfc(d1/sigma/sqrt(2))/2 -- 但不要实际上并没有计算出来;而是将其保留为 1 - K,其中 K = erfc(d1/sigma/sqrt(2))/2。例如,如果 d1 = 5*sigma,则 P(d < d1) = 1 - 2.866516*10 -7

  2. If for example your programming environment doesn't have erf(x) built into the available libraries, you need a good approximation. (I thought I had an easy one to use but I can't find it and I think it was actually for the inverse error function). I found this 1969 article by W. J. Cody which gives a good approximation for erf(x) if |x| < 0.5, and it's better to use erf(x) = 1 - erfc(x) for |x| > 0.5. For example, let's say you want erf(0.2) ≈ 0.2227025892105 from Wolfram Alpha; Cody says evaluate with x * R(x2) where R is a rational function you can get from his table.

If I try this in Javascript (coefficients from Table II of the Cody paper):

 // use only for |x| <= 0.5
 function erf1(x)
 {
    var y = x*x;
    return x*(3.6767877 - 9.7970565e-2*y)/(3.2584593 + y);
 }

then I get erf1(0.2) = 0.22270208866303123 which is pretty close, for a 1st-order rational function. Cody gives tables of coefficients for rational functions up to degree 4; here's degree 2:

 // use only for |x| <= 0.5
 function erf2(x)
 {
    var y = x*x;
    return x*(21.3853322378 + 1.72227577039*y + 0.316652890658*y*y)
      / (18.9522572415 + 7.8437457083*y + y*y);
 }

which gives you erf2(0.2) = 0.22270258922638206 which is correct out to 10 decimal places. The Cody paper also gives you similar formulas for erfc(x) where |x| is between 0.5 and 4.0, and a third formula for erfc(x) where |x| > 4.0, and you can check your results with Wolfram Alpha or known erfc(x) tables for accuracy if you like.

Hope this helps!

于 2012-04-04T02:12:42.883 回答