Initial commit
This commit is contained in:
16
Makefile
Normal file
16
Makefile
Normal 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
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