Ejemplo n.º 1
0
        public void testObservable()
        {
            //.("Testing observability of instruments...");

             SimpleQuote me1 = new SimpleQuote(0.0);
             RelinkableHandle<Quote> h = new RelinkableHandle<Quote>(me1);
             Instrument s = new Stock(h);

             Flag f = new Flag();

             s.registerWith(f.update);

             s.NPV();
             me1.setValue(3.14);
             if (!f.isUp())
            Assert.Fail("Observer was not notified of instrument change");

             s.NPV();
             f.lower();
             SimpleQuote me2 = new SimpleQuote(0.0);
             h.linkTo(me2);
             if (!f.isUp())
            Assert.Fail("Observer was not notified of instrument change");

             f.lower();
             s.freeze();
             s.NPV();
             me2.setValue(2.71);
             if (f.isUp())
            Assert.Fail("Observer was notified of frozen instrument change");
             s.NPV();
             s.unfreeze();
             if (!f.isUp())
            Assert.Fail("Observer was not notified of instrument change");
        }
Ejemplo n.º 2
0
        public void testInitialisation()
        {
            //"Testing caplet LMM process initialisation..."

            //SavedSettings backup;

            DayCounter dayCounter = new Actual360();
            RelinkableHandle<YieldTermStructure> termStructure= new RelinkableHandle<YieldTermStructure>();;
            termStructure.linkTo(Utilities.flatRate(Date.Today, 0.04, dayCounter));

            IborIndex index=new Euribor6M(termStructure);
            OptionletVolatilityStructure capletVol = new ConstantOptionletVolatility(
                                                        termStructure.currentLink().referenceDate(),
                                                        termStructure.currentLink().calendar(),
                                                        BusinessDayConvention.Following,
                                                        0.2,
                                                        termStructure.currentLink().dayCounter());

            Calendar calendar = index.fixingCalendar();

            for (int daysOffset=0; daysOffset < 1825 /* 5 year*/; daysOffset+=8) {
                Date todaysDate = calendar.adjust(Date.Today+daysOffset);
                Settings.setEvaluationDate(todaysDate);
                Date settlementDate =
                    calendar.advance(todaysDate, index.fixingDays(), TimeUnit.Days);

                termStructure.linkTo(Utilities.flatRate(settlementDate, 0.04, dayCounter));

                LiborForwardModelProcess process=new LiborForwardModelProcess(60, index);

                List<double> fixings = process.fixingTimes();
                for (int i=1; i < fixings.Count-1; ++i) {
                    int ileft  = process.nextIndexReset(fixings[i]-0.000001);
                    int iright = process.nextIndexReset(fixings[i]+0.000001);
                    int ii     = process.nextIndexReset(fixings[i]);

                    if ((ileft != i) || (iright != i+1) || (ii != i+1)) {
                        Assert.Fail("Failed to next index resets");
                    }
                }

            }
        }
Ejemplo n.º 3
0
        IborIndex makeIndex(List<Date> dates,
                            List<double> rates)
        {
            DayCounter dayCounter = new Actual360();

            RelinkableHandle<YieldTermStructure> termStructure = new RelinkableHandle<YieldTermStructure>(); ;
            IborIndex index = new Euribor6M(termStructure);

            Date todaysDate =
            index.fixingCalendar().adjust(new Date(4, 9, 2005));
            Settings.setEvaluationDate(todaysDate);

            dates[0] = index.fixingCalendar().advance(todaysDate,
                                                   index.fixingDays(), TimeUnit.Days);
            Linear Interpolator = new Linear();
            termStructure.linkTo(new InterpolatedZeroCurve<Linear>(dates, rates, dayCounter, Interpolator));

            return index;
        }
Ejemplo n.º 4
0
        public void testFSpreadedObs()
        {
            // ("Testing observability of forward-spreaded term structure...");

             CommonVars vars = new CommonVars();

             SimpleQuote me = new SimpleQuote(0.01);
             Handle<Quote> mh = new Handle<Quote>(me);
             RelinkableHandle<YieldTermStructure> h = new RelinkableHandle<YieldTermStructure>(); //(vars.dummyTermStructure);
             YieldTermStructure spreaded = new ForwardSpreadedTermStructure(h, mh);
             Flag flag = new Flag();
             spreaded.registerWith(flag.update);
             h.linkTo(vars.termStructure);
             if (!flag.isUp())
            Console.WriteLine("Observer was not notified of term structure change");
             flag.lower();
             me.setValue(0.005);
             if (!flag.isUp())
            Console.WriteLine("Observer was not notified of spread change");
        }
Ejemplo n.º 5
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());
        }
Ejemplo n.º 6
0
            // setup
            public CommonVars()
            {
                startYears = 1;
                length = 5;
                type = VanillaSwap.Type.Payer;
                nominal = 1000.0;
                settlementDays = 2;
                fixedConvention = BusinessDayConvention.Unadjusted;
                floatingConvention = BusinessDayConvention.ModifiedFollowing;
                fixedFrequency = Frequency.Annual;
                floatingFrequency = Frequency.Semiannual;
                fixedDayCount = new Thirty360();

                termStructure = new RelinkableHandle<YieldTermStructure>();
                termStructure.linkTo(Utilities.flatRate(new Date(19, Month.February, 2002), 0.04875825, new Actual365Fixed()));

                index = new Euribor6M(termStructure);
                calendar = index.fixingCalendar();
                today = calendar.adjust(Date.Today);
                settlement = calendar.advance(today, settlementDays, TimeUnit.Days);
            }
Ejemplo n.º 7
0
        public void testCachedMarketValue()
        {
            // Testing credit-default swap against cached market values...

            SavedSettings backup = new SavedSettings();

            Settings.setEvaluationDate(new Date(9,Month.June,2006));
            Date evalDate = Settings.evaluationDate();
            Calendar calendar = new UnitedStates();

            List<Date> discountDates = new List<Date>();
            discountDates.Add(evalDate);
            discountDates.Add(calendar.advance(evalDate, 1, TimeUnit.Weeks,  BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 1, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 2, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 3, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 6, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate,12, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 2, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 3, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 4, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 5, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 6, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 7, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 8, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate, 9, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate,10, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            discountDates.Add(calendar.advance(evalDate,15, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));

            List<double> dfs = new List<double>();
            dfs.Add(1.0);
            dfs.Add(0.9990151375768731);
            dfs.Add(0.99570502636871183);
            dfs.Add(0.99118260474528685);
            dfs.Add(0.98661167950906203);
            dfs.Add(0.9732592953359388 );
            dfs.Add(0.94724424481038083);
            dfs.Add(0.89844996737120875 );
            dfs.Add(0.85216647839921411 );
            dfs.Add(0.80775477692556874 );
            dfs.Add(0.76517289234200347 );
            dfs.Add(0.72401019553182933 );
            dfs.Add(0.68503909569219212 );
            dfs.Add(0.64797499814013748 );
            dfs.Add(0.61263171936255534 );
            dfs.Add(0.5791942350748791  );
            dfs.Add(0.43518868769953606 );

            DayCounter curveDayCounter = new Actual360();

            RelinkableHandle<YieldTermStructure> discountCurve = new RelinkableHandle<YieldTermStructure>();
            discountCurve.linkTo( new InterpolatedDiscountCurve<LogLinear>( discountDates, dfs, curveDayCounter,null,null,null,new LogLinear() ) );

            DayCounter dayCounter = new Thirty360();
            List<Date> dates = new List<Date>();
            dates.Add(evalDate);
            dates.Add(calendar.advance(evalDate, 6, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing));
            dates.Add(calendar.advance(evalDate, 1, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            dates.Add(calendar.advance(evalDate, 2, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            dates.Add(calendar.advance(evalDate, 3, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            dates.Add(calendar.advance(evalDate, 4, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            dates.Add(calendar.advance(evalDate, 5, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            dates.Add(calendar.advance(evalDate, 7, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
            dates.Add(calendar.advance(evalDate,10, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));

            List<double> defaultProbabilities = new List<double>();
            defaultProbabilities.Add(0.0000);
            defaultProbabilities.Add(0.0047);
            defaultProbabilities.Add(0.0093);
            defaultProbabilities.Add(0.0286);
            defaultProbabilities.Add(0.0619);
            defaultProbabilities.Add(0.0953);
            defaultProbabilities.Add(0.1508);
            defaultProbabilities.Add(0.2288);
            defaultProbabilities.Add(0.3666);

            List<double> hazardRates = new List<double>();
            hazardRates.Add(0.0);
            for (int i=1; i<dates.Count; ++i)
            {
                double t1 = dayCounter.yearFraction(dates[0], dates[i-1]);
                double t2 = dayCounter.yearFraction(dates[0], dates[i]);
                double S1 = 1.0 - defaultProbabilities[i-1];
                double S2 = 1.0 - defaultProbabilities[i];
                hazardRates.Add(Math.Log(S1/S2)/(t2-t1));
            }

            RelinkableHandle<DefaultProbabilityTermStructure> piecewiseFlatHazardRate = new RelinkableHandle<DefaultProbabilityTermStructure>();
            piecewiseFlatHazardRate.linkTo(new InterpolatedHazardRateCurve<BackwardFlat>(dates,hazardRates,new Thirty360()));

            // Testing credit default swap

            // Build the schedule
            Date issueDate = new Date(20, Month.March, 2006);
            Date maturity = new Date(20, Month.June, 2013);
            Frequency cdsFrequency = Frequency.Semiannual;
            BusinessDayConvention cdsConvention = BusinessDayConvention.ModifiedFollowing;

            Schedule schedule = new Schedule(issueDate, maturity, new Period(cdsFrequency), calendar,
                                                   cdsConvention, cdsConvention,
                                                   DateGeneration.Rule.Forward, false);

            // Build the CDS
            double recoveryRate = 0.25;
            double fixedRate=0.0224;
            DayCounter dayCount= new Actual360();
            double cdsNotional=100.0;

            CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, cdsNotional, fixedRate,
                                        schedule, cdsConvention, dayCount, true, true);
            cds.setPricingEngine(new MidPointCdsEngine(piecewiseFlatHazardRate, recoveryRate,discountCurve));

            double calculatedNpv = cds.NPV();
            double calculatedFairRate = cds.fairSpread();

            double npv = -1.364048777;        // from Bloomberg we have 98.15598868 - 100.00;
            double fairRate =  0.0248429452; // from Bloomberg we have 0.0258378;

            double tolerance = 1e-9;

            if (Math.Abs(npv - calculatedNpv) > tolerance)
                Assert.Fail(
                    "Failed to reproduce the npv for the given credit-default swap\n"
                    + "    computed NPV:  " + calculatedNpv + "\n"
                    + "    Given NPV:     " + npv);

            if ( Math.Abs( fairRate - calculatedFairRate ) > tolerance )
                Assert.Fail( "Failed to reproduce the fair rate for the given credit-default swap\n"
                    + "    computed fair rate:  " + calculatedFairRate + "\n"
                    + "    Given fair rate:     " + fairRate );
        }
Ejemplo n.º 8
0
        public void testCachedValue()
        {
            // Testing credit-default swap against cached values...

            SavedSettings backup = new SavedSettings();

            // Initialize curves
            Settings.setEvaluationDate(new Date(9,Month.June,2006));
            Date today = Settings.evaluationDate();
            Calendar calendar = new TARGET();

            Handle<Quote> hazardRate = new Handle<Quote>(new SimpleQuote(0.01234));
            RelinkableHandle<DefaultProbabilityTermStructure> probabilityCurve = new RelinkableHandle<DefaultProbabilityTermStructure>();
            probabilityCurve.linkTo(new FlatHazardRate(0, calendar, hazardRate, new Actual360()));

            RelinkableHandle<YieldTermStructure> discountCurve = new RelinkableHandle<YieldTermStructure>();

            discountCurve.linkTo(new FlatForward(today,0.06,new Actual360()));

            // Build the schedule
            Date issueDate = calendar.advance(today, -1, TimeUnit.Years);
            Date maturity = calendar.advance(issueDate, 10, TimeUnit.Years);
            Frequency frequency = Frequency.Semiannual;
            BusinessDayConvention convention = BusinessDayConvention.ModifiedFollowing;

            Schedule schedule = new Schedule(issueDate, maturity, new Period(frequency), calendar,
                                    convention, convention, DateGeneration.Rule.Forward, false);

            // Build the CDS
            double fixedRate = 0.0120;
            DayCounter dayCount = new Actual360();
            double notional = 10000.0;
            double recoveryRate = 0.4;

            CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, notional, fixedRate,
                                        schedule, convention, dayCount, true, true);
            cds.setPricingEngine(new MidPointCdsEngine(probabilityCurve,recoveryRate,discountCurve));

            double npv = 295.0153398;
            double fairRate = 0.007517539081;

            double calculatedNpv = cds.NPV();
            double calculatedFairRate = cds.fairSpread();
            double tolerance = 1.0e-7;

            if (Math.Abs(calculatedNpv - npv) > tolerance)
                Assert.Fail(
                    "Failed to reproduce NPV with mid-point engine\n"
                    + "    calculated NPV: " + calculatedNpv + "\n"
                    + "    expected NPV:   " + npv);

            if (Math.Abs(calculatedFairRate - fairRate) > tolerance)
                Assert.Fail(
                    "Failed to reproduce fair rate with mid-point engine\n"
                    + "    calculated fair rate: " + calculatedFairRate + "\n"
                    + "    expected fair rate:   " + fairRate);

            cds.setPricingEngine(new IntegralCdsEngine(new Period(1,TimeUnit.Days),probabilityCurve,
                                                                    recoveryRate,discountCurve));

            calculatedNpv = cds.NPV();
            calculatedFairRate = cds.fairSpread();
            tolerance = 1.0e-5;

            if (Math.Abs(calculatedNpv - npv) > notional*tolerance*10)
                Assert.Fail(
                    "Failed to reproduce NPV with integral engine "
                    + "(step = 1 day)\n"
                    + "    calculated NPV: " + calculatedNpv + "\n"
                    + "    expected NPV:   " + npv);

            if (Math.Abs(calculatedFairRate - fairRate) > tolerance)
                Assert.Fail(
                    "Failed to reproduce fair rate with integral engine "
                    + "(step = 1 day)\n"
                    + "    calculated fair rate: " + calculatedFairRate + "\n"
                    + "    expected fair rate:   " + fairRate);

            cds.setPricingEngine(new IntegralCdsEngine(new Period(1,TimeUnit.Weeks),probabilityCurve,recoveryRate,discountCurve));

            calculatedNpv = cds.NPV();
            calculatedFairRate = cds.fairSpread();
            tolerance = 1.0e-5;

            if (Math.Abs(calculatedNpv - npv) > notional*tolerance*10)
                Assert.Fail(
                    "Failed to reproduce NPV with integral engine "
                    +"(step = 1 week)\n"
                    + "    calculated NPV: " + calculatedNpv + "\n"
                    + "    expected NPV:   " + npv);

            if (Math.Abs(calculatedFairRate - fairRate) > tolerance)
                Assert.Fail(
                    "Failed to reproduce fair rate with integral engine "
                    +"(step = 1 week)\n"
                    + "    calculated fair rate: " + calculatedFairRate + "\n"
                    + "    expected fair rate:   " + fairRate);
        }
Ejemplo n.º 9
0
        public void testIsdaEngine()
        {
            // Testing ISDA engine calculations for credit-default swaps

            SavedSettings backup = new SavedSettings();

            Date tradeDate = new Date(21, Month.May, 2009);

            Settings.setEvaluationDate(tradeDate);


            //build an ISDA compliant yield curve
            //data comes from Markit published rates
            List <RateHelper> isdaRateHelpers = new List <RateHelper>();

            int[]    dep_tenors = { 1, 2, 3, 6, 9, 12 };
            double[] dep_quotes = { 0.003081,
                                    0.005525,
                                    0.007163,
                                    0.012413,
                                    0.014,
                                    0.015488 };

            for (int i = 0; i < dep_tenors.Length; i++)
            {
                isdaRateHelpers.Add(new DepositRateHelper(dep_quotes[i], new Period(dep_tenors[i], TimeUnit.Months), 2,
                                                          new WeekendsOnly(), BusinessDayConvention.ModifiedFollowing, false, new Actual360())
                                    );
            }
            int[]    swap_tenors = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 20, 25, 30 };
            double[] swap_quotes = { 0.011907,
                                     0.01699,
                                     0.021198,
                                     0.02444,
                                     0.026937,
                                     0.028967,
                                     0.030504,
                                     0.031719,
                                     0.03279,
                                     0.034535,
                                     0.036217,
                                     0.036981,
                                     0.037246,
                                     0.037605 };

            IborIndex isda_ibor = new IborIndex("IsdaIbor", new Period(3, TimeUnit.Months), 2, new USDCurrency(),
                                                new WeekendsOnly(), BusinessDayConvention.ModifiedFollowing, false, new Actual360());

            for (int i = 0; i < swap_tenors.Length; i++)
            {
                isdaRateHelpers.Add(new SwapRateHelper(swap_quotes[i], new Period(swap_tenors[i], TimeUnit.Years),
                                                       new WeekendsOnly(), Frequency.Semiannual, BusinessDayConvention.ModifiedFollowing, new Thirty360(),
                                                       isda_ibor));
            }

            RelinkableHandle <YieldTermStructure> discountCurve = new RelinkableHandle <YieldTermStructure>();

            discountCurve.linkTo(new PiecewiseYieldCurve <Discount, LogLinear>(0, new WeekendsOnly(), isdaRateHelpers,
                                                                               new Actual365Fixed()));


            RelinkableHandle <DefaultProbabilityTermStructure> probabilityCurve = new RelinkableHandle <DefaultProbabilityTermStructure>();

            Date[]   termDates = { new Date(20, Month.June, 2010),
                                   new Date(20,   Month.June, 2011),
                                   new Date(20,   Month.June, 2012),
                                   new Date(20,   Month.June, 2016),
                                   new Date(20,   Month.June, 2019) };
            double[] spreads    = { 0.001, 0.1 };
            double[] recoveries = { 0.2, 0.4 };

            double[] markitValues = { 97798.29358,  //0.001
                                      97776.11889,  //0.001
                                      -914971.5977, //0.1
                                      -894985.6298, //0.1
                                      186921.3594,  //0.001
                                      186839.8148,  //0.001
                                      -1646623.672, //0.1
                                      -1579803.626, //0.1
                                      274298.9203,
                                      274122.4725,
                                      -2279730.93,
                                      -2147972.527,
                                      592420.2297,
                                      591571.2294,
                                      -3993550.206,
                                      -3545843.418,
                                      797501.1422,
                                      795915.9787,
                                      -4702034.688,
                                      -4042340.999 };
#if !QL_USE_INDEXED_COUPON
            double tolerance = 1.0e-2; //TODO Check calculation , tolerance must be 1.0e-6;
#else
            /* The risk-free curve is a bit off. We might skip the tests
             * altogether and rely on running them with indexed coupons
             * disabled, but leaving them can be useful anyway. */
            double tolerance = 1.0e-3;
#endif

            int l = 0;

            for (int i = 0; i < termDates.Length; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    for (int k = 0; k < 2; k++)
                    {
                        CreditDefaultSwap quotedTrade = new MakeCreditDefaultSwap(termDates[i], spreads[j])
                                                        .withNominal(10000000.0).value();

                        double h = quotedTrade.impliedHazardRate(0.0,
                                                                 discountCurve,
                                                                 new Actual365Fixed(),
                                                                 recoveries[k],
                                                                 1e-10,
                                                                 PricingModel.ISDA);

                        probabilityCurve.linkTo(new FlatHazardRate(0, new WeekendsOnly(), h, new Actual365Fixed()));

                        IsdaCdsEngine engine = new IsdaCdsEngine(probabilityCurve, recoveries[k], discountCurve);

                        CreditDefaultSwap conventionalTrade = new MakeCreditDefaultSwap(termDates[i], 0.01)
                                                              .withNominal(10000000.0)
                                                              .withPricingEngine(engine).value();

                        double x = conventionalTrade.notional().Value;
                        double y = conventionalTrade.fairUpfront();

                        double calculated = Math.Abs((x * y) - markitValues[l]);

                        QAssert.IsTrue(calculated <= tolerance);

                        l++;
                    }
                }
            }
        }
Ejemplo n.º 10
0
        void testBootstrapFromSpread <T, I>()
            where T : ITraits <DefaultProbabilityTermStructure>, new()
            where I : class, IInterpolationFactory, new()
        {
            Calendar calendar = new TARGET();

            Date today = Settings.Instance.evaluationDate();

            int settlementDays = 1;

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

            quote.Add(0.005);
            quote.Add(0.006);
            quote.Add(0.007);
            quote.Add(0.009);

            List <int> n = new List <int>();

            n.Add(1);
            n.Add(2);
            n.Add(3);
            n.Add(5);

            Frequency             frequency  = Frequency.Quarterly;
            BusinessDayConvention convention = BusinessDayConvention.Following;

            DateGeneration.Rule rule       = DateGeneration.Rule.TwentiethIMM;
            DayCounter          dayCounter = new Thirty360();
            double recoveryRate            = 0.4;

            RelinkableHandle <YieldTermStructure> discountCurve = new RelinkableHandle <YieldTermStructure>();

            discountCurve.linkTo(new FlatForward(today, 0.06, new Actual360()));

            List <CdsHelper> helpers = new List <CdsHelper>();

            for (int i = 0; i < n.Count; i++)
            {
                helpers.Add(
                    new SpreadCdsHelper(quote[i], new Period(n[i], TimeUnit.Years),
                                        settlementDays, calendar,
                                        frequency, convention, rule,
                                        dayCounter, recoveryRate,
                                        discountCurve));
            }

            RelinkableHandle <DefaultProbabilityTermStructure> piecewiseCurve = new RelinkableHandle <DefaultProbabilityTermStructure>();

            piecewiseCurve.linkTo(
                new PiecewiseDefaultCurve <T, I>(today, helpers,
                                                 new Thirty360()));

            double notional  = 1.0;
            double tolerance = 1.0e-6;

            // ensure apple-to-apple comparison
            SavedSettings backup = new SavedSettings();

            Settings.Instance.includeTodaysCashFlows = true;

            for (int i = 0; i < n.Count; i++)
            {
                Date protectionStart = today + settlementDays;
                Date startDate       = calendar.adjust(protectionStart, convention);
                Date endDate         = today + new Period(n[i], TimeUnit.Years);

                Schedule schedule = new Schedule(startDate, endDate, new Period(frequency), calendar,
                                                 convention, BusinessDayConvention.Unadjusted, rule, false);

                CreditDefaultSwap cds = new CreditDefaultSwap(CreditDefaultSwap.Protection.Side.Buyer, notional, quote[i],
                                                              schedule, convention, dayCounter,
                                                              true, true, protectionStart);
                cds.setPricingEngine(new MidPointCdsEngine(piecewiseCurve, recoveryRate,
                                                           discountCurve));

                // test
                double inputRate    = quote[i];
                double computedRate = cds.fairSpread();
                if (Math.Abs(inputRate - computedRate) > tolerance)
                {
                    QAssert.Fail(
                        "\nFailed to reproduce fair spread for " + n[i] +
                        "Y credit-default swaps\n"
                        + "    computed rate: " + computedRate.ToString() + "\n"
                        + "    input rate:    " + inputRate.ToString());
                }
            }
        }
Ejemplo n.º 11
0
        public void testCurveConsistency <T, I, B>(CommonVars vars, I interpolator, double tolerance)
            where T : BootstrapTraits, new()
            where I : IInterpolationFactory, new()
            where B : IBootStrap, new()
        {
            vars.termStructure = new PiecewiseYieldCurve <T, I, B>(vars.settlement, vars.instruments,
                                                                   new Actual360(), new List <Handle <Quote> >(), new List <Date>(), 1.0e-12, interpolator);

            RelinkableHandle <YieldTermStructure> curveHandle = new RelinkableHandle <YieldTermStructure>();

            curveHandle.linkTo(vars.termStructure);

            // check deposits
            for (int i = 0; i < vars.deposits; i++)
            {
                Euribor index         = new Euribor(new Period(vars.depositData[i].n, vars.depositData[i].units), curveHandle);
                double  expectedRate  = vars.depositData[i].rate / 100,
                        estimatedRate = index.fixing(vars.today);
                if (Math.Abs(expectedRate - estimatedRate) > tolerance)
                {
                    Console.WriteLine(vars.depositData[i].n + " "
                                      + (vars.depositData[i].units == TimeUnit.Weeks ? "week(s)" : "month(s)")
                                      + " deposit:"
                                      + "\n    estimated rate: " + estimatedRate
                                      + "\n    expected rate:  " + expectedRate);
                }
            }

            // check swaps
            IborIndex euribor6m = new Euribor6M(curveHandle);

            for (int i = 0; i < vars.swaps; i++)
            {
                Period tenor = new Period(vars.swapData[i].n, vars.swapData[i].units);

                VanillaSwap swap = new MakeVanillaSwap(tenor, euribor6m, 0.0)
                                   .withEffectiveDate(vars.settlement)
                                   .withFixedLegDayCount(vars.fixedLegDayCounter)
                                   .withFixedLegTenor(new Period(vars.fixedLegFrequency))
                                   .withFixedLegConvention(vars.fixedLegConvention)
                                   .withFixedLegTerminationDateConvention(vars.fixedLegConvention);

                double expectedRate  = vars.swapData[i].rate / 100,
                       estimatedRate = swap.fairRate();
                double error         = Math.Abs(expectedRate - estimatedRate);
                if (error > tolerance)
                {
                    Console.WriteLine(vars.swapData[i].n + " year(s) swap:\n"
                                      + "\n estimated rate: " + estimatedRate
                                      + "\n expected rate:  " + expectedRate
                                      + "\n error:          " + error
                                      + "\n tolerance:      " + tolerance);
                }
            }

            // check bonds
            vars.termStructure = new PiecewiseYieldCurve <T, I, B>(vars.settlement, vars.bondHelpers,
                                                                   new Actual360(), new List <Handle <Quote> >(), new List <Date>(), 1.0e-12, interpolator);
            curveHandle.linkTo(vars.termStructure);

            for (int i = 0; i < vars.bonds; i++)
            {
                Date          maturity = vars.calendar.advance(vars.today, vars.bondData[i].n, vars.bondData[i].units);
                Date          issue    = vars.calendar.advance(maturity, -vars.bondData[i].length, TimeUnit.Years);
                List <double> coupons  = new List <double>()
                {
                    vars.bondData[i].coupon / 100.0
                };

                FixedRateBond bond = new FixedRateBond(vars.bondSettlementDays, 100.0,
                                                       vars.schedules[i], coupons,
                                                       vars.bondDayCounter, vars.bondConvention,
                                                       vars.bondRedemption, issue);

                IPricingEngine bondEngine = new DiscountingBondEngine(curveHandle);
                bond.setPricingEngine(bondEngine);

                double expectedPrice  = vars.bondData[i].price,
                       estimatedPrice = bond.cleanPrice();
                if (Math.Abs(expectedPrice - estimatedPrice) > tolerance)
                {
                    Console.WriteLine(i + 1 + " bond failure:" +
                                      "\n  estimated price: " + estimatedPrice +
                                      "\n  expected price:  " + expectedPrice);
                }
            }

            // check FRA
            vars.termStructure = new PiecewiseYieldCurve <T, I, B>(vars.settlement, vars.fraHelpers,
                                                                   new Actual360(), new List <Handle <Quote> >(), new List <Date>(), 1.0e-12, interpolator);
            curveHandle.linkTo(vars.termStructure);

            IborIndex euribor3m = new Euribor3M(curveHandle);

            for (int i = 0; i < vars.fras; i++)
            {
                Date start = vars.calendar.advance(vars.settlement,
                                                   vars.fraData[i].n,
                                                   vars.fraData[i].units,
                                                   euribor3m.businessDayConvention(),
                                                   euribor3m.endOfMonth());
                Date end = vars.calendar.advance(start, 3, TimeUnit.Months,
                                                 euribor3m.businessDayConvention(),
                                                 euribor3m.endOfMonth());

                ForwardRateAgreement fra = new ForwardRateAgreement(start, end, Position.Type.Long, vars.fraData[i].rate / 100,
                                                                    100.0, euribor3m, curveHandle);
                double expectedRate  = vars.fraData[i].rate / 100,
                       estimatedRate = fra.forwardRate().rate();
                if (Math.Abs(expectedRate - estimatedRate) > tolerance)
                {
                    Console.WriteLine(i + 1 + " FRA failure:" +
                                      "\n  estimated rate: " + estimatedRate +
                                      "\n  expected rate:  " + expectedRate);
                }
            }
        }
Ejemplo n.º 12
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());
        }
Ejemplo n.º 13
0
        public void testZeroTermStructure()
        {
            // Testing zero inflation term structure...

            SavedSettings backup = new SavedSettings();

            // try the Zero 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, 206.1, -999.0 };

            RelinkableHandle <ZeroInflationTermStructure> hz = new RelinkableHandle <ZeroInflationTermStructure>();
            bool  interp  = false;
            UKRPI iiUKRPI = new UKRPI(interp, hz);

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


            ZeroInflationIndex ii        = iiUKRPI as ZeroInflationIndex;
            YieldTermStructure nominalTS = nominalTermStructure();


            // now build the zero inflation curve

            Datum[] zcData =
            {
                new Datum(new Date(13, Month.August, 2008),  2.93),
                new Datum(new Date(13, Month.August, 2009),  2.95),
                new Datum(new Date(13, Month.August, 2010), 2.965),
                new Datum(new Date(15, Month.August, 2011),  2.98),
                new Datum(new Date(13, Month.August, 2012),   3.0),
                new Datum(new Date(13, Month.August, 2014),  3.06),
                new Datum(new Date(13, Month.August, 2017), 3.175),
                new Datum(new Date(13, Month.August, 2019), 3.243),
                new Datum(new Date(15, Month.August, 2022), 3.293),
                new Datum(new Date(14, Month.August, 2027), 3.338),
                new Datum(new Date(13, Month.August, 2032), 3.348),
                new Datum(new Date(15, Month.August, 2037), 3.348),
                new Datum(new Date(13, Month.August, 2047), 3.308),
                new Datum(new Date(13, Month.August, 2057), 3.228)
            };


            Period     observationLag = new Period(2, TimeUnit.Months);
            DayCounter dc             = new Thirty360();
            Frequency  frequency      = Frequency.Monthly;
            List <BootstrapHelper <ZeroInflationTermStructure> > helpers =
                makeHelpers(zcData, zcData.Length, ii,
                            observationLag,
                            calendar, bdc, dc);

            double baseZeroRate = zcData[0].rate / 100.0;
            PiecewiseZeroInflationCurve <Linear> pZITS = new PiecewiseZeroInflationCurve <Linear>(
                evaluationDate, calendar, dc, observationLag,
                frequency, ii.interpolated(), baseZeroRate,
                new Handle <YieldTermStructure>(nominalTS), helpers);

            pZITS.recalculate();

            // first check that the zero rates on the curve match the data
            // and that the helpers give the correct impled rates
            const double eps = 0.00000001;
            bool         forceLinearInterpolation = false;

            for (int i = 0; i < zcData.Length; i++)
            {
                Assert.IsTrue(Math.Abs(zcData[i].rate / 100.0
                                       - pZITS.zeroRate(zcData[i].date, observationLag, forceLinearInterpolation)) < eps,
                              "ZITS zeroRate != instrument "
                              + pZITS.zeroRate(zcData[i].date, observationLag, forceLinearInterpolation)
                              + " vs " + zcData[i].rate / 100.0
                              + " interpolation: " + ii.interpolated()
                              + " forceLinearInterpolation " + forceLinearInterpolation);

                Assert.IsTrue(Math.Abs(helpers[i].impliedQuote()
                                       - zcData[i].rate / 100.0) < eps,
                              "ZITS implied quote != instrument "
                              + helpers[i].impliedQuote()
                              + " vs " + zcData[i].rate / 100.0);
            }

            // now test the forecasting capability of the index.
            hz.linkTo(pZITS);
            from = hz.link.baseDate();
            to   = hz.link.maxDate() - new Period(1, TimeUnit.Months);             // a bit of margin for adjustments
            Schedule testIndex = new MakeSchedule().from(from).to(to)
                                 .withTenor(new Period(1, TimeUnit.Months))
                                 .withCalendar(new UnitedKingdom())
                                 .withConvention(BusinessDayConvention.ModifiedFollowing).value();

            // we are testing UKRPI which is not interpolated
            Date   bd = hz.link.baseDate();
            double bf = ii.fixing(bd);

            for (int i = 0; i < testIndex.Count; i++)
            {
                Date   d = testIndex[i];
                double z = hz.link.zeroRate(d, new Period(0, TimeUnit.Days));
                double t = hz.link.dayCounter().yearFraction(bd, d);
                if (!ii.interpolated())                   // because fixing constant over period
                {
                    t = hz.link.dayCounter().yearFraction(bd,
                                                          Utils.inflationPeriod(d, ii.frequency()).Key);
                }
                double calc = bf * Math.Pow(1 + z, t);
                if (t <= 0)
                {
                    calc = ii.fixing(d, false);                       // still historical
                }
                if (Math.Abs(calc - ii.fixing(d, true)) / 10000.0 > eps)
                {
                    Assert.Fail("ZC index does not forecast correctly for date " + d
                                + " from base date " + bd
                                + " with fixing " + bf
                                + ", correct:  " + calc
                                + ", fix: " + ii.fixing(d, true)
                                + ", t " + t);
                }
            }

            //===========================================================================================
            // Test zero-inflation-indexed (i.e. cpi ratio) cashflow
            // just ordinary indexed cashflow with a zero inflation index

            Date  baseDate = new Date(1, Month.January, 2006);
            Date  fixDate  = new Date(1, Month.August, 2014);
            Date  payDate  = new UnitedKingdom().adjust(fixDate + new Period(3, TimeUnit.Months), BusinessDayConvention.ModifiedFollowing);
            Index ind      = ii as Index;

            Utils.QL_REQUIRE(ind != null, () => "dynamic_pointer_cast to Index from InflationIndex failed");

            double          notional          = 1000000.0;//1m
            IndexedCashFlow iicf              = new IndexedCashFlow(notional, ind, baseDate, fixDate, payDate);
            double          correctIndexed    = ii.fixing(iicf.fixingDate()) / ii.fixing(iicf.baseDate());
            double          calculatedIndexed = iicf.amount() / iicf.notional();

            Assert.IsTrue(Math.Abs(correctIndexed - calculatedIndexed) < eps,
                          "IndexedCashFlow indexing wrong: " + calculatedIndexed + " vs correct = "
                          + correctIndexed);

            //===========================================================================================
            // Test zero coupon swap

            // first make one ...

            ZeroInflationIndex zii = ii as ZeroInflationIndex;

            Utils.QL_REQUIRE(zii != null, () => "dynamic_pointer_cast to ZeroInflationIndex from UKRPI failed");
            ZeroCouponInflationSwap nzcis =
                new ZeroCouponInflationSwap(ZeroCouponInflationSwap.Type.Payer,
                                            1000000.0,
                                            evaluationDate,
                                            zcData[6].date,                                                                 // end date = maturity
                                            calendar, bdc, dc, zcData[6].rate / 100.0,                                      // fixed rate
                                            zii, observationLag);

            // N.B. no coupon pricer because it is not a coupon, effect of inflation curve via
            //      inflation curve attached to the inflation index.
            Handle <YieldTermStructure> hTS = new Handle <YieldTermStructure>(nominalTS);
            IPricingEngine sppe             = new DiscountingSwapEngine(hTS);

            nzcis.setPricingEngine(sppe);

            // ... and price it, should be zero
            Assert.IsTrue(Math.Abs(nzcis.NPV()) < 0.00001, "ZCIS does not reprice to zero "
                          + nzcis.NPV()
                          + evaluationDate + " to " + zcData[6].date + " becoming " + nzcis.maturityDate()
                          + " rate " + zcData[6].rate
                          + " fixed leg " + nzcis.legNPV(0)
                          + " indexed-predicted inflated leg " + nzcis.legNPV(1)
                          + " discount " + nominalTS.discount(nzcis.maturityDate()));


            //===========================================================================================
            // Test multiplicative seasonality in price
            //

            //Seasonality factors NOT normalized
            //and UKRPI is not interpolated
            Date          trueBaseDate         = Utils.inflationPeriod(hz.link.baseDate(), ii.frequency()).Value;
            Date          seasonallityBaseDate = new Date(31, Month.January, trueBaseDate.year());
            List <double> seasonalityFactors   = new List <double>(12);

            seasonalityFactors.Add(1.003245);
            seasonalityFactors.Add(1.000000);
            seasonalityFactors.Add(0.999715);
            seasonalityFactors.Add(1.000495);
            seasonalityFactors.Add(1.000929);
            seasonalityFactors.Add(0.998687);
            seasonalityFactors.Add(0.995949);
            seasonalityFactors.Add(0.994682);
            seasonalityFactors.Add(0.995949);
            seasonalityFactors.Add(1.000519);
            seasonalityFactors.Add(1.003705);
            seasonalityFactors.Add(1.004186);

            //Creating two different seasonality objects
            //
            MultiplicativePriceSeasonality seasonality_1        = new MultiplicativePriceSeasonality();
            InitializedList <double>       seasonalityFactors_1 = new InitializedList <double>(12, 1.0);

            seasonality_1.set(seasonallityBaseDate, Frequency.Monthly, seasonalityFactors_1);

            MultiplicativePriceSeasonality seasonality_real =
                new MultiplicativePriceSeasonality(seasonallityBaseDate, Frequency.Monthly, seasonalityFactors);

            //Testing seasonality correction when seasonality factors are = 1
            //
            double[] fixing =
            {
                ii.fixing(new Date(14, Month.January,   2013), true),
                ii.fixing(new Date(14, Month.February,  2013), true),
                ii.fixing(new Date(14, Month.March,     2013), true),
                ii.fixing(new Date(14, Month.April,     2013), true),
                ii.fixing(new Date(14, Month.May,       2013), true),
                ii.fixing(new Date(14, Month.June,      2013), true),
                ii.fixing(new Date(14, Month.July,      2013), true),
                ii.fixing(new Date(14, Month.August,    2013), true),
                ii.fixing(new Date(14, Month.September, 2013), true),
                ii.fixing(new Date(14, Month.October,   2013), true),
                ii.fixing(new Date(14, Month.November,  2013), true),
                ii.fixing(new Date(14, Month.December,  2013), true)
            };

            hz.link.setSeasonality(seasonality_1);
            Utils.QL_REQUIRE(hz.link.hasSeasonality(), () => "[44] incorrectly believes NO seasonality correction");

            double[] seasonalityFixing_1 =
            {
                ii.fixing(new Date(14, Month.January,   2013), true),
                ii.fixing(new Date(14, Month.February,  2013), true),
                ii.fixing(new Date(14, Month.March,     2013), true),
                ii.fixing(new Date(14, Month.April,     2013), true),
                ii.fixing(new Date(14, Month.May,       2013), true),
                ii.fixing(new Date(14, Month.June,      2013), true),
                ii.fixing(new Date(14, Month.July,      2013), true),
                ii.fixing(new Date(14, Month.August,    2013), true),
                ii.fixing(new Date(14, Month.September, 2013), true),
                ii.fixing(new Date(14, Month.October,   2013), true),
                ii.fixing(new Date(14, Month.November,  2013), true),
                ii.fixing(new Date(14, Month.December,  2013), true)
            };

            for (int i = 0; i < 12; i++)
            {
                if (Math.Abs(fixing[i] - seasonalityFixing_1[i]) > eps)
                {
                    Assert.Fail("Seasonality doesn't work correctly when seasonality factors are set = 1");
                }
            }

            //Testing seasonality correction when seasonality factors are different from 1
            //
            //0.998687 is the seasonality factor corresponding to June (the base CPI curve month)
            //
            double[] expectedFixing =
            {
                ii.fixing(new Date(14, Month.January,   2013), true) * 1.003245 / 0.998687,
                ii.fixing(new Date(14, Month.February,  2013), true) * 1.000000 / 0.998687,
                ii.fixing(new Date(14, Month.March,     2013), true) * 0.999715 / 0.998687,
                ii.fixing(new Date(14, Month.April,     2013), true) * 1.000495 / 0.998687,
                ii.fixing(new Date(14, Month.May,       2013), true) * 1.000929 / 0.998687,
                ii.fixing(new Date(14, Month.June,      2013), true) * 0.998687 / 0.998687,
                ii.fixing(new Date(14, Month.July,      2013), true) * 0.995949 / 0.998687,
                ii.fixing(new Date(14, Month.August,    2013), true) * 0.994682 / 0.998687,
                ii.fixing(new Date(14, Month.September, 2013), true) * 0.995949 / 0.998687,
                ii.fixing(new Date(14, Month.October,   2013), true) * 1.000519 / 0.998687,
                ii.fixing(new Date(14, Month.November,  2013), true) * 1.003705 / 0.998687,
                ii.fixing(new Date(14, Month.December,  2013), true) * 1.004186 / 0.998687
            };

            hz.link.setSeasonality(seasonality_real);

            double[] seasonalityFixing_real =
            {
                ii.fixing(new Date(14, Month.January,   2013), true),
                ii.fixing(new Date(14, Month.February,  2013), true),
                ii.fixing(new Date(14, Month.March,     2013), true),
                ii.fixing(new Date(14, Month.April,     2013), true),
                ii.fixing(new Date(14, Month.May,       2013), true),
                ii.fixing(new Date(14, Month.June,      2013), true),
                ii.fixing(new Date(14, Month.July,      2013), true),
                ii.fixing(new Date(14, Month.August,    2013), true),
                ii.fixing(new Date(14, Month.September, 2013), true),
                ii.fixing(new Date(14, Month.October,   2013), true),
                ii.fixing(new Date(14, Month.November,  2013), true),
                ii.fixing(new Date(14, Month.December,  2013), true)
            };

            for (int i = 0; i < 12; i++)
            {
                if (Math.Abs(expectedFixing[i] - seasonalityFixing_real[i]) > 0.01)
                {
                    Assert.Fail("Seasonality doesn't work correctly when considering seasonality factors != 1 "
                                + expectedFixing[i] + " vs " + seasonalityFixing_real[i]);
                }
            }


            //Testing Unset function
            //
            Utils.QL_REQUIRE(hz.link.hasSeasonality(), () => "[4] incorrectly believes NO seasonality correction");
            hz.link.setSeasonality();
            Utils.QL_REQUIRE(!hz.link.hasSeasonality(), () => "[5] incorrectly believes HAS seasonality correction");

            double[] seasonalityFixing_unset =
            {
                ii.fixing(new Date(14, Month.January,   2013), true),
                ii.fixing(new Date(14, Month.February,  2013), true),
                ii.fixing(new Date(14, Month.March,     2013), true),
                ii.fixing(new Date(14, Month.April,     2013), true),
                ii.fixing(new Date(14, Month.May,       2013), true),
                ii.fixing(new Date(14, Month.June,      2013), true),
                ii.fixing(new Date(14, Month.July,      2013), true),
                ii.fixing(new Date(14, Month.August,    2013), true),
                ii.fixing(new Date(14, Month.September, 2013), true),
                ii.fixing(new Date(14, Month.October,   2013), true),
                ii.fixing(new Date(14, Month.November,  2013), true),
                ii.fixing(new Date(14, Month.December,  2013), true)
            };

            for (int i = 0; i < 12; i++)
            {
                if (Math.Abs(seasonalityFixing_unset[i] - seasonalityFixing_1[i]) > eps)
                {
                    Assert.Fail("UnsetSeasonality doesn't work correctly "
                                + seasonalityFixing_unset[i] + " vs " + seasonalityFixing_1[i]);
                }
            }


            //==============================================================================
            // now do an INTERPOLATED index, i.e. repeat everything on a fake version of
            // UKRPI (to save making another term structure)

            bool  interpYES  = true;
            UKRPI iiUKRPIyes = new UKRPI(interpYES, hz);

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

            ZeroInflationIndex iiyes = iiUKRPIyes as ZeroInflationIndex;

            // now build the zero inflation curve
            // same data, bigger lag or it will be a self-contradiction
            Period observationLagyes = new Period(3, TimeUnit.Months);
            List <BootstrapHelper <ZeroInflationTermStructure> > helpersyes =
                makeHelpers(zcData, zcData.Length,
                            iiyes, observationLagyes, calendar, bdc, dc);

            PiecewiseZeroInflationCurve <Linear> pZITSyes =
                new PiecewiseZeroInflationCurve <Linear>(
                    evaluationDate, calendar, dc, observationLagyes,
                    frequency, iiyes.interpolated(), baseZeroRate,
                    new Handle <YieldTermStructure>(nominalTS), helpersyes);

            pZITSyes.recalculate();

            // first check that the zero rates on the curve match the data
            // and that the helpers give the correct impled rates
            forceLinearInterpolation = false;               // still
            for (int i = 0; i < zcData.Length; i++)
            {
                Assert.IsTrue(Math.Abs(zcData[i].rate / 100.0
                                       - pZITSyes.zeroRate(zcData[i].date, observationLagyes, forceLinearInterpolation)) < eps,
                              "ZITS INTERPOLATED zeroRate != instrument "
                              + pZITSyes.zeroRate(zcData[i].date, observationLagyes, forceLinearInterpolation)
                              + " date " + zcData[i].date + " observationLagyes " + observationLagyes
                              + " vs " + zcData[i].rate / 100.0
                              + " interpolation: " + iiyes.interpolated()
                              + " forceLinearInterpolation " + forceLinearInterpolation);
                Assert.IsTrue(Math.Abs(helpersyes[i].impliedQuote()
                                       - zcData[i].rate / 100.0) < eps,
                              "ZITS INTERPOLATED implied quote != instrument "
                              + helpersyes[i].impliedQuote()
                              + " vs " + zcData[i].rate / 100.0);
            }


            //======================================================================================
            // now test the forecasting capability of the index.
            hz.linkTo(pZITSyes);
            from      = hz.link.baseDate() + new Period(1, TimeUnit.Months);       // to avoid historical linear bit for rest of base month
            to        = hz.link.maxDate() - new Period(1, TimeUnit.Months);        // a bit of margin for adjustments
            testIndex = new MakeSchedule().from(from).to(to)
                        .withTenor(new Period(1, TimeUnit.Months))
                        .withCalendar(new UnitedKingdom())
                        .withConvention(BusinessDayConvention.ModifiedFollowing).value();

            // we are testing UKRPI which is FAKE interpolated for testing here
            bd = hz.link.baseDate();
            bf = iiyes.fixing(bd);
            for (int i = 0; i < testIndex.Count; i++)
            {
                Date   d    = testIndex[i];
                double z    = hz.link.zeroRate(d, new Period(0, TimeUnit.Days));
                double t    = hz.link.dayCounter().yearFraction(bd, d);
                double calc = bf * Math.Pow(1 + z, t);
                if (t <= 0)
                {
                    calc = iiyes.fixing(d);                             // still historical
                }
                if (Math.Abs(calc - iiyes.fixing(d)) > eps)
                {
                    Assert.Fail("ZC INTERPOLATED index does not forecast correctly for date " + d
                                + " from base date " + bd
                                + " with fixing " + bf
                                + ", correct:  " + calc
                                + ", fix: " + iiyes.fixing(d)
                                + ", t " + t
                                + ", zero " + z);
                }
            }


            //===========================================================================================
            // Test zero coupon swap

            ZeroInflationIndex ziiyes = iiyes as ZeroInflationIndex;

            Utils.QL_REQUIRE(ziiyes != null, () => "dynamic_pointer_cast to ZeroInflationIndex from UKRPI-I failed");
            ZeroCouponInflationSwap nzcisyes = new ZeroCouponInflationSwap(ZeroCouponInflationSwap.Type.Payer,
                                                                           1000000.0,
                                                                           evaluationDate,
                                                                           zcData[6].date,                                                   // end date = maturity
                                                                           calendar, bdc, dc, zcData[6].rate / 100.0,                        // fixed rate
                                                                           ziiyes, observationLagyes);

            // N.B. no coupon pricer because it is not a coupon, effect of inflation curve via
            //      inflation curve attached to the inflation index.
            nzcisyes.setPricingEngine(sppe);

            // ... and price it, should be zero
            Assert.IsTrue(Math.Abs(nzcisyes.NPV()) < 0.00001, "ZCIS-I does not reprice to zero "
                          + nzcisyes.NPV()
                          + evaluationDate + " to " + zcData[6].date + " becoming " + nzcisyes.maturityDate()
                          + " rate " + zcData[6].rate
                          + " fixed leg " + nzcisyes.legNPV(0)
                          + " indexed-predicted inflated leg " + nzcisyes.legNPV(1)
                          + " discount " + nominalTS.discount(nzcisyes.maturityDate())
                          );

            // remove circular refernce
            hz.linkTo(new ZeroInflationTermStructure());
        }
Ejemplo n.º 14
0
        static void Main(string[] args)
        {
            DateTime timer = DateTime.Now;

            /*********************
            ***  MARKET DATA  ***
            *********************/

            Calendar calendar = new TARGET();

            Date settlementDate = new Date(22, Month.September, 2004);
            // must be a business day
            settlementDate = calendar.adjust(settlementDate);

            int fixingDays = 2;
            Date todaysDate = calendar.advance(settlementDate, -fixingDays, TimeUnit.Days);
            // nothing to do with Date::todaysDate
            Settings.setEvaluationDate(todaysDate);

            todaysDate = Settings.evaluationDate();
            Console.WriteLine("Today: {0}, {1}", todaysDate.DayOfWeek, todaysDate);
            Console.WriteLine("Settlement date: {0}, {1}", settlementDate.DayOfWeek, settlementDate);

            // deposits
            double d1wQuote = 0.0382;
            double d1mQuote = 0.0372;
            double d3mQuote = 0.0363;
            double d6mQuote = 0.0353;
            double d9mQuote = 0.0348;
            double d1yQuote = 0.0345;
            // FRAs
            double fra3x6Quote = 0.037125;
            double fra6x9Quote = 0.037125;
            double fra6x12Quote = 0.037125;
            // futures
            double fut1Quote = 96.2875;
            double fut2Quote = 96.7875;
            double fut3Quote = 96.9875;
            double fut4Quote = 96.6875;
            double fut5Quote = 96.4875;
            double fut6Quote = 96.3875;
            double fut7Quote = 96.2875;
            double fut8Quote = 96.0875;
            // swaps
            double s2yQuote = 0.037125;
            double s3yQuote = 0.0398;
            double s5yQuote = 0.0443;
            double s10yQuote = 0.05165;
            double s15yQuote = 0.055175;

            /********************
            ***    QUOTES    ***
            ********************/

            // SimpleQuote stores a value which can be manually changed;
            // other Quote subclasses could read the value from a database
            // or some kind of data feed.

            // deposits
            Quote d1wRate = new SimpleQuote(d1wQuote);
            Quote d1mRate = new SimpleQuote(d1mQuote);
            Quote d3mRate = new SimpleQuote(d3mQuote);
            Quote d6mRate = new SimpleQuote(d6mQuote);
            Quote d9mRate = new SimpleQuote(d9mQuote);
            Quote d1yRate = new SimpleQuote(d1yQuote);
            // FRAs
            Quote fra3x6Rate = new SimpleQuote(fra3x6Quote);
            Quote fra6x9Rate = new SimpleQuote(fra6x9Quote);
            Quote fra6x12Rate = new SimpleQuote(fra6x12Quote);
            // futures
            Quote fut1Price = new SimpleQuote(fut1Quote);
            Quote fut2Price = new SimpleQuote(fut2Quote);
            Quote fut3Price = new SimpleQuote(fut3Quote);
            Quote fut4Price = new SimpleQuote(fut4Quote);
            Quote fut5Price = new SimpleQuote(fut5Quote);
            Quote fut6Price = new SimpleQuote(fut6Quote);
            Quote fut7Price = new SimpleQuote(fut7Quote);
            Quote fut8Price = new SimpleQuote(fut8Quote);
            // swaps
            Quote s2yRate = new SimpleQuote(s2yQuote);
            Quote s3yRate = new SimpleQuote(s3yQuote);
            Quote s5yRate = new SimpleQuote(s5yQuote);
            Quote s10yRate = new SimpleQuote(s10yQuote);
            Quote s15yRate = new SimpleQuote(s15yQuote);

            /*********************
            ***  RATE HELPERS ***
            *********************/

            // RateHelpers are built from the above quotes together with
            // other instrument dependant infos.  Quotes are passed in
            // relinkable handles which could be relinked to some other
            // data source later.

            // deposits
            DayCounter depositDayCounter = new Actual360();

            RateHelper d1w = new DepositRateHelper(new Handle<Quote>(d1wRate), new Period(1, TimeUnit.Weeks),
                fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);
            RateHelper d1m = new DepositRateHelper(new Handle<Quote>(d1mRate), new Period(1, TimeUnit.Months),
                fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);
            RateHelper d3m = new DepositRateHelper(new Handle<Quote>(d3mRate), new Period(3, TimeUnit.Months),
                fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);
            RateHelper d6m = new DepositRateHelper(new Handle<Quote>(d6mRate), new Period(6, TimeUnit.Months),
                fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);
            RateHelper d9m = new DepositRateHelper(new Handle<Quote>(d9mRate), new Period(9, TimeUnit.Months),
                fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);
            RateHelper d1y = new DepositRateHelper(new Handle<Quote>(d1yRate), new Period(1, TimeUnit.Years),
                fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            // setup FRAs
            RateHelper fra3x6 = new FraRateHelper(new Handle<Quote>(fra3x6Rate), 3, 6, fixingDays, calendar,
                        BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);
            RateHelper fra6x9 = new FraRateHelper(new Handle<Quote>(fra6x9Rate), 6, 9, fixingDays, calendar,
                        BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);
            RateHelper fra6x12 = new FraRateHelper(new Handle<Quote>(fra6x12Rate), 6, 12, fixingDays, calendar,
                        BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            // setup futures
            // Handle<Quote> convexityAdjustment = new Handle<Quote>(new SimpleQuote(0.0));
            int futMonths = 3;
            Date imm = IMM.nextDate(settlementDate);

            RateHelper fut1 = new FuturesRateHelper(new Handle<Quote>(fut1Price), imm, futMonths, calendar,
                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            imm = IMM.nextDate(imm + 1);
            RateHelper fut2 = new FuturesRateHelper(new Handle<Quote>(fut2Price), imm, futMonths, calendar,
                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            imm = IMM.nextDate(imm + 1);
            RateHelper fut3 = new FuturesRateHelper(new Handle<Quote>(fut3Price), imm, futMonths, calendar,
                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            imm = IMM.nextDate(imm + 1);
            RateHelper fut4 = new FuturesRateHelper(new Handle<Quote>(fut4Price), imm, futMonths, calendar,
                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            imm = IMM.nextDate(imm + 1);
            RateHelper fut5 = new FuturesRateHelper(new Handle<Quote>(fut5Price), imm, futMonths, calendar,
                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            imm = IMM.nextDate(imm + 1);
            RateHelper fut6 = new FuturesRateHelper(new Handle<Quote>(fut6Price), imm, futMonths, calendar,
                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            imm = IMM.nextDate(imm + 1);
            RateHelper fut7 = new FuturesRateHelper(new Handle<Quote>(fut7Price), imm, futMonths, calendar,
                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            imm = IMM.nextDate(imm + 1);
            RateHelper fut8 = new FuturesRateHelper(new Handle<Quote>(fut8Price), imm, futMonths, calendar,
                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            // setup swaps
            Frequency swFixedLegFrequency = Frequency.Annual;
            BusinessDayConvention swFixedLegConvention = BusinessDayConvention.Unadjusted;
            DayCounter swFixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European);

            IborIndex swFloatingLegIndex = new Euribor6M();

            RateHelper s2y = new SwapRateHelper(new Handle<Quote>(s2yRate), new Period(2, TimeUnit.Years),
                calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex);
            RateHelper s3y = new SwapRateHelper(new Handle<Quote>(s3yRate), new Period(3, TimeUnit.Years),
                calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex);
            RateHelper s5y = new SwapRateHelper(new Handle<Quote>(s5yRate), new Period(5, TimeUnit.Years),
                calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex);
            RateHelper s10y = new SwapRateHelper(new Handle<Quote>(s10yRate), new Period(10, TimeUnit.Years),
                calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex);
            RateHelper s15y = new SwapRateHelper(new Handle<Quote>(s15yRate), new Period(15, TimeUnit.Years),
                calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex);

            /*********************
            **  CURVE BUILDING **
            *********************/

            // Any DayCounter would be fine.
            // ActualActual::ISDA ensures that 30 years is 30.0
            DayCounter termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA);

            double tolerance = 1.0e-15;

            // A depo-swap curve
            List<RateHelper> depoSwapInstruments = new List<RateHelper>();
            depoSwapInstruments.Add(d1w);
            depoSwapInstruments.Add(d1m);
            depoSwapInstruments.Add(d3m);
            depoSwapInstruments.Add(d6m);
            depoSwapInstruments.Add(d9m);
            depoSwapInstruments.Add(d1y);
            depoSwapInstruments.Add(s2y);
            depoSwapInstruments.Add(s3y);
            depoSwapInstruments.Add(s5y);
            depoSwapInstruments.Add(s10y);
            depoSwapInstruments.Add(s15y);
            YieldTermStructure depoSwapTermStructure = new PiecewiseYieldCurve<Discount,LogLinear>(
                        settlementDate, depoSwapInstruments, termStructureDayCounter, new List<Handle<Quote>>(), new List<Date>(), tolerance);

            // A depo-futures-swap curve
            List<RateHelper> depoFutSwapInstruments = new List<RateHelper>();
            depoFutSwapInstruments.Add(d1w);
            depoFutSwapInstruments.Add(d1m);
            depoFutSwapInstruments.Add(fut1);
            depoFutSwapInstruments.Add(fut2);
            depoFutSwapInstruments.Add(fut3);
            depoFutSwapInstruments.Add(fut4);
            depoFutSwapInstruments.Add(fut5);
            depoFutSwapInstruments.Add(fut6);
            depoFutSwapInstruments.Add(fut7);
            depoFutSwapInstruments.Add(fut8);
            depoFutSwapInstruments.Add(s3y);
            depoFutSwapInstruments.Add(s5y);
            depoFutSwapInstruments.Add(s10y);
            depoFutSwapInstruments.Add(s15y);
            YieldTermStructure depoFutSwapTermStructure = new PiecewiseYieldCurve<Discount,LogLinear>(
                    settlementDate, depoFutSwapInstruments, termStructureDayCounter, new List<Handle<Quote>>(), new List<Date>(), tolerance);

            // A depo-FRA-swap curve
            List<RateHelper> depoFRASwapInstruments = new List<RateHelper>();
            depoFRASwapInstruments.Add(d1w);
            depoFRASwapInstruments.Add(d1m);
            depoFRASwapInstruments.Add(d3m);
            depoFRASwapInstruments.Add(fra3x6);
            depoFRASwapInstruments.Add(fra6x9);
            depoFRASwapInstruments.Add(fra6x12);
            depoFRASwapInstruments.Add(s2y);
            depoFRASwapInstruments.Add(s3y);
            depoFRASwapInstruments.Add(s5y);
            depoFRASwapInstruments.Add(s10y);
            depoFRASwapInstruments.Add(s15y);
            YieldTermStructure depoFRASwapTermStructure = new PiecewiseYieldCurve<Discount,LogLinear>(
                    settlementDate, depoFRASwapInstruments, termStructureDayCounter, new List<Handle<Quote>>(), new List<Date>(), tolerance);

            // Term structures that will be used for pricing:
            // the one used for discounting cash flows
            RelinkableHandle<YieldTermStructure> discountingTermStructure = new RelinkableHandle<YieldTermStructure>();
            // the one used for forward rate forecasting
            RelinkableHandle<YieldTermStructure> forecastingTermStructure = new RelinkableHandle<YieldTermStructure>();

            /*********************
            * SWAPS TO BE PRICED *
            **********************/

            // constant nominal 1,000,000 Euro
            double nominal = 1000000.0;
            // fixed leg
            Frequency fixedLegFrequency = Frequency.Annual;
            BusinessDayConvention fixedLegConvention = BusinessDayConvention.Unadjusted;
            BusinessDayConvention floatingLegConvention = BusinessDayConvention.ModifiedFollowing;
            DayCounter fixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European);
            double fixedRate = 0.04;
            DayCounter floatingLegDayCounter = new Actual360();

            // floating leg
            Frequency floatingLegFrequency = Frequency.Semiannual;
            IborIndex euriborIndex = new Euribor6M(forecastingTermStructure);
            double spread = 0.0;

            int lenghtInYears = 5;
            VanillaSwap.Type swapType = VanillaSwap.Type.Payer;

            Date maturity = settlementDate + new Period(lenghtInYears, TimeUnit.Years);
            Schedule fixedSchedule = new Schedule(settlementDate, maturity, new Period(fixedLegFrequency),
                                     calendar, fixedLegConvention, fixedLegConvention, DateGeneration.Rule.Forward, false);
            Schedule floatSchedule = new Schedule(settlementDate, maturity, new Period(floatingLegFrequency),
                                     calendar, floatingLegConvention, floatingLegConvention, DateGeneration.Rule.Forward, false);
            VanillaSwap spot5YearSwap = new VanillaSwap(swapType, nominal, fixedSchedule, fixedRate, fixedLegDayCounter,
                                        floatSchedule, euriborIndex, spread, floatingLegDayCounter);

            Date fwdStart = calendar.advance(settlementDate, 1, TimeUnit.Years);
            Date fwdMaturity = fwdStart + new Period(lenghtInYears, TimeUnit.Years);
            Schedule fwdFixedSchedule = new Schedule(fwdStart, fwdMaturity, new Period(fixedLegFrequency),
                                        calendar, fixedLegConvention, fixedLegConvention, DateGeneration.Rule.Forward, false);
            Schedule fwdFloatSchedule = new Schedule(fwdStart, fwdMaturity, new Period(floatingLegFrequency),
                                        calendar, floatingLegConvention, floatingLegConvention, DateGeneration.Rule.Forward, false);
            VanillaSwap oneYearForward5YearSwap = new VanillaSwap(swapType, nominal, fwdFixedSchedule, fixedRate, fixedLegDayCounter,
                                        fwdFloatSchedule, euriborIndex, spread, floatingLegDayCounter);

            /***************
            * SWAP PRICING *
            ****************/

            // utilities for reporting
            List<string> headers = new List<string>();
            headers.Add("term structure");
            headers.Add("net present value");
            headers.Add("fair spread");
            headers.Add("fair fixed rate");
            string separator = " | ";
            int width = headers[0].Length + separator.Length
                       + headers[1].Length + separator.Length
                       + headers[2].Length + separator.Length
                       + headers[3].Length + separator.Length - 1;
            string rule = string.Format("").PadLeft(width, '-'), dblrule = string.Format("").PadLeft(width, '=');
            string tab = string.Format("").PadLeft(8, ' ');

            // calculations

            Console.WriteLine(dblrule);
            Console.WriteLine("5-year market swap-rate = {0:0.00%}", s5yRate.value());
            Console.WriteLine(dblrule);

            Console.WriteLine(tab + "5-years swap paying {0:0.00%}", fixedRate);
            Console.WriteLine(headers[0] + separator
                      + headers[1] + separator
                      + headers[2] + separator
                      + headers[3] + separator);
            Console.WriteLine(rule);

            double NPV;
            double fairRate;
            double fairSpread;

            IPricingEngine swapEngine = new DiscountingSwapEngine(discountingTermStructure);

            spot5YearSwap.setPricingEngine(swapEngine);
            oneYearForward5YearSwap.setPricingEngine(swapEngine);

            // Of course, you're not forced to really use different curves
            forecastingTermStructure.linkTo(depoSwapTermStructure);
            discountingTermStructure.linkTo(depoSwapTermStructure);

            NPV = spot5YearSwap.NPV();
            fairSpread = spot5YearSwap.fairSpread();
            fairRate = spot5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            // let's check that the 5 years swap has been correctly re-priced
            if (!(Math.Abs(fairRate-s5yQuote)<1e-8))
                throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate-s5yQuote));

            forecastingTermStructure.linkTo(depoFutSwapTermStructure);
            discountingTermStructure.linkTo(depoFutSwapTermStructure);

            NPV = spot5YearSwap.NPV();
            fairSpread = spot5YearSwap.fairSpread();
            fairRate = spot5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            if (!(Math.Abs(fairRate-s5yQuote)<1e-8))
                throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate-s5yQuote));

            forecastingTermStructure.linkTo(depoFRASwapTermStructure);
            discountingTermStructure.linkTo(depoFRASwapTermStructure);

            NPV = spot5YearSwap.NPV();
            fairSpread = spot5YearSwap.fairSpread();
            fairRate = spot5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            if (!(Math.Abs(fairRate-s5yQuote)<1e-8))
                throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate-s5yQuote));

            Console.WriteLine(rule);

            // now let's price the 1Y forward 5Y swap
            Console.WriteLine(tab + "5-years, 1-year forward swap paying {0:0.00%}", fixedRate);
            Console.WriteLine(headers[0] + separator
                      + headers[1] + separator
                      + headers[2] + separator
                      + headers[3] + separator);
            Console.WriteLine(rule);

            forecastingTermStructure.linkTo(depoSwapTermStructure);
            discountingTermStructure.linkTo(depoSwapTermStructure);

            NPV = oneYearForward5YearSwap.NPV();
            fairSpread = oneYearForward5YearSwap.fairSpread();
            fairRate = oneYearForward5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            forecastingTermStructure.linkTo(depoFutSwapTermStructure);
            discountingTermStructure.linkTo(depoFutSwapTermStructure);

            NPV = oneYearForward5YearSwap.NPV();
            fairSpread = oneYearForward5YearSwap.fairSpread();
            fairRate = oneYearForward5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            forecastingTermStructure.linkTo(depoFRASwapTermStructure);
            discountingTermStructure.linkTo(depoFRASwapTermStructure);

            NPV = oneYearForward5YearSwap.NPV();
            fairSpread = oneYearForward5YearSwap.fairSpread();
            fairRate = oneYearForward5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            // now let's say that the 5-years swap rate goes up to 4.60%.
            // A smarter market element--say, connected to a data source-- would
            // notice the change itself. Since we're using SimpleQuotes,
            // we'll have to change the value manually--which forces us to
            // downcast the handle and use the SimpleQuote
            // interface. In any case, the point here is that a change in the
            // value contained in the Quote triggers a new bootstrapping
            // of the curve and a repricing of the swap.

            SimpleQuote fiveYearsRate = s5yRate as SimpleQuote;
            fiveYearsRate.setValue(0.0460);

            Console.WriteLine(dblrule);
            Console.WriteLine("5-year market swap-rate = {0:0.00%}", s5yRate.value());
            Console.WriteLine(dblrule);

            Console.WriteLine(tab + "5-years swap paying {0:0.00%}", fixedRate);
            Console.WriteLine(headers[0] + separator
                      + headers[1] + separator
                      + headers[2] + separator
                      + headers[3] + separator);
            Console.WriteLine(rule);

            // now get the updated results
            forecastingTermStructure.linkTo(depoSwapTermStructure);
            discountingTermStructure.linkTo(depoSwapTermStructure);

            NPV = spot5YearSwap.NPV();
            fairSpread = spot5YearSwap.fairSpread();
            fairRate = spot5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            if (!(Math.Abs(fairRate-s5yRate.value())<1e-8))
                throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate-s5yRate.value()));

            forecastingTermStructure.linkTo(depoFutSwapTermStructure);
            discountingTermStructure.linkTo(depoFutSwapTermStructure);

            NPV = spot5YearSwap.NPV();
            fairSpread = spot5YearSwap.fairSpread();
            fairRate = spot5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            if (!(Math.Abs(fairRate-s5yRate.value())<1e-8))
                throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate-s5yRate.value()));

            forecastingTermStructure.linkTo(depoFRASwapTermStructure);
            discountingTermStructure.linkTo(depoFRASwapTermStructure);

            NPV = spot5YearSwap.NPV();
            fairSpread = spot5YearSwap.fairSpread();
            fairRate = spot5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            if (!(Math.Abs(fairRate-s5yRate.value())<1e-8))
                throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate-s5yRate.value()));

            Console.WriteLine(rule);

            // the 1Y forward 5Y swap changes as well

            Console.WriteLine(tab + "5-years, 1-year forward swap paying {0:0.00%}", fixedRate);
            Console.WriteLine(headers[0] + separator
                      + headers[1] + separator
                      + headers[2] + separator
                      + headers[3] + separator);
            Console.WriteLine(rule);

            forecastingTermStructure.linkTo(depoSwapTermStructure);
            discountingTermStructure.linkTo(depoSwapTermStructure);

            NPV = oneYearForward5YearSwap.NPV();
            fairSpread = oneYearForward5YearSwap.fairSpread();
            fairRate = oneYearForward5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            forecastingTermStructure.linkTo(depoFutSwapTermStructure);
            discountingTermStructure.linkTo(depoFutSwapTermStructure);

            NPV = oneYearForward5YearSwap.NPV();
            fairSpread = oneYearForward5YearSwap.fairSpread();
            fairRate = oneYearForward5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            forecastingTermStructure.linkTo(depoFRASwapTermStructure);
            discountingTermStructure.linkTo(depoFRASwapTermStructure);

            NPV = oneYearForward5YearSwap.NPV();
            fairSpread = oneYearForward5YearSwap.fairSpread();
            fairRate = oneYearForward5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

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

            Console.Write("Press any key to continue ...");
            Console.ReadKey();
        }
Ejemplo n.º 15
0
        public void testFairUpfront()
        {
            // Testing fair-upfront calculation for credit-default swaps...

            using (SavedSettings backup = new SavedSettings())
            {
                // Initialize curves
                Calendar calendar = new TARGET();
                Date     today    = calendar.adjust(Date.Today);
                Settings.setEvaluationDate(today);

                Handle <Quote> hazardRate = new Handle <Quote>(new SimpleQuote(0.01234));
                RelinkableHandle <DefaultProbabilityTermStructure> probabilityCurve =
                    new RelinkableHandle <DefaultProbabilityTermStructure>();
                probabilityCurve.linkTo(new FlatHazardRate(0, calendar, hazardRate, new Actual360()));

                RelinkableHandle <YieldTermStructure> discountCurve =
                    new RelinkableHandle <YieldTermStructure>();
                discountCurve.linkTo(new FlatForward(today, 0.06, new Actual360()));

                // Build the schedule
                Date issueDate = today;
                Date maturity  = calendar.advance(issueDate, 10, TimeUnit.Years);
                BusinessDayConvention convention = BusinessDayConvention.Following;

                Schedule schedule =
                    new MakeSchedule().from(issueDate)
                    .to(maturity)
                    .withFrequency(Frequency.Quarterly)
                    .withCalendar(calendar)
                    .withTerminationDateConvention(convention)
                    .withRule(DateGeneration.Rule.TwentiethIMM).value();

                // Build the CDS
                double     fixedRate    = 0.05;
                double     upfront      = 0.001;
                DayCounter dayCount     = new Actual360();
                double     notional     = 10000.0;
                double     recoveryRate = 0.4;

                IPricingEngine engine = new MidPointCdsEngine(probabilityCurve, recoveryRate, discountCurve, true);

                CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, notional, upfront, fixedRate,
                                                              schedule, convention, dayCount, true, true);
                cds.setPricingEngine(engine);

                double fairUpfront = cds.fairUpfront();

                CreditDefaultSwap fairCds = new CreditDefaultSwap(Protection.Side.Seller, notional,
                                                                  fairUpfront, fixedRate, schedule, convention, dayCount, true, true);
                fairCds.setPricingEngine(engine);

                double fairNPV   = fairCds.NPV();
                double tolerance = 1e-10;

                if (Math.Abs(fairNPV) > tolerance)
                {
                    QAssert.Fail(
                        "Failed to reproduce null NPV with calculated fair upfront\n"
                        + "    calculated upfront: " + fairUpfront + "\n"
                        + "    calculated NPV:     " + fairNPV);
                }

                // same with null upfront to begin with
                upfront = 0.0;
                CreditDefaultSwap cds2 = new CreditDefaultSwap(Protection.Side.Seller, notional, upfront, fixedRate,
                                                               schedule, convention, dayCount, true, true);
                cds2.setPricingEngine(engine);

                fairUpfront = cds2.fairUpfront();

                CreditDefaultSwap fairCds2 = new CreditDefaultSwap(Protection.Side.Seller, notional,
                                                                   fairUpfront, fixedRate, schedule, convention, dayCount, true, true);
                fairCds2.setPricingEngine(engine);

                fairNPV = fairCds2.NPV();

                if (Math.Abs(fairNPV) > tolerance)
                {
                    QAssert.Fail(
                        "Failed to reproduce null NPV with calculated fair upfront\n"
                        + "    calculated upfront: " + fairUpfront + "\n"
                        + "    calculated NPV:     " + fairNPV);
                }
            }
        }
Ejemplo n.º 16
0
        public void testCachedValue()
        {
            // Testing credit-default swap against cached values...

            using (SavedSettings backup = new SavedSettings())
            {
                // Initialize curves
                Settings.setEvaluationDate(new Date(9, Month.June, 2006));
                Date     today    = Settings.evaluationDate();
                Calendar calendar = new TARGET();

                Handle <Quote> hazardRate = new Handle <Quote>(new SimpleQuote(0.01234));
                RelinkableHandle <DefaultProbabilityTermStructure> probabilityCurve = new RelinkableHandle <DefaultProbabilityTermStructure>();
                probabilityCurve.linkTo(new FlatHazardRate(0, calendar, hazardRate, new Actual360()));

                RelinkableHandle <YieldTermStructure> discountCurve = new RelinkableHandle <YieldTermStructure>();

                discountCurve.linkTo(new FlatForward(today, 0.06, new Actual360()));

                // Build the schedule
                Date                  issueDate  = calendar.advance(today, -1, TimeUnit.Years);
                Date                  maturity   = calendar.advance(issueDate, 10, TimeUnit.Years);
                Frequency             frequency  = Frequency.Semiannual;
                BusinessDayConvention convention = BusinessDayConvention.ModifiedFollowing;

                Schedule schedule = new Schedule(issueDate, maturity, new Period(frequency), calendar,
                                                 convention, convention, DateGeneration.Rule.Forward, false);

                // Build the CDS
                double     fixedRate    = 0.0120;
                DayCounter dayCount     = new Actual360();
                double     notional     = 10000.0;
                double     recoveryRate = 0.4;

                CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, notional, fixedRate,
                                                              schedule, convention, dayCount, true, true);
                cds.setPricingEngine(new MidPointCdsEngine(probabilityCurve, recoveryRate, discountCurve));

                double npv      = 295.0153398;
                double fairRate = 0.007517539081;

                double calculatedNpv      = cds.NPV();
                double calculatedFairRate = cds.fairSpread();
                double tolerance          = 1.0e-7;

                if (Math.Abs(calculatedNpv - npv) > tolerance)
                {
                    QAssert.Fail(
                        "Failed to reproduce NPV with mid-point engine\n"
                        + "    calculated NPV: " + calculatedNpv + "\n"
                        + "    expected NPV:   " + npv);
                }

                if (Math.Abs(calculatedFairRate - fairRate) > tolerance)
                {
                    QAssert.Fail(
                        "Failed to reproduce fair rate with mid-point engine\n"
                        + "    calculated fair rate: " + calculatedFairRate + "\n"
                        + "    expected fair rate:   " + fairRate);
                }

                cds.setPricingEngine(new IntegralCdsEngine(new Period(1, TimeUnit.Days), probabilityCurve,
                                                           recoveryRate, discountCurve));

                calculatedNpv      = cds.NPV();
                calculatedFairRate = cds.fairSpread();
                tolerance          = 1.0e-5;

                if (Math.Abs(calculatedNpv - npv) > notional * tolerance * 10)
                {
                    QAssert.Fail(
                        "Failed to reproduce NPV with integral engine "
                        + "(step = 1 day)\n"
                        + "    calculated NPV: " + calculatedNpv + "\n"
                        + "    expected NPV:   " + npv);
                }

                if (Math.Abs(calculatedFairRate - fairRate) > tolerance)
                {
                    QAssert.Fail(
                        "Failed to reproduce fair rate with integral engine "
                        + "(step = 1 day)\n"
                        + "    calculated fair rate: " + calculatedFairRate + "\n"
                        + "    expected fair rate:   " + fairRate);
                }

                cds.setPricingEngine(new IntegralCdsEngine(new Period(1, TimeUnit.Weeks), probabilityCurve, recoveryRate, discountCurve));

                calculatedNpv      = cds.NPV();
                calculatedFairRate = cds.fairSpread();
                tolerance          = 1.0e-5;

                if (Math.Abs(calculatedNpv - npv) > notional * tolerance * 10)
                {
                    QAssert.Fail(
                        "Failed to reproduce NPV with integral engine "
                        + "(step = 1 week)\n"
                        + "    calculated NPV: " + calculatedNpv + "\n"
                        + "    expected NPV:   " + npv);
                }

                if (Math.Abs(calculatedFairRate - fairRate) > tolerance)
                {
                    QAssert.Fail(
                        "Failed to reproduce fair rate with integral engine "
                        + "(step = 1 week)\n"
                        + "    calculated fair rate: " + calculatedFairRate + "\n"
                        + "    expected fair rate:   " + fairRate);
                }
            }
        }
Ejemplo n.º 17
0
        public void testImpliedHazardRate()
        {
            // Testing implied hazard-rate for credit-default swaps...

            using (SavedSettings backup = new SavedSettings())
            {
                // Initialize curves
                Calendar calendar = new TARGET();
                Date     today    = calendar.adjust(Date.Today);
                Settings.setEvaluationDate(today);

                double     h1 = 0.30, h2 = 0.40;
                DayCounter dayCounter = new Actual365Fixed();

                List <Date>   dates       = new List <Date>(3);
                List <double> hazardRates = new List <double>(3);
                dates.Add(today);
                hazardRates.Add(h1);

                dates.Add(today + new Period(5, TimeUnit.Years));
                hazardRates.Add(h1);

                dates.Add(today + new Period(10, TimeUnit.Years));
                hazardRates.Add(h2);

                RelinkableHandle <DefaultProbabilityTermStructure> probabilityCurve =
                    new RelinkableHandle <DefaultProbabilityTermStructure>();
                probabilityCurve.linkTo(new InterpolatedHazardRateCurve <BackwardFlat>(dates,
                                                                                       hazardRates,
                                                                                       dayCounter));

                RelinkableHandle <YieldTermStructure> discountCurve = new RelinkableHandle <YieldTermStructure>();
                discountCurve.linkTo(new FlatForward(today, 0.03, new Actual360()));

                Frequency             frequency  = Frequency.Semiannual;
                BusinessDayConvention convention = BusinessDayConvention.ModifiedFollowing;

                Date       issueDate    = calendar.advance(today, -6, TimeUnit.Months);
                double     fixedRate    = 0.0120;
                DayCounter cdsDayCount  = new Actual360();
                double     notional     = 10000.0;
                double     recoveryRate = 0.4;

                double?latestRate = null;
                for (int n = 6; n <= 10; ++n)
                {
                    Date     maturity = calendar.advance(issueDate, n, TimeUnit.Years);
                    Schedule schedule = new Schedule(issueDate, maturity, new Period(frequency), calendar,
                                                     convention, convention,
                                                     DateGeneration.Rule.Forward, false);

                    CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, notional, fixedRate,
                                                                  schedule, convention, cdsDayCount, true, true);
                    cds.setPricingEngine(new MidPointCdsEngine(probabilityCurve, recoveryRate, discountCurve));

                    double NPV      = cds.NPV();
                    double flatRate = cds.impliedHazardRate(NPV, discountCurve,
                                                            dayCounter,
                                                            recoveryRate);

                    if (flatRate < h1 || flatRate > h2)
                    {
                        QAssert.Fail("implied hazard rate outside expected range\n"
                                     + "    maturity: " + n + " years\n"
                                     + "    expected minimum: " + h1 + "\n"
                                     + "    expected maximum: " + h2 + "\n"
                                     + "    implied rate:     " + flatRate);
                    }

                    if (n > 6 && flatRate < latestRate)
                    {
                        QAssert.Fail("implied hazard rate decreasing with swap maturity\n"
                                     + "    maturity: " + n + " years\n"
                                     + "    previous rate: " + latestRate + "\n"
                                     + "    implied rate:  " + flatRate);
                    }

                    latestRate = flatRate;

                    RelinkableHandle <DefaultProbabilityTermStructure> probability = new RelinkableHandle <DefaultProbabilityTermStructure>();
                    probability.linkTo(new FlatHazardRate(today, new Handle <Quote>(new SimpleQuote(flatRate)), dayCounter));

                    CreditDefaultSwap cds2 = new CreditDefaultSwap(Protection.Side.Seller, notional, fixedRate,
                                                                   schedule, convention, cdsDayCount, true, true);
                    cds2.setPricingEngine(new MidPointCdsEngine(probability, recoveryRate, discountCurve));

                    double NPV2      = cds2.NPV();
                    double tolerance = 1.0;
                    if (Math.Abs(NPV - NPV2) > tolerance)
                    {
                        QAssert.Fail("failed to reproduce NPV with implied rate\n"
                                     + "    expected:   " + NPV + "\n"
                                     + "    calculated: " + NPV2);
                    }
                }
            }
        }
Ejemplo n.º 18
0
        public void testCachedMarketValue()
        {
            // Testing credit-default swap against cached market values...

            using (SavedSettings backup = new SavedSettings())
            {
                Settings.setEvaluationDate(new Date(9, Month.June, 2006));
                Date     evalDate = Settings.evaluationDate();
                Calendar calendar = new UnitedStates();

                List <Date> discountDates = new List <Date>();
                discountDates.Add(evalDate);
                discountDates.Add(calendar.advance(evalDate, 1, TimeUnit.Weeks, BusinessDayConvention.ModifiedFollowing));
                discountDates.Add(calendar.advance(evalDate, 1, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing));
                discountDates.Add(calendar.advance(evalDate, 2, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing));
                discountDates.Add(calendar.advance(evalDate, 3, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing));
                discountDates.Add(calendar.advance(evalDate, 6, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing));
                discountDates.Add(calendar.advance(evalDate, 12, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing));
                discountDates.Add(calendar.advance(evalDate, 2, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
                discountDates.Add(calendar.advance(evalDate, 3, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
                discountDates.Add(calendar.advance(evalDate, 4, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
                discountDates.Add(calendar.advance(evalDate, 5, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
                discountDates.Add(calendar.advance(evalDate, 6, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
                discountDates.Add(calendar.advance(evalDate, 7, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
                discountDates.Add(calendar.advance(evalDate, 8, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
                discountDates.Add(calendar.advance(evalDate, 9, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
                discountDates.Add(calendar.advance(evalDate, 10, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
                discountDates.Add(calendar.advance(evalDate, 15, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));

                List <double> dfs = new List <double>();
                dfs.Add(1.0);
                dfs.Add(0.9990151375768731);
                dfs.Add(0.99570502636871183);
                dfs.Add(0.99118260474528685);
                dfs.Add(0.98661167950906203);
                dfs.Add(0.9732592953359388);
                dfs.Add(0.94724424481038083);
                dfs.Add(0.89844996737120875);
                dfs.Add(0.85216647839921411);
                dfs.Add(0.80775477692556874);
                dfs.Add(0.76517289234200347);
                dfs.Add(0.72401019553182933);
                dfs.Add(0.68503909569219212);
                dfs.Add(0.64797499814013748);
                dfs.Add(0.61263171936255534);
                dfs.Add(0.5791942350748791);
                dfs.Add(0.43518868769953606);

                DayCounter curveDayCounter = new Actual360();

                RelinkableHandle <YieldTermStructure> discountCurve = new RelinkableHandle <YieldTermStructure>();
                discountCurve.linkTo(new InterpolatedDiscountCurve <LogLinear>(discountDates, dfs, curveDayCounter, null, null, null, new LogLinear()));

                DayCounter  dayCounter = new Thirty360();
                List <Date> dates      = new List <Date>();
                dates.Add(evalDate);
                dates.Add(calendar.advance(evalDate, 6, TimeUnit.Months, BusinessDayConvention.ModifiedFollowing));
                dates.Add(calendar.advance(evalDate, 1, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
                dates.Add(calendar.advance(evalDate, 2, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
                dates.Add(calendar.advance(evalDate, 3, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
                dates.Add(calendar.advance(evalDate, 4, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
                dates.Add(calendar.advance(evalDate, 5, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
                dates.Add(calendar.advance(evalDate, 7, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));
                dates.Add(calendar.advance(evalDate, 10, TimeUnit.Years, BusinessDayConvention.ModifiedFollowing));

                List <double> defaultProbabilities = new List <double>();
                defaultProbabilities.Add(0.0000);
                defaultProbabilities.Add(0.0047);
                defaultProbabilities.Add(0.0093);
                defaultProbabilities.Add(0.0286);
                defaultProbabilities.Add(0.0619);
                defaultProbabilities.Add(0.0953);
                defaultProbabilities.Add(0.1508);
                defaultProbabilities.Add(0.2288);
                defaultProbabilities.Add(0.3666);

                List <double> hazardRates = new List <double>();
                hazardRates.Add(0.0);
                for (int i = 1; i < dates.Count; ++i)
                {
                    double t1 = dayCounter.yearFraction(dates[0], dates[i - 1]);
                    double t2 = dayCounter.yearFraction(dates[0], dates[i]);
                    double S1 = 1.0 - defaultProbabilities[i - 1];
                    double S2 = 1.0 - defaultProbabilities[i];
                    hazardRates.Add(Math.Log(S1 / S2) / (t2 - t1));
                }

                RelinkableHandle <DefaultProbabilityTermStructure> piecewiseFlatHazardRate = new RelinkableHandle <DefaultProbabilityTermStructure>();
                piecewiseFlatHazardRate.linkTo(new InterpolatedHazardRateCurve <BackwardFlat>(dates, hazardRates, new Thirty360()));

                // Testing credit default swap

                // Build the schedule
                Date                  issueDate     = new Date(20, Month.March, 2006);
                Date                  maturity      = new Date(20, Month.June, 2013);
                Frequency             cdsFrequency  = Frequency.Semiannual;
                BusinessDayConvention cdsConvention = BusinessDayConvention.ModifiedFollowing;

                Schedule schedule = new Schedule(issueDate, maturity, new Period(cdsFrequency), calendar,
                                                 cdsConvention, cdsConvention,
                                                 DateGeneration.Rule.Forward, false);

                // Build the CDS
                double     recoveryRate = 0.25;
                double     fixedRate    = 0.0224;
                DayCounter dayCount     = new Actual360();
                double     cdsNotional  = 100.0;

                CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, cdsNotional, fixedRate,
                                                              schedule, cdsConvention, dayCount, true, true);
                cds.setPricingEngine(new MidPointCdsEngine(piecewiseFlatHazardRate, recoveryRate, discountCurve));

                double calculatedNpv      = cds.NPV();
                double calculatedFairRate = cds.fairSpread();

                double npv      = -1.364048777; // from Bloomberg we have 98.15598868 - 100.00;
                double fairRate = 0.0248429452; // from Bloomberg we have 0.0258378;

                double tolerance = 1e-9;

                if (Math.Abs(npv - calculatedNpv) > tolerance)
                {
                    QAssert.Fail(
                        "Failed to reproduce the npv for the given credit-default swap\n"
                        + "    computed NPV:  " + calculatedNpv + "\n"
                        + "    Given NPV:     " + npv);
                }

                if (Math.Abs(fairRate - calculatedFairRate) > tolerance)
                {
                    QAssert.Fail("Failed to reproduce the fair rate for the given credit-default swap\n"
                                 + "    computed fair rate:  " + calculatedFairRate + "\n"
                                 + "    Given fair rate:     " + fairRate);
                }
            }
        }
Ejemplo n.º 19
0
Archivo: FRA.cs Proyecto: igitur/qlnet
        static void Main()
        {
            DateTime timer = DateTime.Now;

            /*********************
            ***  MARKET DATA  ***
            *********************/

            RelinkableHandle <YieldTermStructure> euriborTermStructure = new RelinkableHandle <YieldTermStructure>();
            IborIndex euribor3m = new Euribor3M(euriborTermStructure);

            Date todaysDate = new Date(23, Month.May, 2006);

            Settings.setEvaluationDate(todaysDate);

            Calendar calendar       = euribor3m.fixingCalendar();
            int      fixingDays     = euribor3m.fixingDays();
            Date     settlementDate = calendar.advance(todaysDate, fixingDays, TimeUnit.Days);

            Console.WriteLine("Today: " + todaysDate.DayOfWeek + ", " + todaysDate);
            Console.WriteLine("Settlement date: " + settlementDate.DayOfWeek + ", " + settlementDate);


            // 3 month term FRA quotes (index refers to monthsToStart)
            double[] threeMonthFraQuote = new double[10];

            threeMonthFraQuote[1] = 0.030;
            threeMonthFraQuote[2] = 0.031;
            threeMonthFraQuote[3] = 0.032;
            threeMonthFraQuote[6] = 0.033;
            threeMonthFraQuote[9] = 0.034;

            /********************
            ***    QUOTES    ***
            ********************/

            // SimpleQuote stores a value which can be manually changed;
            // other Quote subclasses could read the value from a database
            // or some kind of data feed.


            // FRAs
            SimpleQuote fra1x4Rate  = new SimpleQuote(threeMonthFraQuote[1]);
            SimpleQuote fra2x5Rate  = new SimpleQuote(threeMonthFraQuote[2]);
            SimpleQuote fra3x6Rate  = new SimpleQuote(threeMonthFraQuote[3]);
            SimpleQuote fra6x9Rate  = new SimpleQuote(threeMonthFraQuote[6]);
            SimpleQuote fra9x12Rate = new SimpleQuote(threeMonthFraQuote[9]);

            RelinkableHandle <Quote> h1x4  = new RelinkableHandle <Quote>();  h1x4.linkTo(fra1x4Rate);
            RelinkableHandle <Quote> h2x5  = new RelinkableHandle <Quote>();  h2x5.linkTo(fra2x5Rate);
            RelinkableHandle <Quote> h3x6  = new RelinkableHandle <Quote>();  h3x6.linkTo(fra3x6Rate);
            RelinkableHandle <Quote> h6x9  = new RelinkableHandle <Quote>();  h6x9.linkTo(fra6x9Rate);
            RelinkableHandle <Quote> h9x12 = new RelinkableHandle <Quote>(); h9x12.linkTo(fra9x12Rate);

            /*********************
            ***  RATE HELPERS ***
            *********************/

            // RateHelpers are built from the above quotes together with
            // other instrument dependant infos.  Quotes are passed in
            // relinkable handles which could be relinked to some other
            // data source later.

            DayCounter            fraDayCounter = euribor3m.dayCounter();
            BusinessDayConvention convention    = euribor3m.businessDayConvention();
            bool endOfMonth = euribor3m.endOfMonth();

            RateHelper fra1x4 = new FraRateHelper(h1x4, 1, 4,
                                                  fixingDays, calendar, convention,
                                                  endOfMonth, fraDayCounter);

            RateHelper fra2x5 = new FraRateHelper(h2x5, 2, 5,
                                                  fixingDays, calendar, convention,
                                                  endOfMonth, fraDayCounter);

            RateHelper fra3x6 = new FraRateHelper(h3x6, 3, 6,
                                                  fixingDays, calendar, convention,
                                                  endOfMonth, fraDayCounter);

            RateHelper fra6x9 = new FraRateHelper(h6x9, 6, 9,
                                                  fixingDays, calendar, convention,
                                                  endOfMonth, fraDayCounter);

            RateHelper fra9x12 = new FraRateHelper(h9x12, 9, 12,
                                                   fixingDays, calendar, convention,
                                                   endOfMonth, fraDayCounter);


            /*********************
            **  CURVE BUILDING **
            *********************/

            // Any DayCounter would be fine.
            // ActualActual::ISDA ensures that 30 years is 30.0
            DayCounter termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA);

            double tolerance = 1.0e-15;

            // A FRA curve
            List <RateHelper> fraInstruments = new List <RateHelper>();

            fraInstruments.Add(fra1x4);
            fraInstruments.Add(fra2x5);
            fraInstruments.Add(fra3x6);
            fraInstruments.Add(fra6x9);
            fraInstruments.Add(fra9x12);

            YieldTermStructure fraTermStructure = new PiecewiseYieldCurve <Discount, LogLinear>(
                settlementDate, fraInstruments, termStructureDayCounter,
                new List <Handle <Quote> >(), new List <Date>(), tolerance);


            // Term structures used for pricing/discounting
            RelinkableHandle <YieldTermStructure> discountingTermStructure = new RelinkableHandle <YieldTermStructure>();

            discountingTermStructure.linkTo(fraTermStructure);


            /***********************
            ***  construct FRA's ***
            ***********************/

            Calendar fraCalendar = euribor3m.fixingCalendar();
            BusinessDayConvention fraBusinessDayConvention = euribor3m.businessDayConvention();

            Position.Type fraFwdType    = Position.Type.Long;
            double        fraNotional   = 100.0;
            const int     FraTermMonths = 3;

            int[] monthsToStart = new [] { 1, 2, 3, 6, 9 };

            euriborTermStructure.linkTo(fraTermStructure);

            Console.WriteLine("\nTest FRA construction, NPV calculation, and FRA purchase\n");

            int i;

            for (i = 0; i < monthsToStart.Length; i++)
            {
                Date fraValueDate = fraCalendar.advance(
                    settlementDate, monthsToStart[i], TimeUnit.Months,
                    fraBusinessDayConvention);

                Date fraMaturityDate = fraCalendar.advance(
                    fraValueDate, FraTermMonths, TimeUnit.Months,
                    fraBusinessDayConvention);

                double fraStrikeRate = threeMonthFraQuote[monthsToStart[i]];

                ForwardRateAgreement myFRA = new ForwardRateAgreement(fraValueDate, fraMaturityDate,
                                                                      fraFwdType, fraStrikeRate,
                                                                      fraNotional, euribor3m,
                                                                      discountingTermStructure);

                Console.WriteLine("3m Term FRA, Months to Start: " + monthsToStart[i]);

                Console.WriteLine("strike FRA rate: {0:0.00%}", fraStrikeRate);
                Console.WriteLine("FRA 3m forward rate: {0:0.00%}", myFRA.forwardRate());
                Console.WriteLine("FRA market quote: {0:0.00%}", threeMonthFraQuote[monthsToStart[i]]);
                Console.WriteLine("FRA spot value: " + myFRA.spotValue());
                Console.WriteLine("FRA forward value: " + myFRA.forwardValue());
                Console.WriteLine("FRA implied Yield: {0:0.00%}",
                                  myFRA.impliedYield(myFRA.spotValue(), myFRA.forwardValue(), settlementDate, Compounding.Simple, fraDayCounter));
                Console.WriteLine("market Zero Rate: {0:0.00%}",
                                  discountingTermStructure.link.zeroRate(fraMaturityDate, fraDayCounter, Compounding.Simple));
                Console.WriteLine("FRA NPV [should be zero]: {0}\n", myFRA.NPV());
            }



            Console.WriteLine("\n");
            Console.WriteLine("Now take a 100 basis-point upward shift in FRA quotes and examine NPV\n");


            const double BpsShift = 0.01;

            threeMonthFraQuote[1] = 0.030 + BpsShift;
            threeMonthFraQuote[2] = 0.031 + BpsShift;
            threeMonthFraQuote[3] = 0.032 + BpsShift;
            threeMonthFraQuote[6] = 0.033 + BpsShift;
            threeMonthFraQuote[9] = 0.034 + BpsShift;

            fra1x4Rate.setValue(threeMonthFraQuote[1]);
            fra2x5Rate.setValue(threeMonthFraQuote[2]);
            fra3x6Rate.setValue(threeMonthFraQuote[3]);
            fra6x9Rate.setValue(threeMonthFraQuote[6]);
            fra9x12Rate.setValue(threeMonthFraQuote[9]);


            for (i = 0; i < monthsToStart.Length; i++)
            {
                Date fraValueDate = fraCalendar.advance(
                    settlementDate, monthsToStart[i], TimeUnit.Months,
                    fraBusinessDayConvention);

                Date fraMaturityDate = fraCalendar.advance(
                    fraValueDate, FraTermMonths, TimeUnit.Months,
                    fraBusinessDayConvention);

                double fraStrikeRate = threeMonthFraQuote[monthsToStart[i]] - BpsShift;

                ForwardRateAgreement myFRA = new ForwardRateAgreement(fraValueDate, fraMaturityDate,
                                                                      fraFwdType, fraStrikeRate,
                                                                      fraNotional, euribor3m,
                                                                      discountingTermStructure);

                Console.WriteLine("3m Term FRA, 100 notional, Months to Start: " + monthsToStart[i]);
                Console.WriteLine("strike FRA rate: {0:0.00%}", fraStrikeRate);
                Console.WriteLine("FRA 3m forward rate: {0:0.00%}", myFRA.forwardRate());
                Console.WriteLine("FRA market quote: {0:0.00%}", threeMonthFraQuote[monthsToStart[i]]);
                Console.WriteLine("FRA spot value: " + myFRA.spotValue());
                Console.WriteLine("FRA forward value: " + myFRA.forwardValue());
                Console.WriteLine("FRA implied Yield: {0:0.00%}",
                                  myFRA.impliedYield(myFRA.spotValue(), myFRA.forwardValue(), settlementDate, Compounding.Simple, fraDayCounter));
                Console.WriteLine("market Zero Rate: {0:0.00%}",
                                  discountingTermStructure.link.zeroRate(fraMaturityDate, fraDayCounter, Compounding.Simple));
                Console.WriteLine("FRA NPV [should be positive]: {0}\n", myFRA.NPV());
            }

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

            Console.Write("Press any key to continue ...");
            Console.ReadKey();
        }
Ejemplo n.º 20
0
        static void Main(string[] args)
        {
            double nominal = 575000000;

            Date _marketDate;
            Date _settlementDate;
            Dictionary <string, double> _depositRates;
            Dictionary <string, double> _swapRates;
            List <RateHelper>           _rateHelpers;
            Calendar _calendar   = new TARGET();
            int      _fixingDays = 2;

            _marketDate = new Date(new DateTime(2015, 12, 17));
            Settings.setEvaluationDate(_marketDate);

            _depositRates = new Dictionary <string, double>();
            _depositRates.Add("1M", 0.0045);
            _depositRates.Add("3M", 0.0070);
            _depositRates.Add("6M", 0.0090);

            _swapRates = new Dictionary <string, double>();
            _swapRates.Add("1Y", 0.0080);
            _swapRates.Add("2Y", 0.0109);
            _swapRates.Add("3Y", 0.0134);
            _swapRates.Add("4Y", 0.0153);
            _swapRates.Add("5Y", 0.0169);
            _swapRates.Add("7Y", 0.0193);
            _swapRates.Add("10Y", 0.0218);
            _swapRates.Add("30Y", 0.0262);

            _rateHelpers = new List <RateHelper>();
            foreach (var v in _depositRates)
            {
                SimpleQuote sq = new SimpleQuote(v.Value);
                _rateHelpers.Add(new DepositRateHelper(new Handle <Quote>(sq), new Period(v.Key),
                                                       _fixingDays, _calendar, BusinessDayConvention.ModifiedFollowing, true, new Actual360()));
            }
            foreach (var v in _swapRates)
            {
                SimpleQuote sq = new SimpleQuote(v.Value);
                _rateHelpers.Add(new SwapRateHelper(new Handle <Quote>(sq), new Period(v.Key),
                                                    _calendar, Frequency.Semiannual, BusinessDayConvention.Unadjusted,
                                                    new Thirty360(Thirty360.Thirty360Convention.USA), new Euribor3M()));
            }

            _marketDate     = _calendar.adjust(_marketDate);
            _settlementDate = _calendar.advance(_marketDate, _fixingDays, TimeUnit.Days);

            YieldTermStructure yieldTermStructure = new PiecewiseYieldCurve <Discount, LogLinear>(
                _settlementDate, _rateHelpers, new ActualActual(ActualActual.Convention.ISDA));

            RelinkableHandle <YieldTermStructure> yieldTermStructureHandle = new RelinkableHandle <YieldTermStructure>();


            Frequency             fixedLegFrequency  = Frequency.Semiannual;
            BusinessDayConvention fixedLegConvention = BusinessDayConvention.ModifiedFollowing;
            DayCounter            fixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.USA);
            double fixedRate = 0.0144;

            Frequency             floatLegFrequency  = Frequency.Quarterly;
            BusinessDayConvention floatLegConvention = BusinessDayConvention.ModifiedFollowing;
            DayCounter            floatLegDayCounter = new Actual360();
            IborIndex             iborIndex          = new Euribor3M(yieldTermStructureHandle);

            iborIndex.addFixing(new Date(18, Month.Aug, 2015), 0.0033285);
            iborIndex.addFixing(new Date(18, Month.Nov, 2015), 0.0036960);
            double floatSpread = 0.0;

            VanillaSwap.Type swapType = VanillaSwap.Type.Receiver;

            Date     maturity      = new Date(20, Month.Nov, 2018);
            Date     effective     = new Date(20, Month.Nov, 2013);
            Schedule fixedSchedule = new Schedule(effective, maturity, new Period(fixedLegFrequency), _calendar, fixedLegConvention, fixedLegConvention, DateGeneration.Rule.Forward, false);
            Schedule floatSchedule = new Schedule(effective, maturity, new Period(floatLegFrequency), _calendar, floatLegConvention, floatLegConvention, DateGeneration.Rule.Forward, false);

            VanillaSwap vanillaSwap = new VanillaSwap(swapType, nominal, fixedSchedule, fixedRate, fixedLegDayCounter, floatSchedule, iborIndex, floatSpread, floatLegDayCounter);

            InterestRate        interestRate = new InterestRate(fixedRate, fixedLegDayCounter, Compounding.Simple, fixedLegFrequency);
            List <InterestRate> coupons      = new List <InterestRate>();

            for (int i = 0; i < fixedSchedule.Count; i++)
            {
                coupons.Add(interestRate);
            }
            FixedRateBond    fixedBond = new FixedRateBond(_fixingDays, nominal, fixedSchedule, coupons, BusinessDayConvention.ModifiedFollowing);
            FloatingRateBond floatBond = new FloatingRateBond(_fixingDays, nominal, floatSchedule, iborIndex, floatLegDayCounter);

            IPricingEngine bondPricingEngine = new DiscountingBondEngine(yieldTermStructureHandle);

            fixedBond.setPricingEngine(bondPricingEngine);
            floatBond.setPricingEngine(bondPricingEngine);

            IPricingEngine swapPricingEngine = new DiscountingSwapEngine(yieldTermStructureHandle);

            vanillaSwap.setPricingEngine(swapPricingEngine);

            yieldTermStructureHandle.linkTo(yieldTermStructure);

            double swapNPV      = vanillaSwap.NPV();
            double swapFixedNPV = vanillaSwap.fixedLegNPV();
            double swapFloatNPV = vanillaSwap.floatingLegNPV();

            double bondFixedNPV = fixedBond.NPV();
            double bondFloatNPV = floatBond.NPV();

            int    w = (swapType == VanillaSwap.Type.Receiver ? 1 : -1);
            double asBondsMarketValue      = w * (bondFixedNPV - bondFloatNPV);
            double asBondsMarketValueNoAcc = w * (fixedBond.cleanPrice() - floatBond.cleanPrice()) / 100.0 * nominal;
            double asBondsAccruedInterest  = asBondsMarketValue - asBondsMarketValueNoAcc;

            Console.WriteLine("Vanilla Swap Maket Value      : {0:N}", swapNPV);
            Console.WriteLine("As Bonds Market Value         : {0:N}", asBondsMarketValue);
            Console.WriteLine("As Bonds Market Value (no acc): {0:N}", asBondsMarketValueNoAcc);
            Console.WriteLine("As Bonds Accrued Interest     : {0:N}", asBondsAccruedInterest);

            Date   rollDate      = new Date(1, Month.Nov, 2015);
            double bondFixedCash = 0;

            foreach (CashFlow cf in fixedBond.cashflows())
            {
                if (cf.date() > rollDate & cf.date() <= _marketDate)
                {
                    bondFixedCash += cf.amount();
                }
            }
            double bondFloatCash = 0;

            foreach (CashFlow cf in floatBond.cashflows())
            {
                if (cf.date() > rollDate & cf.date() <= _marketDate)
                {
                    bondFloatCash += cf.amount();
                }
            }
            double asBondsCash = w * (bondFixedCash - bondFloatCash);

            Console.WriteLine("As Bonds Settled Cash         : {0:N}", asBondsCash);
        }
Ejemplo n.º 21
0
 // cleanup
 //SavedSettings backup;
 // setup
 public CommonVars()
 {
     conventions = new SwaptionMarketConventions();
     conventions.setConventions();
     atm = new AtmVolatility();
     atm.setMarketData();
     atmVolMatrix = new RelinkableHandle<SwaptionVolatilityStructure> (new
         SwaptionVolatilityMatrix(conventions.calendar,
                                  conventions.optionBdc,
                                  atm.tenors.options,
                                  atm.tenors.swaps,
                                  atm.volsHandle,
                                  conventions.dayCounter));
     termStructure=new RelinkableHandle<YieldTermStructure>();
     termStructure.linkTo((new FlatForward(0, conventions.calendar,
                                           0.05, new Actual365Fixed())));
 }
Ejemplo n.º 22
0
        public void testBMACurveConsistency <T, I, B>(CommonVars vars, I interpolator, double tolerance)
            where T : BootstrapTraits, new()
            where I : IInterpolationFactory, new()
            where B : IBootStrap, new()
        {
            // readjust settlement
            vars.calendar = new JointCalendar(new BMAIndex().fixingCalendar(),
                                              new USDLibor(new Period(3, TimeUnit.Months)).fixingCalendar(),
                                              JointCalendar.JointCalendarRule.JoinHolidays);
            vars.today = vars.calendar.adjust(Date.Today);
            Settings.setEvaluationDate(vars.today);
            vars.settlement = vars.calendar.advance(vars.today, vars.settlementDays, TimeUnit.Days);

            Handle <YieldTermStructure> riskFreeCurve = new Handle <YieldTermStructure>(
                new FlatForward(vars.settlement, 0.04, new Actual360()));

            BMAIndex  bmaIndex   = new BMAIndex();
            IborIndex liborIndex = new USDLibor(new Period(3, TimeUnit.Months), riskFreeCurve);

            for (int i = 0; i < vars.bmas; ++i)
            {
                Handle <Quote> f = new Handle <Quote>(vars.fractions[i]);
                vars.bmaHelpers.Add(new BMASwapRateHelper(f, new Period(vars.bmaData[i].n, vars.bmaData[i].units),
                                                          vars.settlementDays,
                                                          vars.calendar,
                                                          new Period(vars.bmaFrequency),
                                                          vars.bmaConvention,
                                                          vars.bmaDayCounter,
                                                          bmaIndex,
                                                          liborIndex));
            }

            int  w             = vars.today.weekday();
            Date lastWednesday = (w >= 4) ? vars.today - (w - 4) : vars.today + (4 - w - 7);
            Date lastFixing    = bmaIndex.fixingCalendar().adjust(lastWednesday);

            bmaIndex.addFixing(lastFixing, 0.03);

            vars.termStructure = new PiecewiseYieldCurve <T, I, B>(vars.settlement, vars.bmaHelpers,
                                                                   new Actual360(), new List <Handle <Quote> >(), new List <Date>(), 1.0e-12, interpolator);

            RelinkableHandle <YieldTermStructure> curveHandle = new RelinkableHandle <YieldTermStructure>();

            curveHandle.linkTo(vars.termStructure);

            // check BMA swaps
            BMAIndex  bma     = new BMAIndex(curveHandle);
            IborIndex libor3m = new USDLibor(new Period(3, TimeUnit.Months), riskFreeCurve);

            for (int i = 0; i < vars.bmas; i++)
            {
                Period tenor = new Period(vars.bmaData[i].n, vars.bmaData[i].units);

                Schedule bmaSchedule = new MakeSchedule().from(vars.settlement)
                                       .to(vars.settlement + tenor)
                                       .withFrequency(vars.bmaFrequency)
                                       .withCalendar(bma.fixingCalendar())
                                       .withConvention(vars.bmaConvention)
                                       .backwards()
                                       .value();

                Schedule liborSchedule = new MakeSchedule().from(vars.settlement)
                                         .to(vars.settlement + tenor)
                                         .withTenor(libor3m.tenor())
                                         .withCalendar(libor3m.fixingCalendar())
                                         .withConvention(libor3m.businessDayConvention())
                                         .endOfMonth(libor3m.endOfMonth())
                                         .backwards()
                                         .value();

                BMASwap swap = new BMASwap(BMASwap.Type.Payer, 100.0, liborSchedule, 0.75, 0.0,
                                           libor3m, libor3m.dayCounter(), bmaSchedule, bma, vars.bmaDayCounter);
                swap.setPricingEngine(new DiscountingSwapEngine(libor3m.forwardingTermStructure()));

                double expectedFraction  = vars.bmaData[i].rate / 100,
                       estimatedFraction = swap.fairLiborFraction();
                double error             = Math.Abs(expectedFraction - estimatedFraction);
                if (error > tolerance)
                {
                    Console.WriteLine(vars.bmaData[i].n + " year(s) BMA swap:\n"
                                      + "\n estimated libor fraction: " + estimatedFraction
                                      + "\n expected libor fraction:  " + expectedFraction
                                      + "\n error:          " + error
                                      + "\n tolerance:      " + tolerance);
                }
            }

            // this is a workaround for grabage collection
            // garbage collection needs a proper solution
            IndexManager.instance().clearHistories();
        }
Ejemplo n.º 23
0
        static void Main(string[] args)
        {
            try
            {
                DateTime timer = DateTime.Now;

                int numberOfBonds = 15;

                double[] cleanPrice = new double[numberOfBonds];

                for (int i = 0; i < numberOfBonds; i++)
                {
                    cleanPrice[i] = 100.0;
                }

                List <SimpleQuote> quote = new List <SimpleQuote>();
                for (int i = 0; i < numberOfBonds; i++)
                {
                    SimpleQuote cp = new SimpleQuote(cleanPrice[i]);
                    quote.Add(cp);
                }

                RelinkableHandle <Quote>[] quoteHandle = new RelinkableHandle <Quote> [numberOfBonds];
                for (int i = 0; i < numberOfBonds; i++)
                {
                    quoteHandle[i] = new RelinkableHandle <Quote>();
                    quoteHandle[i].linkTo(quote[i]);
                }

                int[]    lengths = { 2,  4,  6,  8, 10, 12, 14, 16,
                                     18,   20, 22, 24, 26, 28, 30 };
                double[] coupons = { 0.0200, 0.0225, 0.0250, 0.0275, 0.0300,
                                     0.0325, 0.0350, 0.0375, 0.0400, 0.0425,
                                     0.0450, 0.0475, 0.0500, 0.0525, 0.0550 };

                Frequency             frequency         = Frequency.Annual;
                DayCounter            dc                = new SimpleDayCounter();
                BusinessDayConvention accrualConvention = BusinessDayConvention.ModifiedFollowing;
                BusinessDayConvention convention        = BusinessDayConvention.ModifiedFollowing;
                double redemption = 100.0;

                Calendar calendar  = new TARGET();
                Date     today     = calendar.adjust(Date.Today);
                Date     origToday = today;
                Settings.setEvaluationDate(today);

                // changing bondSettlementDays=3 increases calculation
                // time of exponentialsplines fitting method
                int bondSettlementDays  = 0;
                int curveSettlementDays = 0;

                Date bondSettlementDate = calendar.advance(today, new Period(bondSettlementDays, TimeUnit.Days));

                Console.WriteLine();
                Console.WriteLine("Today's date: " + today);
                Console.WriteLine("Bonds' settlement date: " + bondSettlementDate);
                Console.WriteLine("Calculating fit for 15 bonds.....\n");

                List <BondHelper> instrumentsA = new List <BondHelper>();
                List <RateHelper> instrumentsB = new List <RateHelper>();

                for (int j = 0; j < lengths.Length; j++)
                {
                    Date maturity = calendar.advance(bondSettlementDate, new Period(lengths[j], TimeUnit.Years));

                    Schedule schedule = new Schedule(bondSettlementDate, maturity, new Period(frequency),
                                                     calendar, accrualConvention, accrualConvention,
                                                     DateGeneration.Rule.Backward, false);

                    BondHelper helperA = new FixedRateBondHelper(quoteHandle[j],
                                                                 bondSettlementDays,
                                                                 100.0,
                                                                 schedule,
                                                                 new InitializedList <double>(1, coupons[j]),
                                                                 dc,
                                                                 convention,
                                                                 redemption);

                    RateHelper helperB = new FixedRateBondHelper(quoteHandle[j],
                                                                 bondSettlementDays,
                                                                 100.0,
                                                                 schedule,
                                                                 new InitializedList <double>(1, coupons[j]),
                                                                 dc,
                                                                 convention,
                                                                 redemption);
                    instrumentsA.Add(helperA);
                    instrumentsB.Add(helperB);
                }


                bool   constrainAtZero = true;
                double tolerance       = 1.0e-10;
                int    max             = 5000;

                YieldTermStructure ts0 = new PiecewiseYieldCurve <Discount, LogLinear>(curveSettlementDays,
                                                                                       calendar,
                                                                                       instrumentsB,
                                                                                       dc);

                ExponentialSplinesFitting exponentialSplines = new ExponentialSplinesFitting(constrainAtZero);

                FittedBondDiscountCurve ts1 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                          calendar,
                                                                          instrumentsA,
                                                                          dc,
                                                                          exponentialSplines,
                                                                          tolerance,
                                                                          max);

                printOutput("(a) exponential splines", ts1);


                SimplePolynomialFitting simplePolynomial = new SimplePolynomialFitting(3, constrainAtZero);

                FittedBondDiscountCurve ts2 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                          calendar,
                                                                          instrumentsA,
                                                                          dc,
                                                                          simplePolynomial,
                                                                          tolerance,
                                                                          max);

                printOutput("(b) simple polynomial", ts2);


                NelsonSiegelFitting nelsonSiegel = new NelsonSiegelFitting();

                FittedBondDiscountCurve ts3 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                          calendar,
                                                                          instrumentsA,
                                                                          dc,
                                                                          nelsonSiegel,
                                                                          tolerance,
                                                                          max);

                printOutput("(c) Nelson-Siegel", ts3);


                // a cubic bspline curve with 11 knot points, implies
                // n=6 (constrained problem) basis functions

                double[] knots = { -30.0, -20.0,  0.0,  5.0, 10.0, 15.0,
                                   20.0,   25.0, 30.0, 40.0, 50.0 };

                List <double> knotVector = new List <double>();
                for (int i = 0; i < knots.Length; i++)
                {
                    knotVector.Add(knots[i]);
                }

                CubicBSplinesFitting cubicBSplines = new CubicBSplinesFitting(knotVector, constrainAtZero);

                FittedBondDiscountCurve ts4 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                          calendar,
                                                                          instrumentsA,
                                                                          dc,
                                                                          cubicBSplines,
                                                                          tolerance,
                                                                          max);

                printOutput("(d) cubic B-splines", ts4);

                SvenssonFitting svensson = new SvenssonFitting();

                FittedBondDiscountCurve ts5 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                          calendar,
                                                                          instrumentsA,
                                                                          dc,
                                                                          svensson,
                                                                          tolerance,
                                                                          max);

                printOutput("(e) Svensson", ts5);

                Handle <YieldTermStructure> discountCurve = new Handle <YieldTermStructure>(
                    new FlatForward(curveSettlementDays, calendar, 0.01, dc));

                SpreadFittingMethod nelsonSiegelSpread = new SpreadFittingMethod(new NelsonSiegelFitting(), discountCurve);

                FittedBondDiscountCurve ts6 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                          calendar,
                                                                          instrumentsA,
                                                                          dc,
                                                                          nelsonSiegelSpread,
                                                                          tolerance,
                                                                          max);

                printOutput("(f) Nelson-Siegel spreaded", ts6);


                Console.WriteLine("Output par rates for each curve. In this case, ");
                Console.WriteLine("par rates should equal coupons for these par bonds.\n");

                Console.WriteLine(" tenor" + " | "
                                  + "coupon" + " | "
                                  + "bstrap" + " | "
                                  + "   (a)" + " | "
                                  + "   (b)" + " | "
                                  + "   (c)" + " | "
                                  + "   (d)" + " | "
                                  + "   (e)" + " | "
                                  + "   (f)");

                for (int i = 0; i < instrumentsA.Count; i++)
                {
                    List <CashFlow> cfs = instrumentsA[i].bond().cashflows();

                    int         cfSize   = instrumentsA[i].bond().cashflows().Count;
                    List <Date> keyDates = new List <Date>();
                    keyDates.Add(bondSettlementDate);

                    for (int j = 0; j < cfSize - 1; j++)
                    {
                        if (!cfs[j].hasOccurred(bondSettlementDate, false))
                        {
                            Date myDate = cfs[j].date();
                            keyDates.Add(myDate);
                        }
                    }

                    double tenor = dc.yearFraction(today, cfs[cfSize - 1].date());
                    double test  = parRate(ts0, keyDates, dc);

                    Console.WriteLine(tenor.ToString("##.000").PadLeft(6) + " | "
                                      + (100.0 * coupons[i]).ToString("##.000").PadLeft(6) + " | "
                                      // piecewise bootstrap
                                      + (100.0 * parRate(ts0, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // exponential splines
                                      + (100.0 * parRate(ts1, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // simple polynomial
                                      + (100.0 * parRate(ts2, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Nelson-Siegel
                                      + (100.0 * parRate(ts3, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // cubic bsplines
                                      + (100.0 * parRate(ts4, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Svensson
                                      + (100.0 * parRate(ts5, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Nelson-Siegel Spreaded
                                      + (100.0 * parRate(ts6, keyDates, dc)).ToString("##.000").PadLeft(6));
                }

                Console.WriteLine("\n\n");
                Console.WriteLine("Now add 23 months to today. Par rates should be ");
                Console.WriteLine("automatically recalculated because today's date ");
                Console.WriteLine("changes.  Par rates will NOT equal coupons (YTM ");
                Console.WriteLine("will, with the correct compounding), but the ");
                Console.WriteLine("piecewise yield curve par rates can be used as ");
                Console.WriteLine("a benchmark for correct par rates.");
                Console.WriteLine();

                today = calendar.advance(origToday, 23, TimeUnit.Months, convention);
                Settings.setEvaluationDate(today);
                bondSettlementDate = calendar.advance(today, new Period(bondSettlementDays, TimeUnit.Days));

                printOutput("(a) exponential splines", ts1);

                printOutput("(b) simple polynomial", ts2);

                printOutput("(c) Nelson-Siegel", ts3);

                printOutput("(d) cubic B-splines", ts4);

                printOutput("(e) Svensson", ts5);

                printOutput("(f) Nelson-Siegel spreaded", ts6);

                Console.WriteLine("\n");


                Console.WriteLine(" tenor" + " | "
                                  + "coupon" + " | "
                                  + "bstrap" + " | "
                                  + "   (a)" + " | "
                                  + "   (b)" + " | "
                                  + "   (c)" + " | "
                                  + "   (d)" + " | "
                                  + "   (e)" + " | "
                                  + "   (f)");

                for (int i = 0; i < instrumentsA.Count; i++)
                {
                    List <CashFlow> cfs = instrumentsA[i].bond().cashflows();

                    int         cfSize   = instrumentsA[i].bond().cashflows().Count;
                    List <Date> keyDates = new List <Date>();
                    keyDates.Add(bondSettlementDate);

                    for (int j = 0; j < cfSize - 1; j++)
                    {
                        if (!cfs[j].hasOccurred(bondSettlementDate, false))
                        {
                            Date myDate = cfs[j].date();
                            keyDates.Add(myDate);
                        }
                    }

                    double tenor = dc.yearFraction(today, cfs[cfSize - 1].date());

                    double test = parRate(ts0, keyDates, dc);

                    Console.WriteLine(tenor.ToString("##.000").PadLeft(6) + " | "
                                      + (100.0 * coupons[i]).ToString("#.000").PadLeft(6) + " | "
                                      // piecewise bootstrap
                                      + (100.0 * parRate(ts0, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // exponential splines
                                      + (100.0 * parRate(ts1, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // simple polynomial
                                      + (100.0 * parRate(ts2, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Nelson-Siegel
                                      + (100.0 * parRate(ts3, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // cubic bsplines
                                      + (100.0 * parRate(ts4, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Svensson
                                      + (100.0 * parRate(ts5, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Nelson-Siegel Spreaded
                                      + (100.0 * parRate(ts6, keyDates, dc)).ToString("##.000").PadLeft(6));
                }

                Console.WriteLine("\n\n");
                Console.WriteLine("Now add one more month, for a total of two years ");
                Console.WriteLine("from the original date. The first instrument is ");
                Console.WriteLine("now expired and par rates should again equal ");
                Console.WriteLine("coupon values, since clean prices did not change.");
                Console.WriteLine("\n");

                instrumentsA.RemoveRange(0, 1); // TODO
                instrumentsB.RemoveRange(0, 1); // TODO

                today = calendar.advance(origToday, 24, TimeUnit.Months, convention);
                Settings.setEvaluationDate(today);
                bondSettlementDate = calendar.advance(today, new Period(bondSettlementDays, TimeUnit.Days));

                YieldTermStructure ts00 = new PiecewiseYieldCurve <Discount, LogLinear>(curveSettlementDays,
                                                                                        calendar,
                                                                                        instrumentsB,
                                                                                        dc);

                FittedBondDiscountCurve ts11 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                           calendar,
                                                                           instrumentsA,
                                                                           dc,
                                                                           exponentialSplines,
                                                                           tolerance,
                                                                           max);

                printOutput("(a) exponential splines", ts11);


                FittedBondDiscountCurve ts22 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                           calendar,
                                                                           instrumentsA,
                                                                           dc,
                                                                           simplePolynomial,
                                                                           tolerance,
                                                                           max);

                printOutput("(b) simple polynomial", ts22);


                FittedBondDiscountCurve ts33 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                           calendar,
                                                                           instrumentsA,
                                                                           dc,
                                                                           nelsonSiegel,
                                                                           tolerance,
                                                                           max);

                printOutput("(c) Nelson-Siegel", ts33);


                FittedBondDiscountCurve ts44 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                           calendar,
                                                                           instrumentsA,
                                                                           dc,
                                                                           cubicBSplines,
                                                                           tolerance,
                                                                           max);

                printOutput("(d) cubic B-splines", ts44);

                FittedBondDiscountCurve ts55 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                           calendar,
                                                                           instrumentsA,
                                                                           dc,
                                                                           svensson,
                                                                           tolerance,
                                                                           max);

                printOutput("(e) Svensson", ts55);

                FittedBondDiscountCurve ts66 = new FittedBondDiscountCurve(curveSettlementDays,
                                                                           calendar,
                                                                           instrumentsA,
                                                                           dc,
                                                                           nelsonSiegelSpread,
                                                                           tolerance,
                                                                           max);

                printOutput("(f) Nelson-Siegel spreaded", ts66);

                Console.WriteLine(" tenor" + " | "
                                  + "coupon" + " | "
                                  + "bstrap" + " | "
                                  + "   (a)" + " | "
                                  + "   (b)" + " | "
                                  + "   (c)" + " | "
                                  + "   (d)" + " | "
                                  + "   (e)" + " | "
                                  + "   (f)");

                for (int i = 0; i < instrumentsA.Count; i++)
                {
                    List <CashFlow> cfs = instrumentsA[i].bond().cashflows();

                    int         cfSize   = instrumentsA[i].bond().cashflows().Count;
                    List <Date> keyDates = new List <Date>();
                    keyDates.Add(bondSettlementDate);

                    for (int j = 0; j < cfSize - 1; j++)
                    {
                        if (!cfs[j].hasOccurred(bondSettlementDate, false))
                        {
                            Date myDate = cfs[j].date();
                            keyDates.Add(myDate);
                        }
                    }

                    double tenor = dc.yearFraction(today, cfs[cfSize - 1].date());

                    Console.WriteLine(tenor.ToString("##.000").PadLeft(6) + " | "
                                      + (100.0 * coupons[i + 1]).ToString("##.000").PadLeft(6) + " | "
                                      // piecewise bootstrap
                                      + (100.0 * parRate(ts00, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // exponential splines
                                      + (100.0 * parRate(ts11, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // simple polynomial
                                      + (100.0 * parRate(ts22, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Nelson-Siegel
                                      + (100.0 * parRate(ts33, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // cubic bsplines
                                      + (100.0 * parRate(ts44, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Svensson
                                      + (100.0 * parRate(ts55, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Nelson-Siegel Spreaded
                                      + (100.0 * parRate(ts66, keyDates, dc)).ToString("##.000").PadLeft(6));
                }


                Console.WriteLine("\n\n");
                Console.WriteLine("Now decrease prices by a small amount, corresponding");
                Console.WriteLine("to a theoretical five basis point parallel + shift of");
                Console.WriteLine("the yield curve. Because bond quotes change, the new ");
                Console.WriteLine("par rates should be recalculated automatically.");
                Console.WriteLine("\n");

                for (int k = 0; k < lengths.Length - 1; k++)
                {
                    double P   = instrumentsA[k].quote().link.value();
                    Bond   b   = instrumentsA[k].bond();
                    double ytm = BondFunctions.yield(b, P, dc, Compounding.Compounded, frequency, today);
                    double dur = BondFunctions.duration(b, ytm, dc, Compounding.Compounded, frequency,
                                                        Duration.Type.Modified, today);

                    const double bpsChange = 5.0;
                    // dP = -dur * P * dY
                    double deltaP = -dur * P * (bpsChange / 10000.0);
                    quote[k + 1].setValue(P + deltaP);
                }


                Console.WriteLine(" tenor" + " | "
                                  + "coupon" + " | "
                                  + "bstrap" + " | "
                                  + "   (a)" + " | "
                                  + "   (b)" + " | "
                                  + "   (c)" + " | "
                                  + "   (d)" + " | "
                                  + "   (e)" + " | "
                                  + "   (f)");

                for (int i = 0; i < instrumentsA.Count; i++)
                {
                    List <CashFlow> cfs = instrumentsA[i].bond().cashflows();

                    int         cfSize   = instrumentsA[i].bond().cashflows().Count;
                    List <Date> keyDates = new List <Date>();
                    keyDates.Add(bondSettlementDate);

                    for (int j = 0; j < cfSize - 1; j++)
                    {
                        if (!cfs[j].hasOccurred(bondSettlementDate, false))
                        {
                            Date myDate = cfs[j].date();
                            keyDates.Add(myDate);
                        }
                    }

                    double tenor = dc.yearFraction(today, cfs[cfSize - 1].date());

                    Console.WriteLine(tenor.ToString("##.000").PadLeft(6) + " | "
                                      + (100.0 * coupons[i + 1]).ToString("##.000").PadLeft(6) + " | "
                                      // piecewise bootstrap
                                      + (100.0 * parRate(ts00, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // exponential splines
                                      + (100.0 * parRate(ts11, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // simple polynomial
                                      + (100.0 * parRate(ts22, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Nelson-Siegel
                                      + (100.0 * parRate(ts33, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // cubic bsplines
                                      + (100.0 * parRate(ts44, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Svensson
                                      + (100.0 * parRate(ts55, keyDates, dc)).ToString("##.000").PadLeft(6) + " | "
                                      // Nelson-Siegel Spreaded
                                      + (100.0 * parRate(ts66, keyDates, dc)).ToString("##.000").PadLeft(6));
                }



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

                Console.Write("Press any key to continue ...");
                Console.ReadKey();
            }

            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return;
            }
        }
Ejemplo n.º 24
0
        public void testZeroTermStructure()
        {
            // Testing zero inflation term structure...

            SavedSettings backup = new SavedSettings();

            // try the Zero 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, 206.1,  -999.0 };

            RelinkableHandle<ZeroInflationTermStructure> hz = new RelinkableHandle<ZeroInflationTermStructure>();
            bool interp = false;
            UKRPI iiUKRPI = new UKRPI( interp, hz );
            for ( int i = 0; i < rpiSchedule.Count; i++ )
            {
                iiUKRPI.addFixing( rpiSchedule[i], fixData[i] );
            }

            ZeroInflationIndex ii = iiUKRPI as ZeroInflationIndex;
            YieldTermStructure nominalTS = nominalTermStructure();

            // now build the zero inflation curve

            Datum[] zcData = {
               new Datum( new Date(13, Month.August, 2008), 2.93 ),
               new Datum( new Date(13, Month.August, 2009), 2.95 ),
               new Datum( new Date(13, Month.August, 2010), 2.965 ),
               new Datum( new Date(15, Month.August, 2011), 2.98 ),
               new Datum( new Date(13, Month.August, 2012), 3.0 ),
               new Datum( new Date(13, Month.August, 2014), 3.06 ),
               new Datum( new Date(13, Month.August, 2017), 3.175 ),
               new Datum( new Date(13, Month.August, 2019), 3.243 ),
               new Datum( new Date(15, Month.August, 2022), 3.293 ),
               new Datum( new Date(14, Month.August, 2027), 3.338 ),
               new Datum( new Date(13, Month.August, 2032), 3.348 ),
               new Datum( new Date(15, Month.August, 2037), 3.348 ),
               new Datum( new Date(13, Month.August, 2047), 3.308 ),
               new Datum( new Date(13, Month.August, 2057), 3.228 )};

            Period observationLag = new Period( 2, TimeUnit.Months );
            DayCounter dc = new Thirty360();
            Frequency frequency = Frequency.Monthly;
            List<BootstrapHelper<ZeroInflationTermStructure>> helpers =
                makeHelpers( zcData, zcData.Length, ii,
                                                observationLag,
                                                calendar, bdc, dc );

            double baseZeroRate = zcData[0].rate / 100.0;
            PiecewiseZeroInflationCurve<Linear> pZITS = new PiecewiseZeroInflationCurve<Linear>(
                                evaluationDate, calendar, dc, observationLag,
                                frequency, ii.interpolated(), baseZeroRate,
                                new Handle<YieldTermStructure>( nominalTS ), helpers );
            pZITS.recalculate();

            // first check that the zero rates on the curve match the data
            // and that the helpers give the correct impled rates
            const double eps = 0.00000001;
            bool forceLinearInterpolation = false;
            for ( int i = 0; i < zcData.Length; i++ )
            {
                Assert.IsTrue( Math.Abs( zcData[i].rate / 100.0
                - pZITS.zeroRate( zcData[i].date, observationLag, forceLinearInterpolation ) ) < eps,
                "ZITS zeroRate != instrument "
                + pZITS.zeroRate( zcData[i].date, observationLag, forceLinearInterpolation )
                + " vs " + zcData[i].rate / 100.0
                + " interpolation: " + ii.interpolated()
                + " forceLinearInterpolation " + forceLinearInterpolation );

                Assert.IsTrue( Math.Abs( helpers[i].impliedQuote()
                - zcData[i].rate / 100.0 ) < eps,
                "ZITS implied quote != instrument "
                + helpers[i].impliedQuote()
                + " vs " + zcData[i].rate / 100.0 );
            }

            // now test the forecasting capability of the index.
            hz.linkTo( pZITS );
            from = hz.link.baseDate();
            to = hz.link.maxDate() - new Period( 1, TimeUnit.Months ); // a bit of margin for adjustments
            Schedule testIndex = new MakeSchedule().from( from ).to( to )
                                            .withTenor( new Period( 1, TimeUnit.Months ) )
                                            .withCalendar( new UnitedKingdom() )
                                            .withConvention( BusinessDayConvention.ModifiedFollowing ).value();

            // we are testing UKRPI which is not interpolated
            Date bd = hz.link.baseDate();
            double bf = ii.fixing( bd );
            for ( int i = 0; i < testIndex.Count; i++ )
            {
                Date d = testIndex[i];
                double z = hz.link.zeroRate( d, new Period( 0, TimeUnit.Days ) );
                double t = hz.link.dayCounter().yearFraction( bd, d );
                if ( !ii.interpolated() ) // because fixing constant over period
                    t = hz.link.dayCounter().yearFraction( bd,
                     Utils.inflationPeriod( d, ii.frequency() ).Key );
                double calc = bf * Math.Pow( 1 + z, t );
                if ( t <= 0 )
                    calc = ii.fixing( d, false ); // still historical
                if ( Math.Abs( calc - ii.fixing( d, true ) ) / 10000.0 > eps )
                    Assert.Fail( "ZC index does not forecast correctly for date " + d
                                + " from base date " + bd
                                + " with fixing " + bf
                                + ", correct:  " + calc
                                + ", fix: " + ii.fixing( d, true )
                                + ", t " + t );
            }

            //===========================================================================================
            // Test zero-inflation-indexed (i.e. cpi ratio) cashflow
            // just ordinary indexed cashflow with a zero inflation index

            Date baseDate = new Date( 1, Month.January, 2006 );
            Date fixDate = new Date( 1, Month.August, 2014 );
            Date payDate = new UnitedKingdom().adjust( fixDate + new Period( 3, TimeUnit.Months ), BusinessDayConvention.ModifiedFollowing );
            Index ind = ii as Index;
             Utils.QL_REQUIRE( ind != null, () => "dynamic_pointer_cast to Index from InflationIndex failed" );

            double notional = 1000000.0;//1m
            IndexedCashFlow iicf = new IndexedCashFlow( notional, ind, baseDate, fixDate, payDate );
            double correctIndexed = ii.fixing( iicf.fixingDate() ) / ii.fixing( iicf.baseDate() );
            double calculatedIndexed = iicf.amount() / iicf.notional();
            Assert.IsTrue( Math.Abs( correctIndexed - calculatedIndexed ) < eps,
                                  "IndexedCashFlow indexing wrong: " + calculatedIndexed + " vs correct = "
                                  + correctIndexed );

            //===========================================================================================
            // Test zero coupon swap

            // first make one ...

            ZeroInflationIndex zii = ii as ZeroInflationIndex;
             Utils.QL_REQUIRE( zii != null, () => "dynamic_pointer_cast to ZeroInflationIndex from UKRPI failed" );
            ZeroCouponInflationSwap nzcis =
                new ZeroCouponInflationSwap( ZeroCouponInflationSwap.Type.Payer,
                                                     1000000.0,
                                                     evaluationDate,
                                                     zcData[6].date,    // end date = maturity
                                                     calendar, bdc, dc, zcData[6].rate / 100.0, // fixed rate
                                                     zii, observationLag );

            // N.B. no coupon pricer because it is not a coupon, effect of inflation curve via
            //      inflation curve attached to the inflation index.
            Handle<YieldTermStructure> hTS = new Handle<YieldTermStructure>( nominalTS );
            IPricingEngine sppe = new DiscountingSwapEngine( hTS );
            nzcis.setPricingEngine( sppe );

            // ... and price it, should be zero
            Assert.IsTrue( Math.Abs( nzcis.NPV() ) < 0.00001, "ZCIS does not reprice to zero "
                              + nzcis.NPV()
                              + evaluationDate + " to " + zcData[6].date + " becoming " + nzcis.maturityDate()
                              + " rate " + zcData[6].rate
                              + " fixed leg " + nzcis.legNPV( 0 )
                              + " indexed-predicted inflated leg " + nzcis.legNPV( 1 )
                              + " discount " + nominalTS.discount( nzcis.maturityDate() ) );

            //===========================================================================================
            // Test multiplicative seasonality in price
            //

            //Seasonality factors NOT normalized
            //and UKRPI is not interpolated
            Date trueBaseDate = Utils.inflationPeriod( hz.link.baseDate(), ii.frequency() ).Value;
            Date seasonallityBaseDate = new Date( 31, Month.January, trueBaseDate.year() );
            List<double> seasonalityFactors = new List<double>( 12 );
            seasonalityFactors.Add( 1.003245 );
            seasonalityFactors.Add( 1.000000 );
            seasonalityFactors.Add( 0.999715 );
            seasonalityFactors.Add( 1.000495 );
            seasonalityFactors.Add( 1.000929 );
            seasonalityFactors.Add( 0.998687 );
            seasonalityFactors.Add( 0.995949 );
            seasonalityFactors.Add( 0.994682 );
            seasonalityFactors.Add( 0.995949 );
            seasonalityFactors.Add( 1.000519 );
            seasonalityFactors.Add( 1.003705 );
            seasonalityFactors.Add( 1.004186 );

            //Creating two different seasonality objects
            //
            MultiplicativePriceSeasonality seasonality_1 = new MultiplicativePriceSeasonality();
            InitializedList<double> seasonalityFactors_1 = new InitializedList<double>( 12, 1.0 );
            seasonality_1.set( seasonallityBaseDate, Frequency.Monthly, seasonalityFactors_1 );

            MultiplicativePriceSeasonality seasonality_real =
                new MultiplicativePriceSeasonality( seasonallityBaseDate, Frequency.Monthly, seasonalityFactors );
            //Testing seasonality correction when seasonality factors are = 1
            //
            double[] fixing = {
            ii.fixing(new Date(14,Month.January  ,2013),true),
            ii.fixing(new Date(14,Month.February ,2013),true),
            ii.fixing(new Date(14,Month.March    ,2013),true),
            ii.fixing(new Date(14,Month.April    ,2013),true),
            ii.fixing(new Date(14,Month.May      ,2013),true),
            ii.fixing(new Date(14,Month.June     ,2013),true),
            ii.fixing(new Date(14,Month.July     ,2013),true),
            ii.fixing(new Date(14,Month.August   ,2013),true),
            ii.fixing(new Date(14,Month.September,2013),true),
            ii.fixing(new Date(14,Month.October  ,2013),true),
            ii.fixing(new Date(14,Month.November ,2013),true),
            ii.fixing(new Date(14,Month.December ,2013),true)
             };

            hz.link.setSeasonality( seasonality_1 );
             Utils.QL_REQUIRE( hz.link.hasSeasonality(), () => "[44] incorrectly believes NO seasonality correction" );

            double[] seasonalityFixing_1 = {
            ii.fixing(new Date(14,Month.January  ,2013),true),
            ii.fixing(new Date(14,Month.February ,2013),true),
            ii.fixing(new Date(14,Month.March    ,2013),true),
            ii.fixing(new Date(14,Month.April    ,2013),true),
            ii.fixing(new Date(14,Month.May      ,2013),true),
            ii.fixing(new Date(14,Month.June     ,2013),true),
            ii.fixing(new Date(14,Month.July     ,2013),true),
            ii.fixing(new Date(14,Month.August   ,2013),true),
            ii.fixing(new Date(14,Month.September,2013),true),
            ii.fixing(new Date(14,Month.October  ,2013),true),
            ii.fixing(new Date(14,Month.November ,2013),true),
            ii.fixing(new Date(14,Month.December ,2013),true)
             };

            for ( int i = 0; i < 12; i++ )
            {
                if ( Math.Abs( fixing[i] - seasonalityFixing_1[i] ) > eps )
                {
                    Assert.Fail( "Seasonality doesn't work correctly when seasonality factors are set = 1" );
                }
            }

            //Testing seasonality correction when seasonality factors are different from 1
            //
            //0.998687 is the seasonality factor corresponding to June (the base CPI curve month)
            //
            double[] expectedFixing = {
            ii.fixing(new Date(14,Month.January  ,2013),true) * 1.003245/0.998687,
            ii.fixing(new Date(14,Month.February ,2013),true) * 1.000000/0.998687,
            ii.fixing(new Date(14,Month.March    ,2013),true) * 0.999715/0.998687,
            ii.fixing(new Date(14,Month.April    ,2013),true) * 1.000495/0.998687,
            ii.fixing(new Date(14,Month.May      ,2013),true) * 1.000929/0.998687,
            ii.fixing(new Date(14,Month.June     ,2013),true) * 0.998687/0.998687,
            ii.fixing(new Date(14,Month.July     ,2013),true) * 0.995949/0.998687,
            ii.fixing(new Date(14,Month.August   ,2013),true) * 0.994682/0.998687,
            ii.fixing(new Date(14,Month.September,2013),true) * 0.995949/0.998687,
            ii.fixing(new Date(14,Month.October  ,2013),true) * 1.000519/0.998687,
            ii.fixing(new Date(14,Month.November ,2013),true) * 1.003705/0.998687,
            ii.fixing(new Date(14,Month.December ,2013),true) * 1.004186/0.998687
             };

            hz.link.setSeasonality( seasonality_real );

            double[] seasonalityFixing_real = {
            ii.fixing(new Date(14,Month.January  ,2013),true),
            ii.fixing(new Date(14,Month.February ,2013),true),
            ii.fixing(new Date(14,Month.March    ,2013),true),
            ii.fixing(new Date(14,Month.April    ,2013),true),
            ii.fixing(new Date(14,Month.May      ,2013),true),
            ii.fixing(new Date(14,Month.June     ,2013),true),
            ii.fixing(new Date(14,Month.July     ,2013),true),
            ii.fixing(new Date(14,Month.August   ,2013),true),
            ii.fixing(new Date(14,Month.September,2013),true),
            ii.fixing(new Date(14,Month.October  ,2013),true),
            ii.fixing(new Date(14,Month.November ,2013),true),
            ii.fixing(new Date(14,Month.December ,2013),true)
             };

            for ( int i = 0; i < 12; i++ )
            {
                if ( Math.Abs( expectedFixing[i] - seasonalityFixing_real[i] ) > 0.01 )
                {
                    Assert.Fail( "Seasonality doesn't work correctly when considering seasonality factors != 1 "
                                    + expectedFixing[i] + " vs " + seasonalityFixing_real[i] );
                }
            }

            //Testing Unset function
            //
             Utils.QL_REQUIRE( hz.link.hasSeasonality(), () => "[4] incorrectly believes NO seasonality correction" );
            hz.link.setSeasonality();
             Utils.QL_REQUIRE( !hz.link.hasSeasonality(), () => "[5] incorrectly believes HAS seasonality correction" );

            double[] seasonalityFixing_unset = {
            ii.fixing(new Date(14,Month.January  ,2013),true),
            ii.fixing(new Date(14,Month.February ,2013),true),
            ii.fixing(new Date(14,Month.March    ,2013),true),
            ii.fixing(new Date(14,Month.April    ,2013),true),
            ii.fixing(new Date(14,Month.May      ,2013),true),
            ii.fixing(new Date(14,Month.June     ,2013),true),
            ii.fixing(new Date(14,Month.July     ,2013),true),
            ii.fixing(new Date(14,Month.August   ,2013),true),
            ii.fixing(new Date(14,Month.September,2013),true),
            ii.fixing(new Date(14,Month.October  ,2013),true),
            ii.fixing(new Date(14,Month.November ,2013),true),
            ii.fixing(new Date(14,Month.December ,2013),true)
             };

            for ( int i = 0; i < 12; i++ )
            {
                if ( Math.Abs( seasonalityFixing_unset[i] - seasonalityFixing_1[i] ) > eps )
                {
                    Assert.Fail( "UnsetSeasonality doesn't work correctly "
                                    + seasonalityFixing_unset[i] + " vs " + seasonalityFixing_1[i] );
                }
            }

            //==============================================================================
            // now do an INTERPOLATED index, i.e. repeat everything on a fake version of
            // UKRPI (to save making another term structure)

            bool interpYES = true;
            UKRPI iiUKRPIyes = new UKRPI( interpYES, hz );
            for ( int i = 0; i < fixData.Length; i++ )
            {
                iiUKRPIyes.addFixing( rpiSchedule[i], fixData[i] );
            }

            ZeroInflationIndex iiyes = iiUKRPIyes as ZeroInflationIndex;

            // now build the zero inflation curve
            // same data, bigger lag or it will be a self-contradiction
            Period observationLagyes = new Period( 3, TimeUnit.Months );
            List<BootstrapHelper<ZeroInflationTermStructure>> helpersyes =
                makeHelpers( zcData, zcData.Length,
                iiyes, observationLagyes, calendar, bdc, dc );

            PiecewiseZeroInflationCurve<Linear> pZITSyes =
                    new PiecewiseZeroInflationCurve<Linear>(
                    evaluationDate, calendar, dc, observationLagyes,
                    frequency, iiyes.interpolated(), baseZeroRate,
                    new Handle<YieldTermStructure>( nominalTS ), helpersyes );
            pZITSyes.recalculate();

            // first check that the zero rates on the curve match the data
            // and that the helpers give the correct impled rates
            forceLinearInterpolation = false;   // still
            for ( int i = 0; i < zcData.Length; i++ )
            {
                Assert.IsTrue( Math.Abs( zcData[i].rate / 100.0
                                - pZITSyes.zeroRate( zcData[i].date, observationLagyes, forceLinearInterpolation ) ) < eps,
                                "ZITS INTERPOLATED zeroRate != instrument "
                                + pZITSyes.zeroRate( zcData[i].date, observationLagyes, forceLinearInterpolation )
                                + " date " + zcData[i].date + " observationLagyes " + observationLagyes
                                + " vs " + zcData[i].rate / 100.0
                                + " interpolation: " + iiyes.interpolated()
                                + " forceLinearInterpolation " + forceLinearInterpolation );
                Assert.IsTrue( Math.Abs( helpersyes[i].impliedQuote()
                                    - zcData[i].rate / 100.0 ) < eps,
                                "ZITS INTERPOLATED implied quote != instrument "
                                + helpersyes[i].impliedQuote()
                                + " vs " + zcData[i].rate / 100.0 );
            }

            //======================================================================================
            // now test the forecasting capability of the index.
            hz.linkTo( pZITSyes );
            from = hz.link.baseDate() + new Period( 1, TimeUnit.Months ); // to avoid historical linear bit for rest of base month
            to = hz.link.maxDate() - new Period( 1, TimeUnit.Months ); // a bit of margin for adjustments
            testIndex = new MakeSchedule().from( from ).to( to )
            .withTenor( new Period( 1, TimeUnit.Months ) )
            .withCalendar( new UnitedKingdom() )
            .withConvention( BusinessDayConvention.ModifiedFollowing ).value();

            // we are testing UKRPI which is FAKE interpolated for testing here
            bd = hz.link.baseDate();
            bf = iiyes.fixing( bd );
            for ( int i = 0; i < testIndex.Count; i++ )
            {
                Date d = testIndex[i];
                double z = hz.link.zeroRate( d, new Period( 0, TimeUnit.Days ) );
                double t = hz.link.dayCounter().yearFraction( bd, d );
                double calc = bf * Math.Pow( 1 + z, t );
                if ( t <= 0 ) calc = iiyes.fixing( d ); // still historical
                if ( Math.Abs( calc - iiyes.fixing( d ) ) > eps )
                    Assert.Fail( "ZC INTERPOLATED index does not forecast correctly for date " + d
                                    + " from base date " + bd
                                    + " with fixing " + bf
                                    + ", correct:  " + calc
                                    + ", fix: " + iiyes.fixing( d )
                                    + ", t " + t
                                    + ", zero " + z );
            }

            //===========================================================================================
            // Test zero coupon swap

            ZeroInflationIndex ziiyes = iiyes as ZeroInflationIndex;
             Utils.QL_REQUIRE( ziiyes != null, () => "dynamic_pointer_cast to ZeroInflationIndex from UKRPI-I failed" );
            ZeroCouponInflationSwap nzcisyes = new ZeroCouponInflationSwap( ZeroCouponInflationSwap.Type.Payer,
                                                              1000000.0,
                                                              evaluationDate,
                                                              zcData[6].date,    // end date = maturity
                                                              calendar, bdc, dc, zcData[6].rate / 100.0, // fixed rate
                                                              ziiyes, observationLagyes );

            // N.B. no coupon pricer because it is not a coupon, effect of inflation curve via
            //      inflation curve attached to the inflation index.
            nzcisyes.setPricingEngine( sppe );

            // ... and price it, should be zero
            Assert.IsTrue( Math.Abs( nzcisyes.NPV() ) < 0.00001, "ZCIS-I does not reprice to zero "
                                    + nzcisyes.NPV()
                                    + evaluationDate + " to " + zcData[6].date + " becoming " + nzcisyes.maturityDate()
                                    + " rate " + zcData[6].rate
                                    + " fixed leg " + nzcisyes.legNPV( 0 )
                                    + " indexed-predicted inflated leg " + nzcisyes.legNPV( 1 )
                                    + " discount " + nominalTS.discount( nzcisyes.maturityDate() )
                                    );

            // remove circular refernce
            hz.linkTo( new ZeroInflationTermStructure() );
        }
Ejemplo n.º 25
0
        public void testFixing()
        {
            Date tradeDate = new Date( 17, Month.April, 2015 );
             Calendar calendar = new UnitedKingdom();
             Date settlementDate = calendar.advance( tradeDate, 2, TimeUnit.Days, BusinessDayConvention.Following );
             Date maturityDate = calendar.advance( settlementDate, 5, TimeUnit.Years, BusinessDayConvention.Following );

             Date valueDate = new Date( 20, Month.April, 2015 );
             Settings.setEvaluationDate( valueDate );

             List<Date> dates = new List<Date>();
             dates.Add( valueDate );
             dates.Add( valueDate + new Period( 1, TimeUnit.Years ) );
             dates.Add( valueDate + new Period( 2, TimeUnit.Years ) );
             dates.Add( valueDate + new Period( 5, TimeUnit.Years ) );
             dates.Add( valueDate + new Period( 10, TimeUnit.Years ) );
             dates.Add( valueDate + new Period( 20, TimeUnit.Years ) );

             List<double> rates = new List<double>();
             rates.Add( 0.01 );
             rates.Add( 0.01 );
             rates.Add( 0.01 );
             rates.Add( 0.01 );
             rates.Add( 0.01 );
             rates.Add( 0.01 );

             var discountCurveHandle = new RelinkableHandle<YieldTermStructure>();
             var forecastCurveHandle = new RelinkableHandle<YieldTermStructure>();
             GBPLibor index = new GBPLibor( new Period( 6, TimeUnit.Months ), forecastCurveHandle );
             InterpolatedZeroCurve<Linear> zeroCurve = new InterpolatedZeroCurve<Linear>( dates, rates, new Actual360(), new Linear() );
             var fixedSchedule = new Schedule( settlementDate, maturityDate, new Period( 1, TimeUnit.Years ), calendar, BusinessDayConvention.Following, BusinessDayConvention.Following, DateGeneration.Rule.Forward, false );
             var floatSchedule = new Schedule( settlementDate, maturityDate, index.tenor(), calendar, BusinessDayConvention.Following, BusinessDayConvention.Following, DateGeneration.Rule.Forward, false );
             VanillaSwap swap = new VanillaSwap( VanillaSwap.Type.Payer, 1000000, fixedSchedule, 0.01, new Actual360(), floatSchedule, index, 0, new Actual360() );
             discountCurveHandle.linkTo( zeroCurve );
             forecastCurveHandle.linkTo( zeroCurve );
             var swapEngine = new DiscountingSwapEngine( discountCurveHandle, false, null );
             swap.setPricingEngine( swapEngine );

             try
             {
            double npv = swap.NPV();
             }
             catch ( Exception ex )
             {
            Assert.Fail( ex.Message );
            Console.WriteLine( ex );
             }
        }
Ejemplo n.º 26
0
Archivo: FRA.cs Proyecto: ariesy/QLNet
        static void Main()
        {
            DateTime timer = DateTime.Now;

            /*********************
             ***  MARKET DATA  ***
             *********************/

            RelinkableHandle<YieldTermStructure> euriborTermStructure = new RelinkableHandle<YieldTermStructure>();
            IborIndex euribor3m = new Euribor3M(euriborTermStructure);

            Date todaysDate = new Date(23, Month.May, 2006);
            Settings.setEvaluationDate(todaysDate);

            Calendar calendar = euribor3m.fixingCalendar();
            int fixingDays = euribor3m.fixingDays();
            Date settlementDate = calendar.advance(todaysDate, fixingDays, TimeUnit.Days);

            Console.WriteLine("Today: " + todaysDate.DayOfWeek + ", " + todaysDate);
            Console.WriteLine("Settlement date: " + settlementDate.DayOfWeek + ", " + settlementDate);

            // 3 month term FRA quotes (index refers to monthsToStart)
            double[] threeMonthFraQuote = new double[10];

            threeMonthFraQuote[1]=0.030;
            threeMonthFraQuote[2]=0.031;
            threeMonthFraQuote[3]=0.032;
            threeMonthFraQuote[6]=0.033;
            threeMonthFraQuote[9]=0.034;

            /********************
             ***    QUOTES    ***
             ********************/

            // SimpleQuote stores a value which can be manually changed;
            // other Quote subclasses could read the value from a database
            // or some kind of data feed.

            // FRAs
            SimpleQuote fra1x4Rate = new SimpleQuote(threeMonthFraQuote[1]);
            SimpleQuote fra2x5Rate = new SimpleQuote(threeMonthFraQuote[2]);
            SimpleQuote fra3x6Rate = new SimpleQuote(threeMonthFraQuote[3]);
            SimpleQuote fra6x9Rate = new SimpleQuote(threeMonthFraQuote[6]);
            SimpleQuote fra9x12Rate = new SimpleQuote(threeMonthFraQuote[9]);

            RelinkableHandle<Quote> h1x4 = new RelinkableHandle<Quote>();  h1x4.linkTo(fra1x4Rate);
            RelinkableHandle<Quote> h2x5 = new RelinkableHandle<Quote>();  h2x5.linkTo(fra2x5Rate);
            RelinkableHandle<Quote> h3x6 = new RelinkableHandle<Quote>();  h3x6.linkTo(fra3x6Rate);
            RelinkableHandle<Quote> h6x9 = new RelinkableHandle<Quote>();  h6x9.linkTo(fra6x9Rate);
            RelinkableHandle<Quote> h9x12 = new RelinkableHandle<Quote>(); h9x12.linkTo(fra9x12Rate);

            /*********************
             ***  RATE HELPERS ***
             *********************/

            // RateHelpers are built from the above quotes together with
            // other instrument dependant infos.  Quotes are passed in
            // relinkable handles which could be relinked to some other
            // data source later.

            DayCounter fraDayCounter = euribor3m.dayCounter();
            BusinessDayConvention convention = euribor3m.businessDayConvention();
            bool endOfMonth = euribor3m.endOfMonth();

            RateHelper fra1x4 =  new FraRateHelper(h1x4, 1, 4,
                                                 fixingDays, calendar, convention,
                                                 endOfMonth, fraDayCounter);

            RateHelper fra2x5 = new FraRateHelper(h2x5, 2, 5,
                                                 fixingDays, calendar, convention,
                                                 endOfMonth, fraDayCounter);

            RateHelper fra3x6 = new FraRateHelper(h3x6, 3, 6,
                                                 fixingDays, calendar, convention,
                                                 endOfMonth, fraDayCounter);

            RateHelper fra6x9 = new FraRateHelper(h6x9, 6, 9,
                                                 fixingDays, calendar, convention,
                                                 endOfMonth, fraDayCounter);

            RateHelper fra9x12 = new FraRateHelper(h9x12, 9, 12,
                                                 fixingDays, calendar, convention,
                                                 endOfMonth, fraDayCounter);

            /*********************
             **  CURVE BUILDING **
             *********************/

            // Any DayCounter would be fine.
            // ActualActual::ISDA ensures that 30 years is 30.0
            DayCounter termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA);

            double tolerance = 1.0e-15;

            // A FRA curve
            List<RateHelper> fraInstruments = new List<RateHelper>();

            fraInstruments.Add(fra1x4);
            fraInstruments.Add(fra2x5);
            fraInstruments.Add(fra3x6);
            fraInstruments.Add(fra6x9);
            fraInstruments.Add(fra9x12);

            YieldTermStructure fraTermStructure = new PiecewiseYieldCurve<Discount,LogLinear>(
                                             settlementDate, fraInstruments, termStructureDayCounter,
                                             new List<Handle<Quote>>(), new List<Date>(), tolerance);

            // Term structures used for pricing/discounting
            RelinkableHandle<YieldTermStructure> discountingTermStructure = new RelinkableHandle<YieldTermStructure>();
            discountingTermStructure.linkTo(fraTermStructure);

            /***********************
             ***  construct FRA's ***
             ***********************/

            Calendar fraCalendar = euribor3m.fixingCalendar();
            BusinessDayConvention fraBusinessDayConvention = euribor3m.businessDayConvention();
            Position.Type fraFwdType = Position.Type.Long;
            double fraNotional = 100.0;
            const int FraTermMonths = 3;
            int[] monthsToStart = new [] { 1, 2, 3, 6, 9 };

            euriborTermStructure.linkTo(fraTermStructure);

            Console.WriteLine("\nTest FRA construction, NPV calculation, and FRA purchase\n");

            int i;
            for (i=0; i<monthsToStart.Length; i++) {

                Date fraValueDate = fraCalendar.advance(
                                           settlementDate,monthsToStart[i], TimeUnit.Months,
                                           fraBusinessDayConvention);

                Date fraMaturityDate = fraCalendar.advance(
                                                fraValueDate, FraTermMonths, TimeUnit.Months,
                                                fraBusinessDayConvention);

                double fraStrikeRate = threeMonthFraQuote[monthsToStart[i]];

                ForwardRateAgreement myFRA = new ForwardRateAgreement(fraValueDate, fraMaturityDate,
                                           fraFwdType,fraStrikeRate,
                                           fraNotional, euribor3m,
                                           discountingTermStructure);

                Console.WriteLine("3m Term FRA, Months to Start: " + monthsToStart[i]);

                Console.WriteLine("strike FRA rate: {0:0.00%}", fraStrikeRate);
                Console.WriteLine("FRA 3m forward rate: {0:0.00%}", myFRA.forwardRate());
                Console.WriteLine("FRA market quote: {0:0.00%}", threeMonthFraQuote[monthsToStart[i]]);
                Console.WriteLine("FRA spot value: " + myFRA.spotValue());
                Console.WriteLine("FRA forward value: " + myFRA.forwardValue());
                Console.WriteLine("FRA implied Yield: {0:0.00%}",
                     myFRA.impliedYield(myFRA.spotValue(), myFRA.forwardValue(), settlementDate, Compounding.Simple, fraDayCounter));
                Console.WriteLine("market Zero Rate: {0:0.00%}",
                     discountingTermStructure.link.zeroRate(fraMaturityDate, fraDayCounter, Compounding.Simple));
                Console.WriteLine("FRA NPV [should be zero]: {0}\n", myFRA.NPV());
            }

            Console.WriteLine("\n");
            Console.WriteLine("Now take a 100 basis-point upward shift in FRA quotes and examine NPV\n");

            const double BpsShift = 0.01;

            threeMonthFraQuote[1]=0.030+BpsShift;
            threeMonthFraQuote[2]=0.031+BpsShift;
            threeMonthFraQuote[3]=0.032+BpsShift;
            threeMonthFraQuote[6]=0.033+BpsShift;
            threeMonthFraQuote[9]=0.034+BpsShift;

            fra1x4Rate.setValue(threeMonthFraQuote[1]);
            fra2x5Rate.setValue(threeMonthFraQuote[2]);
            fra3x6Rate.setValue(threeMonthFraQuote[3]);
            fra6x9Rate.setValue(threeMonthFraQuote[6]);
            fra9x12Rate.setValue(threeMonthFraQuote[9]);

            for (i=0; i<monthsToStart.Length; i++) {

                Date fraValueDate = fraCalendar.advance(
                                           settlementDate, monthsToStart[i], TimeUnit.Months,
                                           fraBusinessDayConvention);

                Date fraMaturityDate = fraCalendar.advance(
                                                fraValueDate, FraTermMonths, TimeUnit.Months,
                                                fraBusinessDayConvention);

                double fraStrikeRate = threeMonthFraQuote[monthsToStart[i]] - BpsShift;

                ForwardRateAgreement myFRA = new ForwardRateAgreement(fraValueDate, fraMaturityDate,
                                           fraFwdType, fraStrikeRate,
                                           fraNotional, euribor3m,
                                           discountingTermStructure);

                Console.WriteLine("3m Term FRA, 100 notional, Months to Start: " + monthsToStart[i]);
                Console.WriteLine("strike FRA rate: {0:0.00%}", fraStrikeRate);
                Console.WriteLine("FRA 3m forward rate: {0:0.00%}", myFRA.forwardRate());
                Console.WriteLine("FRA market quote: {0:0.00%}", threeMonthFraQuote[monthsToStart[i]]);
                Console.WriteLine("FRA spot value: " + myFRA.spotValue());
                Console.WriteLine("FRA forward value: " + myFRA.forwardValue());
                Console.WriteLine("FRA implied Yield: {0:0.00%}",
                     myFRA.impliedYield(myFRA.spotValue(), myFRA.forwardValue(), settlementDate, Compounding.Simple, fraDayCounter));
                Console.WriteLine("market Zero Rate: {0:0.00%}",
                     discountingTermStructure.link.zeroRate(fraMaturityDate, fraDayCounter, Compounding.Simple));
                Console.WriteLine("FRA NPV [should be positive]: {0}\n", myFRA.NPV());
            }

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

            Console.Write("Press any key to continue ...");
            Console.ReadKey();
        }
Ejemplo n.º 27
0
        static void Main(string[] args)
        {
            DateTime timer = DateTime.Now;

            /*********************
            ***  MARKET DATA  ***
            *********************/

            Calendar calendar = new TARGET();

            Date settlementDate = new Date(18, Month.September, 2008);

            // must be a business day
            settlementDate = calendar.adjust(settlementDate);

            int fixingDays     = 3;
            int settlementDays = 3;

            Date todaysDate = calendar.advance(settlementDate, -fixingDays, TimeUnit.Days);

            // nothing to do with Date::todaysDate
            Settings.setEvaluationDate(todaysDate);

            Console.WriteLine("Today: {0}, {1}", todaysDate.DayOfWeek, todaysDate);
            Console.WriteLine("Settlement date: {0}, {1}", settlementDate.DayOfWeek, settlementDate);


            // Building of the bonds discounting yield curve

            /*********************
            ***  RATE HELPERS ***
            *********************/

            // RateHelpers are built from the above quotes together with
            // other instrument dependant infos.  Quotes are passed in
            // relinkable handles which could be relinked to some other
            // data source later.

            // Common data

            // ZC rates for the short end
            double zc3mQuote = 0.0096;
            double zc6mQuote = 0.0145;
            double zc1yQuote = 0.0194;

            Quote zc3mRate = new SimpleQuote(zc3mQuote);
            Quote zc6mRate = new SimpleQuote(zc6mQuote);
            Quote zc1yRate = new SimpleQuote(zc1yQuote);

            DayCounter zcBondsDayCounter = new Actual365Fixed();

            RateHelper zc3m = new DepositRateHelper(new Handle <Quote>(zc3mRate),
                                                    new Period(3, TimeUnit.Months), fixingDays,
                                                    calendar, BusinessDayConvention.ModifiedFollowing,
                                                    true, zcBondsDayCounter);
            RateHelper zc6m = new DepositRateHelper(new Handle <Quote>(zc6mRate),
                                                    new Period(6, TimeUnit.Months), fixingDays,
                                                    calendar, BusinessDayConvention.ModifiedFollowing,
                                                    true, zcBondsDayCounter);
            RateHelper zc1y = new DepositRateHelper(new Handle <Quote>(zc1yRate),
                                                    new Period(1, TimeUnit.Years), fixingDays,
                                                    calendar, BusinessDayConvention.ModifiedFollowing,
                                                    true, zcBondsDayCounter);

            // setup bonds
            double redemption = 100.0;

            const int numberOfBonds = 5;

            Date[] issueDates =
            {
                new Date(15, Month.March,    2005),
                new Date(15, Month.June,     2005),
                new Date(30, Month.June,     2006),
                new Date(15, Month.November, 2002),
                new Date(15, Month.May, 1987)
            };

            Date[] maturities =
            {
                new Date(31, Month.August, 2010),
                new Date(31, Month.August, 2011),
                new Date(31, Month.August, 2013),
                new Date(15, Month.August, 2018),
                new Date(15, Month.May, 2038)
            };

            double[] couponRates =
            {
                0.02375,
                0.04625,
                0.03125,
                0.04000,
                0.04500
            };

            double[] marketQuotes =
            {
                100.390625,
                106.21875,
                100.59375,
                101.6875,
                102.140625
            };

            List <SimpleQuote> quote = new List <SimpleQuote>();

            for (int i = 0; i < numberOfBonds; i++)
            {
                SimpleQuote cp = new SimpleQuote(marketQuotes[i]);
                quote.Add(cp);
            }

            List <RelinkableHandle <Quote> > quoteHandle = new InitializedList <RelinkableHandle <Quote> >(numberOfBonds);

            for (int i = 0; i < numberOfBonds; i++)
            {
                quoteHandle[i].linkTo(quote[i]);
            }

            // Definition of the rate helpers
            List <FixedRateBondHelper> bondsHelpers = new List <FixedRateBondHelper>();

            for (int i = 0; i < numberOfBonds; i++)
            {
                Schedule schedule = new Schedule(issueDates[i], maturities[i], new Period(Frequency.Semiannual),
                                                 new UnitedStates(UnitedStates.Market.GovernmentBond),
                                                 BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                                 DateGeneration.Rule.Backward, false);

                FixedRateBondHelper bondHelper = new FixedRateBondHelper(quoteHandle[i],
                                                                         settlementDays,
                                                                         100.0,
                                                                         schedule,
                                                                         new List <double>()
                {
                    couponRates[i]
                },
                                                                         new ActualActual(ActualActual.Convention.Bond),
                                                                         BusinessDayConvention.Unadjusted,
                                                                         redemption,
                                                                         issueDates[i]);

                bondsHelpers.Add(bondHelper);
            }

            /*********************
            **  CURVE BUILDING **
            *********************/

            // Any DayCounter would be fine.
            // ActualActual::ISDA ensures that 30 years is 30.0
            DayCounter termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA);

            double tolerance = 1.0e-15;

            // A depo-bond curve
            List <RateHelper> bondInstruments = new List <RateHelper>();

            // Adding the ZC bonds to the curve for the short end
            bondInstruments.Add(zc3m);
            bondInstruments.Add(zc6m);
            bondInstruments.Add(zc1y);

            // Adding the Fixed rate bonds to the curve for the long end
            for (int i = 0; i < numberOfBonds; i++)
            {
                bondInstruments.Add(bondsHelpers[i]);
            }

            YieldTermStructure bondDiscountingTermStructure = new PiecewiseYieldCurve <Discount, LogLinear>(
                settlementDate, bondInstruments,
                termStructureDayCounter,
                new List <Handle <Quote> >(),
                new List <Date>(),
                tolerance);

            // Building of the Libor forecasting curve
            // deposits
            double d1wQuote = 0.043375;
            double d1mQuote = 0.031875;
            double d3mQuote = 0.0320375;
            double d6mQuote = 0.03385;
            double d9mQuote = 0.0338125;
            double d1yQuote = 0.0335125;
            // swaps
            double s2yQuote  = 0.0295;
            double s3yQuote  = 0.0323;
            double s5yQuote  = 0.0359;
            double s10yQuote = 0.0412;
            double s15yQuote = 0.0433;


            /********************
            ***    QUOTES    ***
            ********************/

            // SimpleQuote stores a value which can be manually changed;
            // other Quote subclasses could read the value from a database
            // or some kind of data feed.

            // deposits
            Quote d1wRate = new SimpleQuote(d1wQuote);
            Quote d1mRate = new SimpleQuote(d1mQuote);
            Quote d3mRate = new SimpleQuote(d3mQuote);
            Quote d6mRate = new SimpleQuote(d6mQuote);
            Quote d9mRate = new SimpleQuote(d9mQuote);
            Quote d1yRate = new SimpleQuote(d1yQuote);
            // swaps
            Quote s2yRate  = new SimpleQuote(s2yQuote);
            Quote s3yRate  = new SimpleQuote(s3yQuote);
            Quote s5yRate  = new SimpleQuote(s5yQuote);
            Quote s10yRate = new SimpleQuote(s10yQuote);
            Quote s15yRate = new SimpleQuote(s15yQuote);

            /*********************
            ***  RATE HELPERS ***
            *********************/

            // RateHelpers are built from the above quotes together with
            // other instrument dependant infos.  Quotes are passed in
            // relinkable handles which could be relinked to some other
            // data source later.

            // deposits
            DayCounter depositDayCounter = new Actual360();

            RateHelper d1w = new DepositRateHelper(
                new Handle <Quote>(d1wRate),
                new Period(1, TimeUnit.Weeks), fixingDays,
                calendar, BusinessDayConvention.ModifiedFollowing,
                true, depositDayCounter);
            RateHelper d1m = new DepositRateHelper(
                new Handle <Quote>(d1mRate),
                new Period(1, TimeUnit.Months), fixingDays,
                calendar, BusinessDayConvention.ModifiedFollowing,
                true, depositDayCounter);
            RateHelper d3m = new DepositRateHelper(
                new Handle <Quote>(d3mRate),
                new Period(3, TimeUnit.Months), fixingDays,
                calendar, BusinessDayConvention.ModifiedFollowing,
                true, depositDayCounter);
            RateHelper d6m = new DepositRateHelper(
                new Handle <Quote>(d6mRate),
                new Period(6, TimeUnit.Months), fixingDays,
                calendar, BusinessDayConvention.ModifiedFollowing,
                true, depositDayCounter);
            RateHelper d9m = new DepositRateHelper(
                new Handle <Quote>(d9mRate),
                new Period(9, TimeUnit.Months), fixingDays,
                calendar, BusinessDayConvention.ModifiedFollowing,
                true, depositDayCounter);
            RateHelper d1y = new DepositRateHelper(
                new Handle <Quote>(d1yRate),
                new Period(1, TimeUnit.Years), fixingDays,
                calendar, BusinessDayConvention.ModifiedFollowing,
                true, depositDayCounter);

            // setup swaps
            Frequency             swFixedLegFrequency  = Frequency.Annual;
            BusinessDayConvention swFixedLegConvention = BusinessDayConvention.Unadjusted;
            DayCounter            swFixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European);
            IborIndex             swFloatingLegIndex   = new Euribor6M();

            Period forwardStart = new Period(1, TimeUnit.Days);

            RateHelper s2y = new SwapRateHelper(
                new Handle <Quote>(s2yRate), new Period(2, TimeUnit.Years),
                calendar, swFixedLegFrequency,
                swFixedLegConvention, swFixedLegDayCounter,
                swFloatingLegIndex, new Handle <Quote>(), forwardStart);
            RateHelper s3y = new SwapRateHelper(
                new Handle <Quote>(s3yRate), new Period(3, TimeUnit.Years),
                calendar, swFixedLegFrequency,
                swFixedLegConvention, swFixedLegDayCounter,
                swFloatingLegIndex, new Handle <Quote>(), forwardStart);
            RateHelper s5y = new SwapRateHelper(
                new Handle <Quote>(s5yRate), new Period(5, TimeUnit.Years),
                calendar, swFixedLegFrequency,
                swFixedLegConvention, swFixedLegDayCounter,
                swFloatingLegIndex, new Handle <Quote>(), forwardStart);
            RateHelper s10y = new SwapRateHelper(
                new Handle <Quote>(s10yRate), new Period(10, TimeUnit.Years),
                calendar, swFixedLegFrequency,
                swFixedLegConvention, swFixedLegDayCounter,
                swFloatingLegIndex, new Handle <Quote>(), forwardStart);
            RateHelper s15y = new SwapRateHelper(
                new Handle <Quote>(s15yRate), new Period(15, TimeUnit.Years),
                calendar, swFixedLegFrequency,
                swFixedLegConvention, swFixedLegDayCounter,
                swFloatingLegIndex, new Handle <Quote>(), forwardStart);


            /*********************
            **  CURVE BUILDING **
            *********************/

            // Any DayCounter would be fine.
            // ActualActual::ISDA ensures that 30 years is 30.0

            // A depo-swap curve
            List <RateHelper> depoSwapInstruments = new List <RateHelper>();

            depoSwapInstruments.Add(d1w);
            depoSwapInstruments.Add(d1m);
            depoSwapInstruments.Add(d3m);
            depoSwapInstruments.Add(d6m);
            depoSwapInstruments.Add(d9m);
            depoSwapInstruments.Add(d1y);
            depoSwapInstruments.Add(s2y);
            depoSwapInstruments.Add(s3y);
            depoSwapInstruments.Add(s5y);
            depoSwapInstruments.Add(s10y);
            depoSwapInstruments.Add(s15y);
            YieldTermStructure depoSwapTermStructure = new PiecewiseYieldCurve <Discount, LogLinear>(
                settlementDate, depoSwapInstruments,
                termStructureDayCounter,
                new List <Handle <Quote> >(),
                new List <Date>(),
                tolerance);

            // Term structures that will be used for pricing:
            // the one used for discounting cash flows
            RelinkableHandle <YieldTermStructure> discountingTermStructure = new RelinkableHandle <YieldTermStructure>();
            // the one used for forward rate forecasting
            RelinkableHandle <YieldTermStructure> forecastingTermStructure = new RelinkableHandle <YieldTermStructure>();

            /*********************
             * BONDS TO BE PRICED *
             **********************/

            // Common data
            double faceAmount = 100;

            // Pricing engine
            IPricingEngine bondEngine = new DiscountingBondEngine(discountingTermStructure);

            // Zero coupon bond
            ZeroCouponBond zeroCouponBond = new ZeroCouponBond(
                settlementDays,
                new UnitedStates(UnitedStates.Market.GovernmentBond),
                faceAmount,
                new Date(15, Month.August, 2013),
                BusinessDayConvention.Following,
                116.92,
                new Date(15, Month.August, 2003));

            zeroCouponBond.setPricingEngine(bondEngine);

            // Fixed 4.5% US Treasury Note
            Schedule fixedBondSchedule = new Schedule(new Date(15, Month.May, 2007),
                                                      new Date(15, Month.May, 2017), new Period(Frequency.Semiannual),
                                                      new UnitedStates(UnitedStates.Market.GovernmentBond),
                                                      BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false);

            FixedRateBond fixedRateBond = new FixedRateBond(
                settlementDays,
                faceAmount,
                fixedBondSchedule,
                new List <double>()
            {
                0.045
            },
                new ActualActual(ActualActual.Convention.Bond),
                BusinessDayConvention.ModifiedFollowing,
                100.0, new Date(15, Month.May, 2007));

            fixedRateBond.setPricingEngine(bondEngine);

            // Floating rate bond (3M USD Libor + 0.1%)
            // Should and will be priced on another curve later...

            RelinkableHandle <YieldTermStructure> liborTermStructure = new RelinkableHandle <YieldTermStructure>();
            IborIndex libor3m = new USDLibor(new Period(3, TimeUnit.Months), liborTermStructure);

            libor3m.addFixing(new Date(17, Month.July, 2008), 0.0278625);

            Schedule floatingBondSchedule = new Schedule(new Date(21, Month.October, 2005),
                                                         new Date(21, Month.October, 2010), new Period(Frequency.Quarterly),
                                                         new UnitedStates(UnitedStates.Market.NYSE),
                                                         BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, true);

            FloatingRateBond floatingRateBond = new FloatingRateBond(
                settlementDays,
                faceAmount,
                floatingBondSchedule,
                libor3m,
                new Actual360(),
                BusinessDayConvention.ModifiedFollowing,
                2,
                // Gearings
                new List <double>()
            {
                1.0
            },
                // Spreads
                new List <double>()
            {
                0.001
            },
                // Caps
                new List <double?>(),
                // Floors
                new List <double?>(),
                // Fixing in arrears
                true,
                100.0,
                new Date(21, Month.October, 2005));

            floatingRateBond.setPricingEngine(bondEngine);

            // Coupon pricers
            IborCouponPricer pricer = new BlackIborCouponPricer();

            // optionLet volatilities
            double volatility = 0.0;
            Handle <OptionletVolatilityStructure> vol;

            vol = new Handle <OptionletVolatilityStructure>(
                new ConstantOptionletVolatility(
                    settlementDays,
                    calendar,
                    BusinessDayConvention.ModifiedFollowing,
                    volatility,
                    new Actual365Fixed()));

            pricer.setCapletVolatility(vol);
            Utils.setCouponPricer(floatingRateBond.cashflows(), pricer);

            // Yield curve bootstrapping
            forecastingTermStructure.linkTo(depoSwapTermStructure);
            discountingTermStructure.linkTo(bondDiscountingTermStructure);

            // We are using the depo & swap curve to estimate the future Libor rates
            liborTermStructure.linkTo(depoSwapTermStructure);

            /***************
             * BOND PRICING *
             ****************/

            // write column headings
            int[] widths = { 18, 10, 10, 10 };

            Console.WriteLine("{0,18}{1,10}{2,10}{3,10}", "", "ZC", "Fixed", "Floating");

            int width = widths[0]
                        + widths[1]
                        + widths[2]
                        + widths[3];
            string rule = "".PadLeft(width, '-'), dblrule = "".PadLeft(width, '=');
            string tab = "".PadLeft(8, ' ');

            Console.WriteLine(rule);

            Console.WriteLine("Net present value".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}",
                              zeroCouponBond.NPV(),
                              fixedRateBond.NPV(),
                              floatingRateBond.NPV());

            Console.WriteLine("Clean price".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}",
                              zeroCouponBond.cleanPrice(),
                              fixedRateBond.cleanPrice(),
                              floatingRateBond.cleanPrice());

            Console.WriteLine("Dirty price".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}",
                              zeroCouponBond.dirtyPrice(),
                              fixedRateBond.dirtyPrice(),
                              floatingRateBond.dirtyPrice());

            Console.WriteLine("Accrued coupon".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}",
                              zeroCouponBond.accruedAmount(),
                              fixedRateBond.accruedAmount(),
                              floatingRateBond.accruedAmount());

            Console.WriteLine("Previous coupon".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}",
                              "N/A",
                              fixedRateBond.previousCouponRate(),
                              floatingRateBond.previousCouponRate());

            Console.WriteLine("Next coupon".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}",
                              "N/A",
                              fixedRateBond.nextCouponRate(),
                              floatingRateBond.nextCouponRate());

            Console.WriteLine("Yield".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}",
                              zeroCouponBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual),
                              fixedRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual),
                              floatingRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual));

            Console.WriteLine();

            // Other computations
            Console.WriteLine("Sample indirect computations (for the floating rate bond): ");
            Console.WriteLine(rule);

            Console.WriteLine("Yield to Clean Price: {0:n2}",
                              floatingRateBond.cleanPrice(floatingRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual),
                                                          new Actual360(), Compounding.Compounded, Frequency.Annual,
                                                          settlementDate));

            Console.WriteLine("Clean Price to Yield: {0:0.00%}",
                              floatingRateBond.yield(floatingRateBond.cleanPrice(), new Actual360(), Compounding.Compounded, Frequency.Annual,
                                                     settlementDate));

            /* "Yield to Price"
            *  "Price to Yield" */

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

            Console.Write("Press any key to continue ...");
            Console.ReadKey();
        }
Ejemplo n.º 28
0
        public void testImpliedObs()
        {
            // ("Testing observability of implied term structure...");

             CommonVars vars = new CommonVars();

             Date today = Settings.evaluationDate();
             Date newToday = today + new Period(3, TimeUnit.Years);
             Date newSettlement = vars.calendar.advance(newToday, vars.settlementDays, TimeUnit.Days);
             RelinkableHandle<YieldTermStructure> h = new RelinkableHandle<YieldTermStructure>();
             YieldTermStructure implied = new ImpliedTermStructure(h, newSettlement);
             Flag flag = new Flag();
             implied.registerWith(flag.update);
             h.linkTo(vars.termStructure);
             if (!flag.isUp())
            Console.WriteLine("Observer was not notified of term structure change");
        }
Ejemplo n.º 29
0
        static void Main(string[] args)
        {
            DateTime timer = DateTime.Now;

            /*********************
            ***  MARKET DATA  ***
            *********************/

            Calendar calendar = new TARGET();

            Date settlementDate = new Date(22, Month.September, 2004);

            // must be a business day
            settlementDate = calendar.adjust(settlementDate);

            int  fixingDays = 2;
            Date todaysDate = calendar.advance(settlementDate, -fixingDays, TimeUnit.Days);

            // nothing to do with Date::todaysDate
            Settings.setEvaluationDate(todaysDate);


            todaysDate = Settings.evaluationDate();
            Console.WriteLine("Today: {0}, {1}", todaysDate.DayOfWeek, todaysDate);
            Console.WriteLine("Settlement date: {0}, {1}", settlementDate.DayOfWeek, settlementDate);


            // deposits
            double d1wQuote = 0.0382;
            double d1mQuote = 0.0372;
            double d3mQuote = 0.0363;
            double d6mQuote = 0.0353;
            double d9mQuote = 0.0348;
            double d1yQuote = 0.0345;
            // FRAs
            double fra3x6Quote  = 0.037125;
            double fra6x9Quote  = 0.037125;
            double fra6x12Quote = 0.037125;
            // futures
            double fut1Quote = 96.2875;
            double fut2Quote = 96.7875;
            double fut3Quote = 96.9875;
            double fut4Quote = 96.6875;
            double fut5Quote = 96.4875;
            double fut6Quote = 96.3875;
            double fut7Quote = 96.2875;
            double fut8Quote = 96.0875;
            // swaps
            double s2yQuote  = 0.037125;
            double s3yQuote  = 0.0398;
            double s5yQuote  = 0.0443;
            double s10yQuote = 0.05165;
            double s15yQuote = 0.055175;


            /********************
            ***    QUOTES    ***
            ********************/

            // SimpleQuote stores a value which can be manually changed;
            // other Quote subclasses could read the value from a database
            // or some kind of data feed.

            // deposits
            Quote d1wRate = new SimpleQuote(d1wQuote);
            Quote d1mRate = new SimpleQuote(d1mQuote);
            Quote d3mRate = new SimpleQuote(d3mQuote);
            Quote d6mRate = new SimpleQuote(d6mQuote);
            Quote d9mRate = new SimpleQuote(d9mQuote);
            Quote d1yRate = new SimpleQuote(d1yQuote);
            // FRAs
            Quote fra3x6Rate  = new SimpleQuote(fra3x6Quote);
            Quote fra6x9Rate  = new SimpleQuote(fra6x9Quote);
            Quote fra6x12Rate = new SimpleQuote(fra6x12Quote);
            // futures
            Quote fut1Price = new SimpleQuote(fut1Quote);
            Quote fut2Price = new SimpleQuote(fut2Quote);
            Quote fut3Price = new SimpleQuote(fut3Quote);
            Quote fut4Price = new SimpleQuote(fut4Quote);
            Quote fut5Price = new SimpleQuote(fut5Quote);
            Quote fut6Price = new SimpleQuote(fut6Quote);
            Quote fut7Price = new SimpleQuote(fut7Quote);
            Quote fut8Price = new SimpleQuote(fut8Quote);
            // swaps
            Quote s2yRate  = new SimpleQuote(s2yQuote);
            Quote s3yRate  = new SimpleQuote(s3yQuote);
            Quote s5yRate  = new SimpleQuote(s5yQuote);
            Quote s10yRate = new SimpleQuote(s10yQuote);
            Quote s15yRate = new SimpleQuote(s15yQuote);


            /*********************
            ***  RATE HELPERS ***
            *********************/

            // RateHelpers are built from the above quotes together with
            // other instrument dependant infos.  Quotes are passed in
            // relinkable handles which could be relinked to some other
            // data source later.

            // deposits
            DayCounter depositDayCounter = new Actual360();

            RateHelper d1w = new DepositRateHelper(new Handle <Quote>(d1wRate), new Period(1, TimeUnit.Weeks),
                                                   fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);
            RateHelper d1m = new DepositRateHelper(new Handle <Quote>(d1mRate), new Period(1, TimeUnit.Months),
                                                   fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);
            RateHelper d3m = new DepositRateHelper(new Handle <Quote>(d3mRate), new Period(3, TimeUnit.Months),
                                                   fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);
            RateHelper d6m = new DepositRateHelper(new Handle <Quote>(d6mRate), new Period(6, TimeUnit.Months),
                                                   fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);
            RateHelper d9m = new DepositRateHelper(new Handle <Quote>(d9mRate), new Period(9, TimeUnit.Months),
                                                   fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);
            RateHelper d1y = new DepositRateHelper(new Handle <Quote>(d1yRate), new Period(1, TimeUnit.Years),
                                                   fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            // setup FRAs
            RateHelper fra3x6 = new FraRateHelper(new Handle <Quote>(fra3x6Rate), 3, 6, fixingDays, calendar,
                                                  BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);
            RateHelper fra6x9 = new FraRateHelper(new Handle <Quote>(fra6x9Rate), 6, 9, fixingDays, calendar,
                                                  BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);
            RateHelper fra6x12 = new FraRateHelper(new Handle <Quote>(fra6x12Rate), 6, 12, fixingDays, calendar,
                                                   BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);


            // setup futures
            // Handle<Quote> convexityAdjustment = new Handle<Quote>(new SimpleQuote(0.0));
            int  futMonths = 3;
            Date imm       = IMM.nextDate(settlementDate);

            RateHelper fut1 = new FuturesRateHelper(new Handle <Quote>(fut1Price), imm, futMonths, calendar,
                                                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            imm = IMM.nextDate(imm + 1);
            RateHelper fut2 = new FuturesRateHelper(new Handle <Quote>(fut2Price), imm, futMonths, calendar,
                                                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            imm = IMM.nextDate(imm + 1);
            RateHelper fut3 = new FuturesRateHelper(new Handle <Quote>(fut3Price), imm, futMonths, calendar,
                                                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            imm = IMM.nextDate(imm + 1);
            RateHelper fut4 = new FuturesRateHelper(new Handle <Quote>(fut4Price), imm, futMonths, calendar,
                                                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            imm = IMM.nextDate(imm + 1);
            RateHelper fut5 = new FuturesRateHelper(new Handle <Quote>(fut5Price), imm, futMonths, calendar,
                                                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            imm = IMM.nextDate(imm + 1);
            RateHelper fut6 = new FuturesRateHelper(new Handle <Quote>(fut6Price), imm, futMonths, calendar,
                                                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            imm = IMM.nextDate(imm + 1);
            RateHelper fut7 = new FuturesRateHelper(new Handle <Quote>(fut7Price), imm, futMonths, calendar,
                                                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);

            imm = IMM.nextDate(imm + 1);
            RateHelper fut8 = new FuturesRateHelper(new Handle <Quote>(fut8Price), imm, futMonths, calendar,
                                                    BusinessDayConvention.ModifiedFollowing, true, depositDayCounter);


            // setup swaps
            Frequency             swFixedLegFrequency  = Frequency.Annual;
            BusinessDayConvention swFixedLegConvention = BusinessDayConvention.Unadjusted;
            DayCounter            swFixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European);

            IborIndex swFloatingLegIndex = new Euribor6M();

            RateHelper s2y = new SwapRateHelper(new Handle <Quote>(s2yRate), new Period(2, TimeUnit.Years),
                                                calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex);
            RateHelper s3y = new SwapRateHelper(new Handle <Quote>(s3yRate), new Period(3, TimeUnit.Years),
                                                calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex);
            RateHelper s5y = new SwapRateHelper(new Handle <Quote>(s5yRate), new Period(5, TimeUnit.Years),
                                                calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex);
            RateHelper s10y = new SwapRateHelper(new Handle <Quote>(s10yRate), new Period(10, TimeUnit.Years),
                                                 calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex);
            RateHelper s15y = new SwapRateHelper(new Handle <Quote>(s15yRate), new Period(15, TimeUnit.Years),
                                                 calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex);



            /*********************
            **  CURVE BUILDING **
            *********************/

            // Any DayCounter would be fine.
            // ActualActual::ISDA ensures that 30 years is 30.0
            DayCounter termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA);

            double tolerance = 1.0e-15;

            // A depo-swap curve
            List <RateHelper> depoSwapInstruments = new List <RateHelper>();

            depoSwapInstruments.Add(d1w);
            depoSwapInstruments.Add(d1m);
            depoSwapInstruments.Add(d3m);
            depoSwapInstruments.Add(d6m);
            depoSwapInstruments.Add(d9m);
            depoSwapInstruments.Add(d1y);
            depoSwapInstruments.Add(s2y);
            depoSwapInstruments.Add(s3y);
            depoSwapInstruments.Add(s5y);
            depoSwapInstruments.Add(s10y);
            depoSwapInstruments.Add(s15y);
            YieldTermStructure depoSwapTermStructure = new PiecewiseYieldCurve <Discount, LogLinear>(
                settlementDate, depoSwapInstruments, termStructureDayCounter, new List <Handle <Quote> >(), new List <Date>(), tolerance);


            // A depo-futures-swap curve
            List <RateHelper> depoFutSwapInstruments = new List <RateHelper>();

            depoFutSwapInstruments.Add(d1w);
            depoFutSwapInstruments.Add(d1m);
            depoFutSwapInstruments.Add(fut1);
            depoFutSwapInstruments.Add(fut2);
            depoFutSwapInstruments.Add(fut3);
            depoFutSwapInstruments.Add(fut4);
            depoFutSwapInstruments.Add(fut5);
            depoFutSwapInstruments.Add(fut6);
            depoFutSwapInstruments.Add(fut7);
            depoFutSwapInstruments.Add(fut8);
            depoFutSwapInstruments.Add(s3y);
            depoFutSwapInstruments.Add(s5y);
            depoFutSwapInstruments.Add(s10y);
            depoFutSwapInstruments.Add(s15y);
            YieldTermStructure depoFutSwapTermStructure = new PiecewiseYieldCurve <Discount, LogLinear>(
                settlementDate, depoFutSwapInstruments, termStructureDayCounter, new List <Handle <Quote> >(), new List <Date>(), tolerance);


            // A depo-FRA-swap curve
            List <RateHelper> depoFRASwapInstruments = new List <RateHelper>();

            depoFRASwapInstruments.Add(d1w);
            depoFRASwapInstruments.Add(d1m);
            depoFRASwapInstruments.Add(d3m);
            depoFRASwapInstruments.Add(fra3x6);
            depoFRASwapInstruments.Add(fra6x9);
            depoFRASwapInstruments.Add(fra6x12);
            depoFRASwapInstruments.Add(s2y);
            depoFRASwapInstruments.Add(s3y);
            depoFRASwapInstruments.Add(s5y);
            depoFRASwapInstruments.Add(s10y);
            depoFRASwapInstruments.Add(s15y);
            YieldTermStructure depoFRASwapTermStructure = new PiecewiseYieldCurve <Discount, LogLinear>(
                settlementDate, depoFRASwapInstruments, termStructureDayCounter, new List <Handle <Quote> >(), new List <Date>(), tolerance);

            // Term structures that will be used for pricing:
            // the one used for discounting cash flows
            RelinkableHandle <YieldTermStructure> discountingTermStructure = new RelinkableHandle <YieldTermStructure>();
            // the one used for forward rate forecasting
            RelinkableHandle <YieldTermStructure> forecastingTermStructure = new RelinkableHandle <YieldTermStructure>();


            /*********************
             * SWAPS TO BE PRICED *
             **********************/

            // constant nominal 1,000,000 Euro
            double nominal = 1000000.0;
            // fixed leg
            Frequency             fixedLegFrequency     = Frequency.Annual;
            BusinessDayConvention fixedLegConvention    = BusinessDayConvention.Unadjusted;
            BusinessDayConvention floatingLegConvention = BusinessDayConvention.ModifiedFollowing;
            DayCounter            fixedLegDayCounter    = new Thirty360(Thirty360.Thirty360Convention.European);
            double     fixedRate             = 0.04;
            DayCounter floatingLegDayCounter = new Actual360();

            // floating leg
            Frequency floatingLegFrequency = Frequency.Semiannual;
            IborIndex euriborIndex         = new Euribor6M(forecastingTermStructure);
            double    spread = 0.0;

            int lenghtInYears = 5;

            VanillaSwap.Type swapType = VanillaSwap.Type.Payer;

            Date     maturity      = settlementDate + new Period(lenghtInYears, TimeUnit.Years);
            Schedule fixedSchedule = new Schedule(settlementDate, maturity, new Period(fixedLegFrequency),
                                                  calendar, fixedLegConvention, fixedLegConvention, DateGeneration.Rule.Forward, false);
            Schedule floatSchedule = new Schedule(settlementDate, maturity, new Period(floatingLegFrequency),
                                                  calendar, floatingLegConvention, floatingLegConvention, DateGeneration.Rule.Forward, false);
            VanillaSwap spot5YearSwap = new VanillaSwap(swapType, nominal, fixedSchedule, fixedRate, fixedLegDayCounter,
                                                        floatSchedule, euriborIndex, spread, floatingLegDayCounter);

            Date     fwdStart         = calendar.advance(settlementDate, 1, TimeUnit.Years);
            Date     fwdMaturity      = fwdStart + new Period(lenghtInYears, TimeUnit.Years);
            Schedule fwdFixedSchedule = new Schedule(fwdStart, fwdMaturity, new Period(fixedLegFrequency),
                                                     calendar, fixedLegConvention, fixedLegConvention, DateGeneration.Rule.Forward, false);
            Schedule fwdFloatSchedule = new Schedule(fwdStart, fwdMaturity, new Period(floatingLegFrequency),
                                                     calendar, floatingLegConvention, floatingLegConvention, DateGeneration.Rule.Forward, false);
            VanillaSwap oneYearForward5YearSwap = new VanillaSwap(swapType, nominal, fwdFixedSchedule, fixedRate, fixedLegDayCounter,
                                                                  fwdFloatSchedule, euriborIndex, spread, floatingLegDayCounter);


            /***************
             * SWAP PRICING *
             ****************/

            // utilities for reporting
            List <string> headers = new List <string>();

            headers.Add("term structure");
            headers.Add("net present value");
            headers.Add("fair spread");
            headers.Add("fair fixed rate");
            string separator = " | ";
            int    width     = headers[0].Length + separator.Length
                               + headers[1].Length + separator.Length
                               + headers[2].Length + separator.Length
                               + headers[3].Length + separator.Length - 1;
            string rule = string.Format("").PadLeft(width, '-'), dblrule = string.Format("").PadLeft(width, '=');
            string tab = string.Format("").PadLeft(8, ' ');

            // calculations

            Console.WriteLine(dblrule);
            Console.WriteLine("5-year market swap-rate = {0:0.00%}", s5yRate.value());
            Console.WriteLine(dblrule);

            Console.WriteLine(tab + "5-years swap paying {0:0.00%}", fixedRate);
            Console.WriteLine(headers[0] + separator
                              + headers[1] + separator
                              + headers[2] + separator
                              + headers[3] + separator);
            Console.WriteLine(rule);

            double NPV;
            double fairRate;
            double fairSpread;

            IPricingEngine swapEngine = new DiscountingSwapEngine(discountingTermStructure);

            spot5YearSwap.setPricingEngine(swapEngine);
            oneYearForward5YearSwap.setPricingEngine(swapEngine);

            // Of course, you're not forced to really use different curves
            forecastingTermStructure.linkTo(depoSwapTermStructure);
            discountingTermStructure.linkTo(depoSwapTermStructure);

            NPV        = spot5YearSwap.NPV();
            fairSpread = spot5YearSwap.fairSpread();
            fairRate   = spot5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            // let's check that the 5 years swap has been correctly re-priced
            if (!(Math.Abs(fairRate - s5yQuote) < 1e-8))
            {
                throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate - s5yQuote));
            }


            forecastingTermStructure.linkTo(depoFutSwapTermStructure);
            discountingTermStructure.linkTo(depoFutSwapTermStructure);

            NPV        = spot5YearSwap.NPV();
            fairSpread = spot5YearSwap.fairSpread();
            fairRate   = spot5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            if (!(Math.Abs(fairRate - s5yQuote) < 1e-8))
            {
                throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate - s5yQuote));
            }

            forecastingTermStructure.linkTo(depoFRASwapTermStructure);
            discountingTermStructure.linkTo(depoFRASwapTermStructure);

            NPV        = spot5YearSwap.NPV();
            fairSpread = spot5YearSwap.fairSpread();
            fairRate   = spot5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            if (!(Math.Abs(fairRate - s5yQuote) < 1e-8))
            {
                throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate - s5yQuote));
            }

            Console.WriteLine(rule);

            // now let's price the 1Y forward 5Y swap
            Console.WriteLine(tab + "5-years, 1-year forward swap paying {0:0.00%}", fixedRate);
            Console.WriteLine(headers[0] + separator
                              + headers[1] + separator
                              + headers[2] + separator
                              + headers[3] + separator);
            Console.WriteLine(rule);

            forecastingTermStructure.linkTo(depoSwapTermStructure);
            discountingTermStructure.linkTo(depoSwapTermStructure);

            NPV        = oneYearForward5YearSwap.NPV();
            fairSpread = oneYearForward5YearSwap.fairSpread();
            fairRate   = oneYearForward5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            forecastingTermStructure.linkTo(depoFutSwapTermStructure);
            discountingTermStructure.linkTo(depoFutSwapTermStructure);

            NPV        = oneYearForward5YearSwap.NPV();
            fairSpread = oneYearForward5YearSwap.fairSpread();
            fairRate   = oneYearForward5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            forecastingTermStructure.linkTo(depoFRASwapTermStructure);
            discountingTermStructure.linkTo(depoFRASwapTermStructure);

            NPV        = oneYearForward5YearSwap.NPV();
            fairSpread = oneYearForward5YearSwap.fairSpread();
            fairRate   = oneYearForward5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            // now let's say that the 5-years swap rate goes up to 4.60%.
            // A smarter market element--say, connected to a data source-- would
            // notice the change itself. Since we're using SimpleQuotes,
            // we'll have to change the value manually--which forces us to
            // downcast the handle and use the SimpleQuote
            // interface. In any case, the point here is that a change in the
            // value contained in the Quote triggers a new bootstrapping
            // of the curve and a repricing of the swap.

            SimpleQuote fiveYearsRate = s5yRate as SimpleQuote;

            fiveYearsRate.setValue(0.0460);

            Console.WriteLine(dblrule);
            Console.WriteLine("5-year market swap-rate = {0:0.00%}", s5yRate.value());
            Console.WriteLine(dblrule);

            Console.WriteLine(tab + "5-years swap paying {0:0.00%}", fixedRate);
            Console.WriteLine(headers[0] + separator
                              + headers[1] + separator
                              + headers[2] + separator
                              + headers[3] + separator);
            Console.WriteLine(rule);

            // now get the updated results
            forecastingTermStructure.linkTo(depoSwapTermStructure);
            discountingTermStructure.linkTo(depoSwapTermStructure);

            NPV        = spot5YearSwap.NPV();
            fairSpread = spot5YearSwap.fairSpread();
            fairRate   = spot5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            if (!(Math.Abs(fairRate - s5yRate.value()) < 1e-8))
            {
                throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate - s5yRate.value()));
            }

            forecastingTermStructure.linkTo(depoFutSwapTermStructure);
            discountingTermStructure.linkTo(depoFutSwapTermStructure);

            NPV        = spot5YearSwap.NPV();
            fairSpread = spot5YearSwap.fairSpread();
            fairRate   = spot5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            if (!(Math.Abs(fairRate - s5yRate.value()) < 1e-8))
            {
                throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate - s5yRate.value()));
            }

            forecastingTermStructure.linkTo(depoFRASwapTermStructure);
            discountingTermStructure.linkTo(depoFRASwapTermStructure);

            NPV        = spot5YearSwap.NPV();
            fairSpread = spot5YearSwap.fairSpread();
            fairRate   = spot5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            if (!(Math.Abs(fairRate - s5yRate.value()) < 1e-8))
            {
                throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate - s5yRate.value()));
            }

            Console.WriteLine(rule);

            // the 1Y forward 5Y swap changes as well

            Console.WriteLine(tab + "5-years, 1-year forward swap paying {0:0.00%}", fixedRate);
            Console.WriteLine(headers[0] + separator
                              + headers[1] + separator
                              + headers[2] + separator
                              + headers[3] + separator);
            Console.WriteLine(rule);

            forecastingTermStructure.linkTo(depoSwapTermStructure);
            discountingTermStructure.linkTo(depoSwapTermStructure);

            NPV        = oneYearForward5YearSwap.NPV();
            fairSpread = oneYearForward5YearSwap.fairSpread();
            fairRate   = oneYearForward5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            forecastingTermStructure.linkTo(depoFutSwapTermStructure);
            discountingTermStructure.linkTo(depoFutSwapTermStructure);

            NPV        = oneYearForward5YearSwap.NPV();
            fairSpread = oneYearForward5YearSwap.fairSpread();
            fairRate   = oneYearForward5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);

            forecastingTermStructure.linkTo(depoFRASwapTermStructure);
            discountingTermStructure.linkTo(depoFRASwapTermStructure);

            NPV        = oneYearForward5YearSwap.NPV();
            fairSpread = oneYearForward5YearSwap.fairSpread();
            fairRate   = oneYearForward5YearSwap.fairRate();

            Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap");
            Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV);
            Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread);
            Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate);


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

            Console.Write("Press any key to continue ...");
            Console.ReadKey();
        }
Ejemplo n.º 30
0
Archivo: Repo.cs Proyecto: ariesy/QLNet
        static void Main(string[] args)
        {
            DateTime timer = DateTime.Now;

            Date repoSettlementDate = new Date(14,Month.February,2000);;
            Date repoDeliveryDate = new Date(15,Month.August,2000);
            double repoRate = 0.05;
            DayCounter repoDayCountConvention = new Actual360();
            int repoSettlementDays = 0;
            Compounding repoCompounding = Compounding.Simple;
            Frequency repoCompoundFreq = Frequency.Annual;

            // assume a ten year bond- this is irrelevant
            Date bondIssueDate = new Date(15,Month.September,1995);
            Date bondDatedDate = new Date(15,Month.September,1995);
            Date bondMaturityDate = new Date(15,Month.September,2005);
            double bondCoupon = 0.08;
            Frequency bondCouponFrequency = Frequency.Semiannual;
            // unknown what calendar fincad is using
            Calendar bondCalendar = new NullCalendar();
            DayCounter bondDayCountConvention = new Thirty360(Thirty360.Thirty360Convention.BondBasis);
            // unknown what fincad is using. this may affect accrued calculation
            int bondSettlementDays = 0;
            BusinessDayConvention bondBusinessDayConvention = BusinessDayConvention.Unadjusted;
            double bondCleanPrice = 89.97693786;
            double bondRedemption = 100.0;
            double faceAmount = 100.0;

            Settings.setEvaluationDate(repoSettlementDate);

            RelinkableHandle<YieldTermStructure> bondCurve = new RelinkableHandle<YieldTermStructure>();
            bondCurve.linkTo(new FlatForward(repoSettlementDate,
                                               .01, // dummy rate
                                               bondDayCountConvention,
                                               Compounding.Compounded,
                                               bondCouponFrequency));

            /*
            boost::shared_ptr<FixedRateBond> bond(
                           new FixedRateBond(faceAmount,
                                             bondIssueDate,
                                             bondDatedDate,
                                             bondMaturityDate,
                                             bondSettlementDays,
                                             std::vector<Rate>(1,bondCoupon),
                                             bondCouponFrequency,
                                             bondCalendar,
                                             bondDayCountConvention,
                                             bondBusinessDayConvention,
                                             bondBusinessDayConvention,
                                             bondRedemption,
                                             bondCurve));
            */

            Schedule bondSchedule = new Schedule(bondDatedDate, bondMaturityDate,
                                  new Period(bondCouponFrequency),
                                  bondCalendar,bondBusinessDayConvention,
                                  bondBusinessDayConvention,
                                  DateGeneration.Rule.Backward,false);
            FixedRateBond bond = new FixedRateBond(bondSettlementDays,
                                             faceAmount,
                                             bondSchedule,
                                             new List<double>() { bondCoupon },
                                             bondDayCountConvention,
                                             bondBusinessDayConvention,
                                             bondRedemption,
                                             bondIssueDate);
            bond.setPricingEngine(new DiscountingBondEngine(bondCurve));

            bondCurve.linkTo(new FlatForward(repoSettlementDate,
                                       bond.yield(bondCleanPrice,
                                                   bondDayCountConvention,
                                                   Compounding.Compounded,
                                                   bondCouponFrequency),
                                       bondDayCountConvention,
                                       Compounding.Compounded,
                                       bondCouponFrequency));

            Position.Type fwdType = Position.Type.Long;
            double dummyStrike = 91.5745;

            RelinkableHandle<YieldTermStructure> repoCurve = new RelinkableHandle<YieldTermStructure>();
            repoCurve.linkTo(new FlatForward(repoSettlementDate,
                                               repoRate,
                                               repoDayCountConvention,
                                               repoCompounding,
                                               repoCompoundFreq));

            FixedRateBondForward bondFwd = new FixedRateBondForward(repoSettlementDate,
                                         repoDeliveryDate,
                                         fwdType,
                                         dummyStrike,
                                         repoSettlementDays,
                                         repoDayCountConvention,
                                         bondCalendar,
                                         bondBusinessDayConvention,
                                         bond,
                                         repoCurve,
                                         repoCurve);

            Console.WriteLine("Underlying bond clean price: " + bond.cleanPrice());
            Console.WriteLine("Underlying bond dirty price: " + bond.dirtyPrice());
            Console.WriteLine("Underlying bond accrued at settlement: "
                 + bond.accruedAmount(repoSettlementDate));
            Console.WriteLine("Underlying bond accrued at delivery:   "
                 + bond.accruedAmount(repoDeliveryDate));
            Console.WriteLine("Underlying bond spot income: "
                 + bondFwd.spotIncome(repoCurve));
            Console.WriteLine("Underlying bond fwd income:  "
                 + bondFwd.spotIncome(repoCurve)/
                    repoCurve.link.discount(repoDeliveryDate));
            Console.WriteLine("Repo strike: " + dummyStrike);
            Console.WriteLine("Repo NPV:    " + bondFwd.NPV());
            Console.WriteLine("Repo clean forward price: "
                 + bondFwd.cleanForwardPrice());
            Console.WriteLine("Repo dirty forward price: "
                 + bondFwd.forwardPrice());
            Console.WriteLine("Repo implied yield: "
                 + bondFwd.impliedYield(bond.dirtyPrice(),
                                         dummyStrike,
                                         repoSettlementDate,
                                         repoCompounding,
                                         repoDayCountConvention));
            Console.WriteLine("Market repo rate:   "
                 + repoCurve.link.zeroRate(repoDeliveryDate,
                                        repoDayCountConvention,
                                        repoCompounding,
                                        repoCompoundFreq));

            Console.WriteLine("\nCompare with example given at \n"
                 + "http://www.fincad.com/support/developerFunc/mathref/BFWD.htm");
            Console.WriteLine("Clean forward price = 88.2408");
            Console.WriteLine("\nIn that example, it is unknown what bond calendar they are\n"
                 + "using, as well as settlement Days. For that reason, I have\n"
                 + "made the simplest possible assumptions here: NullCalendar\n"
                 + "and 0 settlement days.\n");

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

              Console.Write("Press any key to continue ...");
              Console.ReadKey();
        }
Ejemplo n.º 31
0
            // setup
            public CommonVars()
            {
                backup    = new SavedSettings();
                cleaner   = new IndexHistoryCleaner();
                nominalUK = new RelinkableHandle <YieldTermStructure>();
                cpiUK     = new RelinkableHandle <ZeroInflationTermStructure>();
                hcpi      = new RelinkableHandle <ZeroInflationTermStructure>();
                zciisD    = new List <Date>();
                zciisR    = new List <double>();
                hii       = new RelinkableHandle <ZeroInflationIndex>();

                nominals = new InitializedList <double>(1, 1000000);
                // option variables
                frequency = Frequency.Annual;
                // usual setup
                volatility = 0.01;
                length     = 7;
                calendar   = new UnitedKingdom();
                convention = BusinessDayConvention.ModifiedFollowing;
                Date today = new Date(25, Month.November, 2009);

                evaluationDate = calendar.adjust(today);
                Settings.Instance.setEvaluationDate(evaluationDate);
                settlementDays = 0;
                fixingDays     = 0;
                settlement     = calendar.advance(today, settlementDays, TimeUnit.Days);
                startDate      = settlement;
                dcZCIIS        = new ActualActual();
                dcNominal      = new ActualActual();

                // uk rpi index
                //      fixing data
                Date     from        = new Date(20, Month.July, 2007);
                Date     to          = new Date(20, Month.November, 2009);
                Schedule rpiSchedule = new MakeSchedule().from(from).to(to)
                                       .withTenor(new Period(1, TimeUnit.Months))
                                       .withCalendar(new UnitedKingdom())
                                       .withConvention(BusinessDayConvention.ModifiedFollowing).value();

                double[] fixData =
                {
                    206.1,  207.3, 208.0, 208.9, 209.7, 210.9,
                    209.8,  211.4, 212.1, 214.0, 215.1, 216.8,
                    216.5,  217.2, 218.4, 217.7,   216,
                    212.9,  210.1, 211.4, 211.3, 211.5,
                    212.8,  213.4, 213.4, 213.4, 214.4,
                    -999.0, -999.0
                };

                // link from cpi index to cpi TS
                bool interp = false;// this MUST be false because the observation lag is only 2 months

                // for ZCIIS; but not for contract if the contract uses a bigger lag.
                ii = new UKRPI(interp, hcpi);
                for (int i = 0; i < rpiSchedule.Count; i++)
                {
                    ii.addFixing(rpiSchedule[i], fixData[i], true); // force overwrite in case multiple use
                }

                Datum[] nominalData =
                {
                    new Datum(new Date(26, Month.November,  2009),   0.475),
                    new Datum(new Date(2,  Month.December,  2009), 0.47498),
                    new Datum(new Date(29, Month.December,  2009), 0.49988),
                    new Datum(new Date(25, Month.February,  2010), 0.59955),
                    new Datum(new Date(18, Month.March,     2010), 0.65361),
                    new Datum(new Date(25, Month.May,       2010), 0.82830),
                    new Datum(new Date(17, Month.June,      2010),     0.7),
                    new Datum(new Date(16, Month.September, 2010), 0.78960),
                    new Datum(new Date(16, Month.December,  2010), 0.93762),
                    new Datum(new Date(17, Month.March,     2011), 1.12037),
                    new Datum(new Date(22, Month.September, 2011), 1.52011),
                    new Datum(new Date(25, Month.November,  2011), 1.78399),
                    new Datum(new Date(26, Month.November,  2012), 2.41170),
                    new Datum(new Date(25, Month.November,  2013), 2.83935),
                    new Datum(new Date(25, Month.November,  2014), 3.12888),
                    new Datum(new Date(25, Month.November,  2015), 3.34298),
                    new Datum(new Date(25, Month.November,  2016), 3.50632),
                    new Datum(new Date(27, Month.November,  2017), 3.63666),
                    new Datum(new Date(26, Month.November,  2018), 3.74723),
                    new Datum(new Date(25, Month.November,  2019), 3.83988),
                    new Datum(new Date(25, Month.November,  2021), 4.00508),
                    new Datum(new Date(25, Month.November,  2024), 4.16042),
                    new Datum(new Date(26, Month.November,  2029), 4.15577),
                    new Datum(new Date(27, Month.November,  2034), 4.04933),
                    new Datum(new Date(25, Month.November,  2039), 3.95217),
                    new Datum(new Date(25, Month.November,  2049), 3.80932),
                    new Datum(new Date(25, Month.November,  2059), 3.80849),
                    new Datum(new Date(25, Month.November,  2069), 3.72677),
                    new Datum(new Date(27, Month.November,  2079), 3.63082)
                };
                int nominalDataLength = 30 - 1;

                List <Date>   nomD = new List <Date>();
                List <double> nomR = new List <double>();

                for (int i = 0; i < nominalDataLength; i++)
                {
                    nomD.Add(nominalData[i].date);
                    nomR.Add(nominalData[i].rate / 100.0);
                }
                YieldTermStructure nominal = new InterpolatedZeroCurve <Linear>(nomD, nomR, dcNominal);

                nominalUK.linkTo(nominal);

                // now build the zero inflation curve
                observationLag                   = new Period(2, TimeUnit.Months);
                contractObservationLag           = new Period(3, TimeUnit.Months);
                contractObservationInterpolation = InterpolationType.Flat;

                Datum[] zciisData =
                {
                    new Datum(new Date(25, Month.November, 2010),  3.0495),
                    new Datum(new Date(25, Month.November, 2011),    2.93),
                    new Datum(new Date(26, Month.November, 2012),  2.9795),
                    new Datum(new Date(25, Month.November, 2013),   3.029),
                    new Datum(new Date(25, Month.November, 2014),  3.1425),
                    new Datum(new Date(25, Month.November, 2015),   3.211),
                    new Datum(new Date(25, Month.November, 2016),  3.2675),
                    new Datum(new Date(25, Month.November, 2017),  3.3625),
                    new Datum(new Date(25, Month.November, 2018),   3.405),
                    new Datum(new Date(25, Month.November, 2019),    3.48),
                    new Datum(new Date(25, Month.November, 2021),   3.576),
                    new Datum(new Date(25, Month.November, 2024),   3.649),
                    new Datum(new Date(26, Month.November, 2029),   3.751),
                    new Datum(new Date(27, Month.November, 2034), 3.77225),
                    new Datum(new Date(25, Month.November, 2039),    3.77),
                    new Datum(new Date(25, Month.November, 2049),   3.734),
                    new Datum(new Date(25, Month.November, 2059), 3.714)
                };
                zciisDataLength = 17;
                for (int i = 0; i < zciisDataLength; i++)
                {
                    zciisD.Add(zciisData[i].date);
                    zciisR.Add(zciisData[i].rate);
                }

                // now build the helpers ...
                List <BootstrapHelper <ZeroInflationTermStructure> > helpers = makeHelpers(zciisData, zciisDataLength, ii,
                                                                                           observationLag, calendar, convention, dcZCIIS);

                // we can use historical or first ZCIIS for this
                // we know historical is WAY off market-implied, so use market implied flat.
                double baseZeroRate = zciisData[0].rate / 100.0;
                PiecewiseZeroInflationCurve <Linear> pCPIts = new PiecewiseZeroInflationCurve <Linear>(
                    evaluationDate, calendar, dcZCIIS, observationLag, ii.frequency(), ii.interpolated(), baseZeroRate,
                    new Handle <YieldTermStructure>(nominalUK), helpers);

                pCPIts.recalculate();
                cpiUK.linkTo(pCPIts);

                // make sure that the index has the latest zero inflation term structure
                hcpi.linkTo(pCPIts);
            }
Ejemplo n.º 32
0
        public void testFairUpfront()
        {
            // Testing fair-upfront calculation for credit-default swaps...

            SavedSettings backup = new SavedSettings();

            // Initialize curves
            Calendar calendar = new TARGET();
            Date today = calendar.adjust(Date.Today);
            Settings.setEvaluationDate(today);

            Handle<Quote> hazardRate = new Handle<Quote>(new SimpleQuote(0.01234));
            RelinkableHandle<DefaultProbabilityTermStructure> probabilityCurve =
                new RelinkableHandle<DefaultProbabilityTermStructure>();
            probabilityCurve.linkTo(new FlatHazardRate(0, calendar, hazardRate, new Actual360()));

            RelinkableHandle<YieldTermStructure> discountCurve =
                new RelinkableHandle<YieldTermStructure>();
            discountCurve.linkTo(new FlatForward(today,0.06,new Actual360()));

            // Build the schedule
            Date issueDate = today;
            Date maturity = calendar.advance(issueDate, 10, TimeUnit.Years);
            BusinessDayConvention convention = BusinessDayConvention.Following;

            Schedule schedule =
                new MakeSchedule().from(issueDate)
                                       .to(maturity)
                                       .withFrequency(Frequency.Quarterly)
                                       .withCalendar(calendar)
                                       .withTerminationDateConvention(convention)
                                       .withRule(DateGeneration.Rule.TwentiethIMM).value();

            // Build the CDS
            double fixedRate = 0.05;
            double upfront = 0.001;
            DayCounter dayCount = new Actual360();
            double notional = 10000.0;
            double recoveryRate = 0.4;

            IPricingEngine engine = new MidPointCdsEngine(probabilityCurve, recoveryRate,	discountCurve, true);

            CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, notional, upfront, fixedRate,
                                        schedule, convention, dayCount, true, true);
            cds.setPricingEngine(engine);

            double fairUpfront = cds.fairUpfront();

            CreditDefaultSwap fairCds = new CreditDefaultSwap(Protection.Side.Seller, notional,
                                            fairUpfront, fixedRate,	schedule, convention, dayCount, true, true);
            fairCds.setPricingEngine(engine);

            double fairNPV = fairCds.NPV();
            double tolerance = 1e-10;

            if (Math.Abs(fairNPV) > tolerance)
                Assert.Fail(
                    "Failed to reproduce null NPV with calculated fair upfront\n"
                    + "    calculated upfront: " + fairUpfront + "\n"
                    + "    calculated NPV:     " + fairNPV);

            // same with null upfront to begin with
            upfront = 0.0;
            CreditDefaultSwap cds2 = new CreditDefaultSwap(Protection.Side.Seller, notional, upfront, fixedRate,
                                        schedule, convention, dayCount, true, true);
            cds2.setPricingEngine(engine);

            fairUpfront = cds2.fairUpfront();

            CreditDefaultSwap fairCds2 = new CreditDefaultSwap(Protection.Side.Seller, notional,
                                                fairUpfront, fixedRate,	schedule, convention, dayCount, true, true);
            fairCds2.setPricingEngine(engine);

            fairNPV = fairCds2.NPV();

            if (Math.Abs(fairNPV) > tolerance)
                Assert.Fail(
                    "Failed to reproduce null NPV with calculated fair upfront\n"
                    + "    calculated upfront: " + fairUpfront + "\n"
                    + "    calculated NPV:     " + fairNPV);
        }
Ejemplo n.º 33
0
 // SET FORECASTING TERM STRUCTURE
 public void setForecastingTermStructure()
 {
     RelinkableHandle <YieldTermStructure> forecastingTermStructure = new RelinkableHandle <YieldTermStructure>();
 }
Ejemplo n.º 34
0
        public void testImpliedHazardRate()
        {
            // Testing implied hazard-rate for credit-default swaps...

            SavedSettings backup = new SavedSettings();

            // Initialize curves
            Calendar calendar = new TARGET();
            Date today = calendar.adjust(Date.Today);
            Settings.setEvaluationDate(today);

            double h1 = 0.30, h2 = 0.40;
            DayCounter dayCounter = new Actual365Fixed();

            List<Date> dates = new List<Date>(3);
            List<double> hazardRates = new List<double>(3);
            dates.Add(today);
            hazardRates.Add(h1);

            dates.Add(today + new Period(5,TimeUnit.Years));
            hazardRates.Add(h1);

            dates.Add(today + new Period(10,TimeUnit.Years));
            hazardRates.Add(h2);

            RelinkableHandle<DefaultProbabilityTermStructure> probabilityCurve =
                new RelinkableHandle<DefaultProbabilityTermStructure>();
            probabilityCurve.linkTo(new InterpolatedHazardRateCurve<BackwardFlat>(dates,
                                                                                            hazardRates,
                                                                                            dayCounter));

            RelinkableHandle<YieldTermStructure> discountCurve = new RelinkableHandle<YieldTermStructure>();
            discountCurve.linkTo(new FlatForward(today,0.03,new Actual360()));

            Frequency frequency = Frequency.Semiannual;
            BusinessDayConvention convention = BusinessDayConvention.ModifiedFollowing;

            Date issueDate = calendar.advance(today, -6, TimeUnit.Months);
            double fixedRate = 0.0120;
            DayCounter cdsDayCount = new Actual360();
            double notional = 10000.0;
            double recoveryRate = 0.4;

            double? latestRate = null;
            for (int n=6; n<=10; ++n)
            {
                Date maturity = calendar.advance(issueDate, n, TimeUnit.Years);
                Schedule schedule = new Schedule(issueDate, maturity, new Period(frequency), calendar,
                                        convention, convention,
                                        DateGeneration.Rule.Forward, false);

                CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, notional, fixedRate,
                                            schedule, convention, cdsDayCount,true, true);
                cds.setPricingEngine(new MidPointCdsEngine(probabilityCurve, recoveryRate, discountCurve));

                double NPV = cds.NPV();
                double flatRate = cds.impliedHazardRate(NPV, discountCurve,
                                                                    dayCounter,
                                                                    recoveryRate);

                if (flatRate < h1 || flatRate > h2) {
                    Assert.Fail("implied hazard rate outside expected range\n"
                                    + "    maturity: " + n + " years\n"
                                    + "    expected minimum: " + h1 + "\n"
                                    + "    expected maximum: " + h2 + "\n"
                                    + "    implied rate:     " + flatRate);
                }

                if (n > 6 && flatRate < latestRate) {
                    Assert.Fail("implied hazard rate decreasing with swap maturity\n"
                                    + "    maturity: " + n + " years\n"
                                    + "    previous rate: " + latestRate + "\n"
                                    + "    implied rate:  " + flatRate);
                }

                latestRate = flatRate;

                RelinkableHandle<DefaultProbabilityTermStructure> probability = new RelinkableHandle<DefaultProbabilityTermStructure>();
                probability.linkTo(new FlatHazardRate(	today,new Handle<Quote>(new SimpleQuote(flatRate)),dayCounter));

                CreditDefaultSwap cds2 = new CreditDefaultSwap(Protection.Side.Seller, notional, fixedRate,
                                                schedule, convention, cdsDayCount,true, true);
                cds2.setPricingEngine(new MidPointCdsEngine(probability,recoveryRate,discountCurve));

                double NPV2 = cds2.NPV();
                double tolerance = 1.0;
                if (Math.Abs(NPV-NPV2) > tolerance) {
                    Assert.Fail("failed to reproduce NPV with implied rate\n"
                                    + "    expected:   " + NPV + "\n"
                                    + "    calculated: " + NPV2);
                }
            }
        }
Ejemplo n.º 35
0
            // setup
            public CommonVars()
            {
                backup    = new SavedSettings();
                nominalUK = new RelinkableHandle <YieldTermStructure>();
                cpiUK     = new RelinkableHandle <ZeroInflationTermStructure>();
                hcpi      = new RelinkableHandle <ZeroInflationTermStructure>();
                zciisD    = new List <Date>();
                zciisR    = new List <double>();
                hii       = new RelinkableHandle <ZeroInflationIndex>();

                nominals = new InitializedList <double>(1, 1000000);
                // option variables
                frequency = Frequency.Annual;
                // usual setup
                volatility = 0.01;
                length     = 7;
                calendar   = new UnitedKingdom();
                convention = BusinessDayConvention.ModifiedFollowing;
                Date today = new Date(1, Month.June, 2010);

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

                // uk rpi index
                //      fixing data
                Date     from        = new Date(1, Month.July, 2007);
                Date     to          = new Date(1, Month.June, 2010);
                Schedule rpiSchedule = new MakeSchedule().from(from).to(to)
                                       .withTenor(new Period(1, TimeUnit.Months))
                                       .withCalendar(new UnitedKingdom())
                                       .withConvention(BusinessDayConvention.ModifiedFollowing).value();

                double[] fixData =
                {
                    206.1, 207.3, 208.0, 208.9, 209.7, 210.9,
                    209.8, 211.4, 212.1, 214.0, 215.1, 216.8, //  2008
                    216.5, 217.2, 218.4, 217.7, 216.0, 212.9,
                    210.1, 211.4, 211.3, 211.5, 212.8, 213.4, //  2009
                    213.4, 214.4, 215.3, 216.0, 216.6, 218.0,
                    217.9, 219.2, 220.7, 222.8,  -999,  -999, //  2010
                    -999
                };

                // link from cpi index to cpi TS
                bool interp = false;// this MUST be false because the observation lag is only 2 months

                // for ZCIIS; but not for contract if the contract uses a bigger lag.
                ii = new UKRPI(interp, hcpi);
                for (int i = 0; i < rpiSchedule.Count; i++)
                {
                    ii.addFixing(rpiSchedule[i], fixData[i], true);// force overwrite in case multiple use
                }

                Datum[] nominalData =
                {
                    new Datum(new Date(2,  Month.June,      2010), 0.499997),
                    new Datum(new Date(3,  Month.June,      2010), 0.524992),
                    new Datum(new Date(8,  Month.June,      2010), 0.524974),
                    new Datum(new Date(15, Month.June,      2010), 0.549942),
                    new Datum(new Date(22, Month.June,      2010), 0.549913),
                    new Datum(new Date(1,  Month.July,      2010), 0.574864),
                    new Datum(new Date(2,  Month.August,    2010), 0.624668),
                    new Datum(new Date(1,  Month.September, 2010), 0.724338),
                    new Datum(new Date(16, Month.September, 2010), 0.769461),
                    new Datum(new Date(1,  Month.December,  2010), 0.997501),
                    //{ Date( 16, December, 2010), 0.838164 ),
                    new Datum(new Date(17, Month.March,     2011), 0.916996),
                    new Datum(new Date(16, Month.June,      2011), 0.984339),
                    new Datum(new Date(22, Month.September, 2011),  1.06085),
                    new Datum(new Date(22, Month.December,  2011), 1.141788),
                    new Datum(new Date(1,  Month.June,      2012), 1.504426),
                    new Datum(new Date(3,  Month.June,      2013),  1.92064),
                    new Datum(new Date(2,  Month.June,      2014), 2.290824),
                    new Datum(new Date(1,  Month.June,      2015), 2.614394),
                    new Datum(new Date(1,  Month.June,      2016), 2.887445),
                    new Datum(new Date(1,  Month.June,      2017), 3.122128),
                    new Datum(new Date(1,  Month.June,      2018), 3.322511),
                    new Datum(new Date(3,  Month.June,      2019), 3.483997),
                    new Datum(new Date(1,  Month.June,      2020), 3.616896),
                    new Datum(new Date(1,  Month.June,      2022),   3.8281),
                    new Datum(new Date(2,  Month.June,      2025),   4.0341),
                    new Datum(new Date(3,  Month.June,      2030), 4.070854),
                    new Datum(new Date(1,  Month.June,      2035), 4.023202),
                    new Datum(new Date(1,  Month.June,      2040), 3.954748),
                    new Datum(new Date(1,  Month.June,      2050), 3.870953),
                    new Datum(new Date(1,  Month.June,      2060),  3.85298),
                    new Datum(new Date(2,  Month.June,      2070), 3.757542),
                    new Datum(new Date(3,  Month.June,      2080), 3.651379)
                };
                int nominalDataLength = 33 - 1;

                List <Date>   nomD = new List <Date>();
                List <double> nomR = new List <double>();

                for (int i = 0; i < nominalDataLength; i++)
                {
                    nomD.Add(nominalData[i].date);
                    nomR.Add(nominalData[i].rate / 100.0);
                }
                YieldTermStructure nominalTS = new InterpolatedZeroCurve <Linear>(nomD, nomR, dcNominal);

                nominalUK.linkTo(nominalTS);

                // now build the zero inflation curve
                observationLag                   = new Period(2, TimeUnit.Months);
                contractObservationLag           = new Period(3, TimeUnit.Months);
                contractObservationInterpolation = InterpolationType.Flat;

                Datum[] zciisData =
                {
                    new Datum(new Date(1, Month.June, 2011), 3.087),
                    new Datum(new Date(1, Month.June, 2012),  3.12),
                    new Datum(new Date(1, Month.June, 2013), 3.059),
                    new Datum(new Date(1, Month.June, 2014),  3.11),
                    new Datum(new Date(1, Month.June, 2015),  3.15),
                    new Datum(new Date(1, Month.June, 2016), 3.207),
                    new Datum(new Date(1, Month.June, 2017), 3.253),
                    new Datum(new Date(1, Month.June, 2018), 3.288),
                    new Datum(new Date(1, Month.June, 2019), 3.314),
                    new Datum(new Date(1, Month.June, 2020), 3.401),
                    new Datum(new Date(1, Month.June, 2022), 3.458),
                    new Datum(new Date(1, Month.June, 2025),  3.52),
                    new Datum(new Date(1, Month.June, 2030), 3.655),
                    new Datum(new Date(1, Month.June, 2035), 3.668),
                    new Datum(new Date(1, Month.June, 2040), 3.695),
                    new Datum(new Date(1, Month.June, 2050), 3.634),
                    new Datum(new Date(1, Month.June, 2060), 3.629),
                };
                zciisDataLength = 17;
                for (int i = 0; i < zciisDataLength; i++)
                {
                    zciisD.Add(zciisData[i].date);
                    zciisR.Add(zciisData[i].rate);
                }

                // now build the helpers ...
                List <BootstrapHelper <ZeroInflationTermStructure> > helpers = makeHelpers(zciisData, zciisDataLength, ii,
                                                                                           observationLag, calendar, convention, dcZCIIS);

                // we can use historical or first ZCIIS for this
                // we know historical is WAY off market-implied, so use market implied flat.
                baseZeroRate = zciisData[0].rate / 100.0;
                PiecewiseZeroInflationCurve <Linear> pCPIts = new PiecewiseZeroInflationCurve <Linear>(
                    evaluationDate, calendar, dcZCIIS, observationLag, ii.frequency(), ii.interpolated(), baseZeroRate,
                    new Handle <YieldTermStructure>(nominalTS), helpers);

                pCPIts.recalculate();
                cpiUK.linkTo(pCPIts);
                hii.linkTo(ii);

                // make sure that the index has the latest zero inflation term structure
                hcpi.linkTo(pCPIts);

                // cpi CF price surf data
                Period[] cfMat = { new Period(3,  TimeUnit.Years),
                                   new Period(5,  TimeUnit.Years),
                                   new Period(7,  TimeUnit.Years),
                                   new Period(10, TimeUnit.Years),
                                   new Period(15, TimeUnit.Years),
                                   new Period(20, TimeUnit.Years),
                                   new Period(30, TimeUnit.Years) };
                double[] cStrike = { 3, 4, 5, 6 };
                double[] fStrike = { -1, 0, 1, 2 };
                int      ncStrikes = 4, nfStrikes = 4, ncfMaturities = 7;

                double[][] cPrice =
                {
                    new double[4] {
                        227.6, 100.27, 38.8, 14.94
                    },
                    new double[4] {
                        345.32, 127.9, 40.59, 14.11
                    },
                    new double[4] {
                        477.95, 170.19, 50.62, 16.88
                    },
                    new double[4] {
                        757.81, 303.95, 107.62, 43.61
                    },
                    new double[4] {
                        1140.73, 481.89, 168.4, 63.65
                    },
                    new double[4] {
                        1537.6, 607.72, 172.27, 54.87
                    },
                    new double[4] {
                        2211.67, 839.24, 184.75, 45.03
                    }
                };

                double[][] fPrice =
                {
                    new double[4] {
                        15.62, 28.38, 53.61, 104.6
                    },
                    new double[4] {
                        21.45, 36.73, 66.66, 129.6
                    },
                    new double[4] {
                        24.45, 42.08, 77.04, 152.24
                    },
                    new double[4] {
                        39.25, 63.52, 109.2, 203.44
                    },
                    new double[4] {
                        36.82, 63.62, 116.97, 232.73
                    },
                    new double[4] {
                        39.7, 67.47, 121.79, 238.56
                    },
                    new double[4] {
                        41.48, 73.9, 139.75, 286.75
                    }
                };

                // now load the data into vector and Matrix classes
                cStrikesUK     = new List <double>();
                fStrikesUK     = new List <double>();
                cfMaturitiesUK = new List <Period>();
                for (int i = 0; i < ncStrikes; i++)
                {
                    cStrikesUK.Add(cStrike[i]);
                }
                for (int i = 0; i < nfStrikes; i++)
                {
                    fStrikesUK.Add(fStrike[i]);
                }
                for (int i = 0; i < ncfMaturities; i++)
                {
                    cfMaturitiesUK.Add(cfMat[i]);
                }
                cPriceUK = new Matrix(ncStrikes, ncfMaturities);
                fPriceUK = new Matrix(nfStrikes, ncfMaturities);
                for (int i = 0; i < ncStrikes; i++)
                {
                    for (int j = 0; j < ncfMaturities; j++)
                    {
                        (cPriceUK)[i, j] = cPrice[j][i] / 10000.0;
                    }
                }
                for (int i = 0; i < nfStrikes; i++)
                {
                    for (int j = 0; j < ncfMaturities; j++)
                    {
                        (fPriceUK)[i, j] = fPrice[j][i] / 10000.0;
                    }
                }
            }
Ejemplo n.º 36
0
        public void testObservableHandle()
        {
            // Testing observability of quote handles

             SimpleQuote me1 = new SimpleQuote(0.0);
             RelinkableHandle<Quote> h = new RelinkableHandle<Quote>(me1);

             Flag f = new Flag();

             h.registerWith(f.update);

             me1.setValue(3.14);

             if (!f.isUp())
               Assert.Fail("Observer was not notified of quote change");

             f.lower();
             SimpleQuote me2 = new SimpleQuote(0.0);
             h.linkTo(me2);

             if (!f.isUp())
               Assert.Fail("Observer was not notified of quote change");
        }
Ejemplo n.º 37
0
            // setup
            public CommonVars()
            {
                backup = new SavedSettings();

                Calendar calendar = new TARGET();

                Date referenceDate = calendar.adjust(Date.Today);

                Settings.setEvaluationDate(referenceDate);

                termStructure = new RelinkableHandle <YieldTermStructure>();
                termStructure.linkTo(Utilities.flatRate(referenceDate, 0.05, new Actual365Fixed()));

                // ATM Volatility structure
                List <Period> atmOptionTenors = new List <Period>();

                atmOptionTenors.Add(new Period(1, TimeUnit.Months));
                atmOptionTenors.Add(new Period(6, TimeUnit.Months));
                atmOptionTenors.Add(new Period(1, TimeUnit.Years));
                atmOptionTenors.Add(new Period(5, TimeUnit.Years));
                atmOptionTenors.Add(new Period(10, TimeUnit.Years));
                atmOptionTenors.Add(new Period(30, TimeUnit.Years));

                List <Period> atmSwapTenors = new List <Period>();

                atmSwapTenors.Add(new Period(1, TimeUnit.Years));
                atmSwapTenors.Add(new Period(5, TimeUnit.Years));
                atmSwapTenors.Add(new Period(10, TimeUnit.Years));
                atmSwapTenors.Add(new Period(30, TimeUnit.Years));

                Matrix m = new Matrix(atmOptionTenors.Count, atmSwapTenors.Count);

                m[0, 0] = 0.1300; m[0, 1] = 0.1560; m[0, 2] = 0.1390; m[0, 3] = 0.1220;
                m[1, 0] = 0.1440; m[1, 1] = 0.1580; m[1, 2] = 0.1460; m[1, 3] = 0.1260;
                m[2, 0] = 0.1600; m[2, 1] = 0.1590; m[2, 2] = 0.1470; m[2, 3] = 0.1290;
                m[3, 0] = 0.1640; m[3, 1] = 0.1470; m[3, 2] = 0.1370; m[3, 3] = 0.1220;
                m[4, 0] = 0.1400; m[4, 1] = 0.1300; m[4, 2] = 0.1250; m[4, 3] = 0.1100;
                m[5, 0] = 0.1130; m[5, 1] = 0.1090; m[5, 2] = 0.1070; m[5, 3] = 0.0930;

                atmVol = new Handle <SwaptionVolatilityStructure>(
                    new SwaptionVolatilityMatrix(calendar, BusinessDayConvention.Following, atmOptionTenors,
                                                 atmSwapTenors, m, new Actual365Fixed()));

                // Vol cubes
                List <Period> optionTenors = new List <Period>();

                optionTenors.Add(new Period(1, TimeUnit.Years));
                optionTenors.Add(new Period(10, TimeUnit.Years));
                optionTenors.Add(new Period(30, TimeUnit.Years));

                List <Period> swapTenors = new List <Period>();

                swapTenors.Add(new Period(2, TimeUnit.Years));
                swapTenors.Add(new Period(10, TimeUnit.Years));
                swapTenors.Add(new Period(30, TimeUnit.Years));

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

                strikeSpreads.Add(-0.020);
                strikeSpreads.Add(-0.005);
                strikeSpreads.Add(+0.000);
                strikeSpreads.Add(+0.005);
                strikeSpreads.Add(+0.020);

                int    nRows            = optionTenors.Count * swapTenors.Count;
                int    nCols            = strikeSpreads.Count;
                Matrix volSpreadsMatrix = new Matrix(nRows, nCols);

                volSpreadsMatrix[0, 0] = 0.0599;
                volSpreadsMatrix[0, 1] = 0.0049;
                volSpreadsMatrix[0, 2] = 0.0000;
                volSpreadsMatrix[0, 3] = -0.0001;
                volSpreadsMatrix[0, 4] = 0.0127;

                volSpreadsMatrix[1, 0] = 0.0729;
                volSpreadsMatrix[1, 1] = 0.0086;
                volSpreadsMatrix[1, 2] = 0.0000;
                volSpreadsMatrix[1, 3] = -0.0024;
                volSpreadsMatrix[1, 4] = 0.0098;

                volSpreadsMatrix[2, 0] = 0.0738;
                volSpreadsMatrix[2, 1] = 0.0102;
                volSpreadsMatrix[2, 2] = 0.0000;
                volSpreadsMatrix[2, 3] = -0.0039;
                volSpreadsMatrix[2, 4] = 0.0065;

                volSpreadsMatrix[3, 0] = 0.0465;
                volSpreadsMatrix[3, 1] = 0.0063;
                volSpreadsMatrix[3, 2] = 0.0000;
                volSpreadsMatrix[3, 3] = -0.0032;
                volSpreadsMatrix[3, 4] = -0.0010;

                volSpreadsMatrix[4, 0] = 0.0558;
                volSpreadsMatrix[4, 1] = 0.0084;
                volSpreadsMatrix[4, 2] = 0.0000;
                volSpreadsMatrix[4, 3] = -0.0050;
                volSpreadsMatrix[4, 4] = -0.0057;

                volSpreadsMatrix[5, 0] = 0.0576;
                volSpreadsMatrix[5, 1] = 0.0083;
                volSpreadsMatrix[5, 2] = 0.0000;
                volSpreadsMatrix[5, 3] = -0.0043;
                volSpreadsMatrix[5, 4] = -0.0014;

                volSpreadsMatrix[6, 0] = 0.0437;
                volSpreadsMatrix[6, 1] = 0.0059;
                volSpreadsMatrix[6, 2] = 0.0000;
                volSpreadsMatrix[6, 3] = -0.0030;
                volSpreadsMatrix[6, 4] = -0.0006;

                volSpreadsMatrix[7, 0] = 0.0533;
                volSpreadsMatrix[7, 1] = 0.0078;
                volSpreadsMatrix[7, 2] = 0.0000;
                volSpreadsMatrix[7, 3] = -0.0045;
                volSpreadsMatrix[7, 4] = -0.0046;

                volSpreadsMatrix[8, 0] = 0.0545;
                volSpreadsMatrix[8, 1] = 0.0079;
                volSpreadsMatrix[8, 2] = 0.0000;
                volSpreadsMatrix[8, 3] = -0.0042;
                volSpreadsMatrix[8, 4] = -0.0020;

                List <List <Handle <Quote> > > volSpreads = new InitializedList <List <Handle <Quote> > >(nRows);

                for (int i = 0; i < nRows; ++i)
                {
                    volSpreads[i] = new InitializedList <Handle <Quote> >(nCols);
                    for (int j = 0; j < nCols; ++j)
                    {
                        volSpreads[i][j] = new Handle <Quote>(new SimpleQuote(volSpreadsMatrix[i, j]));
                    }
                }

                iborIndex = new Euribor6M(termStructure);
                SwapIndex swapIndexBase      = new EuriborSwapIsdaFixA(new Period(10, TimeUnit.Years), termStructure);
                SwapIndex shortSwapIndexBase = new EuriborSwapIsdaFixA(new Period(2, TimeUnit.Years), termStructure);

                bool vegaWeightedSmileFit = false;

                SabrVolCube2 = new Handle <SwaptionVolatilityStructure>(
                    new SwaptionVolCube2(atmVol,
                                         optionTenors,
                                         swapTenors,
                                         strikeSpreads,
                                         volSpreads,
                                         swapIndexBase,
                                         shortSwapIndexBase,
                                         vegaWeightedSmileFit));
                SabrVolCube2.link.enableExtrapolation();

                List <List <Handle <Quote> > > guess = new InitializedList <List <Handle <Quote> > >(nRows);

                for (int i = 0; i < nRows; ++i)
                {
                    guess[i]    = new InitializedList <Handle <Quote> >(4);
                    guess[i][0] = new Handle <Quote>(new SimpleQuote(0.2));
                    guess[i][1] = new Handle <Quote>(new SimpleQuote(0.5));
                    guess[i][2] = new Handle <Quote>(new SimpleQuote(0.4));
                    guess[i][3] = new Handle <Quote>(new SimpleQuote(0.0));
                }
                List <bool> isParameterFixed = new InitializedList <bool>(4, false);

                isParameterFixed[1] = true;

                // FIXME
                bool isAtmCalibrated = false;

                SabrVolCube1 = new Handle <SwaptionVolatilityStructure>(
                    new SwaptionVolCube1x(atmVol,
                                          optionTenors,
                                          swapTenors,
                                          strikeSpreads,
                                          volSpreads,
                                          swapIndexBase,
                                          shortSwapIndexBase,
                                          vegaWeightedSmileFit,
                                          guess,
                                          isParameterFixed,
                                          isAtmCalibrated));
                SabrVolCube1.link.enableExtrapolation();

                yieldCurveModels = new List <GFunctionFactory.YieldCurveModel>();
                yieldCurveModels.Add(GFunctionFactory.YieldCurveModel.Standard);
                yieldCurveModels.Add(GFunctionFactory.YieldCurveModel.ExactYield);
                yieldCurveModels.Add(GFunctionFactory.YieldCurveModel.ParallelShifts);
                yieldCurveModels.Add(GFunctionFactory.YieldCurveModel.NonParallelShifts);
                yieldCurveModels.Add(GFunctionFactory.YieldCurveModel.NonParallelShifts); // for linear tsr model

                Handle <Quote> zeroMeanRev = new Handle <Quote>(new SimpleQuote(0.0));

                numericalPricers = new List <CmsCouponPricer>();
                analyticPricers  = new List <CmsCouponPricer>();
                for (int j = 0; j < yieldCurveModels.Count; ++j)
                {
                    if (j < yieldCurveModels.Count - 1)
                    {
                        numericalPricers.Add(new NumericHaganPricer(atmVol, yieldCurveModels[j], zeroMeanRev));
                    }
                    else
                    {
                        numericalPricers.Add(new LinearTsrPricer(atmVol, zeroMeanRev));
                    }

                    analyticPricers.Add(new AnalyticHaganPricer(atmVol, yieldCurveModels[j], zeroMeanRev));
                }
            }
Ejemplo n.º 38
0
            //public IndexHistoryCleaner indexCleaner;
            // initial setup
            public CommonVars()
            {
                backup = new SavedSettings();
                //indexCleaner = new IndexHistoryCleaner();
                termStructure = new RelinkableHandle<YieldTermStructure>();
                int swapSettlementDays = 2;
                faceAmount = 100.0;
                BusinessDayConvention fixedConvention = BusinessDayConvention.Unadjusted;
                compounding = Compounding.Continuous;
                Frequency fixedFrequency = Frequency.Annual;
                Frequency floatingFrequency = Frequency.Semiannual;
                iborIndex = new Euribor(new Period(floatingFrequency), termStructure);
                Calendar calendar = iborIndex.fixingCalendar();
                swapIndex=  new SwapIndex("EuriborSwapIsdaFixA", new Period(10,TimeUnit.Years), swapSettlementDays,
                                      iborIndex.currency(), calendar,
                                      new Period(fixedFrequency), fixedConvention,
                                      iborIndex.dayCounter(), iborIndex);
                spread = 0.0;
                nonnullspread = 0.003;
                Date today = new Date(24,Month.April,2007);
                Settings.setEvaluationDate(today);

                //Date today = Settings::instance().evaluationDate();
                termStructure.linkTo(Utilities.flatRate(today, 0.05, new Actual365Fixed()));

                pricer = new BlackIborCouponPricer();
                Handle<SwaptionVolatilityStructure> swaptionVolatilityStructure =
                   new Handle<SwaptionVolatilityStructure>(new ConstantSwaptionVolatility(today,
                   new NullCalendar(),BusinessDayConvention.Following, 0.2, new Actual365Fixed()));

                Handle<Quote> meanReversionQuote = new Handle<Quote>(new SimpleQuote(0.01));
                cmspricer = new AnalyticHaganPricer(swaptionVolatilityStructure, GFunctionFactory.YieldCurveModel.Standard, meanReversionQuote);
            }
Ejemplo n.º 39
0
        public void testJpyLibor()
        {
            //"Testing bootstrap over JPY LIBOR swaps...");

            CommonVars vars = new CommonVars();

            vars.today = new Date(4, Month.October, 2007);
            Settings.setEvaluationDate(vars.today);

            vars.calendar   = new Japan();
            vars.settlement = vars.calendar.advance(vars.today, vars.settlementDays, TimeUnit.Days);

            // market elements
            vars.rates = new InitializedList <SimpleQuote>(vars.swaps);
            for (int i = 0; i < vars.swaps; i++)
            {
                vars.rates[i] = new SimpleQuote(vars.swapData[i].rate / 100);
            }

            // rate helpers
            vars.instruments = new InitializedList <RateHelper>(vars.swaps);

            IborIndex index = new JPYLibor(new Period(6, TimeUnit.Months));

            for (int i = 0; i < vars.swaps; i++)
            {
                Handle <Quote> r = new Handle <Quote>(vars.rates[i]);
                vars.instruments[i] = new SwapRateHelper(r, new Period(vars.swapData[i].n, vars.swapData[i].units),
                                                         vars.calendar,
                                                         vars.fixedLegFrequency, vars.fixedLegConvention,
                                                         vars.fixedLegDayCounter, index);
            }

            vars.termStructure = new PiecewiseYieldCurve <Discount, LogLinear>(
                vars.settlement, vars.instruments,
                new Actual360(),
                new List <Handle <Quote> >(),
                new List <Date>(),
                1.0e-12);

            RelinkableHandle <YieldTermStructure> curveHandle = new RelinkableHandle <YieldTermStructure>();

            curveHandle.linkTo(vars.termStructure);

            // check swaps
            IborIndex jpylibor6m = new JPYLibor(new Period(6, TimeUnit.Months), curveHandle);

            for (int i = 0; i < vars.swaps; i++)
            {
                Period tenor = new Period(vars.swapData[i].n, vars.swapData[i].units);

                VanillaSwap swap = new MakeVanillaSwap(tenor, jpylibor6m, 0.0)
                                   .withEffectiveDate(vars.settlement)
                                   .withFixedLegDayCount(vars.fixedLegDayCounter)
                                   .withFixedLegTenor(new Period(vars.fixedLegFrequency))
                                   .withFixedLegConvention(vars.fixedLegConvention)
                                   .withFixedLegTerminationDateConvention(vars.fixedLegConvention)
                                   .withFixedLegCalendar(vars.calendar)
                                   .withFloatingLegCalendar(vars.calendar)
                                   .value();

                double expectedRate  = vars.swapData[i].rate / 100,
                       estimatedRate = swap.fairRate();
                double error         = Math.Abs(expectedRate - estimatedRate);
                double tolerance     = 1.0e-9;

                if (error > tolerance)
                {
                    Assert.Fail(vars.swapData[i].n + " year(s) swap:\n"
                                + "\n estimated rate: " + (estimatedRate)
                                + "\n expected rate:  " + (expectedRate)
                                + "\n error:          " + (error)
                                + "\n tolerance:      " + (tolerance));
                }
            }
        }
Ejemplo n.º 40
0
        static void Main(string[] args) {

            DateTime timer = DateTime.Now;

            /*********************
             ***  MARKET DATA  ***
             *********************/

            Calendar calendar = new TARGET();

            Date settlementDate = new Date(18, Month.September, 2008);
            // must be a business day
            settlementDate = calendar.adjust(settlementDate);

            int fixingDays = 3;
            int settlementDays = 3;

            Date todaysDate = calendar.advance(settlementDate, -fixingDays, TimeUnit.Days);
            // nothing to do with Date::todaysDate
            Settings.setEvaluationDate(todaysDate);

            Console.WriteLine("Today: {0}, {1}", todaysDate.DayOfWeek, todaysDate);
            Console.WriteLine("Settlement date: {0}, {1}", settlementDate.DayOfWeek, settlementDate);


            // Building of the bonds discounting yield curve

            /*********************
             ***  RATE HELPERS ***
             *********************/

            // RateHelpers are built from the above quotes together with
            // other instrument dependant infos.  Quotes are passed in
            // relinkable handles which could be relinked to some other
            // data source later.

            // Common data

            // ZC rates for the short end
             double zc3mQuote=0.0096;
             double zc6mQuote=0.0145;
             double zc1yQuote=0.0194;

             Quote zc3mRate = new SimpleQuote(zc3mQuote);
             Quote zc6mRate = new SimpleQuote(zc6mQuote);
             Quote zc1yRate = new SimpleQuote(zc1yQuote);

             DayCounter zcBondsDayCounter = new Actual365Fixed();

             RateHelper zc3m = new DepositRateHelper(new Handle<Quote>(zc3mRate),
                                                          new Period(3, TimeUnit.Months), fixingDays,
                                                          calendar, BusinessDayConvention.ModifiedFollowing,
                                                          true, zcBondsDayCounter);
             RateHelper zc6m = new DepositRateHelper(new Handle<Quote>(zc6mRate),
                                                          new Period(6, TimeUnit.Months), fixingDays,
                                                          calendar, BusinessDayConvention.ModifiedFollowing,
                                                          true, zcBondsDayCounter);
             RateHelper zc1y = new DepositRateHelper(new Handle<Quote>(zc1yRate),
                                                          new Period(1, TimeUnit.Years), fixingDays,
                                                          calendar, BusinessDayConvention.ModifiedFollowing,
                                                          true, zcBondsDayCounter);

            // setup bonds
            double redemption = 100.0;

            const int numberOfBonds = 5;

            Date[] issueDates = {
                    new Date (15, Month.March, 2005),
                    new Date (15, Month.June, 2005),
                    new Date (30, Month.June, 2006),
                    new Date (15, Month.November, 2002),
                    new Date (15, Month.May, 1987)
            };

            Date[] maturities = {
                    new Date (31, Month.August, 2010),
                    new Date (31, Month.August, 2011),
                    new Date (31, Month.August, 2013),
                    new Date (15, Month.August, 2018),
                    new Date (15, Month.May, 2038)
            };

            double[] couponRates = {
                    0.02375,
                    0.04625,
                    0.03125,
                    0.04000,
                    0.04500
            };

            double[] marketQuotes = {
                    100.390625,
                    106.21875,
                    100.59375,
                    101.6875,
                    102.140625
            };

            List<SimpleQuote> quote = new List<SimpleQuote>();
            for (int i=0; i<numberOfBonds; i++) {
                SimpleQuote cp = new SimpleQuote(marketQuotes[i]);
                quote.Add(cp);
            }

            List<RelinkableHandle<Quote>> quoteHandle = new InitializedList<RelinkableHandle<Quote>>(numberOfBonds);
            for (int i=0; i<numberOfBonds; i++) {
                quoteHandle[i].linkTo(quote[i]);
            }

            // Definition of the rate helpers
            List<FixedRateBondHelper> bondsHelpers = new List<FixedRateBondHelper>();
            for (int i=0; i<numberOfBonds; i++) {

                Schedule schedule = new Schedule(issueDates[i], maturities[i], new Period(Frequency.Semiannual), 
                                                 new UnitedStates(UnitedStates.Market.GovernmentBond),
                                                 BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, 
                                                 DateGeneration.Rule.Backward, false);

                FixedRateBondHelper bondHelper = new FixedRateBondHelper(quoteHandle[i],
                                                                         settlementDays,
                                                                         100.0,
                                                                         schedule,
                                                                         new List<double>() { couponRates[i] },
                                                                         new ActualActual(ActualActual.Convention.Bond),
                                                                         BusinessDayConvention.Unadjusted,
                                                                         redemption,
                                                                         issueDates[i]);

                bondsHelpers.Add(bondHelper);
            }

            /*********************
             **  CURVE BUILDING **
             *********************/

             // Any DayCounter would be fine.
             // ActualActual::ISDA ensures that 30 years is 30.0
             DayCounter termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA);

             double tolerance = 1.0e-15;

             // A depo-bond curve
             List<RateHelper> bondInstruments = new List<RateHelper>();

             // Adding the ZC bonds to the curve for the short end
             bondInstruments.Add(zc3m);
             bondInstruments.Add(zc6m);
             bondInstruments.Add(zc1y);

             // Adding the Fixed rate bonds to the curve for the long end
             for (int i=0; i<numberOfBonds; i++) {
                 bondInstruments.Add(bondsHelpers[i]);
             }

             YieldTermStructure bondDiscountingTermStructure = new PiecewiseYieldCurve<Discount,LogLinear>(
                                                                     settlementDate, bondInstruments,
                                                                     termStructureDayCounter,
                                                                     new List<Handle<Quote>>(),
                                                                     new List<Date>(),
                                                                     tolerance);

             // Building of the Libor forecasting curve
             // deposits
             double d1wQuote=0.043375;
             double d1mQuote=0.031875;
             double d3mQuote=0.0320375;
             double d6mQuote=0.03385;
             double d9mQuote=0.0338125;
             double d1yQuote=0.0335125;
             // swaps
             double s2yQuote=0.0295;
             double s3yQuote=0.0323;
             double s5yQuote=0.0359;
             double s10yQuote=0.0412;
             double s15yQuote=0.0433;


             /********************
              ***    QUOTES    ***
              ********************/

             // SimpleQuote stores a value which can be manually changed;
             // other Quote subclasses could read the value from a database
             // or some kind of data feed.

             // deposits
             Quote d1wRate = new SimpleQuote(d1wQuote);
             Quote d1mRate = new SimpleQuote(d1mQuote);
             Quote d3mRate = new SimpleQuote(d3mQuote);
             Quote d6mRate = new SimpleQuote(d6mQuote);
             Quote d9mRate = new SimpleQuote(d9mQuote);
             Quote d1yRate = new SimpleQuote(d1yQuote);
             // swaps
             Quote s2yRate = new SimpleQuote(s2yQuote);
             Quote s3yRate = new SimpleQuote(s3yQuote);
             Quote s5yRate = new SimpleQuote(s5yQuote);
             Quote s10yRate = new SimpleQuote(s10yQuote);
             Quote s15yRate = new SimpleQuote(s15yQuote);

             /*********************
              ***  RATE HELPERS ***
              *********************/

             // RateHelpers are built from the above quotes together with
             // other instrument dependant infos.  Quotes are passed in
             // relinkable handles which could be relinked to some other
             // data source later.

             // deposits
             DayCounter depositDayCounter = new Actual360();

             RateHelper d1w = new DepositRateHelper(
                     new Handle<Quote>(d1wRate),
                     new Period(1, TimeUnit.Weeks), fixingDays,
                     calendar, BusinessDayConvention.ModifiedFollowing,
                     true, depositDayCounter);
             RateHelper d1m = new DepositRateHelper(
                     new Handle<Quote>(d1mRate),
                     new Period(1, TimeUnit.Months), fixingDays,
                     calendar, BusinessDayConvention.ModifiedFollowing,
                     true, depositDayCounter);
             RateHelper d3m = new DepositRateHelper(
                     new Handle<Quote>(d3mRate),
                     new Period(3, TimeUnit.Months), fixingDays,
                     calendar, BusinessDayConvention.ModifiedFollowing,
                     true, depositDayCounter);
             RateHelper d6m = new DepositRateHelper(
                     new Handle<Quote>(d6mRate),
                     new Period(6, TimeUnit.Months), fixingDays,
                     calendar, BusinessDayConvention.ModifiedFollowing,
                     true, depositDayCounter);
             RateHelper d9m = new DepositRateHelper(
                     new Handle<Quote>(d9mRate),
                     new Period(9, TimeUnit.Months), fixingDays,
                     calendar, BusinessDayConvention.ModifiedFollowing,
                     true, depositDayCounter);
             RateHelper d1y = new DepositRateHelper(
                     new Handle<Quote>(d1yRate),
                     new Period(1, TimeUnit.Years), fixingDays,
                     calendar, BusinessDayConvention.ModifiedFollowing,
                     true, depositDayCounter);

             // setup swaps
             Frequency swFixedLegFrequency =Frequency.Annual;
             BusinessDayConvention swFixedLegConvention = BusinessDayConvention.Unadjusted;
             DayCounter swFixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European);
             IborIndex swFloatingLegIndex = new Euribor6M();

             Period forwardStart = new Period(1, TimeUnit.Days);

             RateHelper s2y = new SwapRateHelper(
                     new Handle<Quote>(s2yRate), new Period(2, TimeUnit.Years),
                     calendar, swFixedLegFrequency,
                     swFixedLegConvention, swFixedLegDayCounter,
                     swFloatingLegIndex, new Handle<Quote>(),forwardStart);
             RateHelper s3y = new SwapRateHelper(
                     new Handle<Quote>(s3yRate), new Period(3, TimeUnit.Years),
                     calendar, swFixedLegFrequency,
                     swFixedLegConvention, swFixedLegDayCounter,
                     swFloatingLegIndex, new Handle<Quote>(),forwardStart);
             RateHelper s5y = new SwapRateHelper(
                     new Handle<Quote>(s5yRate), new Period(5, TimeUnit.Years),
                     calendar, swFixedLegFrequency,
                     swFixedLegConvention, swFixedLegDayCounter,
                     swFloatingLegIndex, new Handle<Quote>(),forwardStart);
             RateHelper s10y = new SwapRateHelper(
                     new Handle<Quote>(s10yRate), new Period(10, TimeUnit.Years),
                     calendar, swFixedLegFrequency,
                     swFixedLegConvention, swFixedLegDayCounter,
                     swFloatingLegIndex, new Handle<Quote>(),forwardStart);
             RateHelper s15y = new SwapRateHelper(
                     new Handle<Quote>(s15yRate), new Period(15, TimeUnit.Years),
                     calendar, swFixedLegFrequency,
                     swFixedLegConvention, swFixedLegDayCounter,
                     swFloatingLegIndex, new Handle<Quote>(),forwardStart);


             /*********************
              **  CURVE BUILDING **
              *********************/

             // Any DayCounter would be fine.
             // ActualActual::ISDA ensures that 30 years is 30.0

             // A depo-swap curve
             List<RateHelper> depoSwapInstruments = new List<RateHelper>();
             depoSwapInstruments.Add(d1w);
             depoSwapInstruments.Add(d1m);
             depoSwapInstruments.Add(d3m);
             depoSwapInstruments.Add(d6m);
             depoSwapInstruments.Add(d9m);
             depoSwapInstruments.Add(d1y);
             depoSwapInstruments.Add(s2y);
             depoSwapInstruments.Add(s3y);
             depoSwapInstruments.Add(s5y);
             depoSwapInstruments.Add(s10y);
             depoSwapInstruments.Add(s15y);
             YieldTermStructure depoSwapTermStructure = new PiecewiseYieldCurve<Discount,LogLinear>(
                             settlementDate, depoSwapInstruments,
                             termStructureDayCounter,
                             new List<Handle<Quote> >(),
                             new List<Date>(),
                             tolerance);

             // Term structures that will be used for pricing:
             // the one used for discounting cash flows
             RelinkableHandle<YieldTermStructure> discountingTermStructure = new RelinkableHandle<YieldTermStructure>();
             // the one used for forward rate forecasting
             RelinkableHandle<YieldTermStructure> forecastingTermStructure = new RelinkableHandle<YieldTermStructure>();

             /*********************
              * BONDS TO BE PRICED *
              **********************/

             // Common data
             double faceAmount = 100;

             // Pricing engine
             IPricingEngine bondEngine = new DiscountingBondEngine(discountingTermStructure);

             // Zero coupon bond
             ZeroCouponBond zeroCouponBond = new ZeroCouponBond(
                     settlementDays,
                     new UnitedStates(UnitedStates.Market.GovernmentBond),
                     faceAmount,
                     new Date(15, Month.August,2013),
                     BusinessDayConvention.Following,
                     116.92,
                     new Date(15, Month.August,2003));

             zeroCouponBond.setPricingEngine(bondEngine);

             // Fixed 4.5% US Treasury Note
             Schedule fixedBondSchedule = new Schedule(new Date(15, Month.May, 2007),
                     new Date(15,Month.May,2017), new Period(Frequency.Semiannual),
                     new UnitedStates(UnitedStates.Market.GovernmentBond),
                     BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false);

             FixedRateBond fixedRateBond = new FixedRateBond(
                     settlementDays,
                     faceAmount,
                     fixedBondSchedule,
                     new List<double>() { 0.045 },
                     new ActualActual(ActualActual.Convention.Bond),
                     BusinessDayConvention.ModifiedFollowing,
                     100.0, new Date(15, Month.May, 2007));

             fixedRateBond.setPricingEngine(bondEngine);

             // Floating rate bond (3M USD Libor + 0.1%)
             // Should and will be priced on another curve later...

             RelinkableHandle<YieldTermStructure> liborTermStructure = new RelinkableHandle<YieldTermStructure>();
             IborIndex libor3m = new USDLibor(new Period(3, TimeUnit.Months), liborTermStructure);
             libor3m.addFixing(new Date(17, Month.July, 2008),0.0278625);

             Schedule floatingBondSchedule = new Schedule(new Date(21, Month.October, 2005),
                     new Date(21, Month.October, 2010), new Period(Frequency.Quarterly),
                     new UnitedStates(UnitedStates.Market.NYSE),
                     BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, true);

             FloatingRateBond floatingRateBond = new FloatingRateBond(
                     settlementDays,
                     faceAmount,
                     floatingBondSchedule,
                     libor3m,
                     new Actual360(),
                     BusinessDayConvention.ModifiedFollowing,
                     2,
                     // Gearings
                     new List<double>() { 1.0 },
                     // Spreads
                     new List<double>() { 0.001 },
                     // Caps
                     new List<double>(),
                     // Floors
                     new List<double>(),
                     // Fixing in arrears
                     true,
                     100.0,
                     new Date(21, Month.October, 2005));

             floatingRateBond.setPricingEngine(bondEngine);

             // Coupon pricers
             IborCouponPricer pricer = new BlackIborCouponPricer();

             // optionLet volatilities
             double volatility = 0.0;
             Handle<OptionletVolatilityStructure> vol;
             vol = new Handle<OptionletVolatilityStructure>(
                                new ConstantOptionletVolatility(
                                     settlementDays,
                                     calendar,
                                     BusinessDayConvention.ModifiedFollowing,
                                     volatility,
                                     new Actual365Fixed()));

             pricer.setCapletVolatility(vol);
             Utils.setCouponPricer(floatingRateBond.cashflows(),pricer);

             // Yield curve bootstrapping
             forecastingTermStructure.linkTo(depoSwapTermStructure);
             discountingTermStructure.linkTo(bondDiscountingTermStructure);

             // We are using the depo & swap curve to estimate the future Libor rates
             liborTermStructure.linkTo(depoSwapTermStructure);

             /***************
              * BOND PRICING *
              ****************/

             // write column headings
             int[] widths = { 18, 10, 10, 10 };

            Console.WriteLine("{0,18}{1,10}{2,10}{3,10}", "", "ZC", "Fixed", "Floating");

            string separator = " | ";
            int width = widths[0]
                                 + widths[1]
                                          + widths[2]
                                                   + widths[3];
            string rule = "".PadLeft(width, '-'), dblrule = "".PadLeft(width, '=');
            string tab = "".PadLeft(8, ' ');

            Console.WriteLine(rule);

            Console.WriteLine("Net present value".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}", 
                                zeroCouponBond.NPV(),
                                fixedRateBond.NPV(),
                                floatingRateBond.NPV());

            Console.WriteLine("Clean price".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}",
                                zeroCouponBond.cleanPrice(),
                                fixedRateBond.cleanPrice(),
                                floatingRateBond.cleanPrice());

            Console.WriteLine("Dirty price".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}",
                                zeroCouponBond.dirtyPrice(),
                                fixedRateBond.dirtyPrice(),
                                floatingRateBond.dirtyPrice());

            Console.WriteLine("Accrued coupon".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}",
                                zeroCouponBond.accruedAmount(),
                                fixedRateBond.accruedAmount(),
                                floatingRateBond.accruedAmount());

            Console.WriteLine("Previous coupon".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}",
                                "N/A",
                                fixedRateBond.previousCoupon(),
                                floatingRateBond.previousCoupon());

            Console.WriteLine("Next coupon".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}",
                              "N/A",
                              fixedRateBond.nextCoupon(),
                              floatingRateBond.nextCoupon());

            Console.WriteLine("Yield".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}",
                              zeroCouponBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual),
                              fixedRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual),
                              floatingRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual));

            Console.WriteLine();

            // Other computations
            Console.WriteLine("Sample indirect computations (for the floating rate bond): ");
            Console.WriteLine(rule);

            Console.WriteLine("Yield to Clean Price: {0:n2}",
                floatingRateBond.cleanPrice(floatingRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual),
                                                                   new Actual360(), Compounding.Compounded, Frequency.Annual,
                                                                   settlementDate));

            Console.WriteLine("Clean Price to Yield: {0:0.00%}",
                floatingRateBond.yield(floatingRateBond.cleanPrice(),new Actual360(), Compounding.Compounded, Frequency.Annual,
                                       settlementDate));

            /* "Yield to Price"
               "Price to Yield" */

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

            Console.Write("Press any key to continue ...");
            Console.ReadKey();
        }
Ejemplo n.º 41
0
        static void Main(string[] args)
        {
            DateTime timer = DateTime.Now;

            Date        repoSettlementDate     = new Date(14, Month.February, 2000);;
            Date        repoDeliveryDate       = new Date(15, Month.August, 2000);
            double      repoRate               = 0.05;
            DayCounter  repoDayCountConvention = new Actual360();
            int         repoSettlementDays     = 0;
            Compounding repoCompounding        = Compounding.Simple;
            Frequency   repoCompoundFreq       = Frequency.Annual;

            // assume a ten year bond- this is irrelevant
            Date      bondIssueDate       = new Date(15, Month.September, 1995);
            Date      bondDatedDate       = new Date(15, Month.September, 1995);
            Date      bondMaturityDate    = new Date(15, Month.September, 2005);
            double    bondCoupon          = 0.08;
            Frequency bondCouponFrequency = Frequency.Semiannual;
            // unknown what calendar fincad is using
            Calendar   bondCalendar           = new NullCalendar();
            DayCounter bondDayCountConvention = new Thirty360(Thirty360.Thirty360Convention.BondBasis);
            // unknown what fincad is using. this may affect accrued calculation
            int bondSettlementDays = 0;
            BusinessDayConvention bondBusinessDayConvention = BusinessDayConvention.Unadjusted;
            double bondCleanPrice = 89.97693786;
            double bondRedemption = 100.0;
            double faceAmount     = 100.0;


            Settings.setEvaluationDate(repoSettlementDate);

            RelinkableHandle <YieldTermStructure> bondCurve = new RelinkableHandle <YieldTermStructure>();

            bondCurve.linkTo(new FlatForward(repoSettlementDate,
                                             .01,                                               // dummy rate
                                             bondDayCountConvention,
                                             Compounding.Compounded,
                                             bondCouponFrequency));

            /*
             * boost::shared_ptr<FixedRateBond> bond(
             *                         new FixedRateBond(faceAmount,
             *                                                               bondIssueDate,
             *                                                               bondDatedDate,
             *                                                               bondMaturityDate,
             *                                                               bondSettlementDays,
             *                                                               std::vector<Rate>(1,bondCoupon),
             *                                                               bondCouponFrequency,
             *                                                               bondCalendar,
             *                                                               bondDayCountConvention,
             *                                                               bondBusinessDayConvention,
             *                                                               bondBusinessDayConvention,
             *                                                               bondRedemption,
             *                                                               bondCurve));
             */

            Schedule bondSchedule = new Schedule(bondDatedDate, bondMaturityDate,
                                                 new Period(bondCouponFrequency),
                                                 bondCalendar, bondBusinessDayConvention,
                                                 bondBusinessDayConvention,
                                                 DateGeneration.Rule.Backward, false);
            FixedRateBond bond = new FixedRateBond(bondSettlementDays,
                                                   faceAmount,
                                                   bondSchedule,
                                                   new List <double>()
            {
                bondCoupon
            },
                                                   bondDayCountConvention,
                                                   bondBusinessDayConvention,
                                                   bondRedemption,
                                                   bondIssueDate);

            bond.setPricingEngine(new DiscountingBondEngine(bondCurve));

            bondCurve.linkTo(new FlatForward(repoSettlementDate,
                                             bond.yield(bondCleanPrice,
                                                        bondDayCountConvention,
                                                        Compounding.Compounded,
                                                        bondCouponFrequency),
                                             bondDayCountConvention,
                                             Compounding.Compounded,
                                             bondCouponFrequency));

            Position.Type fwdType     = Position.Type.Long;
            double        dummyStrike = 91.5745;

            RelinkableHandle <YieldTermStructure> repoCurve = new RelinkableHandle <YieldTermStructure>();

            repoCurve.linkTo(new FlatForward(repoSettlementDate,
                                             repoRate,
                                             repoDayCountConvention,
                                             repoCompounding,
                                             repoCompoundFreq));


            FixedRateBondForward bondFwd = new FixedRateBondForward(repoSettlementDate,
                                                                    repoDeliveryDate,
                                                                    fwdType,
                                                                    dummyStrike,
                                                                    repoSettlementDays,
                                                                    repoDayCountConvention,
                                                                    bondCalendar,
                                                                    bondBusinessDayConvention,
                                                                    bond,
                                                                    repoCurve,
                                                                    repoCurve);


            Console.WriteLine("Underlying bond clean price: " + bond.cleanPrice());
            Console.WriteLine("Underlying bond dirty price: " + bond.dirtyPrice());
            Console.WriteLine("Underlying bond accrued at settlement: "
                              + bond.accruedAmount(repoSettlementDate));
            Console.WriteLine("Underlying bond accrued at delivery:   "
                              + bond.accruedAmount(repoDeliveryDate));
            Console.WriteLine("Underlying bond spot income: "
                              + bondFwd.spotIncome(repoCurve));
            Console.WriteLine("Underlying bond fwd income:  "
                              + bondFwd.spotIncome(repoCurve) /
                              repoCurve.link.discount(repoDeliveryDate));
            Console.WriteLine("Repo strike: " + dummyStrike);
            Console.WriteLine("Repo NPV:    " + bondFwd.NPV());
            Console.WriteLine("Repo clean forward price: "
                              + bondFwd.cleanForwardPrice());
            Console.WriteLine("Repo dirty forward price: "
                              + bondFwd.forwardPrice());
            Console.WriteLine("Repo implied yield: "
                              + bondFwd.impliedYield(bond.dirtyPrice(),
                                                     dummyStrike,
                                                     repoSettlementDate,
                                                     repoCompounding,
                                                     repoDayCountConvention));
            Console.WriteLine("Market repo rate:   "
                              + repoCurve.link.zeroRate(repoDeliveryDate,
                                                        repoDayCountConvention,
                                                        repoCompounding,
                                                        repoCompoundFreq));

            Console.WriteLine("\nCompare with example given at \n"
                              + "http://www.fincad.com/support/developerFunc/mathref/BFWD.htm");
            Console.WriteLine("Clean forward price = 88.2408");
            Console.WriteLine("\nIn that example, it is unknown what bond calendar they are\n"
                              + "using, as well as settlement Days. For that reason, I have\n"
                              + "made the simplest possible assumptions here: NullCalendar\n"
                              + "and 0 settlement days.\n");


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

            Console.Write("Press any key to continue ...");
            Console.ReadKey();
        }