Академический Документы
Профессиональный Документы
Культура Документы
Contents
Break down of Application Code: .......................................................................................... 2 Analysis of the expected performance: ................................................................................. 3 Documented Changes: ......................................................................................................... 4 Evidence of testing: ............................................................................................................... 7 Fig 1.1 Execution of the serial version............................................................................ 7 Fig 1.2 Execution of the basic parallel version ............................................................... 7 Fig 1.3 End of the parallel version .................................................................................. 8
Documented Changes:
The changes are marked in red and explained below:
#include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> #include <mpi.h> #define #define #define #define #define #define #define #define #define #define NRepeats 100 NSim 100000 NDaysAhead 41 Strike 500.0 MaxDimDays 1000 RateOfInterest 2.0/100.0 DaysInYear 255.0 DailyDt 1.0/DaysInYear Pi 4.0*atanf(1.0) Epsilon 1.0e-12
double discountedMean(double MCResults[NSim]) { //work out discounted mean of all monte carlo simulation results //first work out the mean of all monte carlo simulation results int i; double sum, mean,temp; sum=0.0; for(i=0; i<NSim; i++) { sum=sum+MCResults[i]; } //mean of monte carlo simulations mean=sum/NSim; //discounted mean=mean*exp(-RateOfInterest*NDaysAhead) temp=-RateOfInterest*NDaysAhead*DailyDt; mean=mean*exp(temp); return (mean); } double monteCarloSimulation(double Spot, double AnnualVol) { //do a monte carlo simulation for a prediction NDaysAhead of the profit (res) int i; double res, temp1, temp2, rand1, rand2; res = Spot; for (i=1; i<=NDaysAhead; i++) { temp1=(RateOfInterest-0.5*AnnualVol*AnnualVol)*DailyDt; rand1=(double)rand()/RAND_MAX; if (rand1 >= 1.0000) { rand1=1.0-Epsilon; } if (rand1 <= 0.0000) { rand1=Epsilon; } rand1=-2.0*(log(rand1)); rand2=2.0*Pi*(double)rand()/RAND_MAX; temp2=AnnualVol*sqrtf(DailyDt)*sqrtf(rand1)*sinf(rand2); res=res*exp(temp1+temp2); } //printf("Simulated price is: %f\n",res); //calc the call payoff as max(res-Strike,0) if(res > Strike) { res=res-Strike; } else { res=0.0; } return (res); }
double calcVolatility(double prices[MaxDimDays], int NDays, double returns[MaxDimDays]) { int i; double sum, mean, sd, Av; //calculate returns as ln(price[i]/price[i-1]) for (i=1; i<=NDays; i++) {
returns[i]=log(prices[i]/prices[i-1]); } //calculate annual Volatility as std_dev(returns)/sqrt(DailyDt) sum=0.0; for (i=1; i<=NDays; i++) { sum=sum+returns[i]; } mean=sum/NDays; sd=0.0; for (i=1; i<=NDays; i++) { sd=sd+(returns[i]-mean)*(returns[i]-mean); } sd=sqrtf(sd/(NDays-1)); Av=sd/sqrtf(DailyDt); return(Av); } void readDataFile(char fname[128], double prices[MaxDimDays], double *Spot, int *NDays) { FILE *fp; int i = 0; double sv; //Open data file provided by fname and read the data within it. if( (fp = fopen(fname, "r")) == NULL ) { printf("Cannot open file.\n"); exit(1); } do { fscanf(fp,"%lf",&sv); prices[i]=sv; printf("Day %d price is %lf\n",i, prices[i]); i++; } while (!feof(fp)); *NDays=i-1; *Spot=prices[0]; printf("Spot price is: %lf\n",*Spot); fclose( fp ); }
int main(int argc,char **argv) { char fname[128]; int num_of_exp, i, NDays,numprocs,proc,myid,done=0; double prices[MaxDimDays], returns[MaxDimDays]; double MCResults[NSim], Discounted[NRepeats]; double Spot, AnnualVol, option_price; MPI_Status status; int master =0; int tag = 123;
/***** Initializations *****/ MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD,&numprocs); MPI_Comm_rank(MPI_COMM_WORLD,&myid); printf ("MPI task %d has started...\n", myid); srand (time(0)); if ( argc != 2 ) { printf( "usage: %s inputFileName\n", argv[0] ); MPI_Finalize(); return 0; } else { sscanf(argv[1], "%s", &fname); } //get share prices from data file readDataFile(fname, prices, &Spot, &NDays); //compute annual volatilty
AnnualVol = calcVolatility(prices, NDays, returns); printf("Annual Volatility is: %lf\n",AnnualVol); //do a number of monte carlo simulations for(num_of_exp=0; num_of_exp < NRepeats; num_of_exp++) { for(i=0; i<NSim; i++) { MCResults[i] = monteCarloSimulation(Spot, AnnualVol); // printf("MC[%d] is: %f\n",i,MCResults[i]); } //get the discounted mean of these simulation results Discounted[num_of_exp] = discountedMean(MCResults); } /*now work out the mean of all the discounted rates option_price=0.0; for(num_of_exp=0; num_of_exp < NRepeats; num_of_exp++) { option_price=option_price+Discounted[num_of_exp]; } option_price=option_price/(double)NRepeats; //printf("PREDICTED OPTION PRICE is: %lf\n",option_price);*/ } if (myid ==0) { /* if I am the master process gather results from others */ option_price=0.0; for(num_of_exp=0; num_of_exp < NRepeats; num_of_exp++) { MPI_Recv(&num_of_exp,1,MPI_DOUBLE,proc,tag,MPI_COMM_WORLD,&status); option_price=option_price+Discounted[num_of_exp]; } option_price=option_price/(double)NRepeats; printf("PREDICTED OPTION PRICE is: %lf\n",option_price); } else { /* for all the slave processes send results to the master */ printf("Processor %d sending results= %d to master process\n",myid,num_of_exp); MPI_Send(&num_of_exp,1,MPI_DOUBLE,master,tag,MPI_COMM_WORLD); } MPI_Finalize(); return 0; }
Evidence of testing:
The following screenshots are taken during runtime: Fig 1.1 Execution of the serial version
Critical Evaluation:
This attempt to parallelise the serial version of montecarlo is very basic, it can be further improved using various tactics such as sequential optimisation, loop optimisation etc. A basic attempt to parallelise the code was taken but still it is in a very raw form, after conducting a thorough dependence analysis one can see what more could have been done to improve the overall performance and efficiency.