Помогите, кто чем может! Вторые сутки не сплю!
Возникла необходимость расчитывать теор. цену опциона в WealthLab.
Не могу правильно посчитать плотность стандартного нормального распределения для d1.
Напомню теорию, чтобы было понятнее в чем проблема
Цена опциона:
d1:
Считаем d1, теперь нужно сделать N(d1), т.е. плотность стандартного нормального распределения для d1. Именно тут я на ровном месте выпал в аут.
Формула простая
вместо z, соответственно d1.
В екслеле эта формула задана оператором НОРМСТРАСП(), с ним у меня все получается и цена опциона получается как на РТС.
Но мне нужно закодить эту формулу в ручную в WealthLab и никак не получается правильно посчитать, оператор НОРМСТРАСП() выдает разные значения с тем что я считаю вручную. Вроде формула простая, не могу понять в чем ошибка.
НАПРИМЕР:
В ексель для х=1 значение НОРМСТРАСП(1)= 0,841344746
Теперь, что получается у меня (разложу по частям чтоб было понятно что я делаю):
1/корень 2*пи = 0,39894228
e = 2,718281828
-x*x/2 = -1*1/2= -0,5
exp(-x*x/2) = 2,718281828 в степени -0,5 = 0,60653066
теперь 0,39894228*0,60653066= 0,241970725
в чем проблема-то? Что не так? Не могу понять, что я не так делаю.
ПОМОГИТЕ!
РS
Ребята, какие же Вы молодцы! Большое всем спасибо, вставили мне мозг в правильное место.
SmartLab самый умный сайт в мире!
Public Function d_1(ByVal F As Double, ByVal K As Double, ByVal T As Double, ByVal Sigma As Double) As Double
d_1 = (Log(F / K) + T * 0.5 * Sigma * Sigma) / (Sigma * Sqr(T))
End Function
Public Function nd_1(ByVal d1 As Double) As Double
nd_1 = Math.Exp(-1 * (d1 ^ 2) * 0.5) / Sqr(2 * PI)
End Function
Например вот такой (кусок на C#):
//------------------------------------------------------------
double N(double x)
{
double y = 0;
double ax, t, d, p;
if (x > 10)
y = 1;
else if (x < -10)
y = 0;
else
{
ax = Math.Sqrt(x * x);
t = 1 / (1 + 0.2316419 * ax);
d = 0.3989423 * Math.Exp(-0.5 * x * x);
p = d * t * ((((1.330274 * t — 1.821256) * t + 1.781478) * t — 0.3565638) * t + 0.3193815);
y = p;
if (x > 0)
{
y = 1 — p;
}
else
{
y = p;
}
}
return y;
}
Думаю разберетесь.
Дак вот я и не могу понять почему
у меня для единицы например, по форомуле
d = 0.3989423 * Math.Exp(-0.5 * x * x);
получается 0,241970725
а должно получится 0,841344746
корень2пи * Math.Exp(-0.5 * x * x); (из хелпа)
«теперь нужно сделать N(d1), т.е. плотность стандартного нормального распределения для d1»
Функция распределения это определенный интеграл плотности распределения, от минус бесконечности до X.
То, что Вы назвали это уравнение плотности стандартного нормального распределения.
Вам же надо считать через функцию нормального распределения.
Тогда имеем:
Excel:
=НОРМСТРАСП(1)=0.841344746
C++ код:
double NormSdist2(const double& z) {
if (z > 6.0) { return 1.0; }; // this guards against overflow
if (z < -6.0) { return 0.0; };
double b1 = 0.31938153;
double b2 = -0.356563782;
double b3 = 1.781477937;
double b4 = -1.821255978;
double b5 = 1.330274429;
double p = 0.2316419;
double c2 = 0.3989423;
double a=fabs(z);
double t = 1.0/(1.0+a*p);
double b = c2*exp((-z)*(z/2.0));
double n = ((((b5*t+b4)*t+b3)*t+b2)*t+b1)*t;
n = 1.0-b*n;
if ( z < 0.0 ) n = 1.0 — n;
return n;
};
вызов функции:
double ddd=NormSdist2(1);
cout<<ddd<<endl;
0.841345 ******
Для продолжения нажмите любую клавишу...
Этот интеграл (по-английски называется cumulative normal distribution function) не имеет функционального решения, поэтому обычно используют одну из полиномиальных интерполяций, см. здесь (http://stackoverflow.com/questions/5259421/cumulative-distribution-function-in-javascript) и если вдруг ее точности не хватает (что вряд ли), то еще здесь (http://stackoverflow.com/questions/2328258/cumulative-normal-distribution-function-in-c-c), если и этой точности не хватает, тогда только считать в лоб самому.
kbrobot.ru/forum/viewtopic.php?f=2&t=27