/// <summary>
        /// override the <method>DipathByAntitheticMethod</method>.
        /// For Black Scholes model, mu and sigma is constant, and only one random
        /// variate is needed to generate the state for next point
        /// </summary>

        public double[][] DipathByAntitheticMethod(StochasticAssetPrice S, GaussianGenerator nrandom,
                                                   double totalTime, int timeSteps, bool visualizationFlag = false, Form1 form = null)
        {
            double[][] pricePath = new double[2][];
            pricePath[0] = new double[timeSteps + 1];
            pricePath[1] = new double[timeSteps + 1];
            StochasticAssetPrice S2 = new StochasticAssetPrice(S);
            double dt = totalTime / (double)timeSteps;

            pricePath[0][0] = S.CurrentPrice;
            pricePath[1][0] = S.CurrentPrice;
            for (int i = 1; i <= timeSteps; i++)
            {
                double z  = nrandom.NextGaussian();
                double z2 = -z;
                pricePath[0][i] = GetNextPrice(S, dt, z);
                pricePath[1][i] = GetNextPrice(S2, dt, z2);
            }
            if (visualizationFlag & form != null)
            {
                double[] X = new double[timeSteps + 1];
                for (int i = 0; i <= timeSteps; i++)
                {
                    X[i] = i;
                }
                form.add(X, pricePath[0], "");
                form.add(X, pricePath[1], "");
            }
            return(pricePath);
        }
        /// <summary>
        /// Override the <method>GetNextPrice</method> based on Euler Scheme
        /// The StochasticAssetPrice object is updated in this method
        /// </summary>
        /// <returns> a double type value for the price of next stage</returns>

        public override double GetNextPrice(StochasticAssetPrice S, double dt, params double[] Z)
        {
            double nextPrice = S.CurrentPrice + S.Mu * S.CurrentPrice * dt
                               + S.Sigma * S.CurrentPrice * Z[0] * Math.Sqrt(dt);

            S.CurrentPrice = nextPrice;
            return(nextPrice);
        }
Example #3
0
        /// <summary>
        /// Override the <method>GetNextPrice</method> based on Discretization Scheme
        /// for log price and Ito's lemma
        /// The StochasticAssetPrice object is updated in this method
        /// </summary>
        /// <returns> a double type value for the price of next stage</returns>

        public override double GetNextPrice(StochasticAssetPrice S, double dt, params double[] Z)
        {
            double nextPrice = S.CurrentPrice * Math.Exp((S.Mu - 0.5 * Math.Pow(S.Sigma, 2.0)) * dt
                                                         + S.Sigma * Z[0] * Math.Sqrt(dt));

            S.CurrentPrice = nextPrice;
            return(nextPrice);
        }
Example #4
0
        static void Main(string[] args)
        {
            //input needed information from keyboard
            Console.WriteLine("Input spot price of underlying asset:");
            double spotPrice = Convert.ToDouble(Console.ReadLine());
            int    oType;

            do
            {
                Console.WriteLine("Input European option type (0 for call, 1 for put):");
                oType = Convert.ToInt32(Console.ReadLine());
            }while (oType != 0 & oType != 1);
            OptionType optionType = (oType == 0 ? OptionType.Call : OptionType.Put);

            Console.WriteLine("Input option strike price:");
            double strikePrice = Convert.ToDouble(Console.ReadLine());

            Console.WriteLine("Input time to maturity of this option:");
            double timeToMaturity = Convert.ToDouble(Console.ReadLine());

            Console.WriteLine("Input drift parameter for brownian motion:");
            double Mu = Convert.ToDouble(Console.ReadLine());

            Console.WriteLine("Input volatility parameter for brownian motion:");
            double sigma = Convert.ToDouble(Console.ReadLine());

            Console.WriteLine("Input number of scenarios generated by MC simulation:");
            int numOfScenarios = Convert.ToInt32(Console.ReadLine());

            Console.WriteLine("Input number of time steps for Euler discretization:");
            int timeSteps = Convert.ToInt32(Console.ReadLine());

            Console.WriteLine("Input whether to use antithetic variance reduction technique " +
                              "(true for yes,false for no): ");
            bool                  antithetic = Convert.ToBoolean(Console.ReadLine());
            EuropeanOption        Option     = new EuropeanOption(timeToMaturity, strikePrice, optionType);
            EulerSchemeForBSModel Euler      = new EulerSchemeForBSModel();
            StochasticAssetPrice  Asset      = new StochasticAssetPrice(Mu, sigma, spotPrice);

            if (antithetic)
            {
                double[] s1 = Option.PricingByMCSim(Asset, Euler, numOfScenarios, timeSteps,
                                                    true);
                Console.WriteLine("Option price estimated by Monte Carlo Simulation and " +
                                  "antithetic variance reduction is:\n {0:#0.00} \n Standard error is:\n {1:#0.000} ",
                                  s1[0], s1[1]);
            }
            else
            {
                double[] s2 = Option.PricingByMCSim(Asset, Euler, numOfScenarios, timeSteps, false);
                Console.WriteLine("Option price estimated by Monte Carlo Simulation is:\n {0:#0.00} \n" +
                                  "Standard error is:\n {1:#0.000} ", s2[0], s2[1]);
            }
            Console.ReadLine();
        }
        /// <summary>
        /// override the <method>GeneratingRandomPricePath</method>.
        /// For Black Scholes model, mu and sigma is constant, and only one random
        /// variate is needed to generate the state for next point.
        /// </summary>

        public double[] GeneratingRandomPricePath(StochasticAssetPrice S, GaussianGenerator nrandom,
                                                  double totalTime, int timeSteps)
        {
            double[] pricePath = new double[timeSteps + 1];
            double   dt        = totalTime / (double)timeSteps;

            pricePath[0] = S.CurrentPrice;
            for (int i = 1; i <= timeSteps; i++)
            {
                double z = nrandom.NextGaussian();
                pricePath[i] = GetNextPrice(S, dt, z);
            }
            return(pricePath);
        }
        /// <summary>
        /// override the <method>PricingByMCSim</method>
        /// In each scenario, a price path is generated and the option value under
        /// this scenario is only decided by the final price. So, we take the average
        /// for the 'value at maturity' of all the simulated scenarios and
        /// discounted as the approximation for the option value.
        /// This method also outputs the standard error for the approximation.
        /// </summary>

        public override double[] PricingByMCSim(StochasticAssetPrice S, IDiscretizationScheme D, int numOfScenarios,
                                                int timeSteps, bool antitheticFlag)
        {
            double[]          Result   = new double[2];              //record the approximated price and standard error
            double[]          Sample   = new double[numOfScenarios]; //record value at maturity for each scenario
            double            sumValue = 0.0;                        //record cumulative sum of Sample array
            GaussianGenerator nrand    = new GaussianGenerator();

            if (antitheticFlag)
            {
                //when antithetic variance reduction technique is used
                for (int i = 0; i < numOfScenarios; i++)
                {
                    StochasticAssetPrice S1 = new StochasticAssetPrice(S);
                    double[][]           PricePath;
                    PricePath = D.DipathByAntitheticMethod(S1, nrand, T, timeSteps);
                    Sample[i] = (ValueAtMaturity(PricePath[0][timeSteps])
                                 + ValueAtMaturity(PricePath[1][timeSteps])) / 2.0;
                    sumValue += Sample[i];
                }
            }
            else
            {
                //when antithetic variance reduction technique is not used
                for (int i = 0; i < numOfScenarios; i++)
                {
                    StochasticAssetPrice S1 = new StochasticAssetPrice(S);
                    double[]             PricePath;
                    PricePath = D.GeneratingRandomPricePath(S1, nrand, T, timeSteps);
                    Sample[i] = ValueAtMaturity(PricePath[timeSteps]);
                    sumValue += Sample[i];
                }
            }
            double disFactor = Math.Exp(-S.Mu * T);             //discount factor to convert value at maturity to current

            Result[0] = sumValue / (double)numOfScenarios * disFactor;
            double totalVariance = 0.0;

            for (int i = 0; i < numOfScenarios; i++)
            {
                totalVariance += Math.Pow(Sample[i] - Result[0], 2.0);
            }
            if (numOfScenarios > 1)
            {
                double std = Math.Sqrt(totalVariance / (numOfScenarios - 1));
                Result[1] = std / Math.Sqrt(numOfScenarios) * disFactor;
            }
            return(Result);
        }
 /// <summary>
 /// override the <method>DipathByAntitheticMethod</method>.
 /// For Black Scholes model, mu and sigma is constant, and only one random
 /// variate is needed to generate the state for next point
 /// </summary>
 public double[][] DipathByAntitheticMethod(StochasticAssetPrice S, GaussianGenerator nrandom,
     double totalTime, int timeSteps)
 {
     double[][] pricePath = new double[2][];
     pricePath[0] = new double[timeSteps + 1];
     pricePath[1] = new double[timeSteps + 1];
     StochasticAssetPrice S2 = new StochasticAssetPrice(S);
     double dt = totalTime / (double)timeSteps;
     pricePath[0][0] = S.CurrentPrice;
     pricePath[1][0] = S.CurrentPrice;
     for (int i = 1; i <= timeSteps; i++)
     {
         double z = nrandom.NextGaussian();
         double z2 = -z;
         pricePath[0][i] = GetNextPrice(S, dt, z);
         pricePath[1][i] = GetNextPrice(S2, dt, z2);
     }
     return pricePath;
 }
        /// <summary>
        /// override the <method>DipathByAntitheticMethod</method>.
        /// For Black Scholes model, mu and sigma is constant, and only one random
        /// variate is needed to generate the state for next point
        /// </summary>

        public double[][] DipathByAntitheticMethod(StochasticAssetPrice S, GaussianGenerator nrandom,
                                                   double totalTime, int timeSteps)
        {
            double[][] pricePath = new double[2][];
            pricePath[0] = new double[timeSteps + 1];
            pricePath[1] = new double[timeSteps + 1];
            StochasticAssetPrice S2 = new StochasticAssetPrice(S);
            double dt = totalTime / (double)timeSteps;

            pricePath[0][0] = S.CurrentPrice;
            pricePath[1][0] = S.CurrentPrice;
            for (int i = 1; i <= timeSteps; i++)
            {
                double z  = nrandom.NextGaussian();
                double z2 = -z;
                pricePath[0][i] = GetNextPrice(S, dt, z);
                pricePath[1][i] = GetNextPrice(S2, dt, z2);
            }
            return(pricePath);
        }
        /// <summary>
        /// override the <method>GeneratingRandomPricePath</method>.
        /// For Black Scholes model, mu and sigma is constant, and only one random
        /// variate is needed to generate the state for next point.
        /// </summary>

        public double[] GeneratingRandomPricePath(StochasticAssetPrice S, GaussianGenerator nrandom,
                                                  double totalTime, int timeSteps, bool visualizationFlag = false, Form1 form = null)
        {
            double[] pricePath = new double[timeSteps + 1];
            double   dt        = totalTime / (double)timeSteps;

            pricePath[0] = S.CurrentPrice;
            for (int i = 1; i <= timeSteps; i++)
            {
                double z = nrandom.NextGaussian();
                pricePath[i] = GetNextPrice(S, dt, z);
            }
            if (visualizationFlag & form != null)
            {
                double[] X = new double[timeSteps + 1];
                for (int i = 0; i <= timeSteps; i++)
                {
                    X[i] = i;
                }
                form.add(X, pricePath, "");
            }
            return(pricePath);
        }
 /// <summary>
 /// This method gives the estimated the option value 
 /// and the estimation standard error using MC simulation
 /// </summary>
 /// <param name="S"> describes the Brownian motion rule of the underlying asset</param>
 /// <param name="D"> chooses the discretization scheme </param>
 /// <param name="numberOfScenarios">decides the number of random paths to be generated</param>
 /// <param name="timeSteps"> decides the number of intervals for discretization scheme </param>
 /// <param name="antitheticFlag"> chooses whether to use antithetic variance reduction techniques</param>
 /// <param name="visualizationFlag"> chooses whether to generate 
 /// the asset price chart for MC simulation</param>
 /// <param name="form"> defines the window to display the graph</param>
 /// <returns> a 2 elements array. The first one gives the estimated option price, 
 /// the second gives the estimation error</returns>
 public abstract double[] PricingByMCSim(StochasticAssetPrice S, IDiscretizationScheme D,
     int numberOfScenarios, int timeSteps, bool antitheticFlag, bool visualizationFlag, Form1 form = null);
 /// <summary>
 /// Override the <method>GetNextPrice</method> based on Discretization Scheme
 /// for log price and Ito's lemma
 /// The StochasticAssetPrice object is updated in this method
 /// </summary>
 /// <returns> a double type value for the price of next stage</returns>
 public override double GetNextPrice(StochasticAssetPrice S, double dt, params double[] Z)
 {
     double nextPrice = S.CurrentPrice * Math.Exp((S.Mu - 0.5 * Math.Pow(S.Sigma, 2.0)) * dt
         + S.Sigma * Z[0] * Math.Sqrt(dt));
     S.CurrentPrice = nextPrice;
     return nextPrice;
 }
 public abstract double GetNextPrice(StochasticAssetPrice S, double dt, params double[] Z);
 /// Copy method
 public StochasticAssetPrice(StochasticAssetPrice S)
 {
     this.Mu           = S.Mu;
     this.sigma        = S.Sigma;
     this.currentPrice = S.CurrentPrice;
 }
        /// <summary>
        /// This method gives the estimated the option value
        /// and the estimation standard error using MC simulation
        /// </summary>
        /// <param name="S"> describes the Brownian motion rule of the underlying asset</param>
        /// <param name="D"> chooses the discretization scheme </param>
        /// <param name="numberOfScenarios">decides the number of random paths to be generated</param>
        /// <param name="timeSteps"> decides the number of intervals for discretization scheme </param>
        /// <param name="antitheticFlag"> chooses whether to use antithetic variance reduction techniques</param>
        /// <returns> a 2 elements array. The first one gives the estimated option price,
        /// the second gives the estimation error</returns>

        public abstract double[] PricingByMCSim(StochasticAssetPrice S, IDiscretizationScheme D,
                                                int numberOfScenarios, int timeSteps, bool antitheticFlag);
 /// <summary>
 /// override the <method>DipathByAntitheticMethod</method>.
 /// For Black Scholes model, mu and sigma is constant, and only one random
 /// variate is needed to generate the state for next point
 /// </summary>
 public double[][] DipathByAntitheticMethod(StochasticAssetPrice S, GaussianGenerator nrandom,
     double totalTime, int timeSteps, bool visualizationFlag = false, Form1 form = null)
 {
     double[][] pricePath = new double[2][];
     pricePath[0] = new double[timeSteps + 1];
     pricePath[1] = new double[timeSteps + 1];
     StochasticAssetPrice S2 = new StochasticAssetPrice(S);
     double dt = totalTime / (double)timeSteps;
     pricePath[0][0] = S.CurrentPrice;
     pricePath[1][0] = S.CurrentPrice;
     for (int i = 1; i <= timeSteps; i++)
     {
         double z = nrandom.NextGaussian();
         double z2 = -z;
         pricePath[0][i] = GetNextPrice(S, dt, z);
         pricePath[1][i] = GetNextPrice(S2, dt, z2);
     }
     if (visualizationFlag & form != null)
     {
         double[] X = new double[timeSteps + 1];
         for (int i = 0; i <= timeSteps; i++)
         {
             X[i] = i;
         }
         form.add(X, pricePath[0], "");
         form.add(X, pricePath[1], "");
     }
     return pricePath;
 }
 static void Main(string[] args)
 {
     //input needed information from keyboard
     Console.WriteLine("Input spot price of underlying asset:");
     double spotPrice = Convert.ToDouble(Console.ReadLine());
     int oType;
     do
     {
         Console.WriteLine("Input European option type (0 for call, 1 for put):");
         oType = Convert.ToInt32(Console.ReadLine());
     }
     while (oType != 0 & oType != 1);
     OptionType optionType = (oType == 0 ? OptionType.Call : OptionType.Put);
     Console.WriteLine("Input option strike price:");
     double strikePrice = Convert.ToDouble(Console.ReadLine());
     Console.WriteLine("Input time to maturity of this option:");
     double timeToMaturity = Convert.ToDouble(Console.ReadLine());
     Console.WriteLine("Input drift parameter for brownian motion:");
     double Mu = Convert.ToDouble(Console.ReadLine());
     Console.WriteLine("Input volatility parameter for brownian motion:");
     double sigma = Convert.ToDouble(Console.ReadLine());
     Console.WriteLine("Input number of scenarios generated by MC simulation:");
     int numOfScenarios = Convert.ToInt32(Console.ReadLine());
     Console.WriteLine("Input number of time steps for Euler discretization:");
     int timeSteps = Convert.ToInt32(Console.ReadLine());
     Console.WriteLine("Input whether to use antithetic variance reduction technique " +
         "(true for yes,false for no): ");
     bool antithetic = Convert.ToBoolean(Console.ReadLine());
     Console.WriteLine("Input whether to visualize price path (true for yes,false for no): ");
     bool visualizationFlag = Convert.ToBoolean(Console.ReadLine());
     EuropeanOption Option = new EuropeanOption(timeToMaturity, strikePrice, optionType);
     EulerSchemeForBSModel Euler = new EulerSchemeForBSModel();
     StochasticAssetPrice Asset = new StochasticAssetPrice(Mu, sigma, spotPrice);
     if (antithetic)
     {
         Form1 s1form = new Form1("MC Simulation with Antithetic Variance Reduction");
         double[] s1 = Option.PricingByMCSim(Asset, Euler, numOfScenarios, timeSteps,
             true, visualizationFlag, s1form);
         Console.WriteLine("Option price estimated by Monte Carlo Simulation and " +
             "antithetic variance reduction is:\n {0:#0.00} \n Standard error is:\n {1:#0.000} ",
             s1[0], s1[1]);
         if (visualizationFlag)
         {
             // display the graph
             Application.Run(s1form.Display());
         }
     }
     else
     {
         Form1 s2form = new Form1("MC Simulation without Antithetic Variance Reduction");
         double[] s2 = Option.PricingByMCSim(Asset, Euler, numOfScenarios, timeSteps, false,
             visualizationFlag, s2form);
         Console.WriteLine("Option price estimated by Monte Carlo Simulation is:\n {0:#0.00} \n" +
             "Standard error is:\n {1:#0.000} ", s2[0], s2[1]);
         if (visualizationFlag)
         {
             // display the graph
             Application.Run(s2form.Display());
         }
     }
     Console.ReadLine();
 }
 /// <summary>
 /// override the <method>GeneratingRandomPricePath</method>.
 /// For Black Scholes model, mu and sigma is constant, and only one random
 /// variate is needed to generate the state for next point.
 /// </summary>
 public double[] GeneratingRandomPricePath(StochasticAssetPrice S, GaussianGenerator nrandom,
     double totalTime, int timeSteps)
 {
     double[] pricePath = new double[timeSteps + 1];
     double dt = totalTime / (double)timeSteps;
     pricePath[0] = S.CurrentPrice;
     for (int i = 1; i <= timeSteps; i++)
     {
         double z = nrandom.NextGaussian();
         pricePath[i] = GetNextPrice(S, dt, z);
     }
     return pricePath;
 }
 static void Main(string[] args)
 {
     //input needed information from keyboard
     Console.WriteLine("Input spot price of underlying asset:");
     double spotPrice = Convert.ToDouble(Console.ReadLine());
     Console.WriteLine("Input option strike price:");
     double strikePrice = Convert.ToDouble(Console.ReadLine());
     Console.WriteLine("Input time to maturity of this option:");
     double timeToMaturity = Convert.ToDouble(Console.ReadLine());
     Console.WriteLine("Input drift parameter for brownian motion:");
     double Mu = Convert.ToDouble(Console.ReadLine());
     Console.WriteLine("Input volatility parameter for brownian motion:");
     double sigma = Convert.ToDouble(Console.ReadLine());
     Console.WriteLine("Input number of scenarios generated by MC simulation:");
     int numOfScenarios = Convert.ToInt32(Console.ReadLine());
     Console.WriteLine("Input number of time steps for Euler discretization:");
     int timeSteps = Convert.ToInt32(Console.ReadLine());
     Console.WriteLine("Input whether to use antithetic variance reduction technique " +
         "(true for yes,false for no): ");
     bool antithetic = Convert.ToBoolean(Console.ReadLine());
     EuropeanCallOption Option = new EuropeanCallOption(timeToMaturity, strikePrice);
     EulerSchemeForBSModel Euler = new EulerSchemeForBSModel();
     StochasticAssetPrice Asset = new StochasticAssetPrice(Mu, sigma, spotPrice);
     if (antithetic)
     {
         double[] s1 = Option.PricingByMCSim(Asset, Euler, numOfScenarios, timeSteps,
             true);
         Console.WriteLine("Option price estimated by Monte Carlo Simulation and " +
             "antithetic variance reduction is:\n {0:#0.00} \n Standard error is:\n {1:#0.000} ",
             s1[0], s1[1]);
     }
     else
     {
         double[] s2 = Option.PricingByMCSim(Asset, Euler, numOfScenarios, timeSteps, false);
         Console.WriteLine("Option price estimated by Monte Carlo Simulation is:\n {0:#0.00} \n" +
             "Standard error is:\n {1:#0.000} ", s2[0], s2[1]);
     }
     Console.ReadLine();
 }
 /// <summary>
 /// override the <method>PricingByMCSim</method>
 /// In each scenario, a price path is generated and the option value under 
 /// this scenario is only decided by the final price. So, we take the average 
 /// for the 'value at maturity' of all the simulated scenarios and 
 /// discounted as the approximation for the option value. 
 /// This method also outputs the standard error for the approximation.
 /// </summary>
 public override double[] PricingByMCSim(StochasticAssetPrice S, IDiscretizationScheme D, int numOfScenarios,
     int timeSteps, bool antitheticFlag, bool visualizationFlag = false, Form1 form = null)
 {
     double[] Result = new double[2];                     //record the approximated price and standard error
     double[] Sample = new double[numOfScenarios];        //record value at maturity for each scenario
     double sumValue = 0.0;                               //record cumulative sum of Sample array
     GaussianGenerator nrand = new GaussianGenerator();
     if (antitheticFlag)
     {
         //when antithetic variance reduction technique is used
         for (int i = 0; i < numOfScenarios; i++)
         {
             StochasticAssetPrice S1 = new StochasticAssetPrice(S);
             double[][] PricePath;
             PricePath = D.DipathByAntitheticMethod(S1, nrand, T, timeSteps, visualizationFlag, form);
             Sample[i] = (ValueAtMaturity(PricePath[0][timeSteps])
                 + ValueAtMaturity(PricePath[1][timeSteps])) / 2.0;
             sumValue += Sample[i];
         }
     }
     else
     {
         //when antithetic variance reduction technique is not used
         for (int i = 0; i < numOfScenarios; i++)
         {
             StochasticAssetPrice S1 = new StochasticAssetPrice(S);
             double[] PricePath;
             PricePath = D.GeneratingRandomPricePath(S1, nrand, T, timeSteps, visualizationFlag, form);
             Sample[i] = ValueAtMaturity(PricePath[timeSteps]);
             sumValue += Sample[i];
         }
     }
     double disFactor = Math.Exp(-S.Mu * T);             //discount factor to convert value at maturity to current
     Result[0] = sumValue / (double)numOfScenarios * disFactor;
     double totalVariance = 0.0;
     for (int i = 0; i < numOfScenarios; i++)
     {
         totalVariance += Math.Pow(Sample[i] - Result[0], 2.0);
     }
     if (numOfScenarios > 1)
     {
         double std = Math.Sqrt(totalVariance / (numOfScenarios - 1));
         Result[1] = std / Math.Sqrt(numOfScenarios) * disFactor;
     }
     return Result;
 }
Example #20
0
        static void Main(string[] args)
        {
            //input needed information from keyboard
            Console.WriteLine("Input spot price of underlying asset:");
            double spotPrice = Convert.ToDouble(Console.ReadLine());

            while (spotPrice < 0)
            {
                Console.WriteLine("price must be positive, re-enter valide price:");
                spotPrice = Convert.ToDouble(Console.ReadLine());
            }
            int oType;

            do
            {
                Console.WriteLine("Input European option type (0 for call, 1 for put):");
                oType = Convert.ToInt32(Console.ReadLine());
            }while (oType != 0 & oType != 1);
            OptionType optionType = (oType == 0 ? OptionType.Call : OptionType.Put);

            Console.WriteLine("Input option strike price:");
            double strikePrice = Convert.ToDouble(Console.ReadLine());

            Console.WriteLine("Input time to maturity of this option:");
            double timeToMaturity = Convert.ToDouble(Console.ReadLine());

            while (timeToMaturity < 0)
            {
                Console.WriteLine("time to maturity must be non-negative, re-enter valide value:");
                timeToMaturity = Convert.ToDouble(Console.ReadLine());
            }
            Console.WriteLine("Input drift parameter for brownian motion:");
            double Mu = Convert.ToDouble(Console.ReadLine());

            Console.WriteLine("Input volatility parameter for brownian motion:");
            double sigma = Convert.ToDouble(Console.ReadLine());

            while (sigma < 0)
            {
                Console.WriteLine("volatility parameter must be non-negative, re-enter valide value:");
                sigma = Convert.ToDouble(Console.ReadLine());
            }
            Console.WriteLine("Input number of scenarios generated by MC simulation:");
            int numOfScenarios = Convert.ToInt32(Console.ReadLine());

            while (numOfScenarios < 1)
            {
                Console.WriteLine("this number must be positive, re-enter valide value:");
                numOfScenarios = Convert.ToInt32(Console.ReadLine());
            }
            Console.WriteLine("Input number of time steps for discretization:");
            int timeSteps = Convert.ToInt32(Console.ReadLine());

            while (timeSteps < 1)
            {
                Console.WriteLine("this number must be positive, re-enter valide value:");
                timeSteps = Convert.ToInt32(Console.ReadLine());
            }
            Console.WriteLine("Input whether to use antithetic variance reduction technique " +
                              "(true for yes,false for no): ");
            bool antithetic = Convert.ToBoolean(Console.ReadLine());

            Console.WriteLine("Input whether to visualize price path (true for yes,false for no): ");
            bool visualizationFlag = Convert.ToBoolean(Console.ReadLine());
            int  discretizationScheme;

            do
            {
                Console.WriteLine("Input discretization scheme (0 for Euler, 1 for Milstein, 2 for log price scheme):");
                discretizationScheme = Convert.ToInt32(Console.ReadLine());
            }while (discretizationScheme < 0 | discretizationScheme > 2);
            EuropeanOption        Option = new EuropeanOption(timeToMaturity, strikePrice, optionType);
            IDiscretizationScheme scheme;

            if (discretizationScheme == 0)
            {
                scheme = (IDiscretizationScheme)(new EulerSchemeForBSModel());
            }
            else if (discretizationScheme == 1)
            {
                scheme = (IDiscretizationScheme)(new MilsteinSchemeForBSModel());
            }
            else
            {
                scheme = (IDiscretizationScheme)(new LogPriceSchemeForBSModel());
            }
            StochasticAssetPrice Asset = new StochasticAssetPrice(Mu, sigma, spotPrice);

            Form1 s1form = new Form1("MC Simulation");

            double[] s1 = Option.PricingByMCSim(Asset, scheme, numOfScenarios, timeSteps,
                                                antithetic, visualizationFlag, s1form);
            if (antithetic)
            {
                Console.WriteLine("Option price estimated by Monte Carlo Simulation and " +
                                  "antithetic variance reduction is:\n {0:#0.00} \n Standard error is:\n {1:#0.000} ",
                                  s1[0], s1[1]);
            }
            else
            {
                Console.WriteLine("Option price estimated by Monte Carlo Simulation is:\n {0:#0.00} \n" +
                                  "Standard error is:\n {1:#0.000} ", s1[0], s1[1]);
            }
            if (visualizationFlag)
            {
                // display the graph
                Application.Run(s1form.Display());
            }
            Console.ReadLine();
        }
 public abstract double GetNextPrice(StochasticAssetPrice S, double dt, params double[] Z);
 /// <summary>
 /// override the <method>GeneratingRandomPricePath</method>.
 /// For Black Scholes model, mu and sigma is constant, and only one random
 /// variate is needed to generate the state for next point.
 /// </summary>
 public double[] GeneratingRandomPricePath(StochasticAssetPrice S, GaussianGenerator nrandom,
     double totalTime, int timeSteps, bool visualizationFlag = false, Form1 form = null)
 {
     double[] pricePath = new double[timeSteps + 1];
     double dt = totalTime / (double)timeSteps;
     pricePath[0] = S.CurrentPrice;
     for (int i = 1; i <= timeSteps; i++)
     {
         double z = nrandom.NextGaussian();
         pricePath[i] = GetNextPrice(S, dt, z);
     }
     if (visualizationFlag & form != null)
     {
         double[] X = new double[timeSteps + 1];
         for (int i = 0; i <= timeSteps; i++)
         {
             X[i] = i;
         }
         form.add(X, pricePath, "");
     }
     return pricePath;
 }
        static void Main(string[] args)
        {
            //input needed information from keyboard
            Console.WriteLine("Input spot price of underlying asset:");
            double spotPrice = Convert.ToDouble(Console.ReadLine());
            while (spotPrice < 0)
            {
                Console.WriteLine("price must be positive, re-enter valide price:");
                spotPrice = Convert.ToDouble(Console.ReadLine());
            }
            int oType;
            do
            {
                Console.WriteLine("Input European option type (0 for call, 1 for put):");
                oType = Convert.ToInt32(Console.ReadLine());
            }
            while (oType != 0 & oType != 1);
            OptionType optionType = (oType == 0 ? OptionType.Call : OptionType.Put);
            Console.WriteLine("Input option strike price:");
            double strikePrice = Convert.ToDouble(Console.ReadLine());
            Console.WriteLine("Input time to maturity of this option:");
            double timeToMaturity = Convert.ToDouble(Console.ReadLine());
            while (timeToMaturity < 0)
            {
                Console.WriteLine("time to maturity must be non-negative, re-enter valide value:");
                timeToMaturity = Convert.ToDouble(Console.ReadLine());
            }
            Console.WriteLine("Input drift parameter for brownian motion:");
            double Mu = Convert.ToDouble(Console.ReadLine());
            Console.WriteLine("Input volatility parameter for brownian motion:");
            double sigma = Convert.ToDouble(Console.ReadLine());
            while (sigma < 0)
            {
                Console.WriteLine("volatility parameter must be non-negative, re-enter valide value:");
                sigma = Convert.ToDouble(Console.ReadLine());
            }
            Console.WriteLine("Input number of scenarios generated by MC simulation:");
            int numOfScenarios = Convert.ToInt32(Console.ReadLine());
            while (numOfScenarios < 1)
            {
                Console.WriteLine("this number must be positive, re-enter valide value:");
                numOfScenarios = Convert.ToInt32(Console.ReadLine());
            }
            Console.WriteLine("Input number of time steps for discretization:");
            int timeSteps = Convert.ToInt32(Console.ReadLine());
            while (timeSteps < 1)
            {
                Console.WriteLine("this number must be positive, re-enter valide value:");
                timeSteps = Convert.ToInt32(Console.ReadLine());
            }
            Console.WriteLine("Input whether to use antithetic variance reduction technique " +
                "(true for yes,false for no): ");
            bool antithetic = Convert.ToBoolean(Console.ReadLine());
            Console.WriteLine("Input whether to visualize price path (true for yes,false for no): ");
            bool visualizationFlag = Convert.ToBoolean(Console.ReadLine());
            int discretizationScheme;
            do
            {
                Console.WriteLine("Input discretization scheme (0 for Euler, 1 for Milstein, 2 for log price scheme):");
                discretizationScheme = Convert.ToInt32(Console.ReadLine());
            }
            while (discretizationScheme < 0 | discretizationScheme > 2);
            EuropeanOption Option = new EuropeanOption(timeToMaturity, strikePrice, optionType);
            IDiscretizationScheme scheme;
            if (discretizationScheme == 0)
            { scheme = (IDiscretizationScheme)(new EulerSchemeForBSModel()); }
            else if (discretizationScheme == 1)
            { scheme = (IDiscretizationScheme)(new MilsteinSchemeForBSModel()); }
            else
            { scheme = (IDiscretizationScheme)(new LogPriceSchemeForBSModel()); }
            StochasticAssetPrice Asset = new StochasticAssetPrice(Mu, sigma, spotPrice);

            Form1 s1form = new Form1("MC Simulation");
            double[] s1 = Option.PricingByMCSim(Asset, scheme, numOfScenarios, timeSteps,
                antithetic, visualizationFlag, s1form);
            if (antithetic)
            {
                Console.WriteLine("Option price estimated by Monte Carlo Simulation and " +
                    "antithetic variance reduction is:\n {0:#0.00} \n Standard error is:\n {1:#0.000} ",
                    s1[0], s1[1]);
            }
            else
            {
                Console.WriteLine("Option price estimated by Monte Carlo Simulation is:\n {0:#0.00} \n" +
                    "Standard error is:\n {1:#0.000} ", s1[0], s1[1]);
            }
            if (visualizationFlag)
            {
                // display the graph
                Application.Run(s1form.Display());
            }
            Console.ReadLine();
        }
 /// <summary>
 /// Override the <method>GetNextPrice</method> based on Euler Scheme
 /// The StochasticAssetPrice object is updated in this method
 /// </summary>
 /// <returns> a double type value for the price of next stage</returns>
 public override double GetNextPrice(StochasticAssetPrice S, double dt, params double[] Z)
 {
     double nextPrice = S.CurrentPrice +S.Mu*S.CurrentPrice*dt
         +S.Sigma*S.CurrentPrice*Z[0] * Math.Sqrt(dt);
     S.CurrentPrice = nextPrice;
     return nextPrice;
 }
 /// Copy method
 public StochasticAssetPrice(StochasticAssetPrice S)
 {
     this.Mu = S.Mu;
     this.sigma = S.Sigma;
     this.currentPrice = S.CurrentPrice;
 }