/// <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); }
/// <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); }
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; }
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>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; }