public LongstaffSchwartzPathPricer(TimeGrid times, IEarlyExercisePathPricer <PathType, double> pathPricer,
                                           YieldTermStructure termStructure)
        {
            calibrationPhase_ = true;
            pathPricer_       = pathPricer;
            coeff_            = new InitializedList <Vector>(times.size() - 1);
            dF_ = new InitializedList <double>(times.size() - 1);
            v_  = pathPricer_.basisSystem();

            for (int i = 0; i < times.size() - 1; ++i)
            {
                dF_[i] = termStructure.discount(times[i + 1])
                         / termStructure.discount(times[i]);
            }
        }
Пример #2
0
        public MultiPathGenerator(StochasticProcess process, TimeGrid times, GSG generator, bool brownianBridge)
        {
            brownianBridge_ = brownianBridge;
            process_        = process;
            generator_      = generator;
            next_           = new Sample <IPath>(new MultiPath(process.size(), times), 1.0);

            Utils.QL_REQUIRE(generator_.dimension() == process.factors() * (times.size() - 1), () =>
                             "dimension (" + generator_.dimension()
                             + ") is not equal to ("
                             + process.factors() + " * " + (times.size() - 1)
                             + ") the number of factors "
                             + "times the number of time steps");
            Utils.QL_REQUIRE(times.size() > 1, () => "no times given");
        }
Пример #3
0
        public override Lattice tree(TimeGrid grid)
        {
            TermStructureFittingParameter phi = new TermStructureFittingParameter(termStructure());

            ShortRateDynamics numericDynamics =
                new Dynamics(phi, a(), sigma());

            TrinomialTree trinomial =
                new TrinomialTree(numericDynamics.process(), grid);
            ShortRateTree numericTree =
                new ShortRateTree(trinomial, numericDynamics, grid);

            TermStructureFittingParameter.NumericalImpl impl =
                (TermStructureFittingParameter.NumericalImpl)phi.implementation();
            impl.reset();
            double value = 1.0;
            double vMin  = -50.0;
            double vMax  = 50.0;

            for (int i = 0; i < (grid.size() - 1); i++)
            {
                double discountBond = termStructure().link.discount(grid[i + 1]);
                double xMin         = trinomial.underlying(i, 0);
                double dx           = trinomial.dx(i);
                Helper finder       = new Helper(i, xMin, dx, discountBond, numericTree);
                Brent  s1d          = new Brent();
                s1d.setMaxEvaluations(1000);
                value = s1d.solve(finder, 1e-7, value, vMin, vMax);
                impl.setvalue(grid[i], value);
            }
            return(numericTree);
        }
Пример #4
0
        public override Lattice tree(TimeGrid grid)
        {
            TermStructureFittingParameter phi             = new TermStructureFittingParameter(termStructure());
            ShortRateDynamics             numericDynamics = new Dynamics(phi, a(), sigma());
            TrinomialTree trinomial   = new TrinomialTree(numericDynamics.process(), grid);
            ShortRateTree numericTree = new ShortRateTree(trinomial, numericDynamics, grid);

            TermStructureFittingParameter.NumericalImpl impl =
                (TermStructureFittingParameter.NumericalImpl)phi.implementation();
            impl.reset();
            for (int i = 0; i < (grid.size() - 1); i++)
            {
                double discountBond = termStructure().link.discount(grid[i + 1]);
                Vector statePrices  = numericTree.statePrices(i);
                int    size         = numericTree.size(i);
                double dt           = numericTree.timeGrid().dt(i);
                double dx           = trinomial.dx(i);
                double x            = trinomial.underlying(i, 0);
                double value        = 0.0;
                for (int j = 0; j < size; j++)
                {
                    value += statePrices[j] * Math.Exp(-x * dt);
                    x     += dx;
                }
                value = Math.Log(value / discountBond) / dt;
                impl.setvalue(grid[i], value);
            }
            return(numericTree);
        }
Пример #5
0
        protected override IPathGenerator <IRNG> pathGenerator()
        {
            TimeGrid grid = timeGrid();
            IRNG     gen  = new RNG().make_sequence_generator(grid.size() - 1, seed_);

            return(new PathGenerator <IRNG>(process_, grid, gen, brownianBridge_));
        }
 public LatticeShortRateModelEngine(ShortRateModel model,
                                    TimeGrid timeGrid)
     : base(model)
 {
     timeGrid_  = new TimeGrid(timeGrid.Last(), timeGrid.size() - 1 /*timeGrid.dt(1) - timeGrid.dt(0)*/);
     timeGrid_  = timeGrid;
     timeSteps_ = 0;
     lattice_   = this.model_.link.tree(timeGrid);
 }
Пример #7
0
        public PathGenerator(StochasticProcess process, TimeGrid timeGrid, GSG generator, bool brownianBridge)
        {
            brownianBridge_ = brownianBridge;
            generator_      = generator;
            dimension_      = generator_.dimension();
            timeGrid_       = timeGrid;
            process_        = process as StochasticProcess1D;
            next_           = new Sample <IPath>(new Path(timeGrid_), 1.0);
            temp_           = new InitializedList <double>(dimension_);
            bb_             = new BrownianBridge(timeGrid_);

            Utils.QL_REQUIRE(dimension_ == timeGrid_.size() - 1, () =>
                             "sequence generator dimensionality (" + dimension_ + ") != timeSteps (" + (timeGrid_.size() - 1) + ")");
        }
Пример #8
0
        protected override PathPricer <IPath> pathPricer()
        {
            PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff;

            Utils.QL_REQUIRE(payoff != null, () => "non-plain payoff given");

            TimeGrid      grid      = timeGrid();
            List <double> discounts = new InitializedList <double>(grid.size());

            for (int i = 0; i < grid.size(); i++)
            {
                discounts[i] = process_.riskFreeRate().currentLink().discount(grid[i]);
            }

            // do this with template parameters?
            if (isBiased_)
            {
                return(new BiasedBarrierPathPricer(arguments_.barrierType,
                                                   arguments_.barrier,
                                                   arguments_.rebate,
                                                   payoff.optionType(),
                                                   payoff.strike(),
                                                   discounts));
            }
            else
            {
                IRNG sequenceGen = new RandomSequenceGenerator <MersenneTwisterUniformRng>(grid.size() - 1, 5);
                return(new BarrierPathPricer(arguments_.barrierType,
                                             arguments_.barrier,
                                             arguments_.rebate,
                                             payoff.optionType(),
                                             payoff.strike(),
                                             discounts,
                                             process_,
                                             sequenceGen));
            }
        }
Пример #9
0
 //! generic times
 public BrownianBridge(TimeGrid timeGrid)
 {
     size_        = timeGrid.size() - 1;
     t_           = new InitializedList <double>(size_);
     sqrtdt_      = new InitializedList <double>(size_);
     sqrtdt_      = new InitializedList <double>(size_);
     bridgeIndex_ = new InitializedList <int>(size_);
     leftIndex_   = new InitializedList <int>(size_);
     rightIndex_  = new InitializedList <int>(size_);
     leftWeight_  = new InitializedList <double>(size_);
     rightWeight_ = new InitializedList <double>(size_);
     stdDev_      = new InitializedList <double>(size_);
     for (int i = 0; i < size_; ++i)
     {
         t_[i] = timeGrid[i + 1];
     }
     initialize();
 }
Пример #10
0
            //! Tree build-up + numerical fitting to term-structure
            public ShortRateTree(TrinomialTree tree, ShortRateDynamics dynamics, TermStructureFittingParameter.NumericalImpl theta,
                                 TimeGrid timeGrid)
                : base(timeGrid, tree.size(1))
            {
                tree_     = tree;
                dynamics_ = dynamics;
                theta.reset();
                double value = 1.0;
                double vMin  = -100.0;
                double vMax  = 100.0;

                for (int i = 0; i < (timeGrid.size() - 1); i++)
                {
                    double discountBond = theta.termStructure().link.discount(t_[i + 1]);
                    Helper finder       = new Helper(i, discountBond, theta, this);
                    Brent  s1d          = new Brent();
                    s1d.setMaxEvaluations(1000);
                    value = s1d.solve(finder, 1e-7, value, vMin, vMax);
                    theta.change(value);
                }
            }
Пример #11
0
        protected override IPathGenerator <IRNG> pathGenerator()
        {
            int      dimensions = process_.factors();
            TimeGrid grid       = timeGrid();
            IRNG     generator  = (IRNG)FastActivator <RNG> .Create().make_sequence_generator(dimensions * (grid.size() - 1), seed_);

            return(new PathGenerator <IRNG>(process_, grid, generator, brownianBridge_));
        }
Пример #12
0
        protected override IPathGenerator <IRNG> controlPathGenerator()
        {
            int      dimensions = process_.factors();
            TimeGrid grid       = this.timeGrid();
            IRNG     generator  = (IRNG) new  RNG().make_sequence_generator(dimensions * (grid.size() - 1), this.seed_);
            HybridHestonHullWhiteProcess process = process_ as HybridHestonHullWhiteProcess;

            Utils.QL_REQUIRE(process != null, () => "invalid process");
            HybridHestonHullWhiteProcess cvProcess = new HybridHestonHullWhiteProcess(process.hestonProcess(),
                                                                                      process.hullWhiteProcess(), 0.0, process.discretization());

            return(new MultiPathGenerator <IRNG>(cvProcess, grid, generator, false));
        }
        public override void calculate()
        {
            // this is an european option pricer
            Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => "not an European option");

            // plain vanilla
            PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff;

            Utils.QL_REQUIRE(payoff != null, () => "non-striked payoff given");

            double v0        = model_.link.v0();
            double spotPrice = model_.link.s0();

            Utils.QL_REQUIRE(spotPrice > 0.0, () => "negative or null underlying given");

            double strike = payoff.strike();
            double term   = model_.link.riskFreeRate().link.dayCounter().yearFraction(
                model_.link.riskFreeRate().link.referenceDate(), arguments_.exercise.lastDate());
            double riskFreeDiscount = model_.link.riskFreeRate().link.discount(arguments_.exercise.lastDate());
            double dividendDiscount = model_.link.dividendYield().link.discount(arguments_.exercise.lastDate());

            //average values
            TimeGrid timeGrid = model_.link.timeGrid();
            int      n = timeGrid.size() - 1;
            double   kappaAvg = 0.0, thetaAvg = 0.0, sigmaAvg = 0.0, rhoAvg = 0.0;

            for (int i = 1; i <= n; ++i)
            {
                double t = 0.5 * (timeGrid[i - 1] + timeGrid[i]);
                kappaAvg += model_.link.kappa(t);
                thetaAvg += model_.link.theta(t);
                sigmaAvg += model_.link.sigma(t);
                rhoAvg   += model_.link.rho(t);
            }
            kappaAvg /= n;
            thetaAvg /= n;
            sigmaAvg /= n;
            rhoAvg   /= n;

            double c_inf = Math.Min(10.0, Math.Max(0.0001,
                                                   Math.Sqrt(1.0 - Math.Pow(rhoAvg, 2)) / sigmaAvg)) * (v0 + kappaAvg * thetaAvg * term);

            double p1 = integration_.calculate(c_inf,
                                               new Fj_Helper(model_, term, strike, 1).value) / Const.M_PI;

            double p2 = integration_.calculate(c_inf,
                                               new Fj_Helper(model_, term, strike, 2).value) / Const.M_PI;

            switch (payoff.optionType())
            {
            case Option.Type.Call:
                results_.value = spotPrice * dividendDiscount * (p1 + 0.5)
                                 - strike * riskFreeDiscount * (p2 + 0.5);
                break;

            case Option.Type.Put:
                results_.value = spotPrice * dividendDiscount * (p1 - 0.5)
                                 - strike * riskFreeDiscount * (p2 - 0.5);
                break;

            default:
                Utils.QL_FAIL("unknown option type");
                break;
            }
        }
Пример #14
0
 public int length()
 {
     return(timeGrid_.size());
 }