2012-04-04 11 views
1

Ich versuche, ein einfaches Programm zu bauen, um Preisoptionen mit der schwarzen Scholes-Formel http://en.wikipedia.org/wiki/Black%E2%80%93Scholes zu berechnen. Ich versuche herauszufinden, wie wir die Wahrscheinlichkeit einer normalen Verteilung am besten erreichen. Zum Beispiel, wenn ich das von Hand machen würde und ich den Wert von d1 = 0,43 bekommen würde, dann würde ich 0,43 in dieser Tabelle http://www.math.unb.ca/~knight/utility/NormTble.htm nachschlagen und den Wert 0,6664 erhalten.Normalverteilung Beste Annäherung

Ich glaube, dass es keine Funktionen in c oder objective-c gibt, um die Normalverteilung zu finden. Ich denke auch darüber nach, ein zweidimensionales Array zu erstellen und durchzuschleifen, bis ich den gewünschten Wert gefunden habe. Oder vielleicht kann ich 300 Doppelgänger mit dem entsprechenden Wert definieren und diese durchlaufen, bis ich das passende Ergebnis bekomme. Irgendwelche Gedanken über den besten Ansatz?

+2

Nur für die Aufzeichnung, eine [ähnliche Frage über die Berechnung der kumulativen Normalverteilung] (http://stackoverflow.com/questions/2785944/cumulative-normal-distribution-function-in-objective-c) in Objective-C wurde schon mal gefragt. @Jason S. hat eine Möglichkeit zur Verfügung gestellt, aber Sie können auch eine C++ - Bibliothek importieren, in der die normale CDF bereits implementiert ist. –

Antwort

5

Sie müssen klarer definieren, wonach Sie suchen. Auf der Grundlage Ihrer Angaben scheint es, dass Sie nach der kumulativen Verteilungsfunktion P (d < d1) suchen, wobei d1 in Standardabweichungen und d in einer Normalverteilung gemessen wird: an Ihrem Beispiel, wenn d1 = 0,43, dann P (d < d1) = 0,6664. Die gewünschte Funktion wird als Fehlerfunktion erf(x) bezeichnet und es gibt einige gute Näherungswerte.

Offenbar erf(x) ist Teil des Standards math.h in C. (nicht sicher über objective-c, aber ich nehme an, es enthält wahrscheinlich auch so).

Aber erf(x) ist nicht genau die Funktion, die Sie brauchen.

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

wo Sigma ist die Standardabweichung: Die allgemeine Form P (d < d1) von erf(x) in der folgenden Formel berechnet werden. (in Ihrem Fall können Sie Sigma = 1 verwenden.)

Sie können dies auf Wolfram Alpha zum Beispiel testen: f (0.43,1) = (erf (0.43/sqrt (2)) + 1)/2 = 0.666402 die passt zu Ihrem Tisch.

Es gibt zwei weitere Dinge, die wichtig sind:

  1. Wenn Sie für P (d < d1), wo d1 groß (als etwa 3,0 * Sigma größer als absoluter Wert), dann sollten Sie wirklich Verwenden Sie die komplementäre Fehlerfunktion erfc(x) = 1-erf(x), die Ihnen sagt, wie nahe P (d < d1) zu 0 oder 1 ist, ohne in numerische Fehler zu geraten. Für d1 < -3 * sigma, P (d < d1) = (erf (d1/sigma/sqrt (2)) + 1)/2 = erfc (-d1/sigma/sqrt (2))/2 und z d1> 3 * sigma, P (d < d1) = (erf (d1/sigma/sqrt (2)) + 1)/2 = 1 - erfc (d1/sigma/sqrt (2))/2 - aber don berechne das nicht; belassen Sie es stattdessen als 1 - K mit K = erfc (d1/sigma/sqrt (2))/2. Zum Beispiel, wenn d1 = 5 * sigma, dann P (d < d1) = 1 - 2,866516 * 10 -7

  2. Wenn zum Beispiel Ihrer Programmierumgebung nicht erf(x) in die zur Verfügung stehenden Bibliotheken gebaut hat, Sie brauche eine gute Annäherung. (Ich dachte, ich hätte einen einfachen zu verwenden, aber ich kann es nicht finden und ich denke, es war eigentlich für die inverse Fehlerfunktion). Ich fand diese 1969 article by W. J. Cody, die eine gute Näherung für erf (x) gibt, wenn | x | < 0.5, und es ist besser, erf (x) = 1 - erfc (x) für | x | zu verwenden > 0,5. Angenommen, Sie möchten erf (0,2) & ca. 0.2227025892105 von Wolfram Alpha; Cody sagt auswerten mit x * R (x) wo R eine rationale Funktion ist, die Sie von seinem Tisch bekommen können.

Wenn ich versuche, dies in Javascript (Koeffizienten aus der Tabelle II des Cody Papier):

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

dann bekomme ich erf1(0.2) = 0.22270208866303123, die ganz in der Nähe ist, für eine 1. Ordnung rationale Funktion. Cody gibt Tabellen mit Koeffizienten für rationale Funktionen bis Grad 4; hier Grad 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); 
} 

, die Sie erf2(0.2) = 0.22270258922638206 gibt, die aus bis zu 10 Dezimalstellen korrekt ist. Das Cody-Papier liefert Ihnen auch ähnliche Formeln für erfc (x) mit | x | ist zwischen 0,5 und 4,0 und eine dritte Formel für erfc (x) mit | x | > 4.0, und Sie können Ihre Ergebnisse mit Wolfram Alpha oder bekannten erfc (x) -Tabellen auf Genauigkeit überprüfen, wenn Sie möchten.

Hoffe, das hilft!

+0

Danke, ja ich hätte in den Fragen ein wenig klarer sein sollen – SNV7

+0

Ausgezeichnet funktioniert es !! – SNV7

Verwandte Themen