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;
 }
Beispiel #12
0
        //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);
        }
Beispiel #13
0
        //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."); }
        }