Наследование: QLNet.StochasticProcess1D
Пример #1
0
 public HullWhiteForwardProcess(Handle <YieldTermStructure> h, double a, double sigma)
 {
     process_ = new OrnsteinUhlenbeckProcess(a, sigma, h.link.forwardRate(0.0, 0.0,
                                                                          Compounding.Continuous, Frequency.NoFrequency).value());
     h_     = h;
     a_     = a;
     sigma_ = sigma;
 }
Пример #2
0
        public HullWhiteProcess(Handle <YieldTermStructure> h, double a, double sigma)
        {
            process_ = new OrnsteinUhlenbeckProcess(a, sigma, h.link.forwardRate(0.0, 0.0, Compounding.Continuous, Frequency.NoFrequency).value());
            h_       = h;
            a_       = a;
            sigma_   = sigma;

            Utils.QL_REQUIRE(a_ >= 0.0, () => "negative a given");
            Utils.QL_REQUIRE(sigma_ >= 0.0, () => "negative sigma given");
        }
Пример #3
0
        public void testMultiPathGenerator()
        {
            //("Testing n-D path generation against cached values...");

            //SavedSettings backup;

            Settings.setEvaluationDate(new Date(26,4,2005));

            Handle<Quote> x0=new Handle<Quote> (new SimpleQuote(100.0));
            Handle<YieldTermStructure> r =new Handle<YieldTermStructure> (Utilities.flatRate(0.05, new Actual360()));
            Handle<YieldTermStructure> q=new Handle<YieldTermStructure> (Utilities.flatRate(0.02, new Actual360()));
            Handle<BlackVolTermStructure> sigma=new Handle<BlackVolTermStructure> (Utilities.flatVol(0.20, new Actual360()));

            Matrix correlation=new Matrix(3,3);
            correlation[0,0] = 1.0; correlation[0,1] = 0.9; correlation[0,2] = 0.7;
            correlation[1,0] = 0.9; correlation[1,1] = 1.0; correlation[1,2] = 0.4;
            correlation[2,0] = 0.7; correlation[2,1] = 0.4; correlation[2,2] = 1.0;

            List<StochasticProcess1D>  processes = new List<StochasticProcess1D>(3);
            StochasticProcess process;

            processes.Add(new BlackScholesMertonProcess(x0,q,r,sigma));
            processes.Add(new BlackScholesMertonProcess(x0,q,r,sigma));
            processes.Add(new BlackScholesMertonProcess(x0,q,r,sigma));
            process = new StochasticProcessArray(processes,correlation);
            // commented values must be used when Halley's correction is enabled
            double[] result1 = {
                188.2235868185,
                270.6713069569,
                113.0431145652 };
            // Real result1[] = {
            //     188.2235869273,
            //     270.6713071508,
            //     113.0431145652 };
            double[] result1a = {
                64.89105742957,
                45.12494404804,
                108.0475146914 };
            // Real result1a[] = {
            //     64.89105739157,
            //     45.12494401537,
            //     108.0475146914 };
            testMultiple(process, "Black-Scholes", result1, result1a);

            processes[0] = new GeometricBrownianMotionProcess(100.0, 0.03, 0.20);
            processes[1] = new GeometricBrownianMotionProcess(100.0, 0.03, 0.20);
            processes[2] = new GeometricBrownianMotionProcess(100.0, 0.03, 0.20);
            process = new StochasticProcessArray(processes,correlation);
            double[] result2 = {
                174.8266131680,
                237.2692443633,
                119.1168555440 };
            // Real result2[] = {
            //     174.8266132344,
            //     237.2692444869,
            //     119.1168555605 };
            double[] result2a = {
                57.69082393020,
                38.50016862915,
                116.4056510107 };
            // Real result2a[] = {
            //     57.69082387657,
            //     38.50016858691,
            //     116.4056510107 };
            testMultiple(process, "geometric Brownian", result2, result2a);

            processes[0] = new OrnsteinUhlenbeckProcess(0.1, 0.20);
            processes[1] = new OrnsteinUhlenbeckProcess(0.1, 0.20);
            processes[2] = new OrnsteinUhlenbeckProcess(0.1, 0.20);
            process = new StochasticProcessArray(processes,correlation);
            double[] result3 = {
                0.2942058437284,
                0.5525006418386,
                0.02650931054575 };
            double[] result3a = {
                -0.2942058437284,
                -0.5525006418386,
                -0.02650931054575 };
            testMultiple(process, "Ornstein-Uhlenbeck", result3, result3a);

            processes[0] = new SquareRootProcess(0.1, 0.1, 0.20, 10.0);
            processes[1] = new SquareRootProcess(0.1, 0.1, 0.20, 10.0);
            processes[2] = new SquareRootProcess(0.1, 0.1, 0.20, 10.0);
            process = new StochasticProcessArray(processes,correlation);
            double[] result4 = {
                4.279510844897,
                4.943783503533,
                3.590930385958 };
            double[] result4a = {
                2.763967737724,
                2.226487196647,
                3.503859264341 };
            testMultiple(process, "square-root", result4, result4a);
        }
Пример #4
0
        public override void calculate()
        {
            // 1. Term structure
            Handle <YieldTermStructure> ts = model_.currentLink().termStructure();

            // 2. Mesher
            DayCounter dc            = ts.currentLink().dayCounter();
            Date       referenceDate = ts.currentLink().referenceDate();
            double     maturity      = dc.yearFraction(referenceDate,
                                                       arguments_.exercise.lastDate());


            OrnsteinUhlenbeckProcess process = new OrnsteinUhlenbeckProcess(model_.currentLink().a(), model_.currentLink().sigma());

            Fdm1dMesher shortRateMesher =
                new FdmSimpleProcess1DMesher(xGrid_, process, maturity, 1, invEps_);

            FdmMesher mesher = new FdmMesherComposite(shortRateMesher);

            // 3. Inner Value Calculator
            List <Date> exerciseDates     = arguments_.exercise.dates();
            Dictionary <double, Date> t2d = new Dictionary <double, Date>();

            for (int i = 0; i < exerciseDates.Count; ++i)
            {
                double t = dc.yearFraction(referenceDate, exerciseDates[i]);
                Utils.QL_REQUIRE(t >= 0, () => "exercise dates must not contain past date");

                t2d.Add(t, exerciseDates[i]);
            }

            Handle <YieldTermStructure> disTs = model_.currentLink().termStructure();
            Handle <YieldTermStructure> fwdTs
                = arguments_.swap.iborIndex().forwardingTermStructure();

            Utils.QL_REQUIRE(fwdTs.currentLink().dayCounter() == disTs.currentLink().dayCounter(),
                             () => "day counter of forward and discount curve must match");
            Utils.QL_REQUIRE(fwdTs.currentLink().referenceDate() == disTs.currentLink().referenceDate(),
                             () => "reference date of forward and discount curve must match");

            HullWhite fwdModel =
                new HullWhite(fwdTs, model_.currentLink().a(), model_.currentLink().sigma());

            FdmInnerValueCalculator calculator =
                new FdmAffineModelSwapInnerValue <HullWhite>(
                    model_.currentLink(), fwdModel,
                    arguments_.swap, t2d, mesher, 0);

            // 4. Step conditions
            FdmStepConditionComposite conditions =
                FdmStepConditionComposite.vanillaComposite(
                    new DividendSchedule(), arguments_.exercise,
                    mesher, calculator, referenceDate, dc);

            // 5. Boundary conditions
            FdmBoundaryConditionSet boundaries = new FdmBoundaryConditionSet();

            // 6. Solver
            FdmSolverDesc solverDesc = new FdmSolverDesc();

            solverDesc.mesher       = mesher;
            solverDesc.bcSet        = boundaries;
            solverDesc.condition    = conditions;
            solverDesc.calculator   = calculator;
            solverDesc.maturity     = maturity;
            solverDesc.timeSteps    = tGrid_;
            solverDesc.dampingSteps = dampingSteps_;

            FdmHullWhiteSolver solver =
                new FdmHullWhiteSolver(model_, solverDesc, schemeDesc_);

            results_.value = solver.valueAt(0.0);
        }