Inheritance: Euribor
        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");
                    }
                }

            }
        }
Beispiel #2
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;
        }
        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();
        }
Beispiel #4
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();
        }
Beispiel #6
0
        public void testCachedHullWhite()
        {
            //("Testing Hull-White calibration against cached values...");

             Date today=new Date(15, Month.February, 2002);
             Date settlement=new Date(19, Month.February, 2002);
             Settings.setEvaluationDate(today);
             Handle<YieldTermStructure> termStructure=
             new Handle<YieldTermStructure>(Utilities.flatRate(settlement, 0.04875825, new Actual365Fixed()));
             //termStructure.link
             HullWhite model=new HullWhite(termStructure);

             CalibrationData[] data = { new CalibrationData( 1, 5, 0.1148 ),
                                    new CalibrationData( 2, 4, 0.1108 ),
                                    new CalibrationData( 3, 3, 0.1070 ),
                                    new CalibrationData( 4, 2, 0.1021 ),
                                    new CalibrationData( 5, 1, 0.1000 )};
             IborIndex index = new Euribor6M(termStructure);

             IPricingEngine engine = new JamshidianSwaptionEngine(model);

             List<CalibrationHelper> swaptions = new List<CalibrationHelper>();
             for (int i=0; i<data.Length; i++) {
               Quote vol = new SimpleQuote(data[i].volatility);
               CalibrationHelper helper =
                                    new SwaptionHelper(new Period(data[i].start,TimeUnit.Years),
                                                      new Period(data[i].length, TimeUnit.Years),
                                                      new Handle<Quote>(vol),
                                                      index,
                                                      new Period(1, TimeUnit.Years),
                                                      new Thirty360(),
                                                      new Actual360(),
                                                      termStructure);
               helper.setPricingEngine(engine);
               swaptions.Add(helper);
             }

             // Set up the optimization problem
             // Real simplexLambda = 0.1;
             // Simplex optimizationMethod(simplexLambda);
             LevenbergMarquardt optimizationMethod = new LevenbergMarquardt(1.0e-8,1.0e-8,1.0e-8);
             EndCriteria endCriteria = new EndCriteria(10000, 100, 1e-6, 1e-8, 1e-8);

             //Optimize
             model.calibrate(swaptions, optimizationMethod, endCriteria, new Constraint(),new List<double>());
             EndCriteria.Type ecType = model.endCriteria();

             // Check and print out results
             #if QL_USE_INDEXED_COUPON
             double cachedA = 0.0488199, cachedSigma = 0.00593579;
             #else
             double cachedA = 0.0488565, cachedSigma = 0.00593662;
             #endif
             double tolerance = 1.120e-5;
             //double tolerance = 1.0e-6;
             Vector xMinCalculated = model.parameters();
             double yMinCalculated = model.value(xMinCalculated, swaptions);
             Vector xMinExpected = new Vector(2);
             xMinExpected[0]= cachedA;
             xMinExpected[1]= cachedSigma;
             double yMinExpected = model.value(xMinExpected, swaptions);
             if (Math.Abs(xMinCalculated[0]-cachedA) > tolerance
               || Math.Abs(xMinCalculated[1]-cachedSigma) > tolerance) {
               Assert.Fail ("Failed to reproduce cached calibration results:\n"
                           + "calculated: a = " + xMinCalculated[0] + ", "
                           + "sigma = " + xMinCalculated[1] + ", "
                           + "f(a) = " + yMinCalculated + ",\n"
                           + "expected:   a = " + xMinExpected[0] + ", "
                           + "sigma = " + xMinExpected[1] + ", "
                           + "f(a) = " + yMinExpected + ",\n"
                           + "difference: a = " + (xMinCalculated[0]-xMinExpected[0]) + ", "
                           + "sigma = " + (xMinCalculated[1]-xMinExpected[1]) + ", "
                           + "f(a) = " + (yMinCalculated - yMinExpected) + ",\n"
                           + "end criteria = " + ecType );
             }
        }
Beispiel #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);
                        }
                    }
                }
            }
        }