Fix bugs, clean up code, standardize MC Greeks
This commit is contained in:
@@ -22,5 +22,5 @@ void bsm(struct Option *opt)
|
|||||||
price = opt->spot * normalcdf(d1 * opt->type) * opt->type - opt->strike *
|
price = opt->spot * normalcdf(d1 * opt->type) * opt->type - opt->strike *
|
||||||
exp(-opt->rfr * tte) * normalcdf(d2 * opt->type) * opt->type;
|
exp(-opt->rfr * tte) * normalcdf(d2 * opt->type) * opt->type;
|
||||||
opt->fv = price;
|
opt->fv = price;
|
||||||
opt->vega = opt->spot * exp(-opt->rfr * tte) * pow(tte, 0.5) * normalpdf(d1);
|
opt->vega = opt->spot / 100 * exp(-opt->rfr * tte) * pow(tte, 0.5) * normalpdf(d1);
|
||||||
}
|
}
|
||||||
|
|||||||
18
src/gbm_mc.c
18
src/gbm_mc.c
@@ -35,25 +35,25 @@ void gbm(struct Option *opt)
|
|||||||
rand = gaussrand();
|
rand = gaussrand();
|
||||||
level = gbm_simulation(opt->spot, opt->rfr, opt->vol, tte, rand);
|
level = gbm_simulation(opt->spot, opt->rfr, opt->vol, tte, rand);
|
||||||
base += max((level - opt->strike) * opt->type, 0);
|
base += max((level - opt->strike) * opt->type, 0);
|
||||||
level = gbm_simulation(opt->spot + 0.01, opt->rfr, opt->vol, tte, rand);
|
level = gbm_simulation(opt->spot + 1, opt->rfr, opt->vol, tte, rand);
|
||||||
delta_shift += max((level - opt->strike) * opt->type, 0);
|
delta_shift += max((level - opt->strike) * opt->type, 0);
|
||||||
level = gbm_simulation(opt->spot, opt->rfr, opt->vol + 0.01, tte, rand);
|
level = gbm_simulation(opt->spot, opt->rfr, opt->vol + 0.01, tte, rand);
|
||||||
vega_shift += max((level - opt->strike) * opt->type, 0);
|
vega_shift += max((level - opt->strike) * opt->type, 0);
|
||||||
level = gbm_simulation(opt->spot, opt->rfr, opt->vol, tte + 1/365, rand);
|
level = gbm_simulation(opt->spot, opt->rfr, opt->vol, tte - 1./365., rand);
|
||||||
theta_shift += max((level - opt->strike) * opt->type, 0);
|
theta_shift += max((level - opt->strike) * opt->type, 0);
|
||||||
level = gbm_simulation(opt->spot, opt->rfr + 0.0001, opt->vol, tte, rand);
|
level = gbm_simulation(opt->spot, opt->rfr + 0.01, opt->vol, tte, rand);
|
||||||
rho_shift += max((level - opt->strike) * opt->type, 0);
|
rho_shift += max((level - opt->strike) * opt->type, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
price = base / opt->sims * 1 / pow((1 + opt->rfr), tte);
|
price = base / opt->sims * 1 / pow((1 + opt->rfr), tte);
|
||||||
delta = delta_shift / opt->sims * 1 / pow((1 + opt->rfr), tte);
|
delta = delta_shift / opt->sims * 1 / pow((1 + opt->rfr), tte);
|
||||||
vega = vega_shift / opt->sims * 1 / pow((1 + opt->rfr), tte);
|
vega = vega_shift / opt->sims * 1 / pow((1 + opt->rfr), tte);
|
||||||
theta = theta_shift / opt->sims * 1 / pow((1 + opt->rfr), tte);
|
theta = theta_shift / opt->sims * 1 / pow((1 + opt->rfr), tte - 1./365.);
|
||||||
rho = rho_shift / opt->sims * 1 / pow((1 + opt->rfr), tte);
|
rho = rho_shift / opt->sims * 1 / pow((1 + opt->rfr + 0.01), tte);
|
||||||
|
|
||||||
opt->fv = price;
|
opt->fv = price;
|
||||||
opt->delta = (delta - price) * 100 * opt->spot;
|
opt->delta = (delta - price);
|
||||||
opt->vega = (vega - price) * opt->spot;
|
opt->vega = (vega - price);
|
||||||
opt->theta = (theta - price) * opt->spot;
|
opt->theta = (theta - price);
|
||||||
opt->rho = (rho - price) * opt->spot;
|
opt->rho = (rho - price);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ int print_help(void)
|
|||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
double spot = 0, strike = 0, rfr = 0, vol = 0, sims = 1000;
|
double spot = 0, strike = 0, rfr = 0, vol = 0, sims = 1000;
|
||||||
char expiry_date[11], value_date[11], buffer[1024];
|
char expiry_date[11], value_date[11];
|
||||||
int opt, option_index = 0, type = 0;
|
int opt, option_index = 0, type = 0;
|
||||||
struct tm value, expiry;
|
struct tm value, expiry;
|
||||||
struct Option bs_opt, mc_opt;
|
struct Option bs_opt, mc_opt;
|
||||||
@@ -84,7 +84,9 @@ int main(int argc, char *argv[])
|
|||||||
memset(&expiry, 0, sizeof(expiry));
|
memset(&expiry, 0, sizeof(expiry));
|
||||||
memset(&value, 0, sizeof(value));
|
memset(&value, 0, sizeof(value));
|
||||||
|
|
||||||
while ((opt = getopt_long(argc, argv, "s:k:r:v:d:e:N:cp:h", long_options, &option_index)) != -1) {
|
srand(time(NULL));
|
||||||
|
|
||||||
|
while ((opt = getopt_long(argc, argv, "s:k:r:v:d:e:N:cph", long_options, &option_index)) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 's':
|
case 's':
|
||||||
if (sscanf(optarg, "%lf", &spot) == EOF) {
|
if (sscanf(optarg, "%lf", &spot) == EOF) {
|
||||||
@@ -133,14 +135,16 @@ int main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bs_opt.spot = spot;
|
bs_opt.spot = mc_opt.spot = spot;
|
||||||
bs_opt.strike = strike;
|
bs_opt.strike = mc_opt.strike = strike;
|
||||||
bs_opt.expiry_date = &expiry;
|
bs_opt.expiry_date = mc_opt.expiry_date = &expiry;
|
||||||
bs_opt.value_date = &value;
|
bs_opt.value_date = mc_opt.value_date = &value;
|
||||||
bs_opt.rfr = rfr;
|
bs_opt.rfr = mc_opt.rfr = rfr;
|
||||||
bs_opt.vol = vol;
|
bs_opt.vol = mc_opt.vol = vol;
|
||||||
bs_opt.type = type;
|
bs_opt.type = mc_opt.type = type;
|
||||||
|
mc_opt.sims = sims;
|
||||||
|
|
||||||
|
/*
|
||||||
mc_opt.spot = spot;
|
mc_opt.spot = spot;
|
||||||
mc_opt.strike = strike;
|
mc_opt.strike = strike;
|
||||||
mc_opt.expiry_date = &expiry;
|
mc_opt.expiry_date = &expiry;
|
||||||
@@ -148,13 +152,13 @@ int main(int argc, char *argv[])
|
|||||||
mc_opt.rfr = rfr;
|
mc_opt.rfr = rfr;
|
||||||
mc_opt.vol = vol;
|
mc_opt.vol = vol;
|
||||||
mc_opt.type = type;
|
mc_opt.type = type;
|
||||||
mc_opt.sims = sims;
|
*/
|
||||||
|
|
||||||
strftime(expiry_date, 11, "%Y-%m-%d", &expiry);
|
strftime(expiry_date, 11, "%Y-%m-%d", &expiry);
|
||||||
strftime(value_date, 11, "%Y-%m-%d", &value);
|
strftime(value_date, 11, "%Y-%m-%d", &value);
|
||||||
bsm(&bs_opt);
|
bsm(&bs_opt);
|
||||||
gbm(&mc_opt);
|
gbm(&mc_opt);
|
||||||
sprintf(&buffer[0],
|
printf(
|
||||||
"\nValuation date: %s\n\n"
|
"\nValuation date: %s\n\n"
|
||||||
" | BS Analytic | BS Monte Carlo |\n"
|
" | BS Analytic | BS Monte Carlo |\n"
|
||||||
" ---------------------------------------------\n"
|
" ---------------------------------------------\n"
|
||||||
@@ -167,11 +171,11 @@ int main(int argc, char *argv[])
|
|||||||
" |sims: | %4.2f| %4.2f|\n"
|
" |sims: | %4.2f| %4.2f|\n"
|
||||||
" |exp: | %4.2s| %4.2f|\n"
|
" |exp: | %4.2s| %4.2f|\n"
|
||||||
*/
|
*/
|
||||||
" |Fair value: | %10.2f | %13.2f |\n"
|
" |Fair value: | %8.4f | %11.4f |\n"
|
||||||
" |Delta: | %10.2f | %13.2f |\n"
|
" |Delta: | %8.4f | %11.4f |\n"
|
||||||
" |Vega: | %10.2f | %13.2f |\n"
|
" |Vega: | %8.4f | %11.4f |\n"
|
||||||
" |Theta: | %8.4f | %11.4f |\n"
|
" |Theta: | %8.4f | %11.4f |\n"
|
||||||
" |Rho : | %8.4f | %11.4f |\n\n",
|
" |Rho: | %8.4f | %11.4f |\n",
|
||||||
value_date,
|
value_date,
|
||||||
bs_opt.type, mc_opt.type,
|
bs_opt.type, mc_opt.type,
|
||||||
bs_opt.spot, mc_opt.spot,
|
bs_opt.spot, mc_opt.spot,
|
||||||
@@ -183,6 +187,12 @@ int main(int argc, char *argv[])
|
|||||||
bs_opt.vega, mc_opt.vega,
|
bs_opt.vega, mc_opt.vega,
|
||||||
bs_opt.theta, mc_opt.theta,
|
bs_opt.theta, mc_opt.theta,
|
||||||
bs_opt.rho, mc_opt.rho);
|
bs_opt.rho, mc_opt.rho);
|
||||||
printf("%s", buffer);
|
printf(
|
||||||
|
" ---------------------------------------------\n\n"
|
||||||
|
);
|
||||||
|
/*
|
||||||
|
printf("%s", buffer1);
|
||||||
|
printf("%s", buffer2);
|
||||||
|
*/
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#ifndef UTILS_H
|
#ifndef UTILS_H
|
||||||
#define UTILS_H
|
#define UTILS_H
|
||||||
|
|
||||||
|
void srand(unsigned int seed);
|
||||||
|
|
||||||
double normalcdf(double z);
|
double normalcdf(double z);
|
||||||
|
|
||||||
double normalpdf(double z);
|
double normalpdf(double z);
|
||||||
@@ -18,7 +20,7 @@ struct Option {
|
|||||||
double spot;
|
double spot;
|
||||||
double rfr;
|
double rfr;
|
||||||
double vol;
|
double vol;
|
||||||
int sims;
|
long sims;
|
||||||
|
|
||||||
/* fv and greeks */
|
/* fv and greeks */
|
||||||
double fv;
|
double fv;
|
||||||
|
|||||||
Reference in New Issue
Block a user