示例#1
0
        public void testCashedValues()
        {
            Date startDate = new Date(01, 03, 2007);
             Period period = new Period(360, TimeUnit.Months);
             Calendar calendar = new TARGET();
             Date endDate = calendar.advance(startDate,period,BusinessDayConvention.Unadjusted);

             Schedule schedule = new Schedule( startDate, endDate, new Period(1,TimeUnit.Months), calendar,
                                           BusinessDayConvention.Unadjusted,
                                           BusinessDayConvention.Unadjusted,
                                           DateGeneration.Rule.Backward, false);

             // PSA 100%
             PSACurve psa100 = new PSACurve(startDate);
             double[] listCPR = {0.2000,0.4000,0.6000,0.8000,1.0000,1.2000,1.4000,1.6000,1.8000,2.0000,2.2000,2.4000,2.6000,2.8000,
                             3.0000,3.2000,3.4000,3.6000,3.8000,4.0000,4.2000,4.4000,4.6000,4.8000,5.0000,5.2000,5.4000,5.6000,
                             5.8000,6.0000};

             for (int i = 0; i < schedule.Count; i++)
             {
            if ( i <= 29 )
               Assert.AreEqual(listCPR[i], psa100.getCPR(schedule[i])*100,0.001);
            else
               Assert.AreEqual(6.0000, psa100.getCPR(schedule[i])*100);
             }
        }
        public void testDefaultProbability()
        {
            // Testing default-probability structure...

             double hazardRate = 0.0100;
             Handle<Quote> hazardRateQuote = new Handle<Quote>(new SimpleQuote(hazardRate));
             DayCounter dayCounter = new Actual360();
             Calendar calendar = new TARGET();
             int n = 20;

             double tolerance = 1.0e-10;
             Date today = Settings.evaluationDate();
             Date startDate = today;
             Date endDate = startDate;

             FlatHazardRate flatHazardRate = new FlatHazardRate(startDate, hazardRateQuote, dayCounter);

             for(int i=0; i<n; i++)
             {
            startDate = endDate;
            endDate = calendar.advance(endDate, 1, TimeUnit.Years);

            double pStart = flatHazardRate.defaultProbability(startDate);
            double pEnd = flatHazardRate.defaultProbability(endDate);

            double pBetweenComputed =
               flatHazardRate.defaultProbability(startDate, endDate);

            double pBetween = pEnd - pStart;

            if (Math.Abs(pBetween - pBetweenComputed) > tolerance)
               Assert.Fail( "Failed to reproduce probability(d1, d2) "
                            + "for default probability structure\n"
                            + "    calculated probability: " + pBetweenComputed + "\n"
                            + "    expected probability:   " + pBetween);

            double t2 = dayCounter.yearFraction(today, endDate);
            double timeProbability = flatHazardRate.defaultProbability(t2);
            double dateProbability =
               flatHazardRate.defaultProbability(endDate);

            if (Math.Abs(timeProbability - dateProbability) > tolerance)
               Assert.Fail( "single-time probability and single-date probability do not match\n"
                           + "    time probability: " + timeProbability + "\n"
                           + "    date probability: " + dateProbability);

            double t1 = dayCounter.yearFraction(today, startDate);
            timeProbability = flatHazardRate.defaultProbability(t1, t2);
            dateProbability = flatHazardRate.defaultProbability(startDate, endDate);

            if (Math.Abs(timeProbability - dateProbability) > tolerance)
               Assert.Fail( "double-time probability and double-date probability do not match\n"
                            + "    time probability: " + timeProbability + "\n"
                            + "    date probability: " + dateProbability);

             }
        }
        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();
        }
        public void testFlatHazardRate()
        {
            // Testing flat hazard rate...

             double hazardRate = 0.0100;
             Handle<Quote> hazardRateQuote = new Handle<Quote>(new SimpleQuote(hazardRate));
             DayCounter dayCounter = new Actual360();
             Calendar calendar = new TARGET();
             int n = 20;

             double tolerance = 1.0e-10;
             Date today = Settings.evaluationDate();
             Date startDate = today;
             Date endDate = startDate;

             FlatHazardRate flatHazardRate = new FlatHazardRate(today, hazardRateQuote, dayCounter);

             for(int i=0; i<n; i++)
             {
            endDate = calendar.advance(endDate, 1, TimeUnit.Years);
            double t = dayCounter.yearFraction(startDate, endDate);
            double probability = 1.0 - Math.Exp(-hazardRate * t);
            double computedProbability = flatHazardRate.defaultProbability(t);

            if (Math.Abs(probability - computedProbability) > tolerance)
               Assert.Fail( "Failed to reproduce probability for flat hazard rate\n"
                            + "    calculated probability: " + computedProbability + "\n"
                            + "    expected probability:   " + probability);
             }
        }
示例#5
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();
        }
        static void Main(string[] args)
        {

            DateTime timer = DateTime.Now;

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

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

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

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

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

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

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

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

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

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

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


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


            // model calibrations

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

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

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

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


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

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

            Exercise bermudanExercise = new BermudanExercise(bermudanDates);

            Swaption bermudanSwaption = new Swaption(atmSwap, bermudanExercise);

            // Do the pricing for each model

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

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

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

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


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

            Swaption otmBermudanSwaption = new Swaption(otmSwap, bermudanExercise);

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

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

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

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

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

            Swaption itmBermudanSwaption = new Swaption(itmSwap, bermudanExercise);

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

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

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

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


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

            Console.Write("Press any key to continue ...");
            Console.ReadKey();
        }
示例#7
0
        public void testSwaps()
        {
            //BOOST_MESSAGE("Testing Hull-White swap pricing against known values...");

            Date today;  //=Settings::instance().evaluationDate();;

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

            Date settlement = calendar.advance(today, 2, TimeUnit.Days);

            Date[] dates = {
                settlement,
                calendar.advance(settlement,1,TimeUnit.Weeks),
                calendar.advance(settlement,1,TimeUnit.Months),
                calendar.advance(settlement,3,TimeUnit.Months),
                calendar.advance(settlement,6,TimeUnit.Months),
                calendar.advance(settlement,9,TimeUnit.Months),
                calendar.advance(settlement,1,TimeUnit.Years),
                calendar.advance(settlement,2,TimeUnit.Years),
                calendar.advance(settlement,3,TimeUnit.Years),
                calendar.advance(settlement,5,TimeUnit.Years),
                calendar.advance(settlement,10,TimeUnit.Years),
                calendar.advance(settlement,15,TimeUnit.Years)
            };
            double[] discounts = {
                1.0,
                0.999258,
                0.996704,
                0.990809,
                0.981798,
                0.972570,
                0.963430,
                0.929532,
                0.889267,
                0.803693,
                0.596903,
                0.433022
            };

            //for (int i = 0; i < dates.Length; i++)
            //    dates[i] + dates.Length;

            LogLinear Interpolator = new LogLinear();

            Handle<YieldTermStructure> termStructure =
               new Handle<YieldTermStructure>(
                   new InterpolatedDiscountCurve<LogLinear>(
                       dates.ToList<Date>(),
                       discounts.ToList<double>(),
                       new Actual365Fixed(),new Calendar(), null, null , Interpolator)
            );

            HullWhite model = new HullWhite(termStructure);

            int[] start = { -3, 0, 3 };
            int[] length = { 2, 5, 10 };
            double[] rates = { 0.02, 0.04, 0.06 };
            IborIndex euribor = new Euribor6M(termStructure);

            IPricingEngine engine = new TreeVanillaSwapEngine(model, 120, termStructure);

            #if QL_USE_INDEXED_COUPON
            double tolerance = 4.0e-3;
            #else
            double tolerance = 1.0e-8;
            #endif

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

                Date startDate = calendar.advance(settlement,start[i],TimeUnit.Months);
                if (startDate < today) {
                    Date fixingDate = calendar.advance(startDate,-2,TimeUnit.Days);
                    //TimeSeries<double> pastFixings;
                    ObservableValue<TimeSeries<double>> pastFixings = new ObservableValue<TimeSeries<double>>();
                    pastFixings.value()[fixingDate] = 0.03;
                    IndexManager.instance().setHistory(euribor.name(),
                                                        pastFixings);
                }

                for (int j=0; j<length.Length; j++) {

                    Date maturity = calendar.advance(startDate, length[i], TimeUnit.Years);
                    Schedule fixedSchedule = new Schedule(startDate, maturity, new Period(Frequency.Annual),
                                           calendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                           DateGeneration.Rule.Forward, false);
                    Schedule floatSchedule = new Schedule(startDate, maturity, new Period(Frequency.Semiannual),
                                           calendar, BusinessDayConvention.Following, BusinessDayConvention.Following,
                                           DateGeneration.Rule.Forward, false);
                    for (int k=0; k<rates.Length; k++) {

                        VanillaSwap swap = new VanillaSwap(VanillaSwap.Type.Payer, 1000000.0,
                                         fixedSchedule, rates[k], new Thirty360(),
                                         floatSchedule, euribor, 0.0, new Actual360());
                        swap.setPricingEngine(new DiscountingSwapEngine(termStructure));
                        double expected = swap.NPV();
                        swap.setPricingEngine(engine);
                        double calculated = swap.NPV();

                        double error = Math.Abs((expected-calculated)/expected);
                        if (error > tolerance) {
                            Assert.Fail("Failed to reproduce swap NPV:"
                                        //+ QL_FIXED << std::setprecision(9)
                                        + "\n    calculated: " + calculated
                                        + "\n    expected:   " + expected
                                        //+ QL_SCIENTIFIC
                                        + "\n    rel. error: " + error);
                        }
                    }
                }
            }
        }
示例#8
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);
                }
            }
        }
示例#9
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);
        }
示例#10
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);
        }