Ejemplo n.º 1
0
        public LiborForwardModel(LiborForwardModelProcess process,
                                 LmVolatilityModel volaModel,
                                 LmCorrelationModel corrModel)
            : base(volaModel.parameters().Count + corrModel.parameters().Count)
        {
            f_             = new InitializedList <double>(process.size());
            accrualPeriod_ = new InitializedList <double>(process.size());
            covarProxy_    = new LfmCovarianceProxy(volaModel, corrModel);
            process_       = process;

            int k = volaModel.parameters().Count;

            for (int j = 0; j < k; j++)
            {
                arguments_[j] = volaModel.parameters()[j];
            }
            for (int j = 0; j < corrModel.parameters().Count; j++)
            {
                arguments_[j + k] = corrModel.parameters()[j];
            }

            for (int i = 0; i < process.size(); ++i)
            {
                accrualPeriod_[i] = process.accrualEndTimes()[i]
                                    - process.accrualStartTimes()[i];
                f_[i] = 1.0 / (1.0 + accrualPeriod_[i] * process_.initialValues()[i]);
            }
        }
Ejemplo n.º 2
0
        public LiborForwardModel(LiborForwardModelProcess process,
                          LmVolatilityModel volaModel,
                          LmCorrelationModel corrModel)
            : base(volaModel.parameters().Count() + corrModel.parameters().Count())
        {
            f_ = new InitializedList<double>(process.size());
            accrualPeriod_ = new InitializedList<double>(process.size());
            covarProxy_=new LfmCovarianceProxy(volaModel, corrModel);
            process_=process;

            /*copy(volaModel.parameters().begin(), volaModel.parameters().end(),
            arguments_.begin());
            copy(corrModel.parameters().begin(), corrModel.parameters().end(),
            arguments_.begin()+k);*/

            int k=volaModel.parameters().Count;
            for (int j = 0; j < k; j++)
                arguments_[j] = volaModel.parameters()[j];
            for (int j = 0; j < corrModel.parameters().Count; j++)
                arguments_[j+k] = corrModel.parameters()[j];

            for (int i=0; i < process.size(); ++i) {
                accrualPeriod_[i] =  process.accrualEndTimes()[i]
                                - process.accrualStartTimes()[i];
                f_[i] = 1.0/(1.0+accrualPeriod_[i]*process_.initialValues()[i]);
            }
        }
Ejemplo n.º 3
0
        public double discountBondOption(Option.Type type,
                                         double strike, double maturity,
                                         double bondMaturity)
        {
            List <double> accrualStartTimes
                = process_.accrualStartTimes();
            List <double> accrualEndTimes
                = process_.accrualEndTimes();

            if (!(accrualStartTimes.First() <= maturity && accrualStartTimes.Last() >= maturity))
            {
                throw new Exception("capet maturity does not fit to the process");
            }

            int i = accrualStartTimes.BinarySearch(maturity);

            if (i < 0)
            {
                // The lower_bound() algorithm finds the first position in a sequence that value can occupy
                // without violating the sequence's ordering
                // if BinarySearch does not find value the value, the index of the prev minor item is returned
                i = ~i + 1;
            }

            // impose limits. we need the one before last at max or the first at min
            i = Math.Max(Math.Min(i, accrualStartTimes.Count - 1), 0);

            if (!(i < process_.size() &&
                  Math.Abs(maturity - accrualStartTimes[i]) < 100 * Const.QL_EPSILON &&
                  Math.Abs(bondMaturity - accrualEndTimes[i]) < 100 * Const.QL_EPSILON))
            {
                throw new Exception("irregular fixings are not (yet) supported");
            }

            double tenor   = accrualEndTimes[i] - accrualStartTimes[i];
            double forward = process_.initialValues()[i];
            double capRate = (1.0 / strike - 1.0) / tenor;
            double var     = covarProxy_.integratedCovariance(i, i, process_.fixingTimes()[i]);
            double dis     = process_.index().forwardingTermStructure().link.discount(bondMaturity);

            double black = Utils.blackFormula(
                (type == Option.Type.Put ? Option.Type.Call : Option.Type.Put),
                capRate, forward, Math.Sqrt(var));

            double npv = dis * tenor * black;

            return(npv / (1.0 + capRate * tenor));
        }
Ejemplo n.º 4
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());
                    }
                }
            }
        }