static void Main(string[] args) { DateTime timer = DateTime.Now; Date todaysDate = new Date(15, 2, 2002); Calendar calendar = new TARGET(); Date settlementDate = new Date(19, 2, 2002); Settings.setEvaluationDate(todaysDate); // flat yield term structure impling 1x5 swap at 5% Quote flatRate = new SimpleQuote(0.04875825); Handle<YieldTermStructure> rhTermStructure = new Handle<YieldTermStructure>( new FlatForward(settlementDate, new Handle<Quote>(flatRate), new Actual365Fixed())); // Define the ATM/OTM/ITM swaps Frequency fixedLegFrequency = Frequency.Annual; BusinessDayConvention fixedLegConvention = BusinessDayConvention.Unadjusted; BusinessDayConvention floatingLegConvention = BusinessDayConvention.ModifiedFollowing; DayCounter fixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European); Frequency floatingLegFrequency = Frequency.Semiannual; VanillaSwap.Type type = VanillaSwap.Type.Payer; double dummyFixedRate = 0.03; IborIndex indexSixMonths = new Euribor6M(rhTermStructure); Date startDate = calendar.advance(settlementDate, 1, TimeUnit.Years, floatingLegConvention); Date maturity = calendar.advance(startDate, 5, TimeUnit.Years, floatingLegConvention); Schedule fixedSchedule = new Schedule(startDate, maturity, new Period(fixedLegFrequency), calendar, fixedLegConvention, fixedLegConvention, DateGeneration.Rule.Forward, false); Schedule floatSchedule = new Schedule(startDate, maturity, new Period(floatingLegFrequency), calendar, floatingLegConvention, floatingLegConvention, DateGeneration.Rule.Forward, false); VanillaSwap swap = new VanillaSwap( type, 1000.0, fixedSchedule, dummyFixedRate, fixedLegDayCounter, floatSchedule, indexSixMonths, 0.0, indexSixMonths.dayCounter()); swap.setPricingEngine(new DiscountingSwapEngine(rhTermStructure)); double fixedAtmRate = swap.fairRate(); double fixedOtmRate = fixedAtmRate * 1.2; double fixedItmRate = fixedAtmRate * 0.8; VanillaSwap atmSwap = new VanillaSwap( type, 1000.0, fixedSchedule, fixedAtmRate, fixedLegDayCounter, floatSchedule, indexSixMonths, 0.0, indexSixMonths.dayCounter()); VanillaSwap otmSwap = new VanillaSwap( type, 1000.0, fixedSchedule, fixedOtmRate, fixedLegDayCounter, floatSchedule, indexSixMonths, 0.0, indexSixMonths.dayCounter()); VanillaSwap itmSwap = new VanillaSwap( type, 1000.0, fixedSchedule, fixedItmRate, fixedLegDayCounter, floatSchedule, indexSixMonths, 0.0, indexSixMonths.dayCounter()); // defining the swaptions to be used in model calibration List<Period> swaptionMaturities = new List<Period>(5); swaptionMaturities.Add(new Period(1, TimeUnit.Years)); swaptionMaturities.Add(new Period(2, TimeUnit.Years)); swaptionMaturities.Add(new Period(3, TimeUnit.Years)); swaptionMaturities.Add(new Period(4, TimeUnit.Years)); swaptionMaturities.Add(new Period(5, TimeUnit.Years)); List<CalibrationHelper> swaptions = new List<CalibrationHelper>(); // List of times that have to be included in the timegrid List<double> times = new List<double>(); for (int i = 0; i < NumRows; i++) { int j = NumCols - i - 1; // 1x5, 2x4, 3x3, 4x2, 5x1 int k = i * NumCols + j; Quote vol = new SimpleQuote(SwaptionVols[k]); swaptions.Add(new SwaptionHelper(swaptionMaturities[i], new Period(SwapLenghts[j], TimeUnit.Years), new Handle<Quote>(vol), indexSixMonths, indexSixMonths.tenor(), indexSixMonths.dayCounter(), indexSixMonths.dayCounter(), rhTermStructure, false)); swaptions.Last().addTimesTo(times); } // Building time-grid TimeGrid grid = new TimeGrid(times, 30); // defining the models G2 modelG2 = new G2(rhTermStructure); HullWhite modelHw = new HullWhite(rhTermStructure); HullWhite modelHw2 = new HullWhite(rhTermStructure); BlackKarasinski modelBk = new BlackKarasinski(rhTermStructure); // model calibrations Console.WriteLine("G2 (analytic formulae) calibration"); for (int i = 0; i < swaptions.Count; i++) swaptions[i].setPricingEngine(new G2SwaptionEngine(modelG2, 6.0, 16)); CalibrateModel(modelG2, swaptions); Console.WriteLine("calibrated to:\n" + "a = {0:0.000000}, " + "sigma = {1:0.0000000}\n" + "b = {2:0.000000}, " + "eta = {3:0.0000000}\n" + "rho = {4:0.00000}\n", modelG2.parameters()[0], modelG2.parameters()[1], modelG2.parameters()[2], modelG2.parameters()[3], modelG2.parameters()[4]); Console.WriteLine("Hull-White (analytic formulae) calibration"); for (int i = 0; i < swaptions.Count; i++) swaptions[i].setPricingEngine(new JamshidianSwaptionEngine(modelHw)); CalibrateModel(modelHw, swaptions); Console.WriteLine("calibrated to:\n" + "a = {0:0.000000}, " + "sigma = {1:0.0000000}\n", modelHw.parameters()[0], modelHw.parameters()[1]); Console.WriteLine("Hull-White (numerical) calibration"); for (int i = 0; i < swaptions.Count(); i++) swaptions[i].setPricingEngine(new TreeSwaptionEngine(modelHw2, grid)); CalibrateModel(modelHw2, swaptions); Console.WriteLine("calibrated to:\n" + "a = {0:0.000000}, " + "sigma = {1:0.0000000}\n", modelHw2.parameters()[0], modelHw2.parameters()[1]); Console.WriteLine("Black-Karasinski (numerical) calibration"); for (int i = 0; i < swaptions.Count; i++) swaptions[i].setPricingEngine(new TreeSwaptionEngine(modelBk, grid)); CalibrateModel(modelBk, swaptions); Console.WriteLine("calibrated to:\n" + "a = {0:0.000000}, " + "sigma = {1:0.00000}\n", modelBk.parameters()[0], modelBk.parameters()[1]); // ATM Bermudan swaption pricing Console.WriteLine("Payer bermudan swaption " + "struck at {0:0.00000 %} (ATM)", fixedAtmRate); List<Date> bermudanDates = new List<Date>(); List<CashFlow> leg = swap.fixedLeg(); for (int i = 0; i < leg.Count; i++) { Coupon coupon = (Coupon)leg[i]; bermudanDates.Add(coupon.accrualStartDate()); } Exercise bermudanExercise = new BermudanExercise(bermudanDates); Swaption bermudanSwaption = new Swaption(atmSwap, bermudanExercise); // Do the pricing for each model // G2 price the European swaption here, it should switch to bermudan bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelG2, 50)); Console.WriteLine("G2: {0:0.00}", bermudanSwaption.NPV()); bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw, 50)); Console.WriteLine("HW: {0:0.000}", bermudanSwaption.NPV()); bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw2, 50)); Console.WriteLine("HW (num): {0:0.000}", bermudanSwaption.NPV()); bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelBk, 50)); Console.WriteLine("BK: {0:0.000}", bermudanSwaption.NPV()); // OTM Bermudan swaption pricing Console.WriteLine("Payer bermudan swaption " + "struck at {0:0.00000 %} (OTM)", fixedOtmRate); Swaption otmBermudanSwaption = new Swaption(otmSwap, bermudanExercise); // Do the pricing for each model otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelG2, 50)); Console.WriteLine("G2: {0:0.0000}", otmBermudanSwaption.NPV()); otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw, 50)); Console.WriteLine("HW: {0:0.0000}", otmBermudanSwaption.NPV()); otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw2, 50)); Console.WriteLine("HW (num): {0:0.000}", otmBermudanSwaption.NPV()); otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelBk, 50)); Console.WriteLine("BK: {0:0.0000}", otmBermudanSwaption.NPV()); // ITM Bermudan swaption pricing Console.WriteLine("Payer bermudan swaption " + "struck at {0:0.00000 %} (ITM)", fixedItmRate); Swaption itmBermudanSwaption = new Swaption(itmSwap, bermudanExercise); // Do the pricing for each model itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelG2, 50)); Console.WriteLine("G2: {0:0.000}", itmBermudanSwaption.NPV()); itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw, 50)); Console.WriteLine("HW: {0:0.000}", itmBermudanSwaption.NPV()); itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw2, 50)); Console.WriteLine("HW (num): {0:0.000}", itmBermudanSwaption.NPV()); itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelBk, 50)); Console.WriteLine("BK: {0:0.000}", itmBermudanSwaption.NPV()); Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer); Console.WriteLine(); Console.Write("Press any key to continue ..."); Console.ReadKey(); }
public void testCachedValues() { //("Testing Bermudan swaption against cached values..."); CommonVars vars = new CommonVars(); vars.today = new Date(15, Month.February, 2002); Settings.setEvaluationDate(vars.today); vars.settlement = new Date(19, Month.February, 2002); // flat yield term structure impling 1x5 swap at 5% vars.termStructure.linkTo(Utilities.flatRate(vars.settlement, 0.04875825, new Actual365Fixed())); double atmRate = vars.makeSwap(0.0).fairRate(); VanillaSwap itmSwap = vars.makeSwap(0.8*atmRate); VanillaSwap atmSwap = vars.makeSwap(atmRate); VanillaSwap otmSwap = vars.makeSwap(1.2*atmRate); double a = 0.048696, sigma = 0.0058904; ShortRateModel model=new HullWhite(vars.termStructure,a, sigma); List<Date> exerciseDates= new List<Date>(); List<CashFlow> leg = atmSwap.fixedLeg(); for (int i=0; i<leg.Count; i++) { Coupon coupon = (Coupon)(leg[i]); exerciseDates.Add(coupon.accrualStartDate()); } Exercise exercise = new BermudanExercise(exerciseDates); IPricingEngine engine = new TreeSwaptionEngine(model, 50); #if QL_USE_INDEXED_COUPON Real itmValue = 42.2413, atmValue = 12.8789, otmValue = 2.4759; #else double itmValue = 42.2470, atmValue = 12.8826, otmValue = 2.4769; #endif double tolerance = 1.0e-4; Swaption swaption = new Swaption(itmSwap, exercise); swaption.setPricingEngine(engine); if (Math.Abs(swaption.NPV()-itmValue) > tolerance) Assert.Fail("failed to reproduce cached in-the-money swaption value:\n" + "calculated: " + swaption.NPV() + "\n" + "expected: " + itmValue); swaption = new Swaption(atmSwap, exercise); swaption.setPricingEngine(engine); if (Math.Abs(swaption.NPV()-atmValue) > tolerance) Assert.Fail("failed to reproduce cached at-the-money swaption value:\n" + "calculated: " + swaption.NPV() + "\n" + "expected: " + atmValue); swaption = new Swaption(otmSwap, exercise); swaption.setPricingEngine(engine); if (Math.Abs(swaption.NPV()-otmValue) > tolerance) Assert.Fail("failed to reproduce cached out-of-the-money " + "swaption value:\n" + "calculated: " + swaption.NPV() + "\n" + "expected: " + otmValue); for (int j=0; j<exerciseDates.Count; j++) exerciseDates[j] = vars.calendar.adjust(exerciseDates[j]-10); exercise = new BermudanExercise(exerciseDates); #if QL_USE_INDEXED_COUPON itmValue = 42.1917; atmValue = 12.7788; otmValue = 2.4388; #else itmValue = 42.1974; atmValue = 12.7825; otmValue = 2.4399; #endif swaption = new Swaption(itmSwap, exercise); swaption.setPricingEngine(engine); if (Math.Abs(swaption.NPV()-itmValue) > tolerance) Assert.Fail("failed to reproduce cached in-the-money swaption value:\n" + "calculated: " + swaption.NPV() + "\n" + "expected: " + itmValue); swaption = new Swaption(atmSwap, exercise); swaption.setPricingEngine(engine); if (Math.Abs(swaption.NPV()-atmValue) > tolerance) Assert.Fail("failed to reproduce cached at-the-money swaption value:\n" + "calculated: " + swaption.NPV() + "\n" + "expected: " + atmValue); swaption = new Swaption(otmSwap, exercise); swaption.setPricingEngine(engine); if (Math.Abs(swaption.NPV()-otmValue) > tolerance) Assert.Fail("failed to reproduce cached out-of-the-money " + "swaption value:\n" + "calculated: " + swaption.NPV() + "\n" + "expected: " + otmValue); }
//static void Main(string[] args) //{ // List<double> xGrid = Enumerable.Range(0, 100).Select(x => x / 10.0).ToList(); // List<double> yGrid = Enumerable.Range(0, 100).Select(x => x / 10.0).ToList(); // //List<double> xGrid = Enumerable.Range(0, 100); // CubicInterpolation cubic = new CubicInterpolation(xGrid, xGrid.Count, yGrid, // CubicInterpolation.DerivativeApprox.Kruger, true, // CubicInterpolation.BoundaryCondition.SecondDerivative , 0.0, // CubicInterpolation.BoundaryCondition.SecondDerivative , 0.0); //} static void Main(string[] args) { DateTime timer = DateTime.Now; // set up dates Calendar calendar = new TARGET(); Date todaysDate = new Date(15, Month.May, 1998); Date settlementDate = new Date(17, Month.May, 1998); Settings.setEvaluationDate(todaysDate); // our options Option.Type type = Option.Type.Put; double underlying = 36; double strike = 40; double dividendYield = 0.00; double riskFreeRate = 0.06; double volatility = 0.20; Date maturity = new Date(17, Month.May, 1999); DayCounter dayCounter = new Actual365Fixed(); Console.WriteLine("Option type = " + type); Console.WriteLine("Maturity = " + maturity); Console.WriteLine("Underlying price = " + underlying); Console.WriteLine("Strike = " + strike); Console.WriteLine("Risk-free interest rate = {0:0.000000%}", riskFreeRate); Console.WriteLine("Dividend yield = {0:0.000000%}", dividendYield); Console.WriteLine("Volatility = {0:0.000000%}", volatility); Console.Write("\n"); string method; Console.Write("\n"); // write column headings int[] widths = new int[] { 35, 14, 14, 14 }; Console.Write("{0,-" + widths[0] + "}", "Method"); Console.Write("{0,-" + widths[1] + "}", "European"); Console.Write("{0,-" + widths[2] + "}", "Bermudan"); Console.WriteLine("{0,-" + widths[3] + "}", "American"); List<Date> exerciseDates = new List<Date>(); ; for (int i = 1; i <= 4; i++) exerciseDates.Add(settlementDate + new Period(3 * i, TimeUnit.Months)); Exercise europeanExercise = new EuropeanExercise(maturity); Exercise bermudanExercise = new BermudanExercise(exerciseDates); Exercise americanExercise = new AmericanExercise(settlementDate, maturity); Handle<Quote> underlyingH = new Handle<Quote>(new SimpleQuote(underlying)); // bootstrap the yield/dividend/vol curves var flatTermStructure = new Handle<YieldTermStructure>(new FlatForward(settlementDate, riskFreeRate, dayCounter)); var flatDividendTS = new Handle<YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter)); var flatVolTS = new Handle<BlackVolTermStructure>(new BlackConstantVol(settlementDate, calendar, volatility, dayCounter)); StrikedTypePayoff payoff = new PlainVanillaPayoff(type, strike); var bsmProcess = new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS); // options VanillaOption europeanOption = new VanillaOption(payoff, europeanExercise); VanillaOption bermudanOption = new VanillaOption(payoff, bermudanExercise); VanillaOption americanOption = new VanillaOption(payoff, americanExercise); // Analytic formulas: // Black-Scholes for European method = "Black-Scholes"; europeanOption.setPricingEngine(new AnalyticEuropeanEngine(bsmProcess)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + "}", "N/A"); Console.WriteLine("{0,-" + widths[3] + "}", "N/A"); europeanOption.theta(); // Barone-Adesi and Whaley approximation for American method = "Barone-Adesi/Whaley"; americanOption.setPricingEngine(new BaroneAdesiWhaleyApproximationEngine(bsmProcess)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + "}", "N/A"); Console.Write("{0,-" + widths[2] + "}", "N/A"); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); // Bjerksund and Stensland approximation for American method = "Bjerksund/Stensland"; americanOption.setPricingEngine(new BjerksundStenslandApproximationEngine(bsmProcess)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + "}", "N/A"); Console.Write("{0,-" + widths[2] + "}", "N/A"); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); // Integral method = "Integral"; europeanOption.setPricingEngine(new IntegralEngine(bsmProcess)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + "}", "N/A"); Console.WriteLine("{0,-" + widths[3] + "}", "N/A"); // Finite differences int timeSteps = 801; method = "Finite differences"; europeanOption.setPricingEngine(new FDEuropeanEngine(bsmProcess, timeSteps, timeSteps - 1)); bermudanOption.setPricingEngine(new FDBermudanEngine(bsmProcess, timeSteps, timeSteps - 1)); americanOption.setPricingEngine(new FDAmericanEngine(bsmProcess, timeSteps, timeSteps - 1)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); // Binomial method: Jarrow-Rudd method = "Binomial Jarrow-Rudd"; europeanOption.setPricingEngine(new BinomialVanillaEngine<JarrowRudd>(bsmProcess, timeSteps)); bermudanOption.setPricingEngine(new BinomialVanillaEngine<JarrowRudd>(bsmProcess, timeSteps)); americanOption.setPricingEngine(new BinomialVanillaEngine<JarrowRudd>(bsmProcess, timeSteps)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); method = "Binomial Cox-Ross-Rubinstein"; europeanOption.setPricingEngine(new BinomialVanillaEngine<CoxRossRubinstein>(bsmProcess, timeSteps)); bermudanOption.setPricingEngine(new BinomialVanillaEngine<CoxRossRubinstein>(bsmProcess, timeSteps)); americanOption.setPricingEngine(new BinomialVanillaEngine<CoxRossRubinstein>(bsmProcess, timeSteps)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); // Binomial method: Additive equiprobabilities method = "Additive equiprobabilities"; europeanOption.setPricingEngine(new BinomialVanillaEngine<AdditiveEQPBinomialTree>(bsmProcess, timeSteps)); bermudanOption.setPricingEngine(new BinomialVanillaEngine<AdditiveEQPBinomialTree>(bsmProcess, timeSteps)); americanOption.setPricingEngine(new BinomialVanillaEngine<AdditiveEQPBinomialTree>(bsmProcess, timeSteps)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); // Binomial method: Binomial Trigeorgis method = "Binomial Trigeorgis"; europeanOption.setPricingEngine(new BinomialVanillaEngine<Trigeorgis>(bsmProcess, timeSteps)); bermudanOption.setPricingEngine(new BinomialVanillaEngine<Trigeorgis>(bsmProcess, timeSteps)); americanOption.setPricingEngine(new BinomialVanillaEngine<Trigeorgis>(bsmProcess, timeSteps)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); // Binomial method: Binomial Tian method = "Binomial Tian"; europeanOption.setPricingEngine(new BinomialVanillaEngine<Tian>(bsmProcess, timeSteps)); bermudanOption.setPricingEngine(new BinomialVanillaEngine<Tian>(bsmProcess, timeSteps)); americanOption.setPricingEngine(new BinomialVanillaEngine<Tian>(bsmProcess, timeSteps)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); // Binomial method: Binomial Leisen-Reimer method = "Binomial Leisen-Reimer"; europeanOption.setPricingEngine(new BinomialVanillaEngine<LeisenReimer>(bsmProcess, timeSteps)); bermudanOption.setPricingEngine(new BinomialVanillaEngine<LeisenReimer>(bsmProcess, timeSteps)); americanOption.setPricingEngine(new BinomialVanillaEngine<LeisenReimer>(bsmProcess, timeSteps)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); // Binomial method: Binomial Joshi method = "Binomial Joshi"; europeanOption.setPricingEngine(new BinomialVanillaEngine<Joshi4>(bsmProcess, timeSteps)); bermudanOption.setPricingEngine(new BinomialVanillaEngine<Joshi4>(bsmProcess, timeSteps)); americanOption.setPricingEngine(new BinomialVanillaEngine<Joshi4>(bsmProcess, timeSteps)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); // Monte Carlo Method: MC (crude) timeSteps = 1; method = "MC (crude)"; ulong mcSeed = 42; IPricingEngine mcengine1 = new MakeMCEuropeanEngine<PseudoRandom>(bsmProcess) .withSteps(timeSteps) .withAbsoluteTolerance(0.02) .withSeed(mcSeed) .value(); europeanOption.setPricingEngine(mcengine1); // Real errorEstimate = europeanOption.errorEstimate(); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + ":0.000000}", "N/A"); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", "N/A"); // Monte Carlo Method: QMC (Sobol) method = "QMC (Sobol)"; int nSamples = 32768; // 2^15 IPricingEngine mcengine2 = new MakeMCEuropeanEngine<LowDiscrepancy>(bsmProcess) .withSteps(timeSteps) .withSamples(nSamples) .value(); europeanOption.setPricingEngine(mcengine2); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + ":0.000000}", "N/A"); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", "N/A"); // Monte Carlo Method: MC (Longstaff Schwartz) method = "MC (Longstaff Schwartz)"; IPricingEngine mcengine3 = new MakeMCAmericanEngine<PseudoRandom>(bsmProcess) .withSteps(100) .withAntitheticVariate() .withCalibrationSamples(4096) .withAbsoluteTolerance(0.02) .withSeed(mcSeed) .value(); americanOption.setPricingEngine(mcengine3); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", "N/A"); Console.Write("{0,-" + widths[2] + ":0.000000}", "N/A"); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); // End test Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer); Console.WriteLine(); Console.Write("Press any key to continue ..."); Console.ReadKey(); }