Style cleanup, add comments

This commit is contained in:
Kevin Keogh
2017-07-31 00:05:43 -04:00
parent 0ec0e69bfe
commit 186e8e40e9
5 changed files with 82 additions and 66 deletions

Binary file not shown.

View File

@@ -1,5 +1,5 @@
#define _XOPEN_SOURCE #define _XOPEN_SOURCE
#define max(X,Y) (((X) > (Y)) ? (X) : (Y)) #define max(X, Y) (((X) > (Y)) ? (X) : (Y))
#include "gbm_mc.h" #include "gbm_mc.h"
#include "utils.h" #include "utils.h"
@@ -28,6 +28,8 @@ double gbm_simulation(double spot, double rfr, double vol, double tte, double ra
void *run_simulations(void *opt_ptr) void *run_simulations(void *opt_ptr)
{ {
/* A single thread simulation, calculates the PV and Greeks */
int i; int i;
double tte, theta_tte, expiry_date, value_date, level, rand, df; double tte, theta_tte, expiry_date, value_date, level, rand, df;
double delta_shift = 0, vega_shift = 0, theta_shift = 0, rho_shift = 0; double delta_shift = 0, vega_shift = 0, theta_shift = 0, rho_shift = 0;
@@ -36,16 +38,17 @@ void *run_simulations(void *opt_ptr)
double base = 0; double base = 0;
double max_rand = 0; double max_rand = 0;
struct Option *opt = (struct Option*) opt_ptr; struct Option *opt = (struct Option *) opt_ptr;
if (opt->sims < 1) opt->sims = 1; if (opt->sims < 1)
opt->sims = 1;
expiry_date = mktime(opt->expiry_date); expiry_date = mktime(opt->expiry_date);
value_date = mktime(opt->value_date); value_date = mktime(opt->value_date);
tte = difftime(expiry_date, value_date) / (60 * 60 * 24 * 365); tte = difftime(expiry_date, value_date) / (60 * 60 * 24 * 365);
theta_tte = tte - 1. / 365; theta_tte = tte - 1. / 365;
for (i=0; i<opt->sims; i++) { for (i = 0; i < opt->sims; i++) {
rand = opt->randoms[i]; rand = opt->randoms[i];
max_rand = rand > max_rand ? rand : max_rand; max_rand = rand > max_rand ? rand : max_rand;
/* Base scenario */ /* Base scenario */
@@ -103,30 +106,41 @@ void gbm(struct Option *opt)
pthread_t *threads; pthread_t *threads;
struct Option *options; struct Option *options;
double **randoms; double **randoms;
options = malloc(sizeof(struct Option) * NUM_THREADS); options = malloc(sizeof(struct Option) * NUM_THREADS);
randoms = malloc(sizeof(double*) * NUM_THREADS); randoms = malloc(sizeof(double *) * NUM_THREADS);
/* Create 2D array */
for(i=0; i<NUM_THREADS; i++) { for(i=0; i<NUM_THREADS; i++) {
randoms[i] = malloc(sizeof(double) * opt->sims / NUM_THREADS); randoms[i] = malloc(sizeof(double) * opt->sims / NUM_THREADS);
} }
/* generate array of normal randoms */ /* Fill 2D array with normal randoms
for(i=0;;) { * The purpose is to give the Option structs the random
if (j == (opt->sims / NUM_THREADS)) { * numbers they will need for simulations, as opposed to
* having the individual threads do so (rand() is not thread-safe)
*/
j = 0;
i = 0;
for(i = 0; i < NUM_THREADS;){
randoms[i][j] = gaussrand();
if (j >= (opt->sims / NUM_THREADS)) {
j = 0; j = 0;
i += 1; i += 1;
} }
if (i == NUM_THREADS) {
break;
}
randoms[i][j] = gaussrand();
j++; j++;
} }
/* Set the number of simulations on a per-thread basis
*/
opt->sims = opt->sims / NUM_THREADS; opt->sims = opt->sims / NUM_THREADS;
for(i=0; i<NUM_THREADS; i++) { for(i=0; i<NUM_THREADS; i++) {
options[i] = *opt; options[i] = *opt;
/* These are pointers, so need to copy them directly,
* otherwise we will probably have 2 threads trying to
* access them at the same time
*/
options[i].expiry_date = opt->expiry_date; options[i].expiry_date = opt->expiry_date;
options[i].value_date = opt->value_date; options[i].value_date = opt->value_date;
options[i].randoms = randoms[i]; options[i].randoms = randoms[i];
@@ -145,8 +159,9 @@ void gbm(struct Option *opt)
for(i=0; i<NUM_THREADS; i++) { for(i=0; i<NUM_THREADS; i++) {
void *res; void *res;
struct Option *result; struct Option *result;
pthread_join(threads[i], &res); pthread_join(threads[i], &res);
result = (struct Option*) res; result = (struct Option *) res;
opt->fv += result->fv / NUM_THREADS; opt->fv += result->fv / NUM_THREADS;
opt->delta += result->delta / NUM_THREADS; opt->delta += result->delta / NUM_THREADS;
opt->gamma += result->gamma / NUM_THREADS; opt->gamma += result->gamma / NUM_THREADS;
@@ -156,4 +171,9 @@ void gbm(struct Option *opt)
opt->sims += result->sims; opt->sims += result->sims;
} }
free(threads);
for(i=0; i<NUM_THREADS; i++)
free(randoms[i]);
free(randoms);
} }

View File

@@ -10,6 +10,7 @@
#include <locale.h> #include <locale.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <getopt.h> #include <getopt.h>
@@ -42,7 +43,7 @@ static struct helptext options[] = {
"Put or call flag"}, "Put or call flag"},
{"-h, --help", {"-h, --help",
"This help text"}, "This help text"},
{ NULL , NULL } { NULL, NULL }
}; };
@@ -71,7 +72,7 @@ int print_help(void)
} }
char* read_type(struct Option opt) char *read_type(struct Option opt)
{ {
return (opt.type == 1) ? "Call" : "Put"; return (opt.type == 1) ? "Call" : "Put";
} }
@@ -85,9 +86,6 @@ int main(int argc, char *argv[])
struct tm value, expiry; struct tm value, expiry;
struct Option bs_opt, mc_opt; struct Option bs_opt, mc_opt;
extern char *optarg;
extern int getopt_long();
memset(&expiry, 0, sizeof(expiry)); memset(&expiry, 0, sizeof(expiry));
memset(&value, 0, sizeof(value)); memset(&value, 0, sizeof(value));
@@ -132,7 +130,7 @@ int main(int argc, char *argv[])
case 'p': /* set as put */ case 'p': /* set as put */
type = -1; type = -1;
break; break;
case 'h': /* print help*/ case 'h': /* print help */
print_help(); print_help();
return 0; return 0;
} }
@@ -156,7 +154,7 @@ int main(int argc, char *argv[])
bsm(&bs_opt); bsm(&bs_opt);
gbm(&mc_opt); gbm(&mc_opt);
setlocale(LC_ALL,""); setlocale(LC_ALL, "");
printf( printf(
"\nValuation date: %s\n\n" "\nValuation date: %s\n\n"
" | BS Analytic | BS Monte Carlo |\n" " | BS Analytic | BS Monte Carlo |\n"

View File

@@ -35,11 +35,11 @@ double normalpdf(double z)
} }
double gaussrand() double gaussrand(void)
{ {
/* Marsaglia and Bray, ``A Convenient Method for Generating Normal Variables'' */ /* Marsaglia and Bray, ``A Convenient Method for Generating Normal Variables'' */
static double V1, V2, S; static double V1, V2, S;
static int phase = 0; static int phase;
double X; double X;
if (phase == 0) { if (phase == 0) {

View File

@@ -1,13 +1,11 @@
#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);
double gaussrand(); double gaussrand(void);
struct Option { struct Option {
/* option details */ /* option details */