Example #1
0
            internal static double[,] RandomSetMulti(int TrailNum, int StepNum)
            {
                //this is the road which use the multithreading
                double[,] RandomSetMulti = new double[TrailNum, StepNum];
                Random rand2 = new Random();
                // int Thread1 = 1;

                Action <object> MyAct = x =>
                {
                    Parallel.ForEach(Ienum.Step(0, TrailNum, 1), new ParallelOptions {
                        MaxDegreeOfParallelism = cores
                    }, a =>
                    {
                        for (long b = 0; b < StepNum; b++)
                        {
                            RandomSetMulti[a, b] = mt_rand();//Call box muller to generate ONE NORMAL random
                        }
                    });
                };
                Thread th = new Thread(new ParameterizedThreadStart(MyAct));

                th.Start();
                th.Join();
                th.Abort();

                return(RandomSetMulti);

                double mt_rand()
                //Box Muller Norm Random  have to lock when nulti threading

                {
                    //var obj = new Object();
                    double randn1 = 0, randn2 = 0;

                    //for parallel computing in the future, lock to ensure serial access
                    // The item you locked is your Random Class
                    lock (rand2) randn1 = rand2.NextDouble();
                    lock (rand2) randn2 = rand2.NextDouble();

                    double z1 = 0;

                    z1 = Math.Sqrt((-2) * Math.Log(randn1)) * Math.Cos(2 * Math.PI * randn2);
                    return(z1);
                }
            }
Example #2
0
            internal static double[] Simulate(double SO, double K, double sigma, double r, double t, Int32 StepNum, Int32 TrailNum, double[,] Randoms, int Anti, double div, int Deltabase, int MultiThread)
            {
                double[] Result = new double[4];
                double[,] set = new double[1, 4];
                double SumCall = 0.0;
                double SumPut = 0.0;
                double StdCallEr = 0.0;
                double StdCallSum = 0.0;
                double StdPutSum = 0.0;
                double StdPutEr = 0.0;
                double CallSd, PutSd;

                if (Anti == 1)
                {
                    double x, y;
                    if (Deltabase == 1)
                    {
                        double dt, St, St1, Stn, Stn1, cv, cv1, CT, PT, Sum_CT, Sum_PT, Sum_PT2, Sum_CT2, t1, CallDelta = 0, CallDelta1 = 0, PutDelta = 0, PutDelta1 = 0, beta1, nudt, sigsdt, erddt;//I don't know what the beta1 is.
                        dt      = t / (StepNum);
                        nudt    = (r - div - 0.5 * Math.Pow(sigma, 2)) * dt;
                        sigsdt  = sigma * Math.Sqrt(dt);
                        erddt   = Math.Exp((r - div) * dt);
                        Sum_CT  = 0;
                        Sum_CT2 = 0;
                        Sum_PT  = 0;
                        Sum_PT2 = 0;
                        beta1   = -1;
                        double[] DeltaSet  = new double[2];
                        double[] DeltaSet1 = new double[2];
                        //this loop is used for restoring the simulation result
                        if (MultiThread == 1)
                        {
                            int Thread1 = 1;
                            Parallel.ForEach(Ienum.Step(0, TrailNum, 1), new ParallelOptions {
                                MaxDegreeOfParallelism = Thread1
                            }, a =>
                            {
                                St  = SO;
                                St1 = SO;
                                cv  = 0;
                                cv1 = 0;
                                for (int j = 1; j <= StepNum; j++)
                                {
                                    t1         = t - dt * (j - 1);
                                    DeltaSet   = Black_Scholes_Delta.Black_Scholes_DeltaSet(St, t1, K, sigma, r);
                                    DeltaSet1  = Black_Scholes_Delta.Black_Scholes_DeltaSet(St1, t1, K, sigma, r);
                                    CallDelta  = DeltaSet[0];
                                    PutDelta   = DeltaSet[1];
                                    CallDelta1 = DeltaSet1[0];
                                    PutDelta1  = DeltaSet1[1];
                                    Stn        = St * Math.Exp(nudt + sigsdt * Randoms[a, j - 1]);
                                    Stn1       = St1 * Math.Exp(nudt + sigsdt * (-Randoms[a, j - 1]));
                                    cv         = cv + CallDelta * (Stn - St * erddt) + CallDelta1 * (Stn1 - St1 * erddt);
                                    cv1        = cv1 + PutDelta * (Stn - St * erddt) + PutDelta1 * (Stn1 - St1 * erddt);
                                    St         = Stn;
                                    St1        = Stn1;
                                }
                                CT      = Math.Max(St - K, 0) + Math.Max(St1 - K, 0) + beta1 * cv;
                                Sum_CT  = Sum_CT + CT;
                                Sum_CT2 = Sum_CT2 + CT * CT;
                                PT      = Math.Max(K - St, 0) + Math.Max(K - St1, 0) + beta1 * cv1;
                                Sum_PT  = Sum_PT + PT;
                                Sum_PT2 = Sum_PT2 + PT * PT;
                            });
                            x         = Sum_CT * Math.Exp(-r * t) / (2 * TrailNum);;
                            CallSd    = Math.Sqrt((Sum_CT2 - Sum_CT * Sum_CT / (2 * TrailNum)) * Math.Exp(-2 * r * t) / (2 * TrailNum - 1));
                            StdCallEr = CallSd / Math.Sqrt(2 * TrailNum);
                            y         = Sum_PT * Math.Exp(-r * t) / (2 * TrailNum);
                            PutSd     = Math.Sqrt((Sum_PT2 - Sum_PT * Sum_PT / (2 * TrailNum)) * Math.Exp(-2 * r * t) / (2 * TrailNum - 1));
                            StdPutEr  = PutSd / Math.Sqrt(2 * TrailNum);
                        }
                        else
                        {
                            for (int i = 0; i < TrailNum; i++)
                            {
                                St  = SO;
                                St1 = SO;
                                cv  = 0;
                                cv1 = 0;
                                for (int j = 1; j <= StepNum; j++)
                                {
                                    t1         = t - dt * (j - 1);
                                    DeltaSet   = Black_Scholes_Delta.Black_Scholes_DeltaSet(St, t1, K, sigma, r);
                                    DeltaSet1  = Black_Scholes_Delta.Black_Scholes_DeltaSet(St1, t1, K, sigma, r);
                                    CallDelta  = DeltaSet[0];
                                    PutDelta   = DeltaSet[1];
                                    CallDelta1 = DeltaSet1[0];
                                    PutDelta1  = DeltaSet1[1];
                                    Stn        = St * Math.Exp(nudt + sigsdt * Randoms[i, j - 1]);
                                    Stn1       = St1 * Math.Exp(nudt + sigsdt * (-Randoms[i, j - 1]));
                                    cv         = cv + CallDelta * (Stn - St * erddt) + CallDelta1 * (Stn1 - St1 * erddt);
                                    cv1        = cv1 + PutDelta * (Stn - St * erddt) + PutDelta1 * (Stn1 - St1 * erddt);
                                    St         = Stn;
                                    St1        = Stn1;
                                }
                                CT      = Math.Max(St - K, 0) + Math.Max(St1 - K, 0) + beta1 * cv;
                                Sum_CT  = Sum_CT + CT;
                                Sum_CT2 = Sum_CT2 + CT * CT;
                                PT      = Math.Max(K - St, 0) + Math.Max(K - St1, 0) + beta1 * cv1;
                                Sum_PT  = Sum_PT + PT;
                                Sum_PT2 = Sum_PT2 + PT * PT;
                            }
                        }
                        x         = Sum_CT * Math.Exp(-r * t) / (2 * TrailNum);;
                        CallSd    = Math.Sqrt((Sum_CT2 - Sum_CT * Sum_CT / (2 * TrailNum)) * Math.Exp(-2 * r * t) / (2 * TrailNum - 1));
                        StdCallEr = CallSd / Math.Sqrt(2 * TrailNum);
                        y         = Sum_PT * Math.Exp(-r * t) / (2 * TrailNum);
                        PutSd     = Math.Sqrt((Sum_PT2 - Sum_PT * Sum_PT / (2 * TrailNum)) * Math.Exp(-2 * r * t) / (2 * TrailNum - 1));
                        StdPutEr  = PutSd / Math.Sqrt(2 * TrailNum);
                    }
                    else
                    {
                        double[,] sims  = new double[TrailNum, StepNum];
                        double[,] sims1 = new double[TrailNum, StepNum];
                        //int Thread1 = 1;
                        if (MultiThread == 1)
                        {
                            Action <object> MyAct1 = x2 =>
                            {
                                Parallel.ForEach(Ienum.Step(0, TrailNum, 1), new ParallelOptions {
                                    MaxDegreeOfParallelism = cores
                                }, a =>
                                {
                                    lock (sims) sims[a, 0] = SO;
                                    lock (sims1) sims1[a, 0] = SO;

                                    for (int j = 1; j < StepNum; j++)
                                    {
                                        lock (sims) sims[a, j] = sims[a, j - 1] * Math.Exp((r - 0.5 * Math.Pow(sigma, 2)) * (t / (StepNum - 1)) + sigma * Math.Pow((t / (StepNum - 1)), 0.5) * Randoms[a, j]);
                                        lock (sims1) sims1[a, j] = sims1[a, j - 1] * Math.Exp((r - 0.5 * Math.Pow(sigma, 2)) * (t / (StepNum - 1)) + sigma * Math.Pow((t / (StepNum - 1)), 0.5) * (-Randoms[a, j]));
                                    }

                                    lock (sims) lock (sims1) SumCall += Math.Max(sims[a, StepNum - 1] - K, 0) + Math.Max(sims1[a, StepNum - 1] - K, 0);

                                    lock (sims) lock (sims1) SumPut += Math.Max(K - sims[a, StepNum - 1], 0) + Math.Max(K - sims1[a, StepNum - 1], 0);
                                });
                            };
                            Thread th = new Thread(new ParameterizedThreadStart(MyAct1));
                            th.Start();
                            th.Join();
                            th.Abort();

                            x = (SumCall / (2 * TrailNum)) * Math.Exp(-r * t);
                            y = (SumPut / (2 * TrailNum)) * Math.Exp(-r * t);
                            //calculate the sum of call and put
                            Action <object> MyAct2 = x2 =>
                            {
                                Parallel.ForEach(Ienum.Step(0, TrailNum, 1), new ParallelOptions {
                                    MaxDegreeOfParallelism = cores
                                }, a =>
                                {
                                    lock (sims) lock (sims1) StdCallSum = StdCallSum + Math.Pow(((Math.Max(sims[a, StepNum - 1] - K, 0) + Math.Max(sims1[a, StepNum - 1] - K, 0)) / 2 - SumCall / (2 * TrailNum)), 2);
                                    lock (sims) lock (sims1) StdPutSum = StdPutSum + Math.Pow(((Math.Max(K - sims[a, StepNum - 1], 0) + Math.Max(K - sims1[a, StepNum - 1], 0)) / 2 - (SumPut / (2 * TrailNum))), 2);
                                });
                            };

                            Thread th1 = new Thread(new ParameterizedThreadStart(MyAct2));
                            th1.Start();
                            th1.Join();
                            th1.Abort();
                            //calculate the StdError
                            StdCallEr = Math.Sqrt(StdCallSum) * Math.Exp(-r * t) / TrailNum;
                            StdPutEr  = Math.Sqrt(StdPutSum) * Math.Exp(-r * t) / TrailNum;
                        }
                        else
                        {
                            for (int p = 0; p < TrailNum; p++)
                            {
                                sims[p, 0]  = SO;
                                sims1[p, 0] = SO;
                            }
                            //this loop is used for restoring the simulation result
                            for (int i = 0; i < TrailNum; i++)
                            {
                                for (int j = 1; j < StepNum; j++)
                                {
                                    sims[i, j]  = sims[i, j - 1] * Math.Exp((r - 0.5 * Math.Pow(sigma, 2)) * (t / (StepNum - 1)) + sigma * Math.Pow((t / (StepNum - 1)), 0.5) * Randoms[i, j]);
                                    sims1[i, j] = sims1[i, j - 1] * Math.Exp((r - 0.5 * Math.Pow(sigma, 2)) * (t / (StepNum - 1)) + sigma * Math.Pow((t / (StepNum - 1)), 0.5) * (-Randoms[i, j]));
                                }
                            }

                            for (int a = 0; a < TrailNum; a++)
                            {
                                SumCall += Math.Max(sims[a, StepNum - 1] - K, 0) + Math.Max(sims1[a, StepNum - 1] - K, 0);
                                SumPut  += Math.Max(K - sims[a, StepNum - 1], 0) + Math.Max(K - sims1[a, StepNum - 1], 0);
                            }

                            x = (SumCall / (2 * TrailNum)) * Math.Exp(-r * t);
                            y = (SumPut / (2 * TrailNum)) * Math.Exp(-r * t);
                            //calculate the sum of call and put
                            for (int q = 0; q < TrailNum; q++)
                            {
                                StdCallSum = StdCallSum + Math.Pow(((Math.Max(sims[q, StepNum - 1] - K, 0) + Math.Max(sims1[q, StepNum - 1] - K, 0)) / 2 - SumCall / (2 * TrailNum)), 2);
                                StdPutSum  = StdPutSum + Math.Pow(((Math.Max(K - sims[q, StepNum - 1], 0) + Math.Max(K - sims1[q, StepNum - 1], 0)) / 2 - (SumPut / (2 * TrailNum))), 2);
                            }

                            //calculate the StdError
                            StdCallEr = Math.Sqrt(StdCallSum) * Math.Exp(-r * t) / TrailNum;
                            StdPutEr  = Math.Sqrt(StdPutSum) * Math.Exp(-r * t) / TrailNum;
                        }
                    }

                    Result[0] = x;
                    Result[1] = y;
                    Result[2] = StdCallEr;
                    Result[3] = StdPutEr;
                }
                else
                {
                    double[,] sims = new double[TrailNum, StepNum];
                    double x, y;


                    if (Deltabase == 1)
                    {
                        double dt, St, Stn, cv, cv1, CT, PT, Sum_CT, Sum_PT, Sum_PT2, Sum_CT2, t1, CallDelta = 0, PutDelta = 0, beta1, nudt, sigsdt, erddt;//I don't know what the beta1 is.
                        dt      = t / (StepNum);
                        nudt    = (r - div - 0.5 * Math.Pow(sigma, 2)) * dt;
                        sigsdt  = sigma * Math.Sqrt(dt);
                        erddt   = Math.Exp((r - div) * dt);
                        Sum_CT  = 0;
                        Sum_CT2 = 0;
                        Sum_PT  = 0;
                        Sum_PT2 = 0;
                        beta1   = -1;
                        double[] DeltaSet = new double[2];
                        int      Thread1  = 1;
                        //this loop is used for restoring the simulation result
                        if (MultiThread == 1)
                        {
                            Parallel.ForEach(Ienum.Step(0, TrailNum, 1), new ParallelOptions {
                                MaxDegreeOfParallelism = Thread1
                            }, a =>
                            {
                                St  = SO;
                                cv  = 0;
                                cv1 = 0;
                                for (int j = 1; j <= StepNum; j++)
                                {
                                    t1        = t - dt * (j - 1);
                                    DeltaSet  = Black_Scholes_Delta.Black_Scholes_DeltaSet(St, t1, K, sigma, r);
                                    CallDelta = DeltaSet[0];
                                    PutDelta  = DeltaSet[1];
                                    Stn       = St * Math.Exp(nudt + sigsdt * Randoms[a, j - 1]);
                                    cv        = cv + CallDelta * (Stn - St * erddt);
                                    cv1       = cv1 + PutDelta * (Stn - St * erddt);
                                    St        = Stn;
                                }
                                CT      = Math.Max(St - K, 0) + beta1 * cv;
                                Sum_CT  = Sum_CT + CT;
                                Sum_CT2 = Sum_CT2 + CT * CT;
                                PT      = Math.Max(K - St, 0) + beta1 * cv1;
                                Sum_PT  = Sum_PT + PT;
                                Sum_PT2 = Sum_PT2 + PT * PT;
                            });
                        }
                        else
                        {
                            for (int i = 0; i < TrailNum; i++)
                            {
                                St  = SO;
                                cv  = 0;
                                cv1 = 0;
                                for (int j = 1; j <= StepNum; j++)
                                {
                                    t1        = t - dt * (j - 1);
                                    DeltaSet  = Black_Scholes_Delta.Black_Scholes_DeltaSet(St, t1, K, sigma, r);
                                    CallDelta = DeltaSet[0];
                                    PutDelta  = DeltaSet[1];
                                    Stn       = St * Math.Exp(nudt + sigsdt * Randoms[i, j - 1]);
                                    cv        = cv + CallDelta * (Stn - St * erddt);
                                    cv1       = cv1 + PutDelta * (Stn - St * erddt);
                                    St        = Stn;
                                }
                                CT      = Math.Max(St - K, 0) + beta1 * cv;
                                Sum_CT  = Sum_CT + CT;
                                Sum_CT2 = Sum_CT2 + CT * CT;
                                PT      = Math.Max(K - St, 0) + beta1 * cv1;
                                Sum_PT  = Sum_PT + PT;
                                Sum_PT2 = Sum_PT2 + PT * PT;
                            }
                        }
                        x         = Sum_CT * Math.Exp(-r * t) / (TrailNum);;
                        CallSd    = Math.Sqrt((Sum_CT2 - Sum_CT * Sum_CT / (TrailNum)) * Math.Exp(-2 * r * t) / (TrailNum - 1));
                        StdCallEr = CallSd / Math.Sqrt(TrailNum);
                        y         = Sum_PT * Math.Exp(-r * t) / (TrailNum);
                        PutSd     = Math.Sqrt((Sum_PT2 - Sum_PT * Sum_PT / (TrailNum)) * Math.Exp(-2 * r * t) / (TrailNum - 1));
                        StdPutEr  = PutSd / Math.Sqrt(TrailNum);
                    }
                    else
                    {
                        int Thread1 = 1;
                        if (MultiThread == 1)
                        {
                            Action <object> MyAct1 = x2 =>
                            {
                                Parallel.ForEach(Ienum.Step(0, TrailNum, 1), new ParallelOptions {
                                    MaxDegreeOfParallelism = cores
                                }, a =>
                                {
                                    lock (sims) sims[a, 0] = SO;
                                    for (int j = 1; j < StepNum; j++)
                                    {
                                        lock (sims) sims[a, j] = sims[a, j - 1] * Math.Exp((r - 0.5 * Math.Pow(sigma, 2)) * (t / (StepNum - 1)) + sigma * Math.Pow((t / (StepNum - 1)), 0.5) * Randoms[a, j]);
                                    }

                                    lock (sims) SumCall += Math.Max(sims[a, StepNum - 1] - K, 0);
                                    lock (sims) SumPut += Math.Max(K - sims[a, StepNum - 1], 0);
                                });
                            };
                            Thread th = new Thread(new ParameterizedThreadStart(MyAct1));
                            th.Start();
                            th.Join();
                            th.Abort();

                            x = (SumCall / TrailNum) * Math.Exp(-r * t);
                            y = (SumPut / TrailNum) * Math.Exp(-r * t);
                            //calculate the sum of call and put
                            Parallel.ForEach(Ienum.Step(0, TrailNum, 1), new ParallelOptions {
                                MaxDegreeOfParallelism = Thread1
                            }, a =>
                            {
                                StdCallSum = StdCallSum + Math.Pow((Math.Max(sims[a, StepNum - 1] - K, 0) - x), 2);
                                StdPutSum  = StdPutSum + Math.Pow((Math.Max(K - sims[a, StepNum - 1], 0) - y), 2);
                            });
                        }
                        else
                        {
                            for (int p = 0; p < TrailNum; p++)
                            {
                                sims[p, 0] = SO;
                            }
                            //this loop is used for restoring the simulation result
                            for (int i = 0; i < TrailNum; i++)
                            {
                                for (int j = 1; j < StepNum; j++)
                                {
                                    sims[i, j] = sims[i, j - 1] * Math.Exp((r - 0.5 * Math.Pow(sigma, 2)) * (t / (StepNum - 1)) + sigma * Math.Pow((t / (StepNum - 1)), 0.5) * Randoms[i, j]);
                                }
                            }
                            for (int a = 0; a < TrailNum; a++)
                            {
                                SumCall += Math.Max(sims[a, StepNum - 1] - K, 0);
                                SumPut  += Math.Max(K - sims[a, StepNum - 1], 0);
                            }

                            x = (SumCall / TrailNum) * Math.Exp(-r * t);
                            y = (SumPut / TrailNum) * Math.Exp(-r * t);
                            //calculate the sum of call and put
                            for (int q = 0; q < TrailNum; q++)
                            {
                                StdCallSum = StdCallSum + Math.Pow((Math.Max(sims[q, StepNum - 1] - K, 0) - x), 2);
                                StdPutSum  = StdPutSum + Math.Pow((Math.Max(K - sims[q, StepNum - 1], 0) - y), 2);
                            }
                        }

                        //calculate the StdError
                        StdCallEr = Math.Sqrt((1.0 / (TrailNum - 1)) * StdCallSum) / Math.Sqrt(TrailNum);
                        StdPutEr  = Math.Sqrt((1.0 / (TrailNum - 1)) * StdPutSum) / Math.Sqrt(TrailNum);
                    }
                    Result[0] = x;
                    Result[1] = y;
                    Result[2] = StdCallEr;
                    Result[3] = StdPutEr;
                }
                return(Result);
            }