//Asian arithmetic put with monte carlo public double AsianArithmeticPutMonteCarlo(double T, double[] Tsteps, double K, int nrofpaths, int timesteps) { if (T <= 0 || K <= 0 || nrofpaths <= 0 || timesteps <= 0) { throw new System.ArgumentException("Need T,K, number of paths and timesteps > 0"); } this.T = T; this.K = K; double Calloption = 0, Stm; //values for monte carlo method GeneratePath paths = new GeneratePath(this); List <double> path; Parallel.For(0, nrofpaths, i => { Stm = 0.0; path = paths.generate_path(timesteps, T); foreach (double Tm in Tsteps) //For each T1,...,Tm in T to average for asian options { int index = Convert.ToInt32(Tm * timesteps); Stm += path[index]; } double Savg = Stm / Tsteps.Length; //average over S(t1)+,...,+S(Tm) Calloption += Math.Max(Savg - K, 0); //Payoff function for asian arithmetic put function }); return(Math.Exp(-r * T) * Calloption / nrofpaths); //Take average and scale back in time }
//Monte carlo method not using parallel loops to compare performance public double MonteCarloEuropeanCallSlow(double T, double K, int nrofpaths, int timesteps) { if (T <= 0 || K <= 0 || nrofpaths <= 0 || timesteps <= 0) { throw new System.ArgumentException("Need T,K, number of paths and timesteps > 0"); } this.T = T; this.K = K; GeneratePath paths = new GeneratePath(this); //Generate S(t) double TotalCall = 0; double St = S; List <double> path; //Usi multi threading to run For loops in parallel making the simulation faster for (int i = 0; i < nrofpaths; ++i) { path = paths.generate_path(timesteps, T, true); St = path[path.Count - 1]; TotalCall += Math.Max(St - K, 0); } return(Math.Exp(-r * T) * TotalCall / nrofpaths); }
//Pricing look back option public double PricingLookbackOpt(double T, double K, int nrofpaths, int timesteps) { if (T <= 0 || K <= 0 || nrofpaths <= 0 || timesteps <= 0) { throw new System.ArgumentException("Need T,K, number of paths and timesteps > 0"); } this.T = T; this.K = K; GeneratePath paths = new GeneratePath(this); double TotalCall = 0; double St = 0; List <double> path; Parallel.For(0, nrofpaths, i => { path = paths.generate_path(timesteps, T, true); St = path[path.Count - 1]; TotalCall += St - path.Min(); //payoff function }); return(Math.Exp(-r * T) * TotalCall / nrofpaths); //Take average and scale back in time }