commit 99b350a8528a20ad056c799f5f9f87c6be572e86 Author: Kevin Keogh Date: Sun Apr 2 15:35:28 2017 -0400 Initial commit diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..43f3efd --- /dev/null +++ b/Makefile @@ -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 diff --git a/src/black_scholes.c b/src/black_scholes.c new file mode 100644 index 0000000..20ec751 --- /dev/null +++ b/src/black_scholes.c @@ -0,0 +1,32 @@ +#define _XOPEN_SOURCE + +#include "black_scholes.h" +#include +#include +#include +#include +#include +#include + +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; +} diff --git a/src/black_scholes.h b/src/black_scholes.h new file mode 100644 index 0000000..ae5d266 --- /dev/null +++ b/src/black_scholes.h @@ -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 diff --git a/src/gbm_mc.c b/src/gbm_mc.c new file mode 100644 index 0000000..1bce48c --- /dev/null +++ b/src/gbm_mc.c @@ -0,0 +1,55 @@ +#define _XOPEN_SOURCE +#define max(X,Y) (((X) > (Y)) ? (X) : (Y)) + +#include +#include +#include +#include +#include +#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 +#include +#include + +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; +}