//multithreading for monte carlo simulation, method 2 private void multithread2() { int n = System.Environment.ProcessorCount;//the number of cores for CUP Form1 form1 = new Form1(); double e = Convert.ToDouble(form1.volatility1.Value), d = Convert.ToDouble(form1.dividend1.Value); List<int> row = new List<int>(); var inst = from i in portfolio.Trades select i.Id; foreach (var i in inst) { row.Add(i); } List<Basicvalue> basicvalue = new List<Basicvalue>(); Basicvalue basic = new Basicvalue(); for (int i = 0; i < row.Count; i++) { int m = row[i]; var inst2 = (from i2 in portfolio.Trades where i2.Id == m select i2).First(); basic.tradeprice = inst2.Price; basic.S = Convert.ToDouble(inst2.UnderlyingP); basic.instrumentid = inst2.InstrumentId; basic.timestamp = inst2.Timestamp.ToString(); basic.quantity = Convert.ToDouble(inst2.Quantity); var inst3 = (from i3 in portfolio.Instruments where i3.Id == basic.instrumentid select i3).First(); basic.K = Convert.ToDouble(inst3.Strike); basic.T = Convert.ToDouble(inst3.Tenor); basic.iscall = Convert.ToInt16(inst3.IsCall); basic.insttypeid = Convert.ToInt16(inst3.InstTypeId); double ratetemp = new double(); List<double> rate = new List<double>(); var inst4 = from i4 in portfolio.InterestRates select i4; List<InterestRate> ir = new List<InterestRate>(); foreach (var g in inst4) { ir.Add(g); } int h = 0; while (basic.T < ir[h].Tenor) h++; if (h == 0) { double r = Convert.ToDouble(ir[h].Rate); double t = Convert.ToDouble(ir[h].Tenor); ratetemp = basic.T / t * Convert.ToDouble(r); } else { double r1 = Convert.ToDouble(ir[h - 1].Rate), r2 = Convert.ToDouble(ir[h].Rate); ; double t1 = Convert.ToDouble(ir[h - 1].Tenor), t2 = Convert.ToDouble(ir[h].Tenor); ratetemp = r2 + (r2 - r1) / (t2 - t1) * (basic.T - t1); } basic.r = Convert.ToDouble(ratetemp); var inst5 = (from i5 in portfolio.InstTypes where i5.Id == basic.insttypeid select i5).First(); basic.insttype = inst5.TypeName; basic.underlying = inst5.Underlying; if (basic.insttype == "BarrierOption") { var inst6 = (from i6 in portfolio.BarrierOptions where i6.InstTypeId == basic.insttypeid select i6).First(); basic.isup = Convert.ToBoolean(inst6.IsUp); basic.isin = Convert.ToBoolean(inst6.IsIn); basic.barrier = Convert.ToDouble(inst6.barrier); } else if (basic.insttype == "DigitalOption") { var inst7 = (from i7 in portfolio.DigitalOptions where i7.InstTypeId == basic.insttypeid select i7).First(); basic.rebate = Convert.ToDouble(inst7.rebate); } else if (basic.insttype == "LookBackOption") { var inst8 = (from i8 in portfolio.LookBackOptions where i8.InstTypeId == basic.insttypeid select i8).First(); basic.isfix = Convert.ToBoolean(inst8.IsFixed); } if (n != 1)//If the number of core is not 2,4,8, change it to appropriate number { if (n % 2 != 0 && n < 4 && n > 1) { n = 2; } else if (n % 4 != 0 && n < 8 && n > 3) { n = 4; } else if (n % 8 != 0 && n > 8) { n = 8; } } string s, udio = null, lo; if (basic.iscall == 0) s = "call"; else if (basic.iscall == 1) s = "put"; else s = "call"; if (basic.isup == true && basic.isin == true) udio = "up_in"; else if (basic.isup == false && basic.isin == false) udio = "up_out"; else if (basic.isin == true && basic.isup == false) udio = "down_in"; else if (basic.isup == false && basic.isin == false) udio = "down_out"; if (basic.isfix == true) lo = "fix"; else lo = "floating"; if (n == 1)//no need to use multithread { MessageBox.Show("CPU only have one core", "Information"); } else { double[] greeks = new double[5]; if (n == 2)//two cores { Value temp = new Value(basic.S, basic.K, basic.r, e, basic.T, d, Convert.ToInt64(step11.Value), Convert.ToInt64(trail11.Value)); multithreading mul = new multithreading(temp, antithetic.Checked, s, dcv.Checked, basic.insttype, basic.rebate, basic.barrier, udio, lo); Simulator sim = new Simulator(temp.S, temp.K, temp.r, temp.e, temp.T, temp.d, temp.step, temp.trial); Thread t1 = new Thread(new ParameterizedThreadStart(calc2));//This thread is to calculate the path and price Thread t2 = new Thread(new ParameterizedThreadStart(sim.multiregualr));//This thread is to generate random numbers t1.Name = "Thread_1"; t2.Name = "Thread_2"; t1.Start(mul); t2.Start(mul); t1.Join(); t2.Join(); for (int ii = 0; ii < 5; ii++) greeks[ii] = (mul.greeks[ii]); basic.mprice = mul.price[0]; basic.greek = greeks; } else if (n == 4) { Value temp = new Value(basic.S, basic.K, basic.r, e, basic.T, d, Convert.ToInt64(step11.Value), Convert.ToInt64(trail11.Value)); multithreading mul1 = new multithreading(temp, antithetic.Checked, s, dcv.Checked, basic.insttype, basic.rebate, basic.barrier, udio, lo); multithreading mul2 = new multithreading(temp, antithetic.Checked, s, dcv.Checked, basic.insttype, basic.rebate, basic.barrier, udio, lo); Simulator sim = new Simulator(temp.S, temp.K, temp.r, temp.e, temp.T, temp.d, temp.step, temp.trial); Thread t21 = new Thread(new ParameterizedThreadStart(sim.multiregualr));//Generate random numbers Thread t22 = new Thread(new ParameterizedThreadStart(sim.multiregualr)); Thread t11 = new Thread(new ParameterizedThreadStart(calc2));//Calculate the path and price Thread t12 = new Thread(new ParameterizedThreadStart(calc2)); t11.Name = "Thread_11"; t12.Name = "Thread_12"; t21.Name = "Thread_21"; t22.Name = "Thread_22"; t21.Start(mul1); t11.Start(mul1); t21.Join(); t11.Join(); t22.Start(mul2); t12.Start(mul2); t22.Join(); t12.Join(); for (int ii = 0; ii < 5; ii++) greeks[ii] = (mul1.greeks[ii] + mul2.greeks[ii]) * 0.5; basic.mprice = mul1.price[0] + mul2.price[1]; basic.greek = greeks; } else if (n == 8) { Value temp = new Value(basic.S, basic.K, basic.r, e, basic.T, d, Convert.ToInt64(step11.Value), Convert.ToInt64(trail11.Value)); multithreading mul1 = new multithreading(temp, antithetic.Checked, s, dcv.Checked, basic.insttype, basic.rebate, basic.barrier, udio, lo); multithreading mul2 = new multithreading(temp, antithetic.Checked, s, dcv.Checked, basic.insttype, basic.rebate, basic.barrier, udio, lo); multithreading mul3 = new multithreading(temp, antithetic.Checked, s, dcv.Checked, basic.insttype, basic.rebate, basic.barrier, udio, lo); multithreading mul4 = new multithreading(temp, antithetic.Checked, s, dcv.Checked, basic.insttype, basic.rebate, basic.barrier, udio, lo); Simulator sim = new Simulator(temp.S, temp.K, temp.r, temp.e, temp.T, temp.d, temp.step, temp.trial); Thread t51 = new Thread(new ParameterizedThreadStart(sim.multiregualr));//Generate random numbers Thread t52 = new Thread(new ParameterizedThreadStart(sim.multiregualr)); Thread t31 = new Thread(new ParameterizedThreadStart(sim.multiregualr)); Thread t32 = new Thread(new ParameterizedThreadStart(sim.multiregualr)); Thread t21 = new Thread(new ParameterizedThreadStart(sim.multiregualr)); Thread t22 = new Thread(new ParameterizedThreadStart(sim.multiregualr)); Thread t11 = new Thread(new ParameterizedThreadStart(calc2));//Calculate path and price Thread t12 = new Thread(new ParameterizedThreadStart(calc2)); Thread t41 = new Thread(new ParameterizedThreadStart(calc2)); Thread t42 = new Thread(new ParameterizedThreadStart(calc2)); Thread t61 = new Thread(new ParameterizedThreadStart(calc2)); Thread t62 = new Thread(new ParameterizedThreadStart(calc2)); t21.Start(mul1); t11.Start(mul1); t21.Join(); t11.Join(); t22.Start(mul2); t12.Start(mul2); t22.Join(); t12.Join(); t31.Start(mul3); t41.Start(mul3); t31.Join(); t41.Join(); t51.Start(mul4); t61.Start(mul4); t51.Join(); t61.Join(); for (int ii = 0; ii < 5; ii++) greeks[ii] = (mul1.greeks[ii] + mul2.greeks[ii] + mul3.greeks[ii] + mul4.greeks[ii]) * 0.25; basic.mprice = (mul1.price[0] + mul2.price[0] + mul3.price[0] + mul4.price[0]) * 0.25; basic.greek = greeks; } } basic.pl = (basic.tradeprice - basic.mprice) * basic.quantity; var update = (from u in portfolio.Trades where u.Id == n select u).First(); update.PL = basic.pl; update.MarketPrice = basic.mprice; update.Delta = basic.greek[0]; update.Gamma = basic.greek[1]; update.Vega = basic.greek[2]; update.Theta = basic.greek[3]; update.Rho = basic.greek[4]; portfolio.SaveChanges(); basic = new Basicvalue(); } MessageBox.Show("Done!", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information); }
//Monte Carlo Simulation private void montecarlo() { try { Form1 form1 = new Form1(); double e = Convert.ToDouble(form1.volatility1.Value), d = Convert.ToDouble(form1.dividend1.Value); List<int> row = new List<int>(); var inst = from i in portfolio.Trades select i.Id; foreach (var i in inst) { row.Add(i); } List<Basicvalue> basicvalue = new List<Basicvalue>(); Basicvalue basic = new Basicvalue(); for (int i = 0; i < row.Count; i++)//first find all the inputs I need from different table { int oo = row[i]; var type = (from q in portfolio.InstTypes join j in portfolio.Instruments on q.Id equals j.InstTypeId join k in portfolio.Trades on j.Id equals k.InstrumentId where k.Id == oo select q.TypeName).First();//find the insttype if (type.ToUpper() == "STOCK")//stock do not need to do simulation break; int n = row[i]; var inst2 = (from i2 in portfolio.Trades where i2.Id == n select i2).First();//find the historical price for this trade basic.tradeprice = inst2.Price; basic.S = Convert.ToDouble(inst2.UnderlyingP); basic.instrumentid = inst2.InstrumentId; basic.timestamp = inst2.Timestamp.ToString(); basic.quantity = Convert.ToDouble(inst2.Quantity); var inst3 = (from i3 in portfolio.Instruments where i3.Id == basic.instrumentid select i3).First();//find the strike tenor call or put for the trade basic.K = Convert.ToDouble(inst3.Strike); basic.T = Convert.ToDouble(inst3.Tenor); basic.iscall = Convert.ToInt16(inst3.IsCall); basic.insttypeid = Convert.ToInt16(inst3.InstTypeId); double ratetemp = new double();//store the risk free rate List<double> rate = new List<double>(); var inst4 = from i4 in portfolio.InterestRates orderby i4.Tenor ascending select i4; List<InterestRate> ir = new List<InterestRate>(); foreach (var g in inst4) { ir.Add(g); } int h = 0; while (basic.T < ir[h].Tenor)//find out the interval of the T, and compute the rate h++; if (h == 0) { double r = Convert.ToDouble(ir[h].Rate); double t = Convert.ToDouble(ir[h].Tenor); ratetemp = basic.T / t * Convert.ToDouble(r); } else { double r1 = Convert.ToDouble(ir[h - 1].Rate), r2 = Convert.ToDouble(ir[h].Rate); ; double t1 = Convert.ToDouble(ir[h - 1].Tenor), t2 = Convert.ToDouble(ir[h].Tenor); ratetemp = r2 + (r2 - r1) / (t2 - t1) * (basic.T - t1); } basic.r = Convert.ToDouble(ratetemp); var inst5 = (from i5 in portfolio.InstTypes where i5.Id == basic.insttypeid select i5).First(); basic.insttype = inst5.TypeName; basic.underlying = inst5.Underlying; if (basic.insttype == "BarrierOption") { var inst6 = (from i6 in portfolio.BarrierOptions where i6.InstTypeId == basic.insttypeid select i6).First(); basic.isup = Convert.ToBoolean(inst6.IsUp); basic.isin = Convert.ToBoolean(inst6.IsIn); basic.barrier = Convert.ToDouble(inst6.barrier); } else if (basic.insttype == "DigitalOption") { var inst7 = (from i7 in portfolio.DigitalOptions where i7.InstTypeId == basic.insttypeid select i7).First(); basic.rebate = Convert.ToDouble(inst7.rebate); } else if (basic.insttype == "LookBackOption") { var inst8 = (from i8 in portfolio.LookBackOptions where i8.InstTypeId == basic.insttypeid select i8).First(); basic.isfix = Convert.ToBoolean(inst8.IsFixed); } Value temp = new Value(basic.S, basic.K, basic.r, e, basic.T, d, Convert.ToInt64(step11.Value), Convert.ToInt64(trail11.Value)); Simulator sim = new Simulator(temp.S, temp.K, temp.r, temp.e, temp.T, temp.d, temp.step, temp.trial); Option opt = new Option(temp.S, temp.K, temp.r, temp.e, temp.T, temp.d, temp.step, temp.trial); Greeks gre = new Greeks(temp.S, temp.K, temp.r, temp.e, temp.T, temp.d, temp.step, temp.trial); bool isant = true; string s = null; ;//store the choice call or put option string s3 = null;//up,down,in,out string s4 = null;//fixed, floating double[,] randmatrix = new double[temp.trial, temp.step];// store the random matrix double[] origin_price = new double[2];//store the price and standard deviation double[] greeks;//store the greeks if (antithetic.Checked == true) isant = true; else isant = false; randmatrix = sim.generateregular();//generate the random matrix if (basic.iscall == 0) s = "call"; else if (basic.iscall == 1) s = "put"; else s = "neither"; if (basic.isup == true && basic.isin == true) s3 = "up_in"; else if (basic.isup == false && basic.isin == false) s3 = "up_out"; else if (basic.isin == true && basic.isup == false) s3 = "down_in"; else if (basic.isup == false && basic.isin == false) s3 = "down_out"; if (basic.isfix == true) s4 = "fix"; else s4 = "floating"; switch (basic.insttype) { case "EuropeanOption": European eur = new European(temp.S, temp.K, temp.r, temp.e, temp.T, temp.d, temp.step, temp.trial, dcv.Checked); origin_price = eur.Payoff(temp, randmatrix, isant, s);//calculate the option price greeks = gre.calculate(temp, randmatrix, s, isant, eur.Payoff);//calculate the greeks basic.mprice = origin_price[0]; basic.greek = greeks; break; case "AsianOption": Asian asi = new Asian(temp.S, temp.K, temp.r, temp.e, temp.T, temp.d, temp.step, temp.trial, dcv.Checked); origin_price = asi.Payoff(temp, randmatrix, isant, s);//calculate the option price greeks = gre.calculate(temp, randmatrix, s, isant, asi.Payoff);//calculate the greeks basic.mprice = origin_price[0]; basic.greek = greeks; break; case "BarrierOption": Barrier bar = new Barrier(temp.S, temp.K, temp.r, temp.e, temp.T, temp.d, temp.step, temp.trial, basic.barrier, s3, dcv.Checked); origin_price = bar.Payoff(temp, randmatrix, isant, s); greeks = gre.calculate(temp, randmatrix, s, isant, bar.Payoff); basic.mprice = origin_price[0]; basic.greek = greeks; break; case "DigitalOption": Digital dig = new Digital(temp.S, temp.K, temp.r, temp.e, temp.T, temp.d, temp.step, temp.trial, basic.rebate, dcv.Checked); origin_price = dig.Payoff(temp, randmatrix, isant, s); greeks = gre.calculate(temp, randmatrix, s, isant, dig.Payoff); basic.mprice = origin_price[0]; basic.greek = greeks; break; case "LookbackOption": LookBack look = new LookBack(temp.S, temp.K, temp.r, temp.e, temp.T, temp.d, temp.step, temp.trial, s4, dcv.Checked); origin_price = look.Payoff(temp, randmatrix, isant, s); greeks = gre.calculate(temp, randmatrix, s, isant, look.Payoff); basic.mprice = origin_price[0]; basic.greek = greeks; break; case "RangeOption": Range rang = new Range(temp.S, temp.K, temp.r, temp.e, temp.T, temp.d, temp.step, temp.trial); origin_price = rang.Payoff(temp, randmatrix, isant, s); greeks = gre.calculate(temp, randmatrix, s, isant, rang.Payoff); basic.mprice = origin_price[0]; basic.greek = greeks; break; } basic.pl = (basic.tradeprice - basic.mprice) * basic.quantity; var update = (from u in portfolio.Trades where u.Id == n select u).First();//update the price and greeks in trade update.MarketPrice = basic.mprice; update.PL = basic.pl; update.Delta = basic.greek[0]; update.Gamma = basic.greek[1]; update.Vega = basic.greek[2]; update.Theta = basic.greek[3]; update.Rho = basic.greek[4]; portfolio.SaveChanges(); basic = new Basicvalue(); } this.Close(); MessageBox.Show("Done! Please refresh the database again", "Notice", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch { MessageBox.Show("Something wrong, please check wheather the inputs are correct."); } }