Style cleanup, add comments
This commit is contained in:
BIN
build/opt-pricer
BIN
build/opt-pricer
Binary file not shown.
50
src/gbm_mc.c
50
src/gbm_mc.c
@@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|
||||||
@@ -95,46 +93,46 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
while ((opt = getopt_long(argc, argv, "s:k:r:v:d:e:N:cph", long_options, &option_index)) != -1) {
|
while ((opt = getopt_long(argc, argv, "s:k:r:v:d:e:N:cph", long_options, &option_index)) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 's':
|
case 's':
|
||||||
if (sscanf(optarg, "%lf", &spot) == EOF) {
|
if (sscanf(optarg, "%lf", &spot) == EOF) {
|
||||||
return 1;
|
return 1;
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case 'k': /* strike */
|
case 'k': /* strike */
|
||||||
if (sscanf(optarg, "%lf", &strike) == EOF) {
|
if (sscanf(optarg, "%lf", &strike) == EOF) {
|
||||||
return 1;
|
return 1;
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case 'r': /* risk-free rate */
|
case 'r': /* risk-free rate */
|
||||||
if (sscanf(optarg, "%lf.", &rfr) == EOF) {
|
if (sscanf(optarg, "%lf.", &rfr) == EOF) {
|
||||||
return 1;
|
return 1;
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case 'v': /* implied volatility */
|
case 'v': /* implied volatility */
|
||||||
if (sscanf(optarg, "%lf", &vol) == EOF) {
|
if (sscanf(optarg, "%lf", &vol) == EOF) {
|
||||||
return 1;
|
return 1;
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case 'e': /* expiry date, must be YYYY-MM-DD */
|
case 'e': /* expiry date, must be YYYY-MM-DD */
|
||||||
strptime(optarg, "%Y-%m-%d", &expiry);
|
strptime(optarg, "%Y-%m-%d", &expiry);
|
||||||
break;
|
break;
|
||||||
case 'd': /* valuation date, must be YYYY-MM-DD */
|
case 'd': /* valuation date, must be YYYY-MM-DD */
|
||||||
strptime(optarg, "%Y-%m-%d", &value);
|
strptime(optarg, "%Y-%m-%d", &value);
|
||||||
break;
|
break;
|
||||||
case 'N': /* number of simulations */
|
case 'N': /* number of simulations */
|
||||||
if (sscanf(optarg, "%lf", &sims) == EOF) {
|
if (sscanf(optarg, "%lf", &sims) == EOF) {
|
||||||
return 1;
|
return 1;
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case 'c': /* set as call */
|
case 'c': /* set as call */
|
||||||
type = 1;
|
type = 1;
|
||||||
break;
|
break;
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (spot == 0 || strike == 0 || rfr == 0 || vol == 0) {
|
if (spot == 0 || strike == 0 || rfr == 0 || vol == 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"
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
Reference in New Issue
Block a user