Initial commit

This commit is contained in:
Kevin Keogh
2017-04-02 15:35:28 -04:00
commit 99b350a852
6 changed files with 203 additions and 0 deletions

16
Makefile Normal file
View File

@@ -0,0 +1,16 @@
CC=gcc
CFLAGS=-Wall -fPIC -O3 -ansi -pedantic-errors
LDFLAGS=-lgsl -lcblas -lm
pricer : src/optpricer.c gbm.o black_scholes.o
$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@
gbm.o : src/gbm_mc.c
$(CC) $(CFLAGS) -c $^ $(LDFLAGS) -o $@
black_scholes.o : src/black_scholes.c
$(CC) $(CFLAGS) -c $^ $(LDFLAGS) -o $@
.PHONY: clean
clean:
rm -f gbm.o black_scholes.o

32
src/black_scholes.c Normal file
View 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
View 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
View 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
View 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
View 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;
}