예제 #1
0
        public void testYYTermStructure()
        {
            // Testing year-on-year inflation term structure...

            SavedSettings backup = new SavedSettings();
            //IndexHistoryCleaner cleaner;

            // try the YY UK
            Calendar calendar         = new UnitedKingdom();
            BusinessDayConvention bdc = BusinessDayConvention.ModifiedFollowing;
            Date evaluationDate       = new Date(13, Month.August, 2007);

            evaluationDate = calendar.adjust(evaluationDate);
            Settings.setEvaluationDate(evaluationDate);


            // fixing data
            Date     from        = new Date(1, Month.January, 2005);
            Date     to          = new Date(13, Month.August, 2007);
            Schedule rpiSchedule = new MakeSchedule().from(from).to(to)
                                   .withTenor(new Period(1, TimeUnit.Months))
                                   .withCalendar(new UnitedKingdom())
                                   .withConvention(BusinessDayConvention.ModifiedFollowing).value();

            double[] fixData = { 189.9, 189.9, 189.6, 190.5, 191.6, 192.0,
                                 192.2, 192.2, 192.6, 193.1, 193.3, 193.6,
                                 194.1, 193.4, 194.2, 195.0, 196.5, 197.7,
                                 198.5, 198.5, 199.2, 200.1, 200.4, 201.1,
                                 202.7, 201.6, 203.1, 204.4, 205.4, 206.2,
                                 207.3 };

            RelinkableHandle <YoYInflationTermStructure> hy = new RelinkableHandle <YoYInflationTermStructure>();
            bool     interp = false;
            YYUKRPIr iir    = new YYUKRPIr(interp, hy);

            for (int i = 0; i < fixData.Length; i++)
            {
                iir.addFixing(rpiSchedule[i], fixData[i]);
            }

            YieldTermStructure nominalTS = nominalTermStructure();

            // now build the YoY inflation curve
            Datum[] yyData =
            {
                new Datum(new Date(13, Month.August, 2008),  2.95),
                new Datum(new Date(13, Month.August, 2009),  2.95),
                new Datum(new Date(13, Month.August, 2010),  2.93),
                new Datum(new Date(15, Month.August, 2011), 2.955),
                new Datum(new Date(13, Month.August, 2012), 2.945),
                new Datum(new Date(13, Month.August, 2013), 2.985),
                new Datum(new Date(13, Month.August, 2014),  3.01),
                new Datum(new Date(13, Month.August, 2015), 3.035),
                new Datum(new Date(13, Month.August, 2016), 3.055),                    // note that
                new Datum(new Date(13, Month.August, 2017), 3.075),                    // some dates will be on
                new Datum(new Date(13, Month.August, 2019), 3.105),                    // holidays but the payment
                new Datum(new Date(15, Month.August, 2022), 3.135),                    // calendar will roll them
                new Datum(new Date(13, Month.August, 2027), 3.155),
                new Datum(new Date(13, Month.August, 2032), 3.145),
                new Datum(new Date(13, Month.August, 2037), 3.145)
            };

            Period     observationLag = new Period(2, TimeUnit.Months);
            DayCounter dc             = new Thirty360();

            // now build the helpers ...
            List <BootstrapHelper <YoYInflationTermStructure> > helpers =
                makeHelpers(yyData, yyData.Length, iir, observationLag, calendar, bdc, dc);

            double baseYYRate = yyData[0].rate / 100.0;
            PiecewiseYoYInflationCurve <Linear> pYYTS = new PiecewiseYoYInflationCurve <Linear>(
                evaluationDate, calendar, dc, observationLag,
                iir.frequency(), iir.interpolated(), baseYYRate,
                new Handle <YieldTermStructure>(nominalTS), helpers);

            pYYTS.recalculate();

            // validation
            // yoy swaps should reprice to zero
            // yy rates should not equal yySwap rates
            double eps = 0.000001;
            // usual swap engine
            Handle <YieldTermStructure> hTS = new Handle <YieldTermStructure>(nominalTS);
            IPricingEngine sppe             = new DiscountingSwapEngine(hTS);

            // make sure that the index has the latest yoy term structure
            hy.linkTo(pYYTS);

            for (int j = 1; j < yyData.Length; j++)
            {
                from = nominalTS.referenceDate();
                to   = yyData[j].date;
                Schedule yoySchedule = new MakeSchedule().from(from).to(to)
                                       .withConvention(BusinessDayConvention.Unadjusted)  // fixed leg gets calendar from
                                       .withCalendar(calendar)                            // schedule
                                       .withTenor(new Period(1, TimeUnit.Years)).value(); // .back

                YearOnYearInflationSwap yyS2 = new YearOnYearInflationSwap(
                    YearOnYearInflationSwap.Type.Payer,
                    1000000.0,
                    yoySchedule,                    //fixed schedule, but same as yoy
                    yyData[j].rate / 100.0,
                    dc,
                    yoySchedule,
                    iir,
                    observationLag,
                    0.0,                            //spread on index
                    dc,
                    new UnitedKingdom());

                yyS2.setPricingEngine(sppe);



                Assert.IsTrue(Math.Abs(yyS2.NPV()) < eps, "fresh yoy swap NPV!=0 from TS "
                              + "swap quote for pt " + j
                              + ", is " + yyData[j].rate / 100.0
                              + " vs YoY rate " + pYYTS.yoyRate(yyData[j].date - observationLag)
                              + " at quote date " + (yyData[j].date - observationLag)
                              + ", NPV of a fresh yoy swap is " + yyS2.NPV()
                              + "\n      fair rate " + yyS2.fairRate()
                              + " payment " + yyS2.paymentConvention());
            }

            int jj = 3;

            for (int k = 0; k < 14; k++)
            {
                from = nominalTS.referenceDate() - new Period(k, TimeUnit.Months);
                to   = yyData[jj].date - new Period(k, TimeUnit.Months);
                Schedule yoySchedule = new MakeSchedule().from(from).to(to)
                                       .withConvention(BusinessDayConvention.Unadjusted) // fixed leg gets calendar from
                                       .withCalendar(calendar)                           // schedule
                                       .withTenor(new Period(1, TimeUnit.Years))
                                       .value();                                         //backwards()

                YearOnYearInflationSwap yyS3 = new YearOnYearInflationSwap(
                    YearOnYearInflationSwap.Type.Payer,
                    1000000.0,
                    yoySchedule,                    //fixed schedule, but same as yoy
                    yyData[jj].rate / 100.0,
                    dc,
                    yoySchedule,
                    iir,
                    observationLag,
                    0.0,                            //spread on index
                    dc,
                    new UnitedKingdom());

                yyS3.setPricingEngine(sppe);

                Assert.IsTrue(Math.Abs(yyS3.NPV()) < 20000.0,
                              "unexpected size of aged YoY swap, aged "
                              + k + " months: YY aged NPV = " + yyS3.NPV()
                              + ", legs " + yyS3.legNPV(0) + " and " + yyS3.legNPV(1)
                              );
            }
            // remove circular refernce
            hy.linkTo(new YoYInflationTermStructure());
        }
예제 #2
0
            // setup
            public CommonVars()
            {
                // option variables
                nominals = new List <double>()
                {
                    1000000
                };
                frequency = Frequency.Annual;
                // usual setup
                volatility = 0.01;
                length     = 7;
                calendar   = new UnitedKingdom();
                convention = BusinessDayConvention.ModifiedFollowing;
                Date today = new Date(13, Month.August, 2007);

                evaluationDate = calendar.adjust(today);
                Settings.setEvaluationDate(evaluationDate);
                settlementDays = 0;
                fixingDays     = 0;
                settlement     = calendar.advance(today, settlementDays, TimeUnit.Days);
                startDate      = settlement;
                dc             = new Thirty360();

                // yoy index
                //      fixing data
                Date     from        = new Date(1, Month.January, 2005);
                Date     to          = new Date(13, Month.August, 2007);
                Schedule rpiSchedule = new MakeSchedule().from(from).to(to)
                                       .withTenor(new Period(1, TimeUnit.Months))
                                       .withCalendar(new UnitedKingdom())
                                       .withConvention(BusinessDayConvention.ModifiedFollowing).value();

                double[] fixData = { 189.9,  189.9, 189.6, 190.5, 191.6, 192.0,
                                     192.2,  192.2, 192.6, 193.1, 193.3, 193.6,
                                     194.1,  193.4, 194.2, 195.0, 196.5, 197.7,
                                     198.5,  198.5, 199.2, 200.1, 200.4, 201.1,
                                     202.7,  201.6, 203.1, 204.4, 205.4, 206.2,
                                     207.3, -999.0, -999 };
                // link from yoy index to yoy TS
                bool interp = false;

                iir = new YYUKRPIr(interp, hy);
                for (int i = 0; i < rpiSchedule.Count; i++)
                {
                    iir.addFixing(rpiSchedule[i], fixData[i]);
                }

                YieldTermStructure nominalFF = new FlatForward(evaluationDate, 0.05, new ActualActual());

                nominalTS.linkTo(nominalFF);

                // now build the YoY inflation curve
                Period observationLag = new Period(2, TimeUnit.Months);

                Datum[] yyData =
                {
                    new Datum(new Date(13, Month.August, 2008),  2.95),
                    new Datum(new Date(13, Month.August, 2009),  2.95),
                    new Datum(new Date(13, Month.August, 2010),  2.93),
                    new Datum(new Date(15, Month.August, 2011), 2.955),
                    new Datum(new Date(13, Month.August, 2012), 2.945),
                    new Datum(new Date(13, Month.August, 2013), 2.985),
                    new Datum(new Date(13, Month.August, 2014),  3.01),
                    new Datum(new Date(13, Month.August, 2015), 3.035),
                    new Datum(new Date(13, Month.August, 2016), 3.055),                                // note that
                    new Datum(new Date(13, Month.August, 2017), 3.075),                                // some dates will be on
                    new Datum(new Date(13, Month.August, 2019), 3.105),                                // holidays but the payment
                    new Datum(new Date(15, Month.August, 2022), 3.135),                                // calendar will roll them
                    new Datum(new Date(13, Month.August, 2027), 3.155),
                    new Datum(new Date(13, Month.August, 2032), 3.145),
                    new Datum(new Date(13, Month.August, 2037), 3.145)
                };

                // now build the helpers ...
                List <BootstrapHelper <YoYInflationTermStructure> > helpers =
                    makeHelpers(yyData, yyData.Length, iir,
                                observationLag,
                                calendar, convention, dc);

                double baseYYRate = yyData[0].rate / 100.0;
                PiecewiseYoYInflationCurve <Linear> pYYTS = new PiecewiseYoYInflationCurve <Linear>(
                    evaluationDate, calendar, dc, observationLag,
                    iir.frequency(), iir.interpolated(), baseYYRate,
                    new Handle <YieldTermStructure>(nominalTS), helpers);

                pYYTS.recalculate();
                yoyTS = pYYTS as YoYInflationTermStructure;


                // make sure that the index has the latest yoy term structure
                hy.linkTo(pYYTS);
            }
예제 #3
0
        public void testYYIndex()
        {
            // Testing year-on-year inflation indices

            SavedSettings backup = new SavedSettings();
            //IndexHistoryCleaner cleaner = new IndexHistoryCleaner();

            YYEUHICP yyeuhicp = new YYEUHICP(true);

            if (yyeuhicp.name() != "EU YY_HICP" ||
                yyeuhicp.frequency() != Frequency.Monthly ||
                yyeuhicp.revised() ||
                !yyeuhicp.interpolated() ||
                yyeuhicp.ratio() ||
                yyeuhicp.availabilityLag() != new Period(1, TimeUnit.Months))
            {
                Assert.Fail("wrong year-on-year EU HICP data ("
                            + yyeuhicp.name() + ", "
                            + yyeuhicp.frequency() + ", "
                            + yyeuhicp.revised() + ", "
                            + yyeuhicp.interpolated() + ", "
                            + yyeuhicp.ratio() + ", "
                            + yyeuhicp.availabilityLag() + ")");
            }

            YYEUHICPr yyeuhicpr = new YYEUHICPr(true);

            if (yyeuhicpr.name() != "EU YYR_HICP" ||
                yyeuhicpr.frequency() != Frequency.Monthly ||
                yyeuhicpr.revised() ||
                !yyeuhicpr.interpolated() ||
                !yyeuhicpr.ratio() ||
                yyeuhicpr.availabilityLag() != new Period(1, TimeUnit.Months))
            {
                Assert.Fail("wrong year-on-year EU HICPr data ("
                            + yyeuhicpr.name() + ", "
                            + yyeuhicpr.frequency() + ", "
                            + yyeuhicpr.revised() + ", "
                            + yyeuhicpr.interpolated() + ", "
                            + yyeuhicpr.ratio() + ", "
                            + yyeuhicpr.availabilityLag() + ")");
            }

            YYUKRPI yyukrpi = new YYUKRPI(false);

            if (yyukrpi.name() != "UK YY_RPI" ||
                yyukrpi.frequency() != Frequency.Monthly ||
                yyukrpi.revised() ||
                yyukrpi.interpolated() ||
                yyukrpi.ratio() ||
                yyukrpi.availabilityLag() != new Period(1, TimeUnit.Months))
            {
                Assert.Fail("wrong year-on-year UK RPI data ("
                            + yyukrpi.name() + ", "
                            + yyukrpi.frequency() + ", "
                            + yyukrpi.revised() + ", "
                            + yyukrpi.interpolated() + ", "
                            + yyukrpi.ratio() + ", "
                            + yyukrpi.availabilityLag() + ")");
            }

            YYUKRPIr yyukrpir = new YYUKRPIr(false);

            if (yyukrpir.name() != "UK YYR_RPI" ||
                yyukrpir.frequency() != Frequency.Monthly ||
                yyukrpir.revised() ||
                yyukrpir.interpolated() ||
                !yyukrpir.ratio() ||
                yyukrpir.availabilityLag() != new Period(1, TimeUnit.Months))
            {
                Assert.Fail("wrong year-on-year UK RPIr data ("
                            + yyukrpir.name() + ", "
                            + yyukrpir.frequency() + ", "
                            + yyukrpir.revised() + ", "
                            + yyukrpir.interpolated() + ", "
                            + yyukrpir.ratio() + ", "
                            + yyukrpir.availabilityLag() + ")");
            }


            // Retrieval test.
            //----------------
            // make sure of the evaluation date
            Date evaluationDate = new Date(13, Month.August, 2007);

            evaluationDate = new UnitedKingdom().adjust(evaluationDate);
            Settings.setEvaluationDate(evaluationDate);

            // fixing data
            Date     from        = new Date(1, Month.January, 2005);
            Date     to          = new Date(13, Month.August, 2007);
            Schedule rpiSchedule = new MakeSchedule().from(from).to(to)
                                   .withTenor(new Period(1, TimeUnit.Months))
                                   .withCalendar(new UnitedKingdom())
                                   .withConvention(BusinessDayConvention.ModifiedFollowing).value();

            double[] fixData = { 189.9, 189.9, 189.6, 190.5, 191.6, 192.0,
                                 192.2, 192.2, 192.6, 193.1, 193.3, 193.6,
                                 194.1, 193.4, 194.2, 195.0, 196.5, 197.7,
                                 198.5, 198.5, 199.2, 200.1, 200.4, 201.1,
                                 202.7, 201.6, 203.1, 204.4, 205.4, 206.2,
                                 207.3 };

            bool     interp = false;
            YYUKRPIr iir    = new YYUKRPIr(interp);
            YYUKRPIr iirYES = new YYUKRPIr(true);

            for (int i = 0; i < fixData.Length; i++)
            {
                iir.addFixing(rpiSchedule[i], fixData[i]);
                iirYES.addFixing(rpiSchedule[i], fixData[i]);
            }

            Date todayMinusLag             = evaluationDate - iir.availabilityLag();
            KeyValuePair <Date, Date> lim0 = Utils.inflationPeriod(todayMinusLag, iir.frequency());

            todayMinusLag = lim0.Value + 1 - 2 * new Period(iir.frequency());

            double eps = 1.0e-8;

            // Interpolation tests
            //--------------------
            // (no TS so can't forecast).
            for (int i = 13; i < rpiSchedule.Count; i++)
            {
                KeyValuePair <Date, Date> lim    = Utils.inflationPeriod(rpiSchedule[i], iir.frequency());
                KeyValuePair <Date, Date> limBef = Utils.inflationPeriod(rpiSchedule[i - 12], iir.frequency());
                for (Date d = lim.Key; d <= lim.Value; d++)
                {
                    if (d < todayMinusLag)
                    {
                        double expected   = fixData[i] / fixData[i - 12] - 1.0;
                        double calculated = iir.fixing(d);
                        Assert.IsTrue(Math.Abs(calculated - expected) < eps,
                                      "Non-interpolated fixings not constant within a period: "
                                      + calculated
                                      + ", should be "
                                      + expected);

                        double dp    = lim.Value + 1 - lim.Key;
                        double dpBef = limBef.Value + 1 - limBef.Key;
                        double dl    = d - lim.Key;
                        // potentially does not work on 29th Feb
                        double dlBef = new NullCalendar().advance(d, -new Period(1, TimeUnit.Years),
                                                                  BusinessDayConvention.ModifiedFollowing) - limBef.Key;

                        double linearNow     = fixData[i] + (fixData[i + 1] - fixData[i]) * dl / dp;
                        double linearBef     = fixData[i - 12] + (fixData[i + 1 - 12] - fixData[i - 12]) * dlBef / dpBef;
                        double expectedYES   = linearNow / linearBef - 1.0;
                        double calculatedYES = iirYES.fixing(d);
                        Assert.IsTrue(Math.Abs(expectedYES - calculatedYES) < eps,
                                      "Error in interpolated fixings: expect " + expectedYES
                                      + " see " + calculatedYES
                                      + " flat " + calculated
                                      + ", data: " + fixData[i - 12] + ", " + fixData[i + 1 - 12]
                                      + ", " + fixData[i] + ", " + fixData[i + 1]
                                      + ", fac: " + dp + ", " + dl
                                      + ", " + dpBef + ", " + dlBef
                                      + ", to: " + linearNow + ", " + linearBef
                                      );
                    }
                }
            }
        }