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