// ! \warning see VanillaOption for notes on implied-volatility // calculation. // public double impliedVolatility(double targetValue, GeneralizedBlackScholesProcess process, double accuracy = 1.0e-4, int maxEvaluations = 100, double minVol = 1.0e-7, double maxVol = 4.0) { Utils.QL_REQUIRE(!isExpired(), () => "option expired"); SimpleQuote volQuote = new SimpleQuote(); GeneralizedBlackScholesProcess newProcess = ImpliedVolatilityHelper.clone(process, volQuote); // engines are built-in for the time being IPricingEngine engine = null; switch (exercise_.type()) { case Exercise.Type.European: engine = new AnalyticBarrierEngine(newProcess); break; case Exercise.Type.American: case Exercise.Type.Bermudan: Utils.QL_FAIL("Engine not available for non-European barrier option"); break; default: Utils.QL_FAIL("unknown exercise type"); break; } return(ImpliedVolatilityHelper.calculate(this, engine, volQuote, targetValue, accuracy, maxEvaluations, minVol, maxVol)); }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(AnalyticBarrierEngine 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(AnalyticBarrierEngine obj) { return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr); }
public void testFdmHestonBarrierVsBlackScholes() { //Testing FDM with barrier option in Heston model... using (SavedSettings backup = new SavedSettings()) { NewBarrierOptionData[] values = new NewBarrierOptionData[] { /* The data below are from * "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 pag. 72 */ // barrierType, barrier, rebate, type, strike, s, q, r, t, v new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, 100, 100.0, 0.00, 0.08, 1.00, 0.30), new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, 90, 100.0, 0.00, 0.08, 0.25, 0.25), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, 90, 100.0, 0.00, 0.08, 0.25, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, 100, 100.0, 0.00, 0.08, 0.40, 0.25), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.15), new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, 100, 100.0, 0.00, 0.08, 0.40, 0.35), new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.15), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, 110, 100.0, 0.00, 0.00, 1.00, 0.20), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, 110, 100.0, 0.00, 0.08, 1.00, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, 110, 100.0, 0.00, 0.04, 1.00, 0.15), new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 1.00, 0.15), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.30) }; DayCounter dc = new Actual365Fixed(); Date todaysDate = new Date(28, 3, 2004); Date exerciseDate = new Date(28, 3, 2005); Settings.Instance.setEvaluationDate(todaysDate); Handle <Quote> spot = new Handle <Quote>(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)); BlackScholesMertonProcess bsProcess = new BlackScholesMertonProcess(spot, qTS, rTS, volTS); IPricingEngine analyticEngine = new AnalyticBarrierEngine(bsProcess); for (int i = 0; i < values.Length; i++) { Date exDate = todaysDate + Convert.ToInt32(values[i].t * 365 + 0.5); Exercise exercise = new EuropeanExercise(exDate); (spot.currentLink() as SimpleQuote).setValue(values[i].s); qRate.setValue(values[i].q); rRate.setValue(values[i].r); vol.setValue(values[i].v); StrikedTypePayoff payoff = new PlainVanillaPayoff(values[i].type, values[i].strike); BarrierOption barrierOption = new BarrierOption(values[i].barrierType, values[i].barrier, values[i].rebate, payoff, exercise); double v0 = vol.value() * vol.value(); HestonProcess hestonProcess = new HestonProcess(rTS, qTS, spot, v0, 1.0, v0, 0.005, 0.0); barrierOption.setPricingEngine(new FdHestonBarrierEngine(new HestonModel(hestonProcess), 200, 101, 3)); double calculatedHE = barrierOption.NPV(); barrierOption.setPricingEngine(analyticEngine); double expected = barrierOption.NPV(); double tol = 0.0025; if (Math.Abs(calculatedHE - expected) / expected > tol) { QAssert.Fail("Failed to reproduce expected Heston npv" + "\n calculated: " + calculatedHE + "\n expected: " + expected + "\n tolerance: " + tol); } } } }