public FdHestonVanillaEngine(HestonModel model, uint tGrid) : this(NQuantLibcPINVOKE.new_FdHestonVanillaEngine__SWIG_5(HestonModel.getCPtr(model), tGrid), true)
 {
     if (NQuantLibcPINVOKE.SWIGPendingException.Pending)
     {
         throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
     }
 }
 public FdHestonVanillaEngine(HestonModel model, uint tGrid, uint xGrid, uint vGrid, uint dampingSteps, FdmSchemeDesc schemeDesc, LocalVolTermStructure leverageFct) : this(NQuantLibcPINVOKE.new_FdHestonVanillaEngine__SWIG_0(HestonModel.getCPtr(model), tGrid, xGrid, vGrid, dampingSteps, FdmSchemeDesc.getCPtr(schemeDesc), LocalVolTermStructure.getCPtr(leverageFct)), true)
 {
     if (NQuantLibcPINVOKE.SWIGPendingException.Pending)
     {
         throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
     }
 }
Example #3
0
 public AnalyticHestonEngine(HestonModel model, double relTolerance, uint maxEvaluations) : this(NQuantLibcPINVOKE.new_AnalyticHestonEngine__SWIG_2(HestonModel.getCPtr(model), relTolerance, maxEvaluations), true)
 {
     if (NQuantLibcPINVOKE.SWIGPendingException.Pending)
     {
         throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
     }
 }
 public COSHestonEngine(HestonModel model, double L) : this(NQuantLibcPINVOKE.new_COSHestonEngine__SWIG_1(HestonModel.getCPtr(model), L), true)
 {
     if (NQuantLibcPINVOKE.SWIGPendingException.Pending)
     {
         throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
     }
 }
 public FdHestonDoubleBarrierEngine(HestonModel model) : this(NQuantLibcPINVOKE.new_FdHestonDoubleBarrierEngine__SWIG_6(HestonModel.getCPtr(model)), true)
 {
     if (NQuantLibcPINVOKE.SWIGPendingException.Pending)
     {
         throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
     }
 }
 public HestonModelHandle(HestonModel arg0) : this(NQuantLibcPINVOKE.new_HestonModelHandle__SWIG_0(HestonModel.getCPtr(arg0)), true)
 {
     if (NQuantLibcPINVOKE.SWIGPendingException.Pending)
     {
         throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
     }
 }
 public FdHestonDoubleBarrierEngine(HestonModel model, uint tGrid, uint xGrid, uint vGrid, uint dampingSteps, FdmSchemeDesc schemeDesc) : this(NQuantLibcPINVOKE.new_FdHestonDoubleBarrierEngine__SWIG_1(HestonModel.getCPtr(model), tGrid, xGrid, vGrid, dampingSteps, FdmSchemeDesc.getCPtr(schemeDesc)), true)
 {
     if (NQuantLibcPINVOKE.SWIGPendingException.Pending)
     {
         throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
     }
 }
 public FdHestonDoubleBarrierEngine(HestonModel model, uint tGrid, uint xGrid, uint vGrid) : this(NQuantLibcPINVOKE.new_FdHestonDoubleBarrierEngine__SWIG_3(HestonModel.getCPtr(model), tGrid, xGrid, vGrid), true)
 {
     if (NQuantLibcPINVOKE.SWIGPendingException.Pending)
     {
         throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
     }
 }
Example #9
0
 public AnalyticHestonEngine(HestonModel model) : this(NQuantLibcPINVOKE.new_AnalyticHestonEngine__SWIG_1(HestonModel.getCPtr(model)), true)
 {
     if (NQuantLibcPINVOKE.SWIGPendingException.Pending)
     {
         throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
     }
 }
 public AnalyticHestonEngine(HestonModel model, AnalyticHestonEngine.ComplexLogFormula cpxLog, AnalyticHestonEngine.AnalyticHestonEngine_Integration itg) : this(NQuantLibcPINVOKE.new_AnalyticHestonEngine__SWIG_4(HestonModel.getCPtr(model), (int)cpxLog, AnalyticHestonEngine.AnalyticHestonEngine_Integration.getCPtr(itg)), true)
 {
     if (NQuantLibcPINVOKE.SWIGPendingException.Pending)
     {
         throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
     }
 }
 public HestonSLVFDMModel(LocalVolTermStructure localVol, HestonModel model, Date endDate, HestonSLVFokkerPlanckFdmParams params_) : this(NQuantLibcPINVOKE.new_HestonSLVFDMModel__SWIG_2(LocalVolTermStructure.getCPtr(localVol), HestonModel.getCPtr(model), Date.getCPtr(endDate), HestonSLVFokkerPlanckFdmParams.getCPtr(params_)), true)
 {
     if (NQuantLibcPINVOKE.SWIGPendingException.Pending)
     {
         throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
     }
 }
Example #12
0
 public HestonSLVMCModel(LocalVolTermStructure localVol, HestonModel model, BrownianGeneratorFactory brownianGeneratorFactory, Date endDate) : this(NQuantLibcPINVOKE.new_HestonSLVMCModel__SWIG_4(LocalVolTermStructure.getCPtr(localVol), HestonModel.getCPtr(model), BrownianGeneratorFactory.getCPtr(brownianGeneratorFactory), Date.getCPtr(endDate)), true)
 {
     if (NQuantLibcPINVOKE.SWIGPendingException.Pending)
     {
         throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
     }
 }
Example #13
0
 public HestonSLVMCModel(LocalVolTermStructure localVol, HestonModel model, BrownianGeneratorFactory brownianGeneratorFactory, Date endDate, uint timeStepsPerYear, uint nBins, uint calibrationPaths) : this(NQuantLibcPINVOKE.new_HestonSLVMCModel__SWIG_1(LocalVolTermStructure.getCPtr(localVol), HestonModel.getCPtr(model), BrownianGeneratorFactory.getCPtr(brownianGeneratorFactory), Date.getCPtr(endDate), timeStepsPerYear, nBins, calibrationPaths), true)
 {
     if (NQuantLibcPINVOKE.SWIGPendingException.Pending)
     {
         throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
     }
 }
        public HestonModel __deref__()
        {
            global::System.IntPtr cPtr = NQuantLibcPINVOKE.HestonModelHandle___deref__(swigCPtr);
            HestonModel           ret  = (cPtr == global::System.IntPtr.Zero) ? null : new HestonModel(cPtr, true);

            if (NQuantLibcPINVOKE.SWIGPendingException.Pending)
            {
                throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
            }
            return(ret);
        }
Example #15
0
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(HestonModel obj)
 {
     return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr);
 }
        public void testH1HWPricingEngine()
        {
            /*
             * Example taken from Lech Aleksander Grzelak,
             * Equity and Foreign Exchange Hybrid Models for Pricing Long-Maturity
             * Financial Derivatives,
             * http://repository.tudelft.nl/assets/uuid:a8e1a007-bd89-481a-aee3-0e22f15ade6b/PhDThesis_main.pdf
             */
            Date today = new Date(15, Month.July, 2012);

            Settings.Instance.setEvaluationDate(today);
            Date       exerciseDate = new Date(13, Month.July, 2022);
            DayCounter dc           = new Actual365Fixed();

            Exercise exercise = new EuropeanExercise(exerciseDate);

            Handle <Quote> s0 = new Handle <Quote>(new SimpleQuote(100.0));

            double r       = 0.02;
            double q       = 0.00;
            double v0      = 0.05;
            double theta   = 0.05;
            double kappa_v = 0.3;

            double[] sigma_v = { 0.3, 0.6 };
            double   rho_sv  = -0.30;
            double   rho_sr  = 0.6;
            double   kappa_r = 0.01;
            double   sigma_r = 0.01;

            Handle <YieldTermStructure> rTS = new Handle <YieldTermStructure>(Utilities.flatRate(today, r, dc));
            Handle <YieldTermStructure> qTS = new Handle <YieldTermStructure>(Utilities.flatRate(today, q, dc));

            Handle <BlackVolTermStructure> flatVolTS = new Handle <BlackVolTermStructure>(Utilities.flatVol(today, 0.20, dc));
            GeneralizedBlackScholesProcess bsProcess = new GeneralizedBlackScholesProcess(s0, qTS, rTS, flatVolTS);

            HullWhiteProcess hwProcess      = new HullWhiteProcess(rTS, kappa_r, sigma_r);
            HullWhite        hullWhiteModel = new HullWhite(new Handle <YieldTermStructure>(rTS), kappa_r, sigma_r);

            double tol = 0.0001;

            double[]   strikes  = { 40, 80, 100, 120, 180 };
            double[][] expected =
            {
                new double[]  { 0.267503, 0.235742, 0.228223, 0.223461, 0.217855 },
                new double[]  { 0.263626, 0.211625, 0.199907, 0.193502, 0.190025 }
            };

            for (int j = 0; j < sigma_v.Length; ++j)
            {
                HestonProcess hestonProcess = new HestonProcess(rTS, qTS, s0, v0, kappa_v, theta, sigma_v[j], rho_sv);
                HestonModel   hestonModel   = new HestonModel(hestonProcess);

                for (int i = 0; i < strikes.Length; ++i)
                {
                    StrikedTypePayoff payoff = new PlainVanillaPayoff(Option.Type.Call, strikes[i]);

                    VanillaOption option = new VanillaOption(payoff, exercise);

                    IPricingEngine analyticH1HWEngine = new AnalyticH1HWEngine(hestonModel, hullWhiteModel, rho_sr, 144);
                    option.setPricingEngine(analyticH1HWEngine);
                    double impliedH1HW = option.impliedVolatility(option.NPV(), bsProcess);

                    if (Math.Abs(expected[j][i] - impliedH1HW) > tol)
                    {
                        QAssert.Fail("Failed to reproduce H1HW implied volatility"
                                     + "\n   expected       : " + expected[j][i]
                                     + "\n   calculated     : " + impliedH1HW
                                     + "\n   tol            : " + tol
                                     + "\n   strike         : " + strikes[i]
                                     + "\n   sigma          : " + sigma_v[j]);
                    }
                }
            }
        }
        public void testAnalyticHestonHullWhitePricing()
        {
            // Testing analytic Heston Hull-White option pricing
            DayCounter dc    = new Actual360();
            Date       today = Date.Today;

            Settings.Instance.setEvaluationDate(today);

            // construct a strange yield curve to check drifts and discounting
            // of the joint stochastic process

            List <Date>   dates = new List <Date>();
            List <double> times = new List <double>();
            List <double> rates = new List <double>(), divRates = new List <double>();

            for (int i = 0; i <= 40; ++i)
            {
                dates.Add(today + new Period(i, TimeUnit.Years));
                // FLOATING_POINT_EXCEPTION
                rates.Add(0.03 + 0.0001 * Math.Exp(Math.Sin(i / 4.0)));
                divRates.Add(0.02 + 0.0002 * Math.Exp(Math.Sin(i / 3.0)));
                times.Add(dc.yearFraction(today, dates.Last()));
            }

            Date           maturity         = today + new Period(5, TimeUnit.Years);
            Handle <Quote> s0               = new Handle <Quote>(new SimpleQuote(100));
            Handle <YieldTermStructure> rTS = new Handle <YieldTermStructure>(new InterpolatedZeroCurve <Linear>(dates, rates, dc));
            Handle <YieldTermStructure> qTS = new Handle <YieldTermStructure>(new InterpolatedZeroCurve <Linear>(dates, divRates, dc));

            HestonProcess hestonProcess = new HestonProcess(rTS, qTS, s0, 0.08, 1.5, 0.0625, 0.5, -0.8);
            HestonModel   hestonModel   = new HestonModel(hestonProcess);

            HullWhiteForwardProcess hwFwdProcess = new HullWhiteForwardProcess(rTS, 0.01, 0.01);

            hwFwdProcess.setForwardMeasureTime(dc.yearFraction(today, maturity));
            HullWhite hullWhiteModel = new HullWhite(rTS, hwFwdProcess.a(), hwFwdProcess.sigma());

            double tol = 0.002;

            double[]      strike = { 80, 120 };
            Option.Type[] types  = { Option.Type.Put, Option.Type.Call };

            for (int i = 0; i < types.Length; ++i)
            {
                for (int j = 0; j < strike.Length; ++j)
                {
                    HybridHestonHullWhiteProcess jointProcess = new HybridHestonHullWhiteProcess(hestonProcess,
                                                                                                 hwFwdProcess, 0.0, HybridHestonHullWhiteProcess.Discretization.Euler);

                    StrikedTypePayoff payoff   = new PlainVanillaPayoff(types[i], strike[j]);
                    Exercise          exercise = new EuropeanExercise(maturity);

                    VanillaOption optionHestonHW = new VanillaOption(payoff, exercise);
                    optionHestonHW.setPricingEngine(new MakeMCHestonHullWhiteEngine <PseudoRandom, Statistics>(jointProcess)
                                                    .withSteps(1)
                                                    .withAntitheticVariate()
                                                    .withControlVariate()
                                                    .withAbsoluteTolerance(tol)
                                                    .withSeed(42).getAsPricingEngine());

                    VanillaOption optionPureHeston = new VanillaOption(payoff, exercise);
                    optionPureHeston.setPricingEngine(new AnalyticHestonHullWhiteEngine(hestonModel, hullWhiteModel, 128));

                    double calculated = optionHestonHW.NPV();
                    double error      = optionHestonHW.errorEstimate();
                    double expected   = optionPureHeston.NPV();

                    if (Math.Abs(calculated - expected) > 3 * error &&
                        Math.Abs(calculated - expected) > tol)
                    {
                        QAssert.Fail("Failed to reproduce hw heston vanilla prices"
                                     + "\n   strike:     " + strike[j]
                                     + "\n   calculated: " + calculated
                                     + "\n   error:      " + error
                                     + "\n   expected:   " + expected);
                    }
                }
            }
        }
        public void testCompareBsmHWandHestonHW()
        {
            // Comparing European option pricing for a BSM process with one-factor Hull-White model
            DayCounter dc    = new Actual365Fixed();
            Date       today = Date.Today;

            Settings.Instance.setEvaluationDate(today);

            Handle <Quote> spot = new Handle <Quote>(new SimpleQuote(100.0));
            List <Date>    dates = new List <Date>();
            List <double>  rates = new List <double>(), divRates = new List <double>();

            for (int i = 0; i <= 40; ++i)
            {
                dates.Add(today + new Period(i, TimeUnit.Years));
                // FLOATING_POINT_EXCEPTION
                rates.Add(0.01 + 0.0002 * Math.Exp(Math.Sin(i / 4.0)));
                divRates.Add(0.02 + 0.0001 * Math.Exp(Math.Sin(i / 5.0)));
            }

            Handle <Quote> s0               = new Handle <Quote>(new SimpleQuote(100));
            Handle <YieldTermStructure> rTS = new Handle <YieldTermStructure>(
                new InterpolatedZeroCurve <Linear>(dates, rates, dc));
            Handle <YieldTermStructure> qTS = new Handle <YieldTermStructure>(
                new InterpolatedZeroCurve <Linear>(dates, divRates, dc));

            SimpleQuote vol = new SimpleQuote(0.25);
            Handle <BlackVolTermStructure> volTS = new Handle <BlackVolTermStructure>(Utilities.flatVol(today, vol, dc));

            BlackScholesMertonProcess bsmProcess = new BlackScholesMertonProcess(spot, qTS, rTS, volTS);

            HestonProcess hestonProcess = new HestonProcess(rTS, qTS, spot,
                                                            vol.value() * vol.value(), 1.0, vol.value() * vol.value(), 1e-4, 0.0);

            HestonModel hestonModel = new HestonModel(hestonProcess);

            HullWhite hullWhiteModel = new HullWhite(new Handle <YieldTermStructure>(rTS), 0.01, 0.01);

            IPricingEngine bsmhwEngine = new AnalyticBSMHullWhiteEngine(0.0, bsmProcess, hullWhiteModel);

            IPricingEngine hestonHwEngine = new AnalyticHestonHullWhiteEngine(hestonModel, hullWhiteModel, 128);

            double tol = 1e-5;

            double[]      strike   = { 0.25, 0.5, 0.75, 0.8, 0.9, 1.0, 1.1, 1.2, 1.5, 2.0, 4.0 };
            int[]         maturity = { 1, 2, 3, 5, 10, 15, 20, 25, 30 };
            Option.Type[] types    = { Option.Type.Put, Option.Type.Call };

            for (int i = 0; i < types.Length; ++i)
            {
                for (int j = 0; j < strike.Length; ++j)
                {
                    for (int l = 0; l < maturity.Length; ++l)
                    {
                        Date maturityDate = today + new Period(maturity[l], TimeUnit.Years);

                        Exercise exercise = new EuropeanExercise(maturityDate);

                        double fwd = strike[j] * spot.link.value()
                                     * qTS.link.discount(maturityDate) / rTS.link.discount(maturityDate);

                        StrikedTypePayoff payoff = new PlainVanillaPayoff(types[i], fwd);

                        EuropeanOption option = new EuropeanOption(payoff, exercise);

                        option.setPricingEngine(bsmhwEngine);
                        double calculated = option.NPV();

                        option.setPricingEngine(hestonHwEngine);
                        double expected = option.NPV();

                        if (Math.Abs(calculated - expected) > calculated * tol &&
                            Math.Abs(calculated - expected) > tol)
                        {
                            QAssert.Fail("Failed to reproduce npvs"
                                         + "\n    calculated: " + calculated
                                         + "\n    expected  : " + expected
                                         + "\n    strike    : " + strike[j]
                                         + "\n    maturity  : " + maturity[l]
                                         + "\n    type      : "
                                         + ((types[i] == QLCore.Option.Type.Put) ? "Put" : "Call"));
                        }
                    }
                }
            }
        }
Example #19
0
        public void testSpuriousOscillations()
        {
            //Testing for spurious oscillations when solving the Heston PDEs...
            using (SavedSettings backup = new SavedSettings())
            {
                DayCounter dc    = new Actual365Fixed();
                Date       today = new Date(7, 6, 2018);

                Settings.Instance.setEvaluationDate(today);

                Handle <Quote> spot             = new Handle <Quote>(new SimpleQuote(100.0));
                Handle <YieldTermStructure> qTS = new Handle <YieldTermStructure>(Utilities.flatRate(today, 0.1, dc));
                Handle <YieldTermStructure> rTS = new Handle <YieldTermStructure>(Utilities.flatRate(today, 0.0, dc));

                double v0    = 0.005;
                double kappa = 1.0;
                double theta = 0.005;
                double sigma = 0.4;
                double rho   = -0.75;

                Date maturity = today + new Period(1, TimeUnit.Years);

                HestonProcess process =
                    new HestonProcess(
                        rTS, qTS, spot, v0, kappa, theta, sigma, rho);

                HestonModel model =
                    new HestonModel(process);

                FdHestonVanillaEngine hestonEngine =
                    new FdHestonVanillaEngine(
                        model, 6, 200, 13, 0, new FdmSchemeDesc().TrBDF2());

                VanillaOption option = new VanillaOption(new PlainVanillaPayoff(Option.Type.Call, spot.currentLink().value()),
                                                         new EuropeanExercise(maturity));

                option.setupArguments(hestonEngine.getArguments());

                List <Tuple <FdmSchemeDesc, string, bool> > descs = new List <Tuple <FdmSchemeDesc, string, bool> >();
                descs.Add(new Tuple <FdmSchemeDesc, string, bool>(new FdmSchemeDesc().CraigSneyd(), "Craig-Sneyd", true));
                descs.Add(new Tuple <FdmSchemeDesc, string, bool>(new FdmSchemeDesc().Hundsdorfer(), "Hundsdorfer", true));
                descs.Add(new Tuple <FdmSchemeDesc, string, bool>(new FdmSchemeDesc().ModifiedHundsdorfer(), "Mod. Hundsdorfer", true));
                descs.Add(new Tuple <FdmSchemeDesc, string, bool>(new FdmSchemeDesc().Douglas(), "Douglas", true));
                descs.Add(new Tuple <FdmSchemeDesc, string, bool>(new FdmSchemeDesc().CrankNicolson(), "Crank-Nicolson", true));
                descs.Add(new Tuple <FdmSchemeDesc, string, bool>(new FdmSchemeDesc().ImplicitEuler(), "Implicit", false));
                descs.Add(new Tuple <FdmSchemeDesc, string, bool>(new FdmSchemeDesc().TrBDF2(), "TR-BDF2", false));

                for (int j = 0; j < descs.Count; ++j)
                {
                    FdmHestonSolver solver =
                        new FdmHestonSolver(new Handle <HestonProcess>(process),
                                            hestonEngine.getSolverDesc(1.0),
                                            descs[j].Item1);

                    List <double> gammas = new List <double>();
                    for (double x = 99; x < 101.001; x += 0.1)
                    {
                        gammas.Add(solver.gammaAt(x, v0));
                    }

                    double maximum = Double.MinValue;
                    for (int i = 1; i < gammas.Count; ++i)
                    {
                        double diff = Math.Abs(gammas[i] - gammas[i - 1]);
                        if (diff > maximum)
                        {
                            maximum = diff;
                        }
                    }

                    double tol = 0.01;
                    bool   hasSpuriousOscillations = maximum > tol;

                    if (hasSpuriousOscillations != descs[j].Item3)
                    {
                        QAssert.Fail("unable to reproduce spurious oscillation behaviour "
                                     + "\n   scheme name          : " + descs[j].Item2
                                     + "\n   oscillations observed: "
                                     + hasSpuriousOscillations
                                     + "\n   oscillations expected: " + descs[j].Item3
                                     );
                    }
                }
            }
        }
Example #20
0
 public AnalyticHestonEngine(HestonModel model) : this(NQuantLibcPINVOKE.new_AnalyticHestonEngine__SWIG_1(HestonModel.getCPtr(model)), true) {
   if (NQuantLibcPINVOKE.SWIGPendingException.Pending) throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
 }
Example #21
0
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(HestonModel obj) {
   return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
 }
Example #22
0
        static void Main(string[] args)
        {
            DateTime timer = DateTime.Now;

            ////////////////  DATES  //////////////////////////////////////////////

            Calendar calendar       = new TARGET();
            Date     todaysDate     = new Date(15, Month.January, 2017);
            Date     settlementDate = new Date(todaysDate);

            Settings.setEvaluationDate(todaysDate);
            DayCounter dayCounter = new Actual365Fixed();


            ////////////////  MARKET  //////////////////////////////////////////////

            // Spot
            double         underlying  = 4468.17;
            Handle <Quote> underlyingH = new Handle <Quote>(new SimpleQuote(underlying));

            // riskfree
            double riskFreeRate = 0.035;
            Handle <YieldTermStructure> flatTermStructure = new Handle <YieldTermStructure>(new FlatForward(settlementDate, riskFreeRate, dayCounter));

            // dividend
            double dividendYield = 0.0;
            double fixedDiv      = 5.0;

            Handle <YieldTermStructure> flatDividendTS        = new Handle <YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter));
            Handle <YieldTermStructure> FixedDivTermStructure = new Handle <YieldTermStructure>(new FixedForward(settlementDate, fixedDiv, underlying, dayCounter));

            // vol surface

            Date StartDateVol = settlementDate + new Period(1, TimeUnit.Months);


            List <int> maturityInDays = new InitializedList <int>()
            {
                0, 13, 41, 90, 165, 256, 345, 524, 703
            };
            List <Date> datesVol = new InitializedList <Date>();

            for (int d = 1; d < maturityInDays.Count; d++)
            {
                datesVol.Add(calendar.advance(settlementDate, new Period(maturityInDays[d], TimeUnit.Days)));
            }

            List <double> strikes = new InitializedList <double>()
            {
                3400, 3600, 3800, 4000, 4200, 4400, 4500, 4600, 4800, 5000, 5200, 5400, 5600
            };

            Matrix blackVolMatrix = new Matrix(maturityInDays.Count - 1, strikes.Count, 0.2);
            var    vols           = new InitializedList <double>()
            {
                0.6625, 0.4875, 0.4204, 0.3667, 0.3431, 0.3267, 0.3121, 0.3121,
                0.6007, 0.4543, 0.3967, 0.3511, 0.3279, 0.3154, 0.2984, 0.2921,
                0.5084, 0.4221, 0.3718, 0.3327, 0.3155, 0.3027, 0.2919, 0.2889,
                0.4541, 0.3869, 0.3492, 0.3149, 0.2963, 0.2926, 0.2819, 0.2800,
                0.4060, 0.3607, 0.3330, 0.2999, 0.2887, 0.2811, 0.2751, 0.2775,
                0.3726, 0.3396, 0.3108, 0.2781, 0.2788, 0.2722, 0.2661, 0.2686,
                0.3550, 0.3277, 0.3012, 0.2781, 0.2781, 0.2661, 0.2661, 0.2681,
                0.3428, 0.3209, 0.2958, 0.2740, 0.2688, 0.2627, 0.2580, 0.2620,
                0.3302, 0.3062, 0.2799, 0.2631, 0.2573, 0.2533, 0.2504, 0.2544,
                0.3343, 0.2959, 0.2705, 0.2540, 0.2504, 0.2464, 0.2448, 0.2462,
                0.3460, 0.2845, 0.2624, 0.2463, 0.2425, 0.2385, 0.2373, 0.2422,
                0.3857, 0.2860, 0.2578, 0.2399, 0.2357, 0.2327, 0.2312, 0.2351,
                0.3976, 0.2860, 0.2607, 0.2356, 0.2297, 0.2268, 0.2241, 0.2320
            };


            for (int i = 0; i < vols.Count; i++)
            {
                int testraw = (int)(i % (datesVol.Count));
                int testcol = (int)(i / (datesVol.Count));

                blackVolMatrix[testraw, testcol] = vols[i];
            }



            BlackVarianceSurface mySurface = new BlackVarianceSurface(settlementDate, calendar, datesVol,
                                                                      strikes, Matrix.transpose(blackVolMatrix), dayCounter);

            Handle <BlackVolTermStructure> mySurfaceH = new Handle <BlackVolTermStructure>(mySurface);


            ////////////////  CALIBRATION  //////////////////////////////////////////////

            Period helperPeriod = new Period();

            //helpers
            List <CalibrationHelper> calibrationHelpers = new List <CalibrationHelper>();

            for (int k = 0; k < strikes.Count; k++)
            {
                for (int d = 0; d < datesVol.Count; d++)
                {
                    helperPeriod = new Period(datesVol[d] - settlementDate, TimeUnit.Days);
                    calibrationHelpers.Add(new HestonModelHelper(helperPeriod,
                                                                 calendar,
                                                                 underlying,
                                                                 strikes[k],
                                                                 new Handle <Quote>(new SimpleQuote(blackVolMatrix[d, k])),
                                                                 flatTermStructure,
                                                                 flatDividendTS,
                                                                 CalibrationHelper.CalibrationErrorType.ImpliedVolError));
                }
            }


            // starting data
            double v0    = 0.1;
            double kappa = 1.0;
            double theta = 0.1;
            double sigma = 0.5;
            double rho   = -0.5;

            // model
            HestonProcess hestonProcess = new HestonProcess(flatTermStructure,
                                                            flatDividendTS,
                                                            underlyingH,
                                                            v0, kappa, theta, sigma, rho);

            HestonModel hestonmodel = new HestonModel(hestonProcess);

            AnalyticHestonEngine analyticHestonEngine = new AnalyticHestonEngine(hestonmodel);


            foreach (HestonModelHelper hmh in calibrationHelpers)
            {
                hmh.setPricingEngine(analyticHestonEngine);
            }


            // optimization
            double             tolerance          = 1.0e-8;
            LevenbergMarquardt optimizationmethod = new LevenbergMarquardt(tolerance, tolerance, tolerance);

            hestonmodel.calibrate(calibrationHelpers, optimizationmethod, new EndCriteria(400, 40, tolerance, tolerance, tolerance));

            double        error     = 0.0;
            List <double> errorList = new InitializedList <double>();


            ////////////////  CALIBRATION RESULTS  //////////////////////////////////////////////
            Console.WriteLine("Calbration :");
            Console.WriteLine("-----------");

            foreach (HestonModelHelper hmh in calibrationHelpers)
            {
                error += Math.Abs(hmh.calibrationError());
                errorList.Add(Math.Abs(hmh.calibrationError()));
            }

            Vector hestonParameters = hestonmodel.parameters();

            Console.WriteLine("v0    = {0:0.00%}", hestonParameters[4]);
            Console.WriteLine("kappa = {0:0.00%}", hestonParameters[1]);
            Console.WriteLine("theta = {0:0.00%}", hestonParameters[0]);
            Console.WriteLine("sigma = {0:0.00%}", hestonParameters[2]);
            Console.WriteLine("rho   = {0:0.00%}", hestonParameters[3]);
            Console.WriteLine();
            Console.WriteLine("Total error = {0:0.0000}", error);
            Console.WriteLine("Mean error  = {0:0.0000%}", error / (errorList.Count - 1));
            Console.WriteLine();

            int    StepsPerYear      = 52;
            double absoluteTolerance = 80.0;
            ulong  mcSeed            = 42;

            // MC Heston process
            HestonProcess calibratedHestonProcess = new HestonProcess(flatTermStructure,
                                                                      flatDividendTS,
                                                                      underlyingH,
                                                                      hestonParameters[4],
                                                                      hestonParameters[1],
                                                                      hestonParameters[0],
                                                                      hestonParameters[2],
                                                                      hestonParameters[3]);

            // BS process
            GeneralizedBlackScholesProcessTolerance bsmProcess = new GeneralizedBlackScholesProcessTolerance(underlyingH, FixedDivTermStructure, flatTermStructure, mySurfaceH);

            ////////////////  ENGINES  /////////////////////////////////////////////////


            IPricingEngine mcHestonEngine = new MakeMCEuropeanHestonEngine <PseudoRandom, Statistics>(calibratedHestonProcess)
                                            .withStepsPerYear(StepsPerYear)
                                            .withAbsoluteTolerance(absoluteTolerance)
                                            .withSeed(mcSeed)
                                            .getAsPricingEngine();

            double         absoluteTolerance2      = 1.0;
            IPricingEngine mcGenHestonEngineTestbs = new MakeMCGenericScriptInstrument <PseudoRandom>(bsmProcess)
                                                     .withStepsPerYear(StepsPerYear)
                                                     .withAbsoluteTolerance(absoluteTolerance2)
                                                     .withSeed(mcSeed)
                                                     .value();

            IPricingEngine mcGenHestonEngineTestbs2 = new MakeMCGenericScriptInstrument <PseudoRandom>(calibratedHestonProcess)
                                                      .withStepsPerYear(StepsPerYear)
                                                      .withAbsoluteTolerance(absoluteTolerance2)
                                                      .withSeed(mcSeed)
                                                      .value();


            ////////////////  PRICING  //////////////////////////////////////////////
            Console.WriteLine("Pricing Vanilla:");
            Console.WriteLine("---------------");


            Date     maturity         = new Date(17, Month.May, 2019);
            Exercise europeanExercise = new EuropeanExercise(maturity);

            Option.Type       type           = Option.Type.Call;
            double            strike         = underlying;
            StrikedTypePayoff payoff         = new PlainVanillaPayoff(type, strike);
            VanillaOption     europeanOption = new VanillaOption(payoff, europeanExercise);

            // heston
            europeanOption.setPricingEngine(analyticHestonEngine);
            Console.Write("Heston pricing = {0:0.0000}", europeanOption.NPV());
            Console.WriteLine("  ->   {0:0.0000%}", europeanOption.NPV() / underlying);

            // Mc heston
            europeanOption.setPricingEngine(mcHestonEngine);
            Console.Write("HestMC pricing = {0:0.0000}", europeanOption.NPV());
            Console.Write("  ->   {0:0.0000%}", europeanOption.NPV() / underlying);
            Console.WriteLine("  tolerance   {0:0.0} / {1:0.00%}", absoluteTolerance, absoluteTolerance / underlying);

            // analytic bs
            europeanOption.setPricingEngine(new AnalyticEuropeanEngine(bsmProcess));
            Console.Write("BS pricing     = {0:0.0000}", europeanOption.NPV());
            Console.WriteLine("  ->   {0:0.0000%}", europeanOption.NPV() / underlying);


            Console.WriteLine();
            ////////////////  AUTOCALL HESTON //////////////////////////////////////////////

            List <Date> fixingdates = new InitializedList <Date>();
            double      coupon      = 0.05;
            double      barrierlvl  = 0.6;

            for (int i = 1; i <= 4; i++)
            {
                fixingdates.Add(settlementDate + new Period(i, TimeUnit.Years));
            }

            ScriptGenericAutocall myGenericAutocallHTTEst = new ScriptGenericAutocall(fixingdates, coupon, barrierlvl, underlying);

            myGenericAutocallHTTEst.setPricingEngine(mcGenHestonEngineTestbs);

            Console.WriteLine("Pricing Autocall BS :");
            Console.WriteLine("---------------------");
            Console.WriteLine("test = {0:0.0000}", myGenericAutocallHTTEst.NPV());
            Console.WriteLine("Err = {0:0.0000%}", myGenericAutocallHTTEst.errorEstimate() / myGenericAutocallHTTEst.NPV());
            Console.WriteLine("Samples = {0}", myGenericAutocallHTTEst.samples());
            Console.Write("\n");

            for (int i = 0; i < 4; i++)
            {
                Console.WriteLine("ProbaCall {1} = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaCall " + i), i + 1);
            }
            Console.WriteLine("ProbaMid = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaMid"));
            Console.WriteLine("probaDown = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaDown"));
            Console.WriteLine("test = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaDown"));
            Console.WriteLine("AvgDown/Proba = {0:0.0000%}", myGenericAutocallHTTEst.inspout("AvgDown") / myGenericAutocallHTTEst.inspout("ProbaDown"));
            Console.Write("\n");


            myGenericAutocallHTTEst.setPricingEngine(mcGenHestonEngineTestbs2);

            Console.WriteLine("Pricing Autocall Heston:");
            Console.WriteLine("------------------------");
            Console.WriteLine("test = {0:0.0000}", myGenericAutocallHTTEst.NPV());
            Console.WriteLine("Err = {0:0.0000%}", myGenericAutocallHTTEst.errorEstimate() / myGenericAutocallHTTEst.NPV());
            Console.WriteLine("Samples = {0}", myGenericAutocallHTTEst.samples());
            Console.Write("\n");

            for (int i = 0; i < 4; i++)
            {
                Console.WriteLine("ProbaCall {1} = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaCall " + i), i + 1);
            }
            Console.WriteLine("ProbaMid = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaMid"));
            Console.WriteLine("probaDown = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaDown"));
            Console.WriteLine("test = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaDown"));
            Console.WriteLine("AvgDown/Proba = {0:0.0000%}", myGenericAutocallHTTEst.inspout("AvgDown") / myGenericAutocallHTTEst.inspout("ProbaDown"));
            Console.Write("\n");


            ////////////////  END TEST  //////////////////////////////////////////////
            Console.WriteLine();
            Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer);
            Console.WriteLine();

            Console.Write("Press any key to continue ...");
            Console.ReadKey();
        }
Example #23
0
 public AnalyticHestonEngine(HestonModel model, double relTolerance, uint maxEvaluations) : this(NQuantLibcPINVOKE.new_AnalyticHestonEngine__SWIG_2(HestonModel.getCPtr(model), relTolerance, maxEvaluations), true) {
   if (NQuantLibcPINVOKE.SWIGPendingException.Pending) throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve();
 }
Example #24
0
        public void testMethodOfLinesAndCN()
        {
            //Testing method of lines to solve Heston PDEs...

            using (SavedSettings backup = new SavedSettings())
            {
                DayCounter dc    = new Actual365Fixed();
                Date       today = new Date(21, 2, 2018);

                Settings.Instance.setEvaluationDate(today);

                Handle <Quote> spot             = new Handle <Quote>(new SimpleQuote(100.0));
                Handle <YieldTermStructure> qTS = new Handle <YieldTermStructure>(Utilities.flatRate(today, 0.0, dc));
                Handle <YieldTermStructure> rTS = new Handle <YieldTermStructure>(Utilities.flatRate(today, 0.0, dc));

                double v0    = 0.09;
                double kappa = 1.0;
                double theta = v0;
                double sigma = 0.4;
                double rho   = -0.75;

                Date maturity = today + new Period(3, TimeUnit.Months);

                HestonModel model =
                    new HestonModel(
                        new HestonProcess(rTS, qTS, spot, v0, kappa, theta, sigma, rho));

                int xGrid = 21;
                int vGrid = 7;

                IPricingEngine fdmDefault =
                    new FdHestonVanillaEngine(model, 10, xGrid, vGrid, 0);

                IPricingEngine fdmMol =
                    new FdHestonVanillaEngine(
                        model, 10, xGrid, vGrid, 0, new FdmSchemeDesc().MethodOfLines());

                PlainVanillaPayoff payoff =
                    new PlainVanillaPayoff(Option.Type.Put, spot.currentLink().value());

                VanillaOption option = new VanillaOption(payoff, new AmericanExercise(maturity));

                option.setPricingEngine(fdmMol);
                double calculatedMoL = option.NPV();

                option.setPricingEngine(fdmDefault);
                double expected = option.NPV();

                double tol     = 0.005;
                double diffMoL = Math.Abs(expected - calculatedMoL);

                if (diffMoL > tol)
                {
                    QAssert.Fail("Failed to reproduce european option values with MOL"
                                 + "\n    calculated: " + calculatedMoL
                                 + "\n    expected:   " + expected
                                 + "\n    difference: " + diffMoL
                                 + "\n    tolerance:  " + tol);
                }

                IPricingEngine fdmCN =
                    new FdHestonVanillaEngine(model, 10, xGrid, vGrid, 0, new FdmSchemeDesc().CrankNicolson());
                option.setPricingEngine(fdmCN);

                double calculatedCN = option.NPV();
                double diffCN       = Math.Abs(expected - calculatedCN);

                if (diffCN > tol)
                {
                    QAssert.Fail("Failed to reproduce european option values with Crank-Nicolson"
                                 + "\n    calculated: " + calculatedCN
                                 + "\n    expected:   " + expected
                                 + "\n    difference: " + diffCN
                                 + "\n    tolerance:  " + tol);
                }

                BarrierOption barrierOption =
                    new BarrierOption(Barrier.Type.DownOut, 85.0, 10.0,
                                      payoff, new EuropeanExercise(maturity));

                barrierOption.setPricingEngine(new FdHestonBarrierEngine(model, 100, 31, 11));

                double expectedBarrier = barrierOption.NPV();

                barrierOption.setPricingEngine(new FdHestonBarrierEngine(model, 100, 31, 11, 0, new FdmSchemeDesc().MethodOfLines()));

                double calculatedBarrierMoL = barrierOption.NPV();

                double barrierTol     = 0.01;
                double barrierDiffMoL = Math.Abs(expectedBarrier - calculatedBarrierMoL);

                if (barrierDiffMoL > barrierTol)
                {
                    QAssert.Fail("Failed to reproduce barrier option values with MOL"
                                 + "\n    calculated: " + calculatedBarrierMoL
                                 + "\n    expected:   " + expectedBarrier
                                 + "\n    difference: " + barrierDiffMoL
                                 + "\n    tolerance:  " + barrierTol);
                }

                barrierOption.setPricingEngine(new FdHestonBarrierEngine(model, 100, 31, 11, 0, new FdmSchemeDesc().CrankNicolson()));

                double calculatedBarrierCN = barrierOption.NPV();
                double barrierDiffCN       = Math.Abs(expectedBarrier - calculatedBarrierCN);

                if (barrierDiffCN > barrierTol)
                {
                    QAssert.Fail("Failed to reproduce barrier option values with Crank-Nicolson"
                                 + "\n    calculated: " + calculatedBarrierCN
                                 + "\n    expected:   " + expectedBarrier
                                 + "\n    difference: " + barrierDiffCN
                                 + "\n    tolerance:  " + barrierTol);
                }
            }
        }