コード例 #1
0
ファイル: TreeSwaptionEngine.cs プロジェクト: igitur/qlnet
        public override void calculate()
        {
            Utils.QL_REQUIRE(arguments_.settlementType == Settlement.Type.Physical, () =>
                             "cash-settled swaptions not priced with tree engine");

            Utils.QL_REQUIRE(model_ != null, () => "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();
            }

            DiscretizedSwaption swaption = new DiscretizedSwaption(arguments_, referenceDate, dayCounter);
            Lattice             lattice;

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

            List <double> stoppingTimes = new InitializedList <double>(arguments_.exercise.dates().Count);

            for (int i = 0; i < stoppingTimes.Count; ++i)
            {
                stoppingTimes[i] =
                    dayCounter.yearFraction(referenceDate,
                                            arguments_.exercise.date(i));
            }

            swaption.initialize(lattice, stoppingTimes.Last());

            double nextExercise;

            List <double> listExercise = new List <double>();

            listExercise.AddRange(stoppingTimes.FindAll(x => x >= 0));
            nextExercise = listExercise[0];
            swaption.rollback(nextExercise);

            results_.value = swaption.presentValue();
        }
コード例 #2
0
        public override void calculate()
        {
            Utils.QL_REQUIRE(arguments_.settlementType == Settlement.Type.Physical, () =>
                             "cash-settled swaptions not priced by Jamshidian engine");

            Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () =>
                             "cannot use the Jamshidian decomposition on exotic swaptions");

            Utils.QL_REQUIRE(arguments_.swap.spread.IsEqual(0.0), () =>
                             "non zero spread (" + arguments_.swap.spread + ") not allowed");

            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();
            }

            List <double> amounts = new InitializedList <double>(arguments_.fixedCoupons.Count);

            for (int i = 0; i < amounts.Count; i++)
            {
                amounts[i] = arguments_.fixedCoupons[i];
            }
            amounts[amounts.Count - 1] = amounts.Last() + arguments_.nominal;

            double maturity = dayCounter.yearFraction(referenceDate,
                                                      arguments_.exercise.date(0));

            List <double> fixedPayTimes = new InitializedList <double>(arguments_.fixedPayDates.Count);

            for (int i = 0; i < fixedPayTimes.Count; i++)
            {
                fixedPayTimes[i] =
                    dayCounter.yearFraction(referenceDate,
                                            arguments_.fixedPayDates[i]);
            }

            rStarFinder finder = new rStarFinder(model_, arguments_.nominal, maturity,
                                                 fixedPayTimes, amounts);
            Brent  s1d       = new Brent();
            double minStrike = -10.0;
            double maxStrike = 10.0;

            s1d.setMaxEvaluations(10000);
            s1d.setLowerBound(minStrike);
            s1d.setUpperBound(maxStrike);
            double rStar = s1d.solve(finder, 1e-8, 0.05, minStrike, maxStrike);

            Option.Type w = arguments_.type == VanillaSwap.Type.Payer ?
                            Option.Type.Put : Option.Type.Call;
            int size = arguments_.fixedCoupons.Count;

            double value = 0.0;

            for (int i = 0; i < size; i++)
            {
                double fixedPayTime =
                    dayCounter.yearFraction(referenceDate,
                                            arguments_.fixedPayDates[i]);
                double strike = model_.link.discountBond(maturity,
                                                         fixedPayTime,
                                                         rStar);
                double dboValue = model_.link.discountBondOption(
                    w, strike, maturity,
                    fixedPayTime);
                value += amounts[i] * dboValue;
            }
            results_.value = value;
        }
コード例 #3
0
        protected GMRESResult solveImpl(Vector b, Vector x0)
        {
            double      bn = Vector.Norm2(b);
            GMRESResult result;

            if (bn.IsEqual(0.0))
            {
                result = new GMRESResult(new InitializedList <double>(1, 0.0), b);
                return(result);
            }

            Vector x = !x0.empty() ? x0 : new Vector(b.size(), 0.0);
            Vector r = b - A_(x);

            double g = Vector.Norm2(r);

            if (g / bn < relTol_)
            {
                result = new GMRESResult(new InitializedList <double>(1, g / bn), x);
                return(result);
            }

            List <Vector> v = new InitializedList <Vector>(1, r / g);
            List <Vector> h = new InitializedList <Vector>(1, new Vector(maxIter_, 0.0));
            List <double> c = new List <double>(maxIter_ + 1),
                          s = new List <double>(maxIter_ + 1),
                          z = new List <double>(maxIter_ + 1);

            z[0] = g;

            List <double> errors = new InitializedList <double>(1, g / bn);

            for (int j = 0; j < maxIter_ && errors.Last() >= relTol_; ++j)
            {
                h.Add(new Vector(maxIter_, 0.0));
                Vector w = A_((M_ != null) ? M_(v[j]) : v[j]);

                for (int i = 0; i <= j; ++i)
                {
                    h[i][j] = Vector.DotProduct(w, v[i]);
                    w      -= h[i][j] * v[i];
                }

                h[j + 1][j] = Vector.Norm2(w);

                if (h[j + 1][j] < Const.QL_EPSILON * Const.QL_EPSILON)
                {
                    break;
                }

                v.Add(w / h[j + 1][j]);

                for (int i = 0; i < j; ++i)
                {
                    double h0 = c[i] * h[i][j] + s[i] * h[i + 1][j];
                    double h1 = -s[i] * h[i][j] + c[i] * h[i + 1][j];

                    h[i][j]     = h0;
                    h[i + 1][j] = h1;
                }

                double nu = Math.Sqrt((h[j][j]) * (h[j][j])
                                      + (h[j + 1][j]) * (h[j + 1][j]));

                c[j] = h[j][j] / nu;
                s[j] = h[j + 1][j] / nu;

                h[j][j]     = nu;
                h[j + 1][j] = 0.0;

                z[j + 1] = -s[j] * z[j];
                z[j]     = c[j] * z[j];

                errors.Add(Math.Abs(z[j + 1] / bn));
            }

            int k = v.Count - 1;

            Vector y = new Vector(k, 0.0);

            y[k - 1] = z[k - 1] / h[k - 1][k - 1];

            for (int i = k - 2; i >= 0; --i)
            {
                y[i] = (z[i] - h[i].inner_product(
                            i + 1, k, i + 1, y, 0.0)) / h[i][i];
            }

            Vector xm = new Vector(x.Count, 0.0);

            for (int i = 0; i < x.Count; i++)
            {
                xm[i] = v[i].inner_product(0, k, 0, y, 0.0);
            }

            xm = x + ((M_ != null) ? M_(xm) : xm);

            result = new GMRESResult(errors, xm);
            return(result);
        }