예제 #1
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);
        }
예제 #2
0
        public PiecewiseTimeDependentHestonModel(Handle <YieldTermStructure> riskFreeRate,
                                                 Handle <YieldTermStructure> dividendYield,
                                                 Handle <Quote> s0,
                                                 double v0,
                                                 Parameter theta,
                                                 Parameter kappa,
                                                 Parameter sigma,
                                                 Parameter rho,
                                                 TimeGrid timeGrid)
            : base(5)
        {
            s0_            = s0;
            riskFreeRate_  = riskFreeRate;
            dividendYield_ = dividendYield;
            timeGrid_      = timeGrid;

            arguments_[0] = theta;
            arguments_[1] = kappa;
            arguments_[2] = sigma;
            arguments_[3] = rho;
            arguments_[4] = new ConstantParameter(v0, new PositiveConstraint());

            s0.registerWith(update);
            riskFreeRate.registerWith(update);
            dividendYield.registerWith(update);
        }
예제 #3
0
 public TreeLattice(TimeGrid timeGrid, int n) : base(timeGrid)
 {
     n_ = n;
     Utils.QL_REQUIRE(n > 0, () => "there is no zeronomial lattice!");
     statePrices_      = new InitializedList <Vector>(1, new Vector(1, 1.0));
     statePricesLimit_ = 0;
 }
예제 #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);
        }
            //! 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);
                    // vMin = value - 1.0;
                    // vMax = value + 1.0;
                    theta.change(value);
                }
            }
예제 #6
0
 public TreeCallableFixedRateBondEngine(ShortRateModel model, TimeGrid timeGrid,
                                        Handle <YieldTermStructure> termStructure)
     : base(model, timeGrid)
 {
     termStructure_ = termStructure;
     termStructure_.registerWith(update);
 }
예제 #7
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_));
        }
예제 #8
0
파일: multipath.cs 프로젝트: Yenyenx/qlnet
 public MultiPath(int nAsset, TimeGrid timeGrid)
 {
     multiPath_ = new List<Path>(nAsset);
     for (int i = 0; i < nAsset; i++)
         multiPath_.Add(new Path(timeGrid));
     if (!(nAsset > 0)) throw new ApplicationException("number of asset must be positive");
 }
예제 #9
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;
 }
예제 #10
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);
                // vMin = value - 10.0;
                // vMax = value + 10.0;
            }
            return numericTree;
        }
        //! Return by default a trinomial recombining tree
        public override Lattice tree(TimeGrid grid)
        {
            //throw new NotImplementedException();
            TrinomialTree trinomial = new TrinomialTree(dynamics().process(), grid);

            return(new ShortRateTree(trinomial, dynamics(), grid));
        }
 //! Plain tree build-up from short-rate dynamics
 public ShortRateTree(TrinomialTree tree,
                      ShortRateDynamics dynamics,
                      TimeGrid timeGrid)
     : base(timeGrid, tree.size(1))
 {
     tree_     = tree;
     dynamics_ = dynamics;
 }
예제 #13
0
 public TreeVanillaSwapEngine(ShortRateModel model,
                              TimeGrid timeGrid,
                              Handle <YieldTermStructure> termStructure)
     : base(model, timeGrid)
 {
     termStructure_ = termStructure;
     termStructure_.registerWith(update);
 }
예제 #14
0
        public override Lattice tree(TimeGrid grid)
        {
            ShortRateDynamics dyn   = dynamics();
            TrinomialTree     tree1 = new TrinomialTree(dyn.xProcess(), grid);
            TrinomialTree     tree2 = new TrinomialTree(dyn.yProcess(), grid);

            return((Lattice)(new ShortRateTree(tree1, tree2, dyn)));
        }
예제 #15
0
파일: multipath.cs 프로젝트: scchess/QLNet
 public MultiPath(int nAsset, TimeGrid timeGrid)
 {
     multiPath_ = new List <Path>(nAsset);
     for (int i = 0; i < nAsset; i++)
     {
         multiPath_.Add(new Path(timeGrid));
     }
     Utils.QL_REQUIRE(nAsset > 0, () => "number of asset must be positive");
 }
예제 #16
0
 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);
 }
예제 #17
0
파일: path.cs 프로젝트: akasolace/qlnet
        public Path(TimeGrid timeGrid, Vector values) {
            timeGrid_ = timeGrid;
            values_ = (Vector)values.Clone();
            if (values_.empty())
                values_ = new Vector(timeGrid_.size());

            if (values_.size() != timeGrid_.size())
                throw new ApplicationException("different number of times and asset values");
        }
예제 #18
0
파일: lattice.cs 프로젝트: sandboxorg/QLNet
 public TreeLattice(TimeGrid timeGrid, int n) : base(timeGrid)
 {
     n_ = n;
     if (!(n > 0))
     {
         throw new Exception("there is no zeronomial lattice!");
     }
     statePrices_      = new InitializedList <Vector>(1, new Vector(1, 1.0));
     statePricesLimit_ = 0;
 }
        public TrinomialTree(StochasticProcess1D process,
                             TimeGrid timeGrid,
                             bool isPositive /*= false*/)
            : base(timeGrid.size())
        {
            branchings_ = new List <Branching>();
            dx_         = new InitializedList <double>(1);
            timeGrid_   = timeGrid;
            x0_         = process.x0();

            int nTimeSteps = timeGrid.size() - 1;
            int jMin       = 0;
            int jMax       = 0;

            for (int i = 0; i < nTimeSteps; i++)
            {
                double t  = timeGrid[i];
                double dt = timeGrid.dt(i);

                //Variance must be independent of x
                double v2 = process.variance(t, 0.0, dt);
                double v  = Math.Sqrt(v2);
                dx_.Add(v * Math.Sqrt(3.0));

                Branching branching = new Branching();
                for (int j = jMin; j <= jMax; j++)
                {
                    double x    = x0_ + j * dx_[i];
                    double m    = process.expectation(t, x, dt);
                    int    temp = (int)(Math.Floor((m - x0_) / dx_[i + 1] + 0.5));

                    if (isPositive)
                    {
                        while (x0_ + (temp - 1) * dx_[i + 1] <= 0)
                        {
                            temp++;
                        }
                    }

                    double e  = m - (x0_ + temp * dx_[i + 1]);
                    double e2 = e * e;
                    double e3 = e * Math.Sqrt(3.0);

                    double p1 = (1.0 + e2 / v2 - e3 / v) / 6.0;
                    double p2 = (2.0 - e2 / v2) / 3.0;
                    double p3 = (1.0 + e2 / v2 + e3 / v) / 6.0;

                    branching.add(temp, p1, p2, p3);
                }
                branchings_.Add(branching);

                jMin = branching.jMin();
                jMax = branching.jMax();
            }
        }
예제 #20
0
        private Sample <IPath> next(bool antithetic)
        {
            if (brownianBridge_)
            {
                Utils.QL_FAIL("Brownian bridge not supported");
                return(null);
            }

            Sample <List <double> > sequence_ =
                antithetic
            ? generator_.lastSequence()
            : generator_.nextSequence();

            int m = process_.size();
            int n = process_.factors();

            MultiPath path = (MultiPath)next_.value;

            Vector asset = process_.initialValues();

            for (int j = 0; j < m; j++)
            {
                path[j].setFront(asset[j]);
            }

            Vector temp;

            next_.weight = sequence_.weight;

            TimeGrid timeGrid = path[0].timeGrid();
            double   t, dt;

            for (int i = 1; i < path.pathSize(); i++)
            {
                int offset = (i - 1) * n;
                t  = timeGrid[i - 1];
                dt = timeGrid.dt(i - 1);
                if (antithetic)
                {
                    temp = -1 * new Vector(sequence_.value.GetRange(offset, n));
                }
                else
                {
                    temp = new Vector(sequence_.value.GetRange(offset, n));
                }

                asset = process_.evolve(t, asset, dt, temp);
                for (int j = 0; j < m; j++)
                {
                    path[j][i] = asset[j];
                }
            }
            return(next_);
        }
예제 #21
0
        public Path(TimeGrid timeGrid, Vector values)
        {
            timeGrid_ = timeGrid;
            values_   = (Vector)values.Clone();
            if (values_.empty())
            {
                values_ = new Vector(timeGrid_.size());
            }

            Utils.QL_REQUIRE(values_.size() == timeGrid_.size(), () => "different number of times and asset values");
        }
예제 #22
0
 public MultiPath(int nAsset, TimeGrid timeGrid)
 {
     multiPath_ = new List <Path>(nAsset);
     for (int i = 0; i < nAsset; i++)
     {
         multiPath_.Add(new Path(timeGrid));
     }
     if (!(nAsset > 0))
     {
         throw new Exception("number of asset must be positive");
     }
 }
예제 #23
0
        public DiscretizedVanillaOption(VanillaOption.Arguments args, StochasticProcess process, TimeGrid grid) {
            arguments_ = args;

            stoppingTimes_ = new InitializedList<double>(args.exercise.dates().Count);
            for (int i=0; i<stoppingTimes_.Count; ++i) {
                stoppingTimes_[i] = process.time(args.exercise.date(i));
                if (!grid.empty()) {
                    // adjust to the given grid
                    stoppingTimes_[i] = grid.closestTime(stoppingTimes_[i]);
                }
            }
        }
예제 #24
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));
        }
예제 #25
0
 // constructors
 public PathGenerator(StochasticProcess process, double length, int timeSteps, GSG generator, bool brownianBridge)
 {
     brownianBridge_ = brownianBridge;
     generator_      = generator;
     dimension_      = generator_.dimension();
     timeGrid_       = new TimeGrid(length, timeSteps);
     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_ == timeSteps, () =>
                      "sequence generator dimensionality (" + dimension_ + ") != timeSteps (" + timeSteps + ")");
 }
예제 #26
0
        public override void calculate()
        {
            if (base.model_ == null)
            {
                throw new ArgumentException("no model specified");
            }

            Date       referenceDate;
            DayCounter dayCounter;

            ITermStructureConsistentModel tsmodel =
                (ITermStructureConsistentModel)base.model_.link;

            try
            {
                if (tsmodel != null)
                {
                    referenceDate = tsmodel.termStructure().link.referenceDate();
                    dayCounter    = tsmodel.termStructure().link.dayCounter();
                }
                else
                {
                    referenceDate = termStructure_.link.referenceDate();
                    dayCounter    = termStructure_.link.dayCounter();
                }
            }
            catch
            {
                referenceDate = termStructure_.link.referenceDate();
                dayCounter    = termStructure_.link.dayCounter();
            }

            DiscretizedSwap swap  = new DiscretizedSwap(arguments_, referenceDate, dayCounter);
            List <double>   times = swap.mandatoryTimes();
            Lattice         lattice;

            if (lattice_ != null)
            {
                lattice = lattice_;
            }
            else
            {
                TimeGrid timeGrid = new TimeGrid(times, times.Count, timeSteps_);
                lattice = model_.link.tree(timeGrid);
            }

            swap.initialize(lattice, times.Last());
            swap.rollback(0.0);

            results_.value = swap.presentValue();
        }
예제 #27
0
        public Path(TimeGrid timeGrid, Vector values)
        {
            timeGrid_ = timeGrid;
            values_   = (Vector)values.Clone();
            if (values_.empty())
            {
                values_ = new Vector(timeGrid_.size());
            }

            if (values_.size() != timeGrid_.size())
            {
                throw new ApplicationException("different number of times and asset values");
            }
        }
예제 #28
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");
        }
예제 #29
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();
 }
예제 #30
0
        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]);
            }
        }
        private void pathGenerator(UnderlyingInfo under)
        {
            ulong seed = 1;
            int timeSteps = 365;
            //
            int dimensions = this.processArr_.factors();

            double t = processArr_.time(maturity);

            TimeGrid grid = new TimeGrid(t, timeSteps);

            IRNG rndGenerator = (IRNG)new PseudoRandom().make_sequence_generator(dimensions * (grid.size() - 1), seed);

            this.pathGenerator_ = new MultiPathGenerator<IRNG>(this.processArr_, grid, rndGenerator, false);

        }
예제 #32
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_);

            if (dimension_ != timeGrid_.size() - 1)
            {
                throw new Exception("sequence generator dimensionality (" + dimension_
                                    + ") != timeSteps (" + (timeGrid_.size() - 1) + ")");
            }
        }
예제 #33
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();
 }
예제 #34
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);

            if (generator_.dimension() != process.factors() * (times.size() - 1))
            {
                throw new Exception("dimension (" + generator_.dimension()
                                    + ") is not equal to ("
                                    + process.factors() + " * " + (times.size() - 1)
                                    + ") the number of factors "
                                    + "times the number of time steps");
            }
            if (!(times.size() > 1))
            {
                throw new Exception("no times given");
            }
        }
예제 #35
0
        //@}
        public override void calculate()
        {
            Utils.QL_REQUIRE(model_ != null, () => "no model specified");

            Date       referenceDate;
            DayCounter dayCounter;

            ITermStructureConsistentModel tsmodel = (ITermStructureConsistentModel)base.model_.link;

            if (tsmodel != null)
            {
                referenceDate = tsmodel.termStructure().link.referenceDate();
                dayCounter    = tsmodel.termStructure().link.dayCounter();
            }
            else
            {
                referenceDate = termStructure_.link.referenceDate();
                dayCounter    = termStructure_.link.dayCounter();
            }

            DiscretizedCallableFixedRateBond callableBond = new DiscretizedCallableFixedRateBond(arguments_, referenceDate, dayCounter);
            Lattice lattice;

            if (lattice_ != null)
            {
                lattice = lattice_;
            }
            else
            {
                List <double> times    = callableBond.mandatoryTimes();
                TimeGrid      timeGrid = new TimeGrid(times, times.Count, timeSteps_);
                lattice = model_.link.tree(timeGrid);
            }

            double redemptionTime = dayCounter.yearFraction(referenceDate, arguments_.redemptionDate);

            callableBond.initialize(lattice, redemptionTime);
            callableBond.rollback(0.0);
            results_.value = results_.settlementValue = callableBond.presentValue();
        }
예제 #36
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));
            }
        }
        public override void calculate()
        {
            DayCounter rfdc   = process_.riskFreeRate().link.dayCounter();
            DayCounter divdc  = process_.dividendYield().link.dayCounter();
            DayCounter voldc  = process_.blackVolatility().link.dayCounter();
            Calendar   volcal = process_.blackVolatility().link.calendar();

            double s0 = process_.stateVariable().link.value();

            if (!(s0 > 0.0))
            {
                throw new ApplicationException("negative or null underlying given");
            }
            double v             = process_.blackVolatility().link.blackVol(arguments_.exercise.lastDate(), s0);
            Date   maturityDate  = arguments_.exercise.lastDate();
            double r             = process_.riskFreeRate().link.zeroRate(maturityDate, rfdc, Compounding.Continuous, Frequency.NoFrequency).rate();
            double q             = process_.dividendYield().link.zeroRate(maturityDate, divdc, Compounding.Continuous, Frequency.NoFrequency).rate();
            Date   referenceDate = process_.riskFreeRate().link.referenceDate();

            // binomial trees with constant coefficient
            var flatRiskFree  = new Handle <YieldTermStructure>(new FlatForward(referenceDate, r, rfdc));
            var flatDividends = new Handle <YieldTermStructure>(new FlatForward(referenceDate, q, divdc));
            var flatVol       = new Handle <BlackVolTermStructure>(new BlackConstantVol(referenceDate, volcal, v, voldc));

            PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff;

            if (payoff == null)
            {
                throw new ApplicationException("non-plain payoff given");
            }

            double maturity = rfdc.yearFraction(referenceDate, maturityDate);

            StochasticProcess1D bs =
                new GeneralizedBlackScholesProcess(process_.stateVariable(), flatDividends, flatRiskFree, flatVol);

            TimeGrid grid = new TimeGrid(maturity, timeSteps_);

            T tree = new T().factory(bs, maturity, timeSteps_, payoff.strike());

            BlackScholesLattice <T> lattice = new BlackScholesLattice <T>(tree, r, maturity, timeSteps_);

            DiscretizedVanillaOption option = new DiscretizedVanillaOption(arguments_, process_, grid);

            option.initialize(lattice, maturity);

            // Partial derivatives calculated from various points in the
            // binomial tree (Odegaard)

            // Rollback to third-last step, and get underlying price (s2) &
            // option values (p2) at this point
            option.rollback(grid[2]);
            Vector va2 = new Vector(option.values());

            if (!(va2.size() == 3))
            {
                throw new ApplicationException("Expect 3 nodes in grid at second step");
            }
            double p2h = va2[2];                   // high-price
            double s2  = lattice.underlying(2, 2); // high price

            // Rollback to second-last step, and get option value (p1) at
            // this point
            option.rollback(grid[1]);
            Vector va = new Vector(option.values());

            if (!(va.size() == 2))
            {
                throw new ApplicationException("Expect 2 nodes in grid at first step");
            }
            double p1 = va[1];

            // Finally, rollback to t=0
            option.rollback(0.0);
            double p0 = option.presentValue();
            double s1 = lattice.underlying(1, 1);

            // Calculate partial derivatives
            double delta0 = (p1 - p0) / (s1 - s0);   // dp/ds
            double delta1 = (p2h - p1) / (s2 - s1);  // dp/ds

            // Store results
            results_.value = p0;
            results_.delta = delta0;
            results_.gamma = 2.0 * (delta1 - delta0) / (s2 - s0);    //d(delta)/ds
            results_.theta = Utils.blackScholesTheta(process_,
                                                     results_.value.GetValueOrDefault(),
                                                     results_.delta.GetValueOrDefault(),
                                                     results_.gamma.GetValueOrDefault());
        }
 override public void setPosition(TimeGrid timeGrid,
                           DayCounter dayCounter,
                           Calendar calendar) 
 {
 
 }
예제 #39
0
 public override Lattice tree(TimeGrid grid){
     TrinomialTree trinomial = new TrinomialTree(dynamics().process(), grid, true);
     return new ShortRateTree(trinomial, dynamics(), grid);
 }
예제 #40
0
        public void testLambdaBootstrapping()
        {
            //"Testing caplet LMM lambda bootstrapping..."

            //SavedSettings backup;

            double tolerance = 1e-10;
            double[] lambdaExpected = {14.3010297550, 19.3821411939, 15.9816590141,
                                          15.9953118303, 14.0570815635, 13.5687599894,
                                          12.7477197786, 13.7056638165, 11.6191989567};

            LiborForwardModelProcess process = makeProcess();
            Matrix covar = process.covariance(0.0, null, 1.0);

            for (int i=0; i<9; ++i) {
                double calculated = Math.Sqrt(covar[i+1,i+1]);
                double expected   = lambdaExpected[i]/100;

                if (Math.Abs(calculated - expected) > tolerance)
                    Assert.Fail("Failed to reproduce expected lambda values"
                                + "\n    calculated: " + calculated
                                + "\n    expected:   " + expected);
            }

            LfmCovarianceParameterization param =  process.covarParam();

            List<double> tmp = process.fixingTimes();
            TimeGrid grid= new TimeGrid(tmp.Last(), 14);

            for (int t=0; t<grid.size(); ++t) {
                //verifier la presence du null
                Matrix diff = param.integratedCovariance(grid[t],null)
                            - param.integratedCovariance(grid[t], null);

                for (int i=0; i<diff.rows(); ++i)
                {
                    for (int j=0; j<diff.columns(); ++j)
                    {
                        if (Math.Abs(diff[i,j]) > tolerance)
                        {
                             Assert.Fail("Failed to reproduce integrated covariance"
                                          + "\n    calculated: " + diff[i,j]
                                          + "\n    expected:   " + 0);
                        }
                    }
                }
            }
        }
예제 #41
0
        public void testMonteCarloCapletPricing()
        {
            //"Testing caplet LMM Monte-Carlo caplet pricing..."

            //SavedSettings backup;

            /* factor loadings are taken from Hull & White article
               plus extra normalisation to get orthogonal eigenvectors
               http://www.rotman.utoronto.ca/~amackay/fin/libormktmodel2.pdf */
            double[] compValues = {0.85549771, 0.46707264, 0.22353259,
                                 0.91915359, 0.37716089, 0.11360610,
                                 0.96438280, 0.26413316,-0.01412414,
                                 0.97939148, 0.13492952,-0.15028753,
                                 0.95970595,-0.00000000,-0.28100621,
                                 0.97939148,-0.13492952,-0.15028753,
                                 0.96438280,-0.26413316,-0.01412414,
                                 0.91915359,-0.37716089, 0.11360610,
                                 0.85549771,-0.46707264, 0.22353259};

            Matrix volaComp=new Matrix(9,3);
            List<double> lcompValues=new InitializedList<double>(27,0);
            List<double> ltemp = new InitializedList<double>(3, 0);
            lcompValues=compValues.ToList();
            //std::copy(compValues, compValues+9*3, volaComp.begin());
            for (int i = 0; i < 9; i++)
            {
                ltemp = lcompValues.GetRange(3*i, 3);
                for (int j = 0; j < 3; j++)
                    volaComp[i, j] = ltemp[j];
            }
            LiborForwardModelProcess process1 = makeProcess();
            LiborForwardModelProcess process2 = makeProcess(volaComp);

            List<double> tmp = process1.fixingTimes();
            TimeGrid grid=new TimeGrid(tmp ,12);

            List<int> location=new List<int>();
            for (int i=0; i < tmp.Count; ++i) {
                location.Add(grid.index(tmp[i])) ;
            }

            // set-up a small Monte-Carlo simulation to price caplets
            // and ratchet caps using a one- and a three factor libor market model

             ulong seed = 42;
             LowDiscrepancy.icInstance = new InverseCumulativeNormal();
             IRNG rsg1 = (IRNG)new LowDiscrepancy().make_sequence_generator(
                                                            process1.factors()*(grid.size()-1), seed);
             IRNG rsg2 = (IRNG)new LowDiscrepancy().make_sequence_generator(
                                                            process2.factors()*(grid.size()-1), seed);

            MultiPathGenerator<IRNG> generator1=new MultiPathGenerator<IRNG> (process1, grid, rsg1, false);
            MultiPathGenerator<IRNG> generator2=new MultiPathGenerator<IRNG> (process2, grid, rsg2, false);

            const int nrTrails = 250000;
            List<GeneralStatistics> stat1 = new InitializedList<GeneralStatistics>(process1.size());
            List<GeneralStatistics> stat2 = new InitializedList<GeneralStatistics>(process2.size());
            List<GeneralStatistics> stat3 = new InitializedList<GeneralStatistics>(process2.size() - 1);
            for (int i=0; i<nrTrails; ++i) {
                Sample<MultiPath> path1 = generator1.next();
                Sample<MultiPath> path2 = generator2.next();

                List<double> rates1=new InitializedList<double>(len);
                List<double> rates2 = new InitializedList<double>(len);
                for (int j=0; j<process1.size(); ++j) {
                    rates1[j] = path1.value[j][location[j]];
                    rates2[j] = path2.value[j][location[j]];
                }

                List<double> dis1 = process1.discountBond(rates1);
                List<double> dis2 = process2.discountBond(rates2);

                for (int k=0; k<process1.size(); ++k) {
                    double accrualPeriod =  process1.accrualEndTimes()[k]
                                        - process1.accrualStartTimes()[k];
                    // caplet payoff function, cap rate at 4%
                    double payoff1 = Math.Max(rates1[k] - 0.04, 0.0) * accrualPeriod;

                    double payoff2 = Math.Max(rates2[k] - 0.04, 0.0) * accrualPeriod;
                    stat1[k].add(dis1[k] * payoff1);
                    stat2[k].add(dis2[k] * payoff2);

                    if (k != 0) {
                        // ratchet cap payoff function
                        double payoff3 =  Math.Max(rates2[k] - (rates2[k-1]+0.0025), 0.0)
                                      * accrualPeriod;
                        stat3[k-1].add(dis2[k] * payoff3);
                    }
                }

            }

            double[] capletNpv = {0.000000000000, 0.000002841629, 0.002533279333,
                                0.009577143571, 0.017746502618, 0.025216116835,
                                0.031608230268, 0.036645683881, 0.039792254012,
                                0.041829864365};

            double[] ratchetNpv = {0.0082644895, 0.0082754754, 0.0082159966,
                                 0.0082982822, 0.0083803357, 0.0084366961,
                                 0.0084173270, 0.0081803406, 0.0079533814};

            for (int k=0; k < process1.size(); ++k) {

                double calculated1 = stat1[k].mean();
                double tolerance1  = stat1[k].errorEstimate();
                double expected    = capletNpv[k];

                if (Math.Abs(calculated1 - expected) > tolerance1) {
                    Assert.Fail("Failed to reproduce expected caplet NPV"
                                + "\n    calculated: " + calculated1
                                + "\n    error int:  " + tolerance1
                                + "\n    expected:   " + expected);
                }

                double calculated2 = stat2[k].mean();
                double tolerance2  = stat2[k].errorEstimate();

                if (Math.Abs(calculated2 - expected) > tolerance2) {
                    Assert.Fail("Failed to reproduce expected caplet NPV"
                                + "\n    calculated: " + calculated2
                                + "\n    error int:  " + tolerance2
                                + "\n    expected:   " + expected);
                }

                if (k != 0) {
                    double calculated3 = stat3[k-1].mean();
                    double tolerance3  = stat3[k-1].errorEstimate();
                    expected    = ratchetNpv[k-1];

                    double refError = 1e-5; // 1e-5. error bars of the reference values

                    if (Math.Abs(calculated3 - expected) > tolerance3 + refError) {
                        Assert.Fail("Failed to reproduce expected caplet NPV"
                                    + "\n    calculated: " + calculated3
                                    + "\n    error int:  " + tolerance3 + refError
                                    + "\n    expected:   " + expected);
                    }
                }
            }
        }
예제 #42
0
파일: model.cs 프로젝트: ammachado/QLNet
 public abstract Lattice tree(TimeGrid t);
예제 #43
0
        public void testSwaptionPricing()
        {
            //"Testing forward swap and swaption pricing...");

            //SavedSettings backup;

            const int size  = 10;
            const int steps = 8*size;
            #if QL_USE_INDEXED_COUPON
            const double tolerance = 1e-6;
            #else
            const double tolerance = 1e-12;
            #endif

            List<Date> dates = new List<Date>();
            List<double> rates = new List<double>();
            dates.Add(new Date(4,9,2005));
            dates.Add(new Date(4,9,2011));
            rates.Add(0.04);
            rates.Add(0.08);

            IborIndex index = makeIndex(dates, rates);

            LiborForwardModelProcess process = new LiborForwardModelProcess(size, index);

            LmCorrelationModel corrModel = new LmExponentialCorrelationModel(size, 0.5);

            LmVolatilityModel volaModel = new LmLinearExponentialVolatilityModel(process.fixingTimes(),
                                                                                0.291, 1.483, 0.116, 0.00001);

               // set-up pricing engine
            process.setCovarParam((LfmCovarianceParameterization)
                                       new LfmCovarianceProxy(volaModel, corrModel));

            // set-up a small Monte-Carlo simulation to price swations
            List<double> tmp = process.fixingTimes();

            TimeGrid grid=new TimeGrid(tmp ,steps);

            List<int> location=new List<int>();
            for (int i=0; i < tmp.Count; ++i) {
                location.Add(grid.index(tmp[i])) ;
            }

            ulong seed=42;
            const int nrTrails = 5000;
            LowDiscrepancy.icInstance = new InverseCumulativeNormal();

            IRNG rsg = (InverseCumulativeRsg<RandomSequenceGenerator<MersenneTwisterUniformRng>
                                                                    ,InverseCumulativeNormal>)
            new PseudoRandom().make_sequence_generator(process.factors()*(grid.size()-1),seed);

            MultiPathGenerator<IRNG> generator=new MultiPathGenerator<IRNG>(process,
                                                                            grid,
                                                                            rsg, false);

            LiborForwardModel liborModel = new LiborForwardModel(process, volaModel, corrModel);

            Calendar calendar = index.fixingCalendar();
            DayCounter dayCounter = index.forwardingTermStructure().link.dayCounter();
            BusinessDayConvention convention = index.businessDayConvention();

            Date settlement = index.forwardingTermStructure().link.referenceDate();

            SwaptionVolatilityMatrix m = liborModel.getSwaptionVolatilityMatrix();

            for (int i=1; i < size; ++i) {
                for (int j=1; j <= size-i; ++j) {
                    Date fwdStart    = settlement + new Period(6*i, TimeUnit.Months);
                    Date fwdMaturity = fwdStart + new Period(6*j, TimeUnit.Months);

                    Schedule schedule =new Schedule(fwdStart, fwdMaturity, index.tenor(), calendar,
                                       convention, convention, DateGeneration.Rule.Forward, false);

                    double swapRate  = 0.0404;
                    VanillaSwap forwardSwap = new VanillaSwap(VanillaSwap.Type.Receiver, 1.0,
                                                                schedule, swapRate, dayCounter,
                                                                schedule, index, 0.0, index.dayCounter());
                    forwardSwap.setPricingEngine(new DiscountingSwapEngine(index.forwardingTermStructure()));

                    // check forward pricing first
                    double expected = forwardSwap.fairRate();
                    double calculated = liborModel.S_0(i-1,i+j-1);

                    if (Math.Abs(expected - calculated) > tolerance)
                        Assert.Fail("Failed to reproduce fair forward swap rate"
                                    + "\n    calculated: " + calculated
                                    + "\n    expected:   " + expected);

                    swapRate = forwardSwap.fairRate();
                    forwardSwap =
                        new VanillaSwap(VanillaSwap.Type.Receiver, 1.0,
                                        schedule, swapRate, dayCounter,
                                        schedule, index, 0.0, index.dayCounter());
                    forwardSwap.setPricingEngine(new DiscountingSwapEngine(index.forwardingTermStructure()));

                    if (i == j && i<=size/2) {
                        IPricingEngine engine =
                            new LfmSwaptionEngine(liborModel, index.forwardingTermStructure());
                        Exercise exercise =
                            new EuropeanExercise(process.fixingDates()[i]);

                        Swaption swaption =
                            new Swaption(forwardSwap, exercise);
                        swaption.setPricingEngine(engine);

                        GeneralStatistics stat = new GeneralStatistics();

                        for (int n=0; n<nrTrails; ++n) {
                            Sample<MultiPath> path = (n%2!=0) ? generator.antithetic()
                                                     : generator.next();

                            //Sample<MultiPath> path = generator.next();
                            List<double> rates_ = new InitializedList<double>(size);
                            for (int k=0; k<process.size(); ++k) {
                                rates_[k] = path.value[k][location[i]];
                            }
                            List<double> dis = process.discountBond(rates_);

                            double npv=0.0;
                            for (int k=i; k < i+j; ++k) {
                                npv += (swapRate - rates_[k])
                                       * (  process.accrualEndTimes()[k]
                                          - process.accrualStartTimes()[k])*dis[k];
                            }
                            stat.add(Math.Max(npv, 0.0));
                        }

                        if (Math.Abs(swaption.NPV() - stat.mean())
                            > stat.errorEstimate()*2.35)
                            Assert.Fail("Failed to reproduce swaption npv"
                                        + "\n    calculated: " + stat.mean()
                                        + "\n    expected:   " + swaption.NPV());
                    }
                }
            }
        }
        static void Main(string[] args)
        {

            DateTime timer = DateTime.Now;

            Date todaysDate = new Date(15, 2, 2002);
            Calendar calendar = new TARGET();
            Date settlementDate = new Date(19, 2, 2002);
            Settings.setEvaluationDate(todaysDate);

            // flat yield term structure impling 1x5 swap at 5%
            Quote flatRate = new SimpleQuote(0.04875825);
            Handle<YieldTermStructure> rhTermStructure = new Handle<YieldTermStructure>(
                          new FlatForward(settlementDate, new Handle<Quote>(flatRate),
                                          new Actual365Fixed()));

            // Define the ATM/OTM/ITM swaps
            Frequency fixedLegFrequency = Frequency.Annual;
            BusinessDayConvention fixedLegConvention = BusinessDayConvention.Unadjusted;
            BusinessDayConvention floatingLegConvention = BusinessDayConvention.ModifiedFollowing;
            DayCounter fixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European);
            Frequency floatingLegFrequency = Frequency.Semiannual;
            VanillaSwap.Type type = VanillaSwap.Type.Payer;
            double dummyFixedRate = 0.03;
            IborIndex indexSixMonths = new Euribor6M(rhTermStructure);

            Date startDate = calendar.advance(settlementDate, 1, TimeUnit.Years,
                                              floatingLegConvention);
            Date maturity = calendar.advance(startDate, 5, TimeUnit.Years,
                                             floatingLegConvention);
            Schedule fixedSchedule = new Schedule(startDate, maturity, new Period(fixedLegFrequency),
                                                    calendar, fixedLegConvention, fixedLegConvention,
                                                    DateGeneration.Rule.Forward, false);
            Schedule floatSchedule = new Schedule(startDate, maturity, new Period(floatingLegFrequency),
                                                    calendar, floatingLegConvention, floatingLegConvention,
                                                    DateGeneration.Rule.Forward, false);

            VanillaSwap swap = new VanillaSwap(
                type, 1000.0,
                fixedSchedule, dummyFixedRate, fixedLegDayCounter,
                floatSchedule, indexSixMonths, 0.0,
                indexSixMonths.dayCounter());
            swap.setPricingEngine(new DiscountingSwapEngine(rhTermStructure));
            double fixedAtmRate = swap.fairRate();
            double fixedOtmRate = fixedAtmRate * 1.2;
            double fixedItmRate = fixedAtmRate * 0.8;

            VanillaSwap atmSwap = new VanillaSwap(
                type, 1000.0,
                fixedSchedule, fixedAtmRate, fixedLegDayCounter,
                floatSchedule, indexSixMonths, 0.0,
                indexSixMonths.dayCounter());
            VanillaSwap otmSwap = new VanillaSwap(
                type, 1000.0,
                fixedSchedule, fixedOtmRate, fixedLegDayCounter,
                floatSchedule, indexSixMonths, 0.0,
                indexSixMonths.dayCounter());
            VanillaSwap itmSwap = new VanillaSwap(
                type, 1000.0,
                fixedSchedule, fixedItmRate, fixedLegDayCounter,
                floatSchedule, indexSixMonths, 0.0,
                indexSixMonths.dayCounter());

            // defining the swaptions to be used in model calibration
            List<Period> swaptionMaturities = new List<Period>(5);
            swaptionMaturities.Add(new Period(1, TimeUnit.Years));
            swaptionMaturities.Add(new Period(2, TimeUnit.Years));
            swaptionMaturities.Add(new Period(3, TimeUnit.Years));
            swaptionMaturities.Add(new Period(4, TimeUnit.Years));
            swaptionMaturities.Add(new Period(5, TimeUnit.Years));

            List<CalibrationHelper> swaptions = new List<CalibrationHelper>();

            // List of times that have to be included in the timegrid
            List<double> times = new List<double>();

            for (int i = 0; i < NumRows; i++)
            {
                int j = NumCols - i - 1; // 1x5, 2x4, 3x3, 4x2, 5x1
                int k = i * NumCols + j;
                Quote vol = new SimpleQuote(SwaptionVols[k]);
                swaptions.Add(new SwaptionHelper(swaptionMaturities[i],
                                   new Period(SwapLenghts[j], TimeUnit.Years),
                                   new Handle<Quote>(vol),
                                   indexSixMonths,
                                   indexSixMonths.tenor(),
                                   indexSixMonths.dayCounter(),
                                   indexSixMonths.dayCounter(),
                                   rhTermStructure, false));
                swaptions.Last().addTimesTo(times);
            }

            // Building time-grid
            TimeGrid grid = new TimeGrid(times, 30);


            // defining the models
            G2 modelG2 = new G2(rhTermStructure);
            HullWhite modelHw = new HullWhite(rhTermStructure);
            HullWhite modelHw2 = new HullWhite(rhTermStructure);
            BlackKarasinski modelBk = new BlackKarasinski(rhTermStructure);


            // model calibrations

            Console.WriteLine("G2 (analytic formulae) calibration");
            for (int i = 0; i < swaptions.Count; i++)
                swaptions[i].setPricingEngine(new G2SwaptionEngine(modelG2, 6.0, 16));
            CalibrateModel(modelG2, swaptions);
            Console.WriteLine("calibrated to:\n" +
                                "a     = {0:0.000000}, " +
                                "sigma = {1:0.0000000}\n" +
                                "b     = {2:0.000000}, " +
                                "eta   = {3:0.0000000}\n" +
                                "rho   = {4:0.00000}\n",
                                modelG2.parameters()[0],
                                modelG2.parameters()[1],
                                modelG2.parameters()[2],
                                modelG2.parameters()[3],
                                modelG2.parameters()[4]);

            Console.WriteLine("Hull-White (analytic formulae) calibration");
            for (int i = 0; i < swaptions.Count; i++)
                swaptions[i].setPricingEngine(new JamshidianSwaptionEngine(modelHw));
            CalibrateModel(modelHw, swaptions);
            Console.WriteLine("calibrated to:\n" +
                              "a = {0:0.000000}, " +
                              "sigma = {1:0.0000000}\n",
                              modelHw.parameters()[0],
                              modelHw.parameters()[1]);

            Console.WriteLine("Hull-White (numerical) calibration");
            for (int i = 0; i < swaptions.Count(); i++)
                swaptions[i].setPricingEngine(new TreeSwaptionEngine(modelHw2, grid));
            CalibrateModel(modelHw2, swaptions);
            Console.WriteLine("calibrated to:\n" +
                              "a = {0:0.000000}, " +
                              "sigma = {1:0.0000000}\n",
                              modelHw2.parameters()[0],
                              modelHw2.parameters()[1]);

            Console.WriteLine("Black-Karasinski (numerical) calibration");
            for (int i = 0; i < swaptions.Count; i++)
                swaptions[i].setPricingEngine(new TreeSwaptionEngine(modelBk, grid));
            CalibrateModel(modelBk, swaptions);
            Console.WriteLine("calibrated to:\n" +
                              "a = {0:0.000000}, " +
                              "sigma = {1:0.00000}\n",
                              modelBk.parameters()[0],
                              modelBk.parameters()[1]);


            // ATM Bermudan swaption pricing
            Console.WriteLine("Payer bermudan swaption "
                              + "struck at {0:0.00000 %} (ATM)",
                              fixedAtmRate);

            List<Date> bermudanDates = new List<Date>();
            List<CashFlow> leg = swap.fixedLeg();
            for (int i = 0; i < leg.Count; i++)
            {
                Coupon coupon = (Coupon)leg[i];
                bermudanDates.Add(coupon.accrualStartDate());
            }

            Exercise bermudanExercise = new BermudanExercise(bermudanDates);

            Swaption bermudanSwaption = new Swaption(atmSwap, bermudanExercise);

            // Do the pricing for each model

            // G2 price the European swaption here, it should switch to bermudan
            bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelG2, 50));
            Console.WriteLine("G2:       {0:0.00}", bermudanSwaption.NPV());

            bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw, 50));
            Console.WriteLine("HW:       {0:0.000}", bermudanSwaption.NPV());

            bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw2, 50));
            Console.WriteLine("HW (num): {0:0.000}", bermudanSwaption.NPV());

            bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelBk, 50));
            Console.WriteLine("BK:       {0:0.000}", bermudanSwaption.NPV());


            // OTM Bermudan swaption pricing
            Console.WriteLine("Payer bermudan swaption "
                              + "struck at {0:0.00000 %} (OTM)",
                              fixedOtmRate);

            Swaption otmBermudanSwaption = new Swaption(otmSwap, bermudanExercise);

            // Do the pricing for each model
            otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelG2, 50));
            Console.WriteLine("G2:       {0:0.0000}", otmBermudanSwaption.NPV());

            otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw, 50));
            Console.WriteLine("HW:       {0:0.0000}", otmBermudanSwaption.NPV());

            otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw2, 50));
            Console.WriteLine("HW (num): {0:0.000}", otmBermudanSwaption.NPV());

            otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelBk, 50));
            Console.WriteLine("BK:       {0:0.0000}", otmBermudanSwaption.NPV());

            // ITM Bermudan swaption pricing
            Console.WriteLine("Payer bermudan swaption "
                              + "struck at {0:0.00000 %} (ITM)",
                              fixedItmRate);

            Swaption itmBermudanSwaption = new Swaption(itmSwap, bermudanExercise);

            // Do the pricing for each model
            itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelG2, 50));
            Console.WriteLine("G2:       {0:0.000}", itmBermudanSwaption.NPV());

            itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw, 50));
            Console.WriteLine("HW:       {0:0.000}", itmBermudanSwaption.NPV());

            itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw2, 50));
            Console.WriteLine("HW (num): {0:0.000}", itmBermudanSwaption.NPV());

            itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelBk, 50));
            Console.WriteLine("BK:       {0:0.000}", itmBermudanSwaption.NPV());


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

            Console.Write("Press any key to continue ...");
            Console.ReadKey();
        }
예제 #45
0
파일: path.cs 프로젝트: Yenyenx/qlnet
 public Path(TimeGrid timeGrid)
     : this(timeGrid, new Vector())
 {
 }
예제 #46
0
 public Lattice(TimeGrid timeGrid)
 {
     t_ = timeGrid;
 }