//
// BSMC.c
//
//
// Created by Federico Ricciardelli on 21/11/16.
//
//
#include <stdio.h>
#include <math.h>
#include <time.h>
#define max(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a > _b ? _a : _b; })
double z[1000000];
struct tm create_tm(int year, int month, int day){
struct tm my_time = { .tm_year=year, .tm_mon=month, .tm_mday=day,
.tm_hour=0, .tm_min=0, .tm_sec=0 };
return my_time;
}
void asset(int mod, double s0, double k, double sigma, double rf, double t,int nSteps, int nSim, double z[], double path[nSim][nSteps+1]){
double dt = t/nSteps;
for(int i=0; i<nSim; i++) path[i][0] = s0;
for(int i=0; i<nSim; i++){
for(int j=0; j<nSteps; j++){
if(mod==0) path[i][j+1] = path[i][j]*exp((rf-(pow(sigma, 2)/2))*dt+sigma*sqrt(dt)*z[i]);
if(mod==1) path[i][j+1] = path[i][j]*exp((rf-(pow(sigma, 2)/2))*dt+sigma*sqrt(dt)*(-z[i]));
}
}
return;
}
void insertToZeta(char* filename, int length, double z[length]){
FILE* file = fopen(filename, "r");
int i = 0;
while(i<length){
fscanf(file, "%lf", &z[i]);
i++;
}
return;
}
int main(){
int s0=100, k=100, t=1, nSim=1000000, nSteps=1;
double rf=0.01, sigma=0.4, discountPayOff[nSim], totalDiscount = 0.0, totalPath = 0.0;
double vc[nSim], path[nSim][nSteps+1], pathAV[nSim][nSteps+1] ,z[nSim];
time_t start = time(NULL);
insertToZeta("matlab_1mln.txt", nSim, z);
asset(0, s0, k, sigma, rf, t, nSteps, nSim, z, path);
int i;
for(i=0; i<nSim; i++){
discountPayOff[i] = max(path[i][1]-k, 0)*exp(-rf*t);
totalDiscount += discountPayOff[i];
}
double discountPayOffAvg = totalDiscount/nSim;
double variance1 = 0.0;
for ( i = 0; i < nSim; i++) variance1 += pow(discountPayOff[i],2) - pow(discountPayOffAvg,2);
double variance = variance1 / (nSim - 1);
double standardDeviation= sqrt(variance);
double lower = discountPayOffAvg - (1.96 * standardDeviation / sqrt(nSim));
double higher = discountPayOffAvg + (1.96 * standardDeviation / sqrt(nSim));
printf("Price: %.2f\n", discountPayOffAvg);
printf("Confidence interval: [%.2f - %.2f]\n", lower, higher);
printf("Wall time elapsed: %ld\n", (time(NULL)-start));
return 0;
}