ヨーロピアンオプションの価格を計算したりインプライドボラティリティを計算したりするC言語のプログラムです。
#include<math.h>
double NormalCDF(double x){
int n;
double a, c, z;
z = fabs(x);
if(z<=3.5){
c = 1;
a = 0;
for(n=1; n<=44; n++){
a += x/(2*n-1)*c;
c *= -x*x/(2*n);
}
return 0.5+a/sqrt(2*M_PI);
} else {
a = 0;
if(z<1.0E50){
for(n =44; n>=1; n--){
a = n/(z+a);
}
a = exp(-z*z/2)/(z+a)/sqrt(2*M_PI);
}
if(x<0){
return a;
} else {
return 1-a;
}
}
}
#include<math.h>
double NormalCDF(double x){
中略
}
double EuropeanCall(double S, double K, double r, double v, double T, double t){
double d1, d2, a, b;
a = log(S/K);
b = v*sqrt(T-t);
d1 = (a+(r+v*v/2)*(T-t))/b;
d2 = (a+(r-v*v/2)*(T-t))/b;
return S*NormalCDF(d1) - K*exp(-r*(T-t))*NormalCDF(d2);
}
double EuropeanPut(double S, double K, double r, double v, double T, double t){
double d1, d2, a, b;
a = log(S/K);
b = v*sqrt(T-t);
d1 = (a+(r+v*v/2)*(T-t))/b;
d2 = (a+(r-v*v/2)*(T-t))/b;
return K*exp(-r*(T-t))*NormalCDF(-d2) - S*NormalCDF(-d1);
}
#include<math.h>
#include<stdio.h>
double NormalCDF(double x){
中略
}
double EuropeanCall(double S, double K, double r, double v, double T, double t){
中略
}
double EuropeanPut(double S, double K, double r, double v, double T, double t){
中略
}
#define Price(v) EuropeanCall(S,K,r,v,T,t)
double ImpliedVol(int *err, double P, double S, double K, double r, double v, double T, double t){
double vh, vl, vm, w;
for(vh = v; Price(vh)<P; vh*=2){
if(vh > 1000){
*err = 1;
return 0.0;
}
}
for(vl = v; Price(vl)>P; vl/=2){
if(vl < 0.001){
*err = -1;
return 0.0;
}
}
w = vh - vl;
while(w>1.0E-16){
vm = (vh+vl)/2;
if(Price(vm) > P){
vh = vm;
} else {
vl = vm;
}
w /= 2;
}
*err = 0;
return (vh+vl)/2;
}
int main(){
int err;
double vol;
vol = ImpliedVol(&err, 1500, 19300, 19000, 0.01, 0.3, 1.0, 0.7);
if(err>0){
printf("ボラティリティを最大限に大きくしても合致する値が見つかりません。\n",vol);
return 1;
}
if(err<0){
printf("ボラティリティを最小限に小さくしても合致する値が見つかりません。\n",vol);
return 1;
}
printf("インプライドボラティリティは %.15f です。\n",vol);
return 0;
}