public void testFdEuropeanValues() { // Testing finite-difference dividend European option values... SavedSettings backup = new SavedSettings(); double tolerance = 1.0e-2; int gridPoints = 300; int timeSteps = 40; Option.Type[] types = { Option.Type.Call, Option.Type.Put }; double[] strikes = { 50.0, 99.5, 100.0, 100.5, 150.0 }; double[] underlyings = { 100.0 }; // Rate qRates[] = { 0.00, 0.10, 0.30 }; // Analytic dividend may not be handling q correctly double[] qRates = { 0.00 }; double[] rRates = { 0.01, 0.05, 0.15 }; int[] lengths = { 1, 2 }; double[] vols = { 0.05, 0.20, 0.40 }; DayCounter dc = new Actual360(); Date today = Date.Today; Settings.setEvaluationDate(today); SimpleQuote spot = new SimpleQuote(0.0); SimpleQuote qRate = new SimpleQuote(0.0); Handle <YieldTermStructure> qTS = new Handle <YieldTermStructure>(Utilities.flatRate(qRate, dc)); SimpleQuote rRate = new SimpleQuote(0.0); Handle <YieldTermStructure> rTS = new Handle <YieldTermStructure>(Utilities.flatRate(rRate, dc)); SimpleQuote vol = new SimpleQuote(0.0); Handle <BlackVolTermStructure> volTS = new Handle <BlackVolTermStructure>(Utilities.flatVol(vol, dc)); for (int i = 0; i < types.Length; i++) { for (int j = 0; j < strikes.Length; j++) { for (int k = 0; k < lengths.Length; k++) { Date exDate = today + new Period(lengths[k], TimeUnit.Years); Exercise exercise = new EuropeanExercise(exDate); List <Date> dividendDates = new List <Date>(); List <double> dividends = new List <double>(); for (Date d = today + new Period(3, TimeUnit.Months); d < exercise.lastDate(); d += new Period(6, TimeUnit.Months)) { dividendDates.Add(d); dividends.Add(5.0); } StrikedTypePayoff payoff = new PlainVanillaPayoff(types[i], strikes[j]); BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle <Quote>(spot), qTS, rTS, volTS); IPricingEngine engine = new FDDividendEuropeanEngine(stochProcess, timeSteps, gridPoints); IPricingEngine ref_engine = new AnalyticDividendEuropeanEngine(stochProcess); DividendVanillaOption option = new DividendVanillaOption(payoff, exercise, dividendDates, dividends); option.setPricingEngine(engine); DividendVanillaOption ref_option = new DividendVanillaOption(payoff, exercise, dividendDates, dividends); ref_option.setPricingEngine(ref_engine); for (int l = 0; l < underlyings.Length; l++) { for (int m = 0; m < qRates.Length; m++) { for (int n = 0; n < rRates.Length; n++) { for (int p = 0; p < vols.Length; p++) { double u = underlyings[l]; double q = qRates[m], r = rRates[n]; double v = vols[p]; spot.setValue(u); qRate.setValue(q); rRate.setValue(r); vol.setValue(v); // FLOATING_POINT_EXCEPTION double calculated = option.NPV(); if (calculated > spot.value() * 1.0e-5) { double expected = ref_option.NPV(); double error = Math.Abs(calculated - expected); if (error > tolerance) { REPORT_FAILURE("value", payoff, exercise, u, q, r, today, v, expected, calculated, error, tolerance); } } } } } } } } } }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(FDDividendEuropeanEngine obj) { return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr; }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(FDDividendEuropeanEngine obj) { return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr); }