コード例 #1
0
ファイル: T_FdHeston.cs プロジェクト: OpenDerivatives/QLCore
        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
                                     );
                    }
                }
            }
        }