2012-04-04 3 views
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에 함수가 없다고 생각합니다. 또한 원하는 값을 찾을 때까지 2 차원 배열을 만들고 반복 할 생각입니다. 또는 적절한 값을 얻을 때까지 해당 값으로 반복하여 300 개의 double을 정의 할 수 있습니다. 최선의 접근 방법에 대한 생각?

+2

Objective-C의 [누적 정규 분포 계산에 관한 비슷한 질문] (http://stackoverflow.com/questions/2785944/cumulative-normal-distribution-function-in-objective-c) 전에 물었다. @ Jason S.은 한 가지 방법을 제공했지만, 이미 구현 된 정상적인 CDF가있는 C++ 라이브러리를 가져올 수도 있습니다. –

답변

5

더 명확하게 찾고 싶은 것을 정의해야합니다. 게시 한 내용에 따라 누적 분포 함수 또는 P (d < d1)를 찾고있는 것으로 보입니다. 여기서 d1은 표준 편차로, d는 정규 분포입니다. 예를 들어 d1 = 0.43이면 P (d < d1) = 0.6664이다.

원하는 기능을 오류 기능 erf(x)이라고하며, 이에 대한 좋은 근사가 있습니다.

분명히 erf(x)은 C의 표준 math.h에 포함되어 있습니다 (객관적인 -c에 대해서는 확실하지 않지만 아마도 그 내용도 포함되어 있다고 가정합니다).

그러나 erf(x)은 꼭 필요한 기능이 아닙니다. 일반적인 형태의 P (d < D1)는 다음 식으로부터 계산 될 erf(x)

시그마의 표준 편차이다
P(d<d1) = f(d1,sigma) = (erf(x/sigma/sqrt(2))+1)/2 

. (귀하의 경우에는 σ = 1을 사용할 수 있습니다)

Wolfram Alpha에서 이것을 테스트 할 수 있습니다 : f (0.43,1) = (erf (0.43/sqrt (2)) +1)/2 = 0.666402 당신의 테이블과 일치합니다.

중요한 두 가지가 있습니다

  1. 당신은 D1 (약 3.0 * 시그마보다 절대 값이 큰) 큰 P (D < D1)를 찾고 있다면 그때 당신이해야 정말 수치 오류가 발생하지 않고 P (d < d1)가 0 또는 1에 가까워지는 것을 알려주는 상보 오류 기능 erfc(x) = 1-erf(x)을 사용하십시오. df = (erf (d1/σ/sqrt (2)) + 1)/2 = erfc (-d1/σ/sqrt (2))/2에 대해, d1> 3 * 시그마, P (d< d1) = (erf (d1/σ/sqrt (2)) +1)/2 = 1- erfc (d1/시그마/sqrt (2) 실제로 그것을 계산하지 않습니다. 대신 K = erfc (d1/σ/sqrt (2))/2 인 1 - K로 두십시오. 예를 들어, D1 = 5 * 시그마, 다음 P (D < D1) = 1-2.866516 * 10 -7

  2. 예를 들어 프로그래밍 환경이 erf(x) 가능한 라이브러리로 구축하지 않으면, 당신에게 좋은 근사가 필요합니다. (나는 사용하기 쉬운 하나가 있다고 생각했지만 그것을 찾을 수 없으며 그것은 실제로 역 오류 기능을위한 것이라고 생각한다). 이 1969 article by W. J. Cody은 erf (x)에 대한 좋은 근사값을 제공합니다. | x | < 0.5이고, | x |에 대해 erf (x) = 1 - erfc (x)를 사용하는 것이 더 좋습니다. > 0.5. 예를 들어, erf (0.2) & approx; Wolfram Alpha의 0.2227025892105; Cody는 x * R (x)으로 평가합니다. 여기서 R은 테이블에서 얻을 수있는 유리 함수입니다.

나는이 자바 스크립트합니다 (코디 용지의 표 2에서 계수)를 시도하는 경우 :

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

그때 나는 1 차 합리적 기능, 꽤 가까운 erf1(0.2) = 0.22270208866303123를 얻을. 코디는 4까지의 합리적인 함수에 대한 계수 테이블을 제공합니다.

// 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); 
} 

당신에게 10 소수점 이하 자릿수를 올바른 erf2(0.2) = 0.22270258922638206을 제공합니다 : 여기에도 2입니다. Cody 논문은 또한 erfc (x)에 대한 유사한 수식을 제공합니다. 여기서 | x | 는 0.5와 4.0 사이이며, erfc (x)에 대한 세 번째 공식은 | x | > 4.0이며 원하는 경우 Wolfram Alpha 또는 알려진 erfc (x) 테이블을 사용하여 결과를 확인할 수 있습니다.

희망이 도움이됩니다.

+0

고마워, 네 질문에 좀 더 분명해야 했어 – SNV7

+0

훌륭해! – SNV7

관련 문제