Initial commit
This commit is contained in:
32
src/black_scholes.c
Normal file
32
src/black_scholes.c
Normal file
@@ -0,0 +1,32 @@
|
||||
#define _XOPEN_SOURCE
|
||||
|
||||
#include "black_scholes.h"
|
||||
#include <cblas.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
double normalcdf(double value)
|
||||
{
|
||||
return 0.5 * erfc(-value * M_SQRT1_2);
|
||||
}
|
||||
|
||||
double bsm(double spot, double rfr, double vol, double strike,
|
||||
struct tm expiry, struct tm value, int type)
|
||||
{
|
||||
double d1, d2, tte, price;
|
||||
time_t value_date, expiry_date;
|
||||
|
||||
expiry_date = mktime(&expiry);
|
||||
value_date = mktime(&value);
|
||||
tte = difftime(expiry_date, value_date) / (60 * 60 * 24 * 365);
|
||||
d1 = log(spot / strike) + tte * (rfr + pow(vol, 2) / 2)
|
||||
/ (vol * pow(tte, 0.5));
|
||||
d2 = d1 - (vol * pow(tte, 0.5));
|
||||
|
||||
price = spot * normalcdf(d1 * type) * type -
|
||||
strike * exp(-rfr * tte) * normalcdf(d2 * type) * type;
|
||||
return price;
|
||||
}
|
||||
14
src/black_scholes.h
Normal file
14
src/black_scholes.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef BLACK_SCHOLES_H_
|
||||
#define BLACK_SCHOLES_H_
|
||||
|
||||
struct tm;
|
||||
|
||||
double gbm(double spot, double rfr, double vol, double strike, struct tm expiry,
|
||||
struct tm value, int type, int sims);
|
||||
|
||||
double normalcdf(double value);
|
||||
|
||||
double bsm(double spot, double rfr, double vol, double strike, struct tm expiry,
|
||||
struct tm value, int type);
|
||||
|
||||
#endif
|
||||
55
src/gbm_mc.c
Normal file
55
src/gbm_mc.c
Normal file
@@ -0,0 +1,55 @@
|
||||
#define _XOPEN_SOURCE
|
||||
#define max(X,Y) (((X) > (Y)) ? (X) : (Y))
|
||||
|
||||
#include <gsl/gsl_statistics_double.h>
|
||||
#include <gsl/gsl_rng.h>
|
||||
#include <gsl/gsl_randist.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include "gbm_mc.h"
|
||||
|
||||
double gbm_simulation(double spot, double rfr, double vol, double tte, double rand)
|
||||
{
|
||||
double drift, stoch;
|
||||
drift = (rfr - pow(vol, 2) / 2) * tte;
|
||||
stoch = vol * pow(tte, 0.5) * rand;
|
||||
return spot * exp(drift + stoch);
|
||||
|
||||
}
|
||||
|
||||
double gbm(double spot, double rfr, double vol, double strike, struct tm expiry, struct tm value, int type, int sims)
|
||||
{
|
||||
const gsl_rng_type *T;
|
||||
gsl_rng *r;
|
||||
double tte, expiry_date, value_date, level, price;
|
||||
double *rands, *results;
|
||||
int i;
|
||||
|
||||
rands = (double *)malloc(sizeof(double) * sims);
|
||||
results = (double *)malloc(sizeof(double) * sims);
|
||||
|
||||
expiry_date = mktime(&expiry);
|
||||
value_date = mktime(&value);
|
||||
tte = difftime(expiry_date, value_date) / (60 * 60 * 24 * 365);
|
||||
|
||||
/* get array of normal random numbers */
|
||||
gsl_rng_env_setup();
|
||||
T = gsl_rng_default;
|
||||
r = gsl_rng_alloc(T);
|
||||
|
||||
for (i=0; i<sims; i++) {
|
||||
rands[i] = gsl_ran_gaussian(r, 1);
|
||||
}
|
||||
|
||||
for (i=0; i<sims; i++) {
|
||||
level = gbm_simulation(spot, rfr, vol, tte, rands[i]);
|
||||
results[i] = max((level - strike) * type, 0);
|
||||
}
|
||||
|
||||
price = gsl_stats_mean(results, 1, sims) * 1 / pow((1 + rfr), tte);
|
||||
|
||||
gsl_rng_free(r);
|
||||
free(rands);
|
||||
free(results);
|
||||
return price;
|
||||
}
|
||||
8
src/gbm_mc.h
Normal file
8
src/gbm_mc.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef GBM_MC
|
||||
#define GBM_MC
|
||||
|
||||
double gbm_simulation(double spot, double rfr, double vol, double tte, double rand);
|
||||
|
||||
double gbm(double spot, double rfr, double vol, double strike, struct tm expiry, struct tm value, int type, int sims);
|
||||
|
||||
#endif
|
||||
78
src/optpricer.c
Normal file
78
src/optpricer.c
Normal file
@@ -0,0 +1,78 @@
|
||||
#define _XOPEN_SOURCE
|
||||
|
||||
#include "black_scholes.h"
|
||||
#include "gbm_mc.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
double spot = 0, strike = 0, rfr = 0, vol = 0, sims = 1000;
|
||||
double bs_price, mc_price;
|
||||
char expiry_date[11], buffer[512];
|
||||
int opt, type = 0;
|
||||
struct tm expiry, value;
|
||||
|
||||
memset(&expiry, 0, sizeof(expiry));
|
||||
memset(&value, 0, sizeof(value));
|
||||
|
||||
while ((opt = getopt(argc, argv, "s:k:r:v:d:e:n:cp")) != -1) {
|
||||
switch (opt) {
|
||||
case 's':
|
||||
if (sscanf(optarg, "%lf", &spot) == EOF) {
|
||||
return 1;
|
||||
};
|
||||
break;
|
||||
case 'k':
|
||||
if (sscanf(optarg, "%lf", &strike) == EOF) {
|
||||
return 1;
|
||||
};
|
||||
break;
|
||||
case 'r':
|
||||
if (sscanf(optarg, "%lf.", &rfr) == EOF) {
|
||||
return 1;
|
||||
};
|
||||
break;
|
||||
case 'v':
|
||||
if (sscanf(optarg, "%lf", &vol) == EOF) {
|
||||
return 1;
|
||||
};
|
||||
break;
|
||||
case 'n':
|
||||
if (sscanf(optarg, "%lf", &sims) == EOF) {
|
||||
return 1;
|
||||
};
|
||||
break;
|
||||
case 'e':
|
||||
strptime(optarg, "%Y-%m-%d", &expiry);
|
||||
break;
|
||||
case 'd':
|
||||
strptime(optarg, "%Y-%m-%d", &value);
|
||||
break;
|
||||
case 'c':
|
||||
type = 1;
|
||||
break;
|
||||
case 'p':
|
||||
type = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
strftime(expiry_date, 11, "%Y-%m-%d", &expiry);
|
||||
bs_price = bsm(spot, rfr, vol, strike, expiry, value, type);
|
||||
mc_price = gbm(spot, rfr, vol, strike, expiry, value, type, sims);
|
||||
sprintf(&buffer[0], "Arguments:\n"
|
||||
"spot: %f\n"
|
||||
"strike: %f\n"
|
||||
"rfr: %f\n"
|
||||
"vol: %f\n"
|
||||
"sims: %f\n"
|
||||
"exp: %s\n"
|
||||
"BS price: %f\n"
|
||||
"MC price: %f\n",
|
||||
spot, strike, rfr, vol, sims, expiry_date, bs_price, mc_price);
|
||||
printf("%s", buffer);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user