public multithreading(Value v,bool ant, string S,bool CV,string ty,double re,double B,string u,string lb) { underlyings = v; anti = ant; s = S; cv = CV; type = ty; barrier = B; udio = u; rebate = re; lookback = lb; }
public double[] Payoff(Value origin, double[,] randmatrix, bool isant, string s)//payoff function for european option, origin is values, matrix is random number matrix, s is call or put { double sum_CT = 0, sum_CT2 = 0, SD = 0; double[,] temp1 = new double[origin.trial, 2]; double[,] temp2 = new double[origin.trial, 2]; double[] result = new double[2]; double dt = Convert.ToDouble(origin.T) / Convert.ToDouble(origin.step - 1); double[,] matrix1 = new double[origin.trial, origin.step]; double[,] matrix2 = new double[origin.trial, origin.step]; for (int i = 0; i < trial; i++) { matrix1[i, 0] = origin.S; matrix2[i, 0] = origin.S; temp1[i, 0] = origin.S; temp2[i, 0] = origin.S; temp1[i, 1] = origin.S; temp2[i, 1] = origin.S; //temp1[i, 0] = 0; temp2[i, 0] = 0; temp1[i, 1] = 0; temp2[i, 1] = 0; for (int j = 1; j < step; j++) { matrix1[i, j] = matrix1[i, j - 1] * Math.Exp((origin.r - origin.d - origin.e * origin.e * 0.5) * dt + (origin.e * Math.Sqrt(dt) * randmatrix[i, j])); temp1[i, 0] = Math.Max(matrix1[i, j], temp1[i, 0]);//store the max price in one path temp1[i, 1] = Math.Min(matrix1[i, j], temp1[i, 1]);//store the min price in one path if (isant == true) { matrix2[i, j] = matrix2[i, j - 1] * Math.Exp((origin.r - origin.d - origin.e * origin.e * 0.5) * dt + (origin.e * Math.Sqrt(dt) * -randmatrix[i, j])); temp2[i, 0] = Math.Max(matrix2[i, j], temp2[i, 0]);//store the max price in one path temp2[i, 1] = Math.Min(matrix2[i, j], temp2[i, 1]);//store the min price in one path } } temp1[i, 0] = temp1[i, 0] - temp1[i, 1];//max-min for regular random number if (isant == true) { temp2[i, 0] = temp2[i, 0] - temp2[i, 1];//max-min for antithetic random number temp1[i, 0] = 0.5 * (temp1[i, 0] + temp2[i, 0]); } sum_CT = sum_CT + temp1[i, 0]; sum_CT2 = sum_CT2 + temp1[i, 0] * temp1[i, 0]; } result[0] = sum_CT / origin.trial * Math.Exp(-origin.r * origin.T); SD = Math.Sqrt((sum_CT2 - sum_CT * sum_CT / origin.trial) * Math.Exp(-2 * origin.r * origin.T) / (origin.trial - 1)); result[1] = SD / Math.Sqrt(origin.trial);//sample standard deviation return result; }
public double[] Payoff(Value origin, double[,] randmatrix, bool isant, string s) { double dt = (double)origin.T / (origin.step - 1); double nudt = (origin.r - origin.d - 0.5 * origin.e * origin.e) * dt; double sigsdt = origin.e * Math.Sqrt(dt); double[,] matrix1 = new double[origin.trial, origin.step]; double[,] matrix2 = new double[origin.trial, origin.step]; double[] temp1 = new double[origin.trial]; double[] temp2 = new double[origin.trial]; double[] result = new double[2]; double SD = 0, sum_CT = 0, sum_CT2 = 0, cv = 0, cv2 = 0, delta = 0, delta2 = 0, d1 = 0; for (int i = 0; i < origin.trial; i++) { matrix1[i, 0] = origin.S; matrix2[i, 0] = origin.S; cv=0; cv2=0; for (int j = 1; j < origin.step; j++) { matrix1[i, j] = matrix1[i, j - 1] * Math.Exp(nudt + sigsdt * randmatrix[i, j]); if (iscv == true) { d1 = (Math.Log((matrix1[i, j - 1] / origin.K)) + (origin.r + origin.e * origin.e / 2) * origin.T) / (origin.e * Math.Sqrt(origin.T)); delta = Phi(d1); if (s == "call") cv = cv + delta * (matrix1[i, j] - matrix1[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); else if (s == "put") cv = cv + (delta - 1) * (matrix1[i, j] - matrix1[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); } if (isant == true) { matrix2[i, j] = matrix2[i, j - 1] * Math.Exp(nudt + sigsdt * -randmatrix[i, j]); if (iscv == true) { d1 = (Math.Log((matrix2[i, j - 1] / origin.K)) + (origin.r + origin.e * origin.e / 2) * origin.T) / (origin.e * Math.Sqrt(origin.T)); delta2 = Phi(d1); if (s == "call") { cv2 = cv2 + delta2 * (matrix2[i, j] - matrix2[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); } else if (s == "put") { cv2 = cv2 + (delta2 - 1) * (matrix2[i, j] - matrix2[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); } } } } if (iscv == false) { if (s == "call") { temp1[i] = (matrix1[i, origin.step - 1] - origin.K) > 0 ? rebate : 0; if (isant == true) temp2[i] = (matrix2[i, origin.step - 1] - origin.K) > 0 ? rebate : 0; } else if (s == "put") { temp1[i] = (origin.K - matrix1[i, origin.step - 1]) > 0 ? rebate : 0; if (isant == true) temp2[i] = (origin.K - matrix1[i, origin.step - 1]) > 0 ? rebate : 0; } if (isant == true) { temp1[i] = 0.5 * (temp1[i] + temp2[i]); } } else if (iscv == true) { if (s == "call") { temp1[i] = (matrix1[i, origin.step - 1] - origin.K) > 0 ? rebate : 0 + -1 * cv; if (isant == true) temp2[i] = (matrix2[i, origin.step - 1] - origin.K) > 0 ? rebate : 0 + -1 * cv2; } else if (s == "put") { temp1[i] = (origin.K - matrix1[i, origin.step - 1]) > 0 ? rebate : 0 + -1 * cv; if (isant == true) temp2[i] = (origin.K - matrix1[i, origin.step - 1]) > 0 ? rebate : 0 + -1 * cv2; } if (isant == true) { temp1[i] = 0.5 * (temp1[i] + temp2[i]); } } sum_CT = sum_CT + temp1[i]; sum_CT2 = sum_CT2 + temp1[i] * temp1[i]; } result[0] = sum_CT / origin.trial * Math.Exp(-origin.r * origin.T); SD = Math.Sqrt((sum_CT2 - sum_CT * sum_CT / origin.trial) * Math.Exp(-2 * origin.r * origin.T) / (origin.trial - 1)); result[1] = SD / Math.Sqrt(origin.trial);//sample standard deviation return result; }
}//constructor public double[] Payoff(Value origin, double[,] randmatrix, bool isant, string s)//payoff function for european option, origin is values, matrix is random number matrix, s is call or put { double sum_CT = 0, sum_CT2 = 0, SD = 0, cv = 0, cv2 = 0, delta = 0, delta2 = 0,d1=0; double dt = Convert.ToDouble(origin.T) / Convert.ToDouble(origin.step - 1); double[] result = new double[2]; double[,] temp1 = new double[origin.trial, 2];//for regular random number store the max and min double[,] temp2 = new double[origin.trial, 2];//for antithemtic random number store the max and min double[,] matrix1 = new double[origin.trial, origin.step]; double[,] matrix2 = new double[origin.trial, origin.step]; for (int i = 0; i < trial; i++) { matrix1[i, 0] = origin.S; matrix2[i, 0] = origin.S; temp1[i, 0] = origin.S; temp2[i, 0] = origin.S; temp1[i, 1] = origin.S; temp2[i, 1] = origin.S;//initial the first price in order to compare cv = 0; cv2 = 0; for (int j = 1; j < step; j++) { matrix1[i, j] = matrix1[i, j - 1] * Math.Exp((origin.r - origin.d - origin.e * origin.e * 0.5) * dt + (origin.e * Math.Sqrt(dt) * randmatrix[i, j])); temp1[i, 0] = Math.Max(matrix1[i, j], temp1[i, 0]);//store the max price in one path temp1[i, 1] = Math.Min(matrix1[i, j], temp1[i, 1]);//store the min price in one path if(iscv==true)//using control variate { d1 = (Math.Log((matrix1[i, j - 1] / origin.K)) + (origin.r + origin.e * origin.e / 2) * origin.T) / (origin.e * Math.Sqrt(origin.T)); delta = Phi(d1); if (s == "call") cv = cv + delta * (matrix1[i, j] - matrix1[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); else if (s == "put") cv = cv + (delta - 1) * (matrix1[i, j] - matrix1[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); } if (isant == true)//using antithemtic random number { matrix2[i, j] = matrix2[i, j - 1] * Math.Exp((origin.r - origin.d - origin.e * origin.e * 0.5) * dt + (origin.e * Math.Sqrt(dt) * -randmatrix[i, j])); temp2[i, 0] = Math.Max(matrix2[i, j], temp2[i, 0]); temp2[i, 1] = Math.Min(matrix2[i, j], temp2[i, 1]); if(iscv==true) { d1 = (Math.Log((matrix2[i, j - 1] / origin.K)) + (origin.r + origin.e * origin.e / 2) * origin.T) / (origin.e * Math.Sqrt(origin.T)); delta2 = Phi(d1); if (s == "call") { cv2 = cv2 + delta2 * (matrix2[i, j] - matrix2[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); } else if (s == "put") { cv2 = cv2 + (delta2 - 1) * (matrix2[i, j] - matrix2[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); } } } } if (iscv == false) { if (S2 == "fix")//fixed { if (s == "call") { temp1[i, 0] = Math.Max(temp1[i, 0] - origin.K, 0.00); if (isant == true) temp2[i, 0] = Math.Max(temp2[i, 0] - origin.K, 0.00); } else if (s == "put") { temp1[i, 0] = Math.Max(origin.K - temp1[i, 1], 0.00); if (isant == true) temp2[i, 0] = Math.Max(origin.K - temp2[i, 1], 0.00); } if (isant == true) { temp1[i, 0] = 0.5 * (temp1[i, 0] + temp2[i, 0]); } sum_CT = sum_CT + temp1[i, 0]; sum_CT2 = sum_CT2 + temp1[i, 0] * temp1[i, 0]; } else if (S2 == "floating")//floating { if (s == "call") { temp1[i, 1] = Math.Max(matrix1[i, origin.step - 1] - temp1[i,1], 0.00); if (isant == true) temp2[i, 1] = Math.Max(matrix2[i, origin.step - 1] - temp2[i,1], 0.00); } else if (s == "put") { temp1[i, 1] = Math.Max(temp1[i,0] - matrix1[i, origin.step - 1], 0.00); if (isant == true) temp2[i, 1] = Math.Max(temp1[i,0] - matrix2[i, origin.step - 1], 0.00); } if (isant == true) { temp1[i, 1] = 0.5 * (temp1[i, 1] + temp2[i, 1]); } sum_CT = sum_CT + temp1[i, 1]; sum_CT2 = sum_CT2 + temp1[i, 1] * temp1[i, 1]; } } else if (iscv == true) { if (S2 == "fix") { if (s == "call") { temp1[i, 0] = Math.Max(temp1[i, 0] - origin.K, 0.00) + -1 * cv; if (isant == true) temp2[i, 0] = Math.Max(temp2[i, 0] - origin.K, 0.00) + -1 * cv2; } else if (s == "put") { temp1[i, 0] = Math.Max(origin.K - temp1[i, 1], 0.00) + -1 * cv; if (isant == true) temp2[i, 0] = Math.Max(origin.K - temp2[i, 1], 0.00) + -1 * cv2; } if (isant == true) { temp1[i, 0] = 0.5 * (temp1[i, 0] + temp2[i, 0]); } sum_CT = sum_CT + temp1[i, 0]; sum_CT2 = sum_CT2 + temp1[i, 0] * temp1[i, 0]; } else if (S2 == "floating") { if (s == "call") { temp1[i, 1] = Math.Max(matrix1[i, origin.step - 1] - origin.K, 0.00) + -1 * cv; if (isant == true) temp2[i, 1] = Math.Max(matrix2[i, origin.step - 1] - origin.K, 0.00) + -1 * cv2; } else if (s == "put") { temp1[i, 1] = Math.Max(origin.K - matrix1[i, origin.step - 1], 0.00) + -1 * cv; if (isant == true) temp2[i, 1] = Math.Max(origin.K - matrix2[i, origin.step - 1], 0.00) + -1 * cv2; } if (isant == true) { temp1[i, 1] = 0.5 * (temp1[i, 1] + temp2[i, 1]); } sum_CT = sum_CT + temp1[i, 1]; sum_CT2 = sum_CT2 + temp1[i, 1] * temp1[i, 1]; } } } result[0] = sum_CT / origin.trial * Math.Exp(-origin.r * origin.T); SD = Math.Sqrt((sum_CT2 - sum_CT * sum_CT / origin.trial) * Math.Exp(-2 * origin.r * origin.T) / (origin.trial - 1)); result[1] = SD / Math.Sqrt(origin.trial);//sample standard deviation return result; }
public double[] Payoff(Value origin, double[,] randmatrix, bool isant, string s) { double dt = (double)origin.T / origin.step; double nudt = (origin.r - origin.d - 0.5 * origin.e * origin.e) * dt; double sigsdt = origin.e * Math.Sqrt(dt); double[,] matrix1 = new double[origin.trial, origin.step]; double[,] matrix2 = new double[origin.trial, origin.step]; double[] result = new double[2]; bool barrier_crossed = false; bool barrier_crossed2 = false; double sum1 = 0, sum2 = 0, SD = 0, cv = 0, cv2 = 0, delta = 0, delta2 = 0, d1 = 0; for (int i = 0; i < trial; i++) { matrix1[i, 0] = origin.S; matrix2[i, 0] = origin.S; cv = 0; cv2 = 0; barrier_crossed = false;//wheather the price path cross the barrier for regular random number barrier_crossed2 = false;//wheather the price path cross the barrier for antithemtic random number for (int j = 1; j < step; j++) { matrix1[i, j] = matrix1[i, j - 1] * Math.Exp(nudt + sigsdt * randmatrix[i, j]); if (iscv == true)//using control variate { d1 = (Math.Log((matrix1[i, j - 1] / origin.K)) + (origin.r + origin.e * origin.e / 2) * origin.T) / (origin.e * Math.Sqrt(origin.T)); delta = Phi(d1); if (s == "call") cv = cv + delta * (matrix1[i, j] - matrix1[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); else if (s == "put") cv = cv + (delta - 1) * (matrix1[i, j] - matrix1[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); } if (isant == true)//using antithemtic random number { matrix2[i, j] = matrix2[i, j - 1] * Math.Exp(nudt + sigsdt * -randmatrix[i, j]); if (iscv == true)//using control variate { d1 = (Math.Log((matrix1[i, j - 1] / origin.K)) + (origin.r + origin.e * origin.e / 2) * origin.T) / (origin.e * Math.Sqrt(origin.T)); delta2 = Phi(d1); if (s == "call") { cv2 = cv2 + delta2 * (matrix2[i, j] - matrix2[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); } else if (s == "put") { cv2 = cv2 + (delta2 - 1) * (matrix2[i, j] - matrix2[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); } } } if (S2 == "down_out") { if (matrix1[i, j] <= Sb) { barrier_crossed = true; if (isant == true) if (matrix2[i, j] <= Sb) barrier_crossed2 = true; break; } } else if (S2 == "up_out") { if (matrix1[i, j] >= Sb) { barrier_crossed = true; if (isant == true) if (matrix2[i, j] >= Sb) barrier_crossed2 = true; break; } } else if (S2 == "up_in") { if (matrix1[i, j] >= Sb) { barrier_crossed = true; if (isant == true) if (matrix2[i, j] >= Sb) barrier_crossed2 = true; } } else if (S2 == "down_in") { if (matrix1[i, j] <= Sb) { barrier_crossed = true; if (isant == true) if (matrix2[i, j] <= Sb) barrier_crossed2 = true; } } } if (S2 == "down_out" || S2 == "up_out")//if the price crossed the barrier, set the terminal price 0 { if (barrier_crossed == true) matrix1[i, step - 1] = 0; if (barrier_crossed2 == true) matrix2[i, step - 1] = 0; } else if (S2 == "down_in" || S2 == "up_in")//if the price doesn't crossed the barrier, set the terminal price 0 { if (barrier_crossed == false) matrix1[i, step - 1] = 0; if (barrier_crossed2 == false) matrix2[i, step - 1] = 0; } if (s == "call") { matrix1[i, step - 1] = Math.Max(0, matrix1[i, step - 1] - origin.K); if (isant == true) matrix2[i, step - 1] = Math.Max(0, matrix2[i, step - 1] - origin.K); if (iscv == true) { matrix1[i, step - 1] = Math.Max(0, matrix1[i, step - 1] - origin.K) + -1 * cv; if (isant == true) matrix2[i, step - 1] = Math.Max(0, matrix2[i, step - 1] - origin.K) + -1 * cv2; } } else if (s == "put") { if (barrier_crossed == false && (S2 == "up_out" || S2 == "down_out"))//ensure that when the termial price equals to 0, don't using K-price matrix1[i, step - 1] = Math.Max(0.00, origin.K - matrix1[i, step - 1]); else if (barrier_crossed == true && (S2 == "up_out" || S2 == "down_out")) matrix1[i, step - 1] = 0; else if (barrier_crossed == false && (S2 == "up_in" || S2 == "down_in")) matrix1[i, step - 1] = 0; else if(barrier_crossed==true&&(S2=="up_in"||S2=="down_in")) matrix1[i, step - 1] = Math.Max(0.00, origin.K - matrix1[i, step - 1]); if (isant == true) { if (barrier_crossed == false && (S2 == "up_out" || S2 == "down_out")) matrix2[i, step - 1] = Math.Max(0.00, origin.K - matrix2[i, step - 1]); else if (barrier_crossed == true && (S2 == "up_out" || S2 == "down_out")) matrix2[i, step - 1] = 0; else if (barrier_crossed == false && (S2 == "up_in" || S2 == "down_in")) matrix2[i, step - 1] = 0; else if (barrier_crossed == true && (S2 == "up_in" || S2 == "down_in")) matrix2[i, step - 1] = Math.Max(0.00, origin.K - matrix2[i, step - 1]); } if (iscv == true) { if (barrier_crossed == false && (S2 == "up_out" || S2 == "down_out")) matrix1[i, step - 1] = Math.Max(0.00, origin.K - matrix1[i, step - 1]) - 1 * cv; else if (barrier_crossed == true && (S2 == "up_out" || S2 == "down_out")) matrix1[i, step - 1] = 0 - 1 * cv; else if (barrier_crossed == false && (S2 == "up_in" || S2 == "down_in")) matrix1[i, step - 1] = 0 - 1 * cv; else if (barrier_crossed == true && (S2 == "up_in" || S2 == "down_in")) matrix1[i, step - 1] = Math.Max(0.00, origin.K - matrix1[i, step - 1]) - 1 * cv; if (isant == true) { if (barrier_crossed == false && (S2 == "up_out" || S2 == "down_out")) matrix2[i, step - 1] = Math.Max(0.00, origin.K - matrix2[i, step - 1]) - 1 * cv2; else if (barrier_crossed == true && (S2 == "up_out" || S2 == "down_out")) matrix2[i, step - 1] = 0 - 1 * cv2; else if (barrier_crossed == false && (S2 == "up_in" || S2 == "down_in")) matrix2[i, step - 1] = 0 - 1 * cv2; else if (barrier_crossed == true && (S2 == "up_in" || S2 == "down_in")) matrix2[i, step - 1] = Math.Max(0.00, origin.K - matrix2[i, step - 1]) - 1 * cv2; } } } if (isant == true) matrix1[i, step - 1] = (matrix1[i, step - 1] + matrix2[i, step - 1]) * 0.5; sum1 = sum1 + matrix1[i, step - 1]; sum2 = sum2 + matrix1[i, step - 1] * matrix1[i, step - 1]; } result[0] = Math.Exp(-origin.r * origin.T) * sum1 / origin.trial; SD = Math.Sqrt((sum2 - sum1 * sum1 / origin.trial) * Math.Exp(-2 * origin.r * origin.T) / (trial - 1)); result[1] = SD / Math.Sqrt(trial); return result; }
public double[] Payoff(Value origin, double[,] randmatrix, bool isant, string s) { double dt = (double)origin.T / (origin.step - 1); double nudt = (origin.r - origin.d - 0.5 * origin.e * origin.e) * dt; double sigsdt = origin.e * Math.Sqrt(dt); double[,] matrix1 = new double[origin.trial, origin.step];//store regular random number double[,] matrix2 = new double[origin.trial, origin.step];//store antithetic random number double[] result = new double[2]; double sum1 = 0; double sum2 = 0; double SD = 0, sum = 0, summ = 0, cv = 0, delta = 0, d1 = 0, cv2 = 0, delta2 = 0; for (int i = 0; i < origin.trial; i++) { matrix1[i, 0] = origin.S; matrix2[i, 0] = origin.S; sum = 0;//for regular summ = 0;//for antithemtic random number cv = 0; cv2 = 0; for (int j = 1; j < origin.step; j++) { if (iscv == false)//if not using control variate { matrix1[i, j] = matrix1[i, j - 1] * Math.Exp(nudt + sigsdt * randmatrix[i, j]); sum = sum + matrix1[i, j]; if (isant == true)//if using antithetic random number { matrix2[i, j] = (matrix2[i, j - 1] * Math.Exp(nudt + sigsdt * -randmatrix[i, j])); summ = summ + matrix2[i, j]; } } else if (iscv == true)//if using control variate { matrix1[i, j] = matrix1[i, j - 1] * Math.Exp(nudt + sigsdt * randmatrix[i, j]); d1 = (Math.Log((matrix1[i, j - 1] / origin.K)) + (origin.r + origin.e * origin.e / 2) * origin.T) / (origin.e * Math.Sqrt(origin.T)); delta = Phi(d1); if (s == "call") cv = cv + delta * (matrix1[i, j] - matrix1[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); else if (s == "put") cv = cv + (delta - 1) * (matrix1[i, j] - matrix1[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); sum = sum + matrix1[i, j]; if (isant == true)//if using antithetic random number { matrix2[i, j] = matrix2[i, j - 1] * Math.Exp((origin.r - origin.d - origin.e * origin.e * 0.5) * dt + (origin.e * Math.Sqrt(dt) * -randmatrix[i, j])); d1 = (Math.Log((matrix2[i, j - 1] / origin.K)) + (origin.r + origin.e * origin.e / 2) * origin.T) / (origin.e * Math.Sqrt(origin.T)); delta2 = Phi(d1); if (iscv == true)//if using control variate { if (s == "call") { // cv = cv + delta * (matrix1[i, j] - matrix1[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); cv2 = cv2 + delta2 * (matrix2[i, j] - matrix2[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); } else if (s == "put") { // cv = cv + (delta - 1) * (matrix1[i, j] - matrix1[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); cv2 = cv2 + (delta2 - 1) * (matrix2[i, j] - matrix2[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); } } summ = summ + matrix2[i, j]; } } } sum = sum / (origin.step - 1); summ = summ / (origin.step - 1); if (isant == false)//if not using antithemtic random number { if (iscv == false)//if not using control variate { if (s == "call") { matrix1[i, step - 1] = Math.Max(sum - origin.K, 0); } else if (s == "put") { matrix1[i, step - 1] = Math.Max(origin.K - sum, 0); } } else if (iscv == true)//if using control variate { if (s == "call") { matrix1[i, step - 1] = Math.Max(sum - origin.K, 0) + -1 * cv; } else if (s == "put") { matrix1[i, step - 1] = Math.Max(origin.K - sum, 0) + -1 * cv; } } } else if (isant == true)//if using antithetic random number { if (iscv == false)//if not using control variate { if (s == "call") { matrix1[i, step - 1] = Math.Max(sum - origin.K, 0); matrix2[i, step - 1] = Math.Max(summ - origin.K, 0); } else if (s == "put") { matrix1[i, step - 1] = Math.Max(origin.K - sum, 0); matrix2[i, step - 1] = Math.Max(origin.K - summ, 0); } } else if (iscv == true)//if using control variate { if (s == "call") { matrix1[i, step - 1] = Math.Max(sum - origin.K, 0) + -1 * cv; matrix2[i, step - 1] = Math.Max(summ - origin.K, 0) + -1 * cv2; } else if (s == "put") { matrix1[i, step - 1] = Math.Max(origin.K - sum, 0) + -1 * cv; matrix2[i, step - 1] = Math.Max(origin.K - summ, 0) + -1 * cv2; } } matrix1[i, step - 1] = (matrix1[i, step - 1] + matrix2[i, step - 1]) * 0.5; } sum1 = sum1 + matrix1[i, step - 1]; sum2 = sum2 + matrix1[i, step - 1] * matrix1[i, step - 1]; } SD = Math.Sqrt((sum2 - sum1 * sum1 / origin.trial) * Math.Exp(-2 * origin.r * origin.T) / (origin.trial - 1)); result[0] = Math.Exp(-origin.r * origin.T) * sum1 / trial; result[1] = SD / Math.Sqrt(origin.trial); return result; }
}//constructor public double[] Payoff(Value origin, double[,] randmatrix, bool isant, string s)//payoff function for european option, origin is values, matrix is random number matrix, s is call or put { double sum_CT = 0, sum_CT2 = 0, SD = 0; double[] temp1 = new double[origin.trial]; double[] temp2 = new double[origin.trial]; double[] result = new double[2]; double dt = Convert.ToDouble(origin.T) / Convert.ToDouble(origin.step - 1), d1 = 0, delta = 0, delta2 = 0, cv = 0, cv2 = 0; double[,] matrix1 = new double[origin.trial, origin.step]; double[,] matrix2 = new double[origin.trial, origin.step]; for (int i = 0; i < trial; i++) { matrix1[i, 0] = origin.S; matrix2[i, 0] = origin.S; cv = 0; cv2 = 0; for (int j = 1; j < step; j++) { matrix1[i, j] = matrix1[i, j - 1] * Math.Exp((origin.r - origin.d - origin.e * origin.e * 0.5) * dt + (origin.e * Math.Sqrt(dt) * randmatrix[i, j])); if (iscv == true) { d1 = (Math.Log((matrix1[i, j - 1] / origin.K)) + (origin.r + origin.e * origin.e / 2) * origin.T) / (origin.e * Math.Sqrt(origin.T)); delta = Phi(d1); if (s == "call") cv = cv + delta * (matrix1[i, j] - matrix1[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); else if (s == "put") cv = cv + (delta - 1) * (matrix1[i, j] - matrix1[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); } if (isant == true) { d1 = (Math.Log((matrix2[i, j - 1] / origin.K)) + (origin.r + origin.e * origin.e / 2) * origin.T) / (origin.e * Math.Sqrt(origin.T)); delta2 = Phi(d1); matrix2[i, j] = matrix2[i, j - 1] * Math.Exp((origin.r - origin.d - origin.e * origin.e * 0.5) * dt + (origin.e * Math.Sqrt(dt) * -randmatrix[i, j])); if (iscv == true) { if (s == "call") { // cv = cv + delta * (matrix1[i, j] - matrix1[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); cv2 = cv2 + delta2 * (matrix2[i, j] - matrix2[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); } else if (s == "put") { // cv = cv + (delta - 1) * (matrix1[i, j] - matrix1[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); cv2 = cv2 + (delta2 - 1) * (matrix2[i, j] - matrix2[i, j - 1] * Math.Exp((origin.r - origin.d) * dt)); } } } } if (s == "call") { if (iscv == false) { temp1[i] = Math.Max(matrix1[i, origin.step - 1] - origin.K, 0.00); } else if (iscv == true) { temp1[i] = Math.Max(0.00, matrix1[i, origin.step - 1] - origin.K) + -1 * cv; } if (isant == true) { if (iscv == false) { temp2[i] = Math.Max(matrix2[i, origin.step - 1] - origin.K, 0.00); } else if (iscv == true) { temp2[i] = Math.Max(matrix2[i, origin.step - 1] - origin.K, 0.00) + -1 * cv2; } } } else if (s == "put") { if (iscv == false) { temp1[i] = Math.Max(origin.K - matrix1[i, origin.step - 1], 0.00); } else if (iscv == true) { temp1[i] = Math.Max(0, origin.K - matrix1[i, origin.step - 1]) + -1 * cv; } if (isant == true) { if (iscv == false) { temp2[i] = Math.Max(origin.K - matrix2[i, origin.step - 1], 0.00); } else if (iscv == true) { temp2[i] = Math.Max(origin.K - matrix2[i, origin.step - 1], 0.00) + -1 * cv2; } } } if (isant == true) { temp1[i] = 0.5 * (temp1[i] + temp2[i]); } sum_CT = sum_CT + temp1[i]; sum_CT2 = sum_CT2 + temp1[i] * temp1[i]; } result[0] = sum_CT / origin.trial * Math.Exp(-origin.r * origin.T); SD = Math.Sqrt((sum_CT2 - sum_CT * sum_CT / origin.trial) * Math.Exp(-2 * origin.r * origin.T) / (origin.trial - 1)); result[1] = SD / Math.Sqrt(origin.trial);//sample standard deviation return result; }
public double[] calculate(Value temp, double[,] matrix, string p, bool isant, PayoffDelegate2 payoff)//calculate all the greeks, temp is all values, matrix is random number matrix, payoff is Payoff function { double[] result = new double[5]; double s = temp.S, k = temp.K, r = temp.r, e = temp.e, t = temp.T; double a, b, c, dd = 0.01; temp.S = (1 + dd) * s; a = diff(temp, matrix, p, isant, payoff)[0]; temp.S = s; temp.S = (1 - dd) * s; b = diff(temp, matrix, p, isant, payoff)[0]; result[0] = greek(a, b, s, "delta"); temp.S = s; // f.BeginInvoke(f.myDelegate); c = diff(temp, matrix, p, isant, payoff)[0]; temp.K = (1 + dd) * k; a = diff(temp, matrix, p, isant, payoff)[0]; temp.K = k; temp.K = (1 - dd) * k; b = diff(temp, matrix, p, isant, payoff)[0]; result[1] = greek(a, b, c, "gamma"); temp.K = k; // f.BeginInvoke(f.myDelegate); temp.e = (1 + dd) * e; a = diff(temp, matrix, p, isant, payoff)[0]; temp.e = e; temp.e = (1 - dd) * e; b = diff(temp, matrix, p, isant, payoff)[0]; result[2] = greek(a, b, e, "vega"); temp.e = e; // f.BeginInvoke(f.myDelegate); temp.T = (1 + dd) * t; a = diff(temp, matrix, p, isant, payoff)[0]; temp.T = t; temp.T = (1 - dd) * t; b = diff(temp, matrix, p, isant, payoff)[0]; result[3] = -greek(a, b, t, "theta"); temp.T = t; // f.BeginInvoke(f.myDelegate); temp.r = (1 + dd) * r; a = diff(temp, matrix, p, isant, payoff)[0]; temp.r = r; temp.r = (1 - dd) * r; b = diff(temp, matrix, p, isant, payoff)[0]; result[4] = greek(a, b, r, "rho"); temp.r = r; // f.BeginInvoke(f.myDelegate); return result; }
private double[] diff(Value temp, double[,] matrix, string s, bool isant, PayoffDelegate2 payoff)//calculate the greeks, matrix is the random matrix generated before { double dt = temp.T / (temp.step - 1); double[] result = new double[2]; /*for (int i = 0; i < temp.trial; i++) { newmatrix[i, 0] = temp.S; for (int j = 1; j < temp.step; j++) newmatrix[i, j] = newmatrix[i, j - 1] * Math.Exp((temp.r - temp.e * temp.e * 0.5) *dt + (temp.e * Math.Sqrt(dt) * matrix[i, j])); }*/ result = payoff(temp, matrix, isant, s); return result; }
public double[] delta_CV(Value origin, double[,] randmatrix, bool anti, string c)//delta-based-control-variate { double[] result = new double[2]; double dt = origin.T / (origin.step - 1);// sum = 0; double nudt = (origin.r - origin.d - 0.5 * origin.e * origin.e) * dt; double sigsdt = origin.e * Math.Sqrt(dt); double erddt = Math.Exp((origin.r - origin.d) * dt); double beta1 = -1, sum_CT = 0, sum_CT2 = 0, St = 0, Stn = 0, cv = 0, t = 0, delta = 0, d1 = 0, CT = 0, SD = 0; if (anti == false) { for (int i = 0; i < origin.trial; i++) { St = origin.S; cv = 0; for (int j = 1; j < origin.step; j++) { //t = (j - 1) * dt; d1 = (Math.Log((St / origin.K)) + (origin.r + origin.e * origin.e / 2) * origin.T) / (origin.e * Math.Sqrt(origin.T)); delta = Phi1(d1); Stn = St * Math.Exp(nudt + sigsdt * randmatrix[i, j]); if (c == "call") cv = cv + delta * (Stn - St * erddt); else if (c == "put") cv = cv + (delta - 1) * (Stn - St * erddt); St = Stn; } if (s2 == "European") { if (c == "call") { CT = Math.Max(0, St - origin.K) + beta1 * cv; } else if (c == "put") { CT = Math.Max(0, origin.K - St) + beta1 * cv; } } sum_CT = sum_CT + CT; sum_CT2 = sum_CT2 + CT * CT; } } else if (anti == true) { double St2 = origin.S, cv2 = 0, delta2 = 0, Stn2 = 0; for (int i = 0; i < origin.trial; i++) { St = origin.S; St2 = origin.S; cv = 0; cv2 = 0; for (int j = 1; j < origin.step; j++) { t = (i - 1) * dt; d1 = (Math.Log(St / origin.K) + (origin.r + origin.e * origin.e / 2) * origin.T) / (origin.e * Math.Sqrt(origin.T)); delta = Phi1(d1); d1 = (Math.Log(St2 / origin.K) + (origin.r + origin.e * origin.e / 2) * origin.T) / (origin.e * Math.Sqrt(origin.T)); delta2 = Phi1(d1); Stn = St * Math.Exp(nudt + sigsdt * randmatrix[i, j]); Stn2 = St2 * Math.Exp(nudt + sigsdt * -randmatrix[i, j]); if (c == "call") { cv = cv + delta * (Stn - St * erddt); cv2 = cv2 + delta2 * (Stn2 - St2 * erddt); } else if (c == "put") { cv = cv + (delta - 1) * (Stn - St * erddt); cv2 = cv2 + (delta2 - 1) * (Stn2 - St2 * erddt); } St = Stn; St2 = Stn2; } if (c == "call") { CT = 0.5 * (Math.Max(0, St - origin.K) + beta1 * cv + Math.Max(0, St2 - origin.K) + beta1 * cv2); } else if (c == "put") { CT = 0.5 * (Math.Max(0, origin.K - St) + beta1 * cv + Math.Max(0, origin.K - St2) + beta1 * cv2); } sum_CT = sum_CT + CT; sum_CT2 = sum_CT2 + CT * CT; } } result[0] = sum_CT / origin.trial * Math.Exp(-origin.r * origin.T); SD = Math.Sqrt((sum_CT2 - sum_CT * sum_CT / origin.trial) * Math.Exp(-2 * origin.r * origin.T) / (origin.trial - 1)); result[1] = SD / Math.Sqrt(origin.trial); return result; }
public double[] delta_gamma_CV(Value origin, double[,] randmatrix, bool anti, string c)//delta-gamma-based-control-variate { double[] result = new double[2]; double dt = origin.T / (origin.step - 1); double nudt = (origin.r - origin.d - 0.5 * origin.e * origin.e) * dt; double sigsdt = origin.e * Math.Sqrt(dt); double erddt = Math.Exp((origin.r - origin.d) * dt); double egamma = Math.Exp((2 * (origin.r - origin.d) + origin.e * origin.e) * dt) - 2 * erddt + 1; double d2 = 0, gamma = 0, gamma2 = 0, delta2 = 0, beta1 = -1, beta2 = -0.5, cv2 = 0, St2 = 0, sum_CT = 0; double sum_CT2 = 0, St = 0, Stn = 0, Stn2 = 0, cv = 0, t = 0, delta = 0, d1 = 0, CT = 0, SD = 0; for (int i = 0; i < origin.trial; i++) { St = origin.S; St2 = origin.S; cv = 0; cv2 = 0; for (int j = 1; j < origin.step; j++) { t = (j - 1) * dt; d1 = (Math.Log((St / origin.K)) + (origin.r + origin.e * origin.e / 2) * origin.T) / (origin.e * Math.Sqrt(origin.T)); delta = Phi(d1); gamma = f(d1) / (St * origin.e * Math.Sqrt(origin.T)); d2 = (Math.Log((St2 / origin.K)) + (origin.r + origin.e * origin.e / 2) * origin.T) / (origin.e * Math.Sqrt(origin.T)); delta2 = normcdf(d1); gamma2 = f(d2) / (St2 * origin.e * Math.Sqrt(origin.T)); Stn = St * Math.Exp(nudt + sigsdt * randmatrix[i, j]); Stn2 = St2 * Math.Exp(nudt + sigsdt * randmatrix[i, j]); if (c == "call") cv = cv + delta * (Stn - St * erddt) + delta2 * (Stn2 - St2 * erddt); else if (c == "put") cv = cv + (delta - 1) * (Stn - St * erddt) + (delta2 - 1) * (Stn2 - St2 * erddt); cv2 = cv2 + gamma * ((Stn - St) * (Stn - St) - St * St * egamma) + gamma2 * ((Stn2 - St2) * (Stn2 - St2) - St2 * St2 * egamma); St = Stn; St2 = Stn2; } if (c == "call") CT = 0.5 * (Math.Max(0, St - origin.K) + Math.Max(0, St2 - origin.K) + beta1 * cv + beta2 * cv2); else if (c == "put") CT = 0.5 * (Math.Max(0, origin.K - St) + Math.Max(0, origin.K - St2) + beta1 * cv + beta2 * cv2); sum_CT = sum_CT + CT; sum_CT2 = sum_CT2 + CT * CT; } result[0] = sum_CT / origin.trial * Math.Exp(-origin.r * origin.T); SD = Math.Sqrt((sum_CT2 - sum_CT * sum_CT / origin.trial) * Math.Exp(-2 * origin.r * origin.T) / (origin.trial - 1)); result[1] = SD / Math.Sqrt(origin.trial); return result; }
//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."); } }