/*! \warning Setting a pricing engine to the passed bond from
                     external code will cause the bootstrap to fail or
                     to give wrong results. It is advised to discard
                     the bond after creating the helper, so that the
                     helper has sole ownership of it.
        */
        public BondHelper(Handle<Quote> cleanPrice, Bond bond) : base(cleanPrice) {
            bond_ = bond;

            latestDate_ = bond_.maturityDate();
            initializeDates();

            IPricingEngine bondEngine = new DiscountingBondEngine(termStructureHandle_);
            bond_.setPricingEngine(bondEngine);        
        }
        /*! \warning Setting a pricing engine to the passed bond from
         *           external code will cause the bootstrap to fail or
         *           to give wrong results. It is advised to discard
         *           the bond after creating the helper, so that the
         *           helper has sole ownership of it.
         */
        public BondHelper(Handle <Quote> cleanPrice, Bond bond) : base(cleanPrice)
        {
            bond_ = bond;

            latestDate_ = bond_.maturityDate();
            initializeDates();

            IPricingEngine bondEngine = new DiscountingBondEngine(termStructureHandle_);

            bond_.setPricingEngine(bondEngine);
        }
Exemple #3
0
        /*! \warning Setting a pricing engine to the passed bond from
         *                       external code will cause the bootstrap to fail or
         *                       to give wrong results. It is advised to discard
         *                       the bond after creating the helper, so that the
         *                       helper has sole ownership of it.
         */

        protected AbstractBondHelper(Handle <Quote> cleanPrice, T bond)
            : base(cleanPrice)
        {
            _bond = bond;

            latestDate_ = _bond.maturityDate();
            initializeDates();

            _termStructureHandle = new RelinkableHandle <YieldTermStructure>();
            IPricingEngine bondEngine = new DiscountingBondEngine(_termStructureHandle);

            _bond.setPricingEngine(bondEngine);
        }
        public override void Update()
        {
            var bond = GetInputNode<FixedRateBond>("Bond");
            var discountCurve = GetInputNode<YieldTermStructure>("DiscountCurve");

            var termStructure = new Handle<YieldTermStructure>(discountCurve);
            var bondEngine = new DiscountingBondEngine(termStructure);

            bond.setPricingEngine(bondEngine);

            Value = NetPV = bond.NPV();
            CleanPrice = bond.cleanPrice();
            DirtyPrice = bond.dirtyPrice();

            Diagnostics.WriteLine(
                this, String.Format("[{0}] NetPV = {1}", Name, NetPV));
        }
Exemple #5
0
        public void testImpliedValue()
        {
            // Testing implied bond value against asset-swap fair price with null spread
             CommonVars vars = new CommonVars();

             Calendar bondCalendar = new TARGET();
             int settlementDays = 3;
             int fixingDays = 2;
             bool payFixedRate = true;
             bool parAssetSwap = true;
             bool inArrears = false;

             // Fixed Underlying bond (Isin: DE0001135275 DBR 4 01/04/37)
             // maturity doesn't occur on a business day

             Schedule fixedBondSchedule1 = new Schedule( new Date(4,Month.January,2005),
                                                     new Date(4,Month.January,2037),
                                                     new Period(Frequency.Annual), bondCalendar,
                                                     BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                                     DateGeneration.Rule.Backward, false);
             Bond fixedBond1 = new FixedRateBond(settlementDays, vars.faceAmount,
                                                fixedBondSchedule1,
                                                new List<double>(){0.04},
                                                new ActualActual(ActualActual.Convention.ISDA),
                                                BusinessDayConvention.Following,
                                                100.0, new Date(4,Month.January,2005));

             IPricingEngine bondEngine = new DiscountingBondEngine(vars.termStructure);
             IPricingEngine swapEngine = new DiscountingSwapEngine(vars.termStructure);
             fixedBond1.setPricingEngine(bondEngine);

             double fixedBondPrice1 = fixedBond1.cleanPrice();
             AssetSwap fixedBondAssetSwap1 = new AssetSwap(payFixedRate, fixedBond1, fixedBondPrice1, vars.iborIndex, vars.spread,
                                                       null, vars.iborIndex.dayCounter(), parAssetSwap);
             fixedBondAssetSwap1.setPricingEngine(swapEngine);
             double fixedBondAssetSwapPrice1 = fixedBondAssetSwap1.fairCleanPrice();
             double tolerance = 1.0e-13;
             double error1 = Math.Abs(fixedBondAssetSwapPrice1-fixedBondPrice1);

             if (error1>tolerance) {
            Assert.Fail("wrong zero spread asset swap price for fixed bond:" +
                        "\n  bond's clean price:    " + fixedBondPrice1 +
                        "\n  asset swap fair price: " + fixedBondAssetSwapPrice1 +
                        "\n  error:                 " + error1 +
                        "\n  tolerance:             " + tolerance);
             }

             // Fixed Underlying bond (Isin: IT0006527060 IBRD 5 02/05/19)
             // maturity occurs on a business day

             Schedule fixedBondSchedule2 = new Schedule( new Date(5,Month.February,2005),
                                                     new Date(5,Month.February,2019),
                                                     new Period(Frequency.Annual), bondCalendar,
                                                     BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                                     DateGeneration.Rule.Backward, false);
             Bond fixedBond2 = new FixedRateBond(settlementDays, vars.faceAmount,
                                             fixedBondSchedule2,
                                             new List<double>(){0.05},
                                             new Thirty360(Thirty360.Thirty360Convention.BondBasis),
                                             BusinessDayConvention.Following,
                                             100.0, new Date(5,Month.February,2005));

             fixedBond2.setPricingEngine(bondEngine);

             double fixedBondPrice2 = fixedBond2.cleanPrice();
             AssetSwap fixedBondAssetSwap2 = new AssetSwap(payFixedRate, fixedBond2, fixedBondPrice2, vars.iborIndex, vars.spread,
                                                       null, vars.iborIndex.dayCounter(),  parAssetSwap);
             fixedBondAssetSwap2.setPricingEngine(swapEngine);
             double fixedBondAssetSwapPrice2 = fixedBondAssetSwap2.fairCleanPrice();
             double error2 = Math.Abs(fixedBondAssetSwapPrice2-fixedBondPrice2);

             if (error2>tolerance) {
            Assert.Fail("wrong zero spread asset swap price for fixed bond:" +
                        "\n  bond's clean price:    " + fixedBondPrice2 +
                        "\n  asset swap fair price: " + fixedBondAssetSwapPrice2 +
                        "\n  error:                 " + error2 +
                        "\n  tolerance:             " + tolerance);
             }

             // FRN Underlying bond (Isin: IT0003543847 ISPIM 0 09/29/13)
             // maturity doesn't occur on a business day

             Schedule floatingBondSchedule1 = new Schedule( new Date(29,Month.September,2003),
                                                        new Date(29,Month.September,2013),
                                                        new Period(Frequency.Semiannual), bondCalendar,
                                                        BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                                        DateGeneration.Rule.Backward, false);

             Bond floatingBond1 = new FloatingRateBond(settlementDays, vars.faceAmount,
                                                   floatingBondSchedule1,
                                                   vars.iborIndex, new Actual360(),
                                                   BusinessDayConvention.Following, fixingDays,
                                                   new List<double>(){1},
                                                   new List<double>(){0.0056},
                                                   new List<double>(),
                                                   new List<double>(),
                                                   inArrears,
                                                   100.0, new Date(29,Month.September,2003));

             floatingBond1.setPricingEngine(bondEngine);

             Utils.setCouponPricer(floatingBond1.cashflows(), vars.pricer);
             vars.iborIndex.addFixing(new Date(27,Month.March,2007), 0.0402);
             double floatingBondPrice1 = floatingBond1.cleanPrice();
             AssetSwap floatingBondAssetSwap1 = new AssetSwap(payFixedRate, floatingBond1, floatingBondPrice1, vars.iborIndex, vars.spread,
                                                          null, vars.iborIndex.dayCounter(), parAssetSwap);
             floatingBondAssetSwap1.setPricingEngine(swapEngine);
             double floatingBondAssetSwapPrice1 = floatingBondAssetSwap1.fairCleanPrice();
             double error3 = Math.Abs(floatingBondAssetSwapPrice1-floatingBondPrice1);

             if (error3>tolerance) {
            Assert.Fail("wrong zero spread asset swap price for floater:" +
                        "\n  bond's clean price:    " + floatingBondPrice1 +
                        "\n  asset swap fair price: " + floatingBondAssetSwapPrice1 +
                        "\n  error:                 " + error3 +
                        "\n  tolerance:             " + tolerance);
             }

             // FRN Underlying bond (Isin: XS0090566539 COE 0 09/24/18)
             // maturity occurs on a business day

             Schedule floatingBondSchedule2 = new Schedule( new Date(24,Month.September,2004),
                                                        new Date(24,Month.September,2018),
                                                        new Period(Frequency.Semiannual), bondCalendar,
                                                        BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing,
                                                        DateGeneration.Rule.Backward, false);
             Bond floatingBond2 = new FloatingRateBond( settlementDays, vars.faceAmount,
                                                    floatingBondSchedule2,
                                                    vars.iborIndex, new Actual360(),
                                                    BusinessDayConvention.ModifiedFollowing, fixingDays,
                                                    new List<double>(){1},
                                                    new List<double>(){0.0025},
                                                    new List<double>(),
                                                    new List<double>(),
                                                    inArrears,
                                                    100.0, new Date(24,Month.September,2004));

             floatingBond2.setPricingEngine(bondEngine);

             Utils.setCouponPricer(floatingBond2.cashflows(), vars.pricer);
             vars.iborIndex.addFixing( new Date(22,Month.March,2007), 0.04013);
             double currentCoupon=0.04013+0.0025;
             double floatingCurrentCoupon= floatingBond2.nextCouponRate();
             double error4= Math.Abs(floatingCurrentCoupon-currentCoupon);
             if (error4>tolerance) {
            Assert.Fail("wrong current coupon is returned for floater bond:" +
                        "\n  bond's calculated current coupon:      " +
                        currentCoupon +
                        "\n  current coupon asked to the bond: " +
                        floatingCurrentCoupon +
                        "\n  error:                 " + error4 +
                        "\n  tolerance:             " + tolerance);
             }

             double floatingBondPrice2 = floatingBond2.cleanPrice();
             AssetSwap floatingBondAssetSwap2 = new AssetSwap(payFixedRate,floatingBond2, floatingBondPrice2, vars.iborIndex, vars.spread,
                                                          null, vars.iborIndex.dayCounter(), parAssetSwap);
             floatingBondAssetSwap2.setPricingEngine(swapEngine);
             double floatingBondAssetSwapPrice2 = floatingBondAssetSwap2.fairCleanPrice();
             double error5 = Math.Abs(floatingBondAssetSwapPrice2-floatingBondPrice2);

             if (error5>tolerance) {
            Assert.Fail("wrong zero spread asset swap price for floater:" +
                        "\n  bond's clean price:    " + floatingBondPrice2 +
                        "\n  asset swap fair price: " + floatingBondAssetSwapPrice2 +
                        "\n  error:                 " + error5 +
                        "\n  tolerance:             " + tolerance);
             }

             // CMS Underlying bond (Isin: XS0228052402 CRDIT 0 8/22/20)
             // maturity doesn't occur on a business day

             Schedule cmsBondSchedule1 = new Schedule( new Date(22,Month.August,2005),
                                 new Date(22,Month.August,2020),
                                 new Period(Frequency.Annual), bondCalendar,
                                 BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                 DateGeneration.Rule.Backward, false);
             Bond cmsBond1 = new CmsRateBond(settlementDays, vars.faceAmount,
                                             cmsBondSchedule1,
                                             vars.swapIndex, new Thirty360(),
                                             BusinessDayConvention.Following, fixingDays,
                                             new List<double>(){1.0},
                                             new List<double>(){0.0},
                                             new List<double>(){0.055},
                                             new List<double>(){0.025},
                                             inArrears,
                                             100.0, new Date(22,Month.August,2005));

             cmsBond1.setPricingEngine(bondEngine);

             Utils.setCouponPricer(cmsBond1.cashflows(), vars.cmspricer);
             vars.swapIndex.addFixing( new Date(18,Month.August,2006), 0.04158);
             double cmsBondPrice1 = cmsBond1.cleanPrice();
             AssetSwap cmsBondAssetSwap1 = new AssetSwap(payFixedRate, cmsBond1, cmsBondPrice1, vars.iborIndex, vars.spread,
                                                     null,vars.iborIndex.dayCounter(), parAssetSwap);
             cmsBondAssetSwap1.setPricingEngine(swapEngine);
             double cmsBondAssetSwapPrice1 = cmsBondAssetSwap1.fairCleanPrice();
             double error6 = Math.Abs(cmsBondAssetSwapPrice1-cmsBondPrice1);

             if (error6>tolerance) {
            Assert.Fail("wrong zero spread asset swap price for cms bond:" +
                        "\n  bond's clean price:    " + cmsBondPrice1 +
                        "\n  asset swap fair price: " + cmsBondAssetSwapPrice1 +
                        "\n  error:                 " + error6 +
                        "\n  tolerance:             " + tolerance);
             }

             // CMS Underlying bond (Isin: XS0218766664 ISPIM 0 5/6/15)
             // maturity occurs on a business day

             Schedule cmsBondSchedule2 = new Schedule( new Date(06,Month.May,2005),
                                                   new Date(06,Month.May,2015),
                                                   new Period(Frequency.Annual), bondCalendar,
                                                   BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                                   DateGeneration.Rule.Backward, false);
            Bond cmsBond2 = new CmsRateBond(settlementDays, vars.faceAmount, cmsBondSchedule2,
                        vars.swapIndex, new Thirty360(),
                        BusinessDayConvention.Following, fixingDays,
                        new List<double>(){0.84}, new List<double>(){0.0},
                        new List<double>(), new List<double>(),
                        inArrears,
                        100.0, new Date(06,Month.May,2005));

             cmsBond2.setPricingEngine(bondEngine);

             Utils.setCouponPricer(cmsBond2.cashflows(), vars.cmspricer);
             vars.swapIndex.addFixing( new Date(04,Month.May,2006), 0.04217);
             double cmsBondPrice2 = cmsBond2.cleanPrice();
             AssetSwap cmsBondAssetSwap2 = new AssetSwap(payFixedRate,cmsBond2, cmsBondPrice2, vars.iborIndex, vars.spread,
                                                     null, vars.iborIndex.dayCounter(), parAssetSwap);
             cmsBondAssetSwap2.setPricingEngine(swapEngine);
             double cmsBondAssetSwapPrice2 = cmsBondAssetSwap2.fairCleanPrice();
             double error7 = Math.Abs(cmsBondAssetSwapPrice2-cmsBondPrice2);

             if (error7>tolerance) {
            Assert.Fail("wrong zero spread asset swap price for cms bond:" +
                        "\n  bond's clean price:    " + cmsBondPrice2 +
                        "\n  asset swap fair price: " + cmsBondAssetSwapPrice2 +
                        "\n  error:                 " + error7 +
                        "\n  tolerance:             " + tolerance);
             }

             // Zero Coupon bond (Isin: DE0004771662 IBRD 0 12/20/15)
             // maturity doesn't occur on a business day

             Bond zeroCpnBond1 = new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount,
                                                new Date(20,Month.December,2015),
                                                BusinessDayConvention.Following,
                                                100.0, new Date(19,Month.December,1985));

             zeroCpnBond1.setPricingEngine(bondEngine);

             double zeroCpnBondPrice1 = zeroCpnBond1.cleanPrice();
             AssetSwap zeroCpnAssetSwap1 = new AssetSwap(payFixedRate,zeroCpnBond1, zeroCpnBondPrice1, vars.iborIndex, vars.spread,
                                                     null, vars.iborIndex.dayCounter(), parAssetSwap);
             zeroCpnAssetSwap1.setPricingEngine(swapEngine);
             double zeroCpnBondAssetSwapPrice1 = zeroCpnAssetSwap1.fairCleanPrice();
             double error8 = Math.Abs(cmsBondAssetSwapPrice1-cmsBondPrice1);

             if (error8>tolerance) {
            Assert.Fail("wrong zero spread asset swap price for zero cpn bond:" +
                        "\n  bond's clean price:    " + zeroCpnBondPrice1 +
                        "\n  asset swap fair price: " + zeroCpnBondAssetSwapPrice1 +
                        "\n  error:                 " + error8 +
                        "\n  tolerance:             " + tolerance);
             }

             // Zero Coupon bond (Isin: IT0001200390 ISPIM 0 02/17/28)
             // maturity occurs on a business day

             Bond zeroCpnBond2 = new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount,
                           new Date(17,Month.February,2028),
                           BusinessDayConvention.Following,
                           100.0, new Date(17,Month.February,1998));

             zeroCpnBond2.setPricingEngine(bondEngine);

             double zeroCpnBondPrice2 = zeroCpnBond2.cleanPrice();
             AssetSwap zeroCpnAssetSwap2 = new AssetSwap(payFixedRate, zeroCpnBond2, zeroCpnBondPrice2,  vars.iborIndex, vars.spread,
                                                     null,vars.iborIndex.dayCounter(), parAssetSwap);
             zeroCpnAssetSwap2.setPricingEngine(swapEngine);
             double zeroCpnBondAssetSwapPrice2 = zeroCpnAssetSwap2.fairCleanPrice();
             double error9 = Math.Abs(cmsBondAssetSwapPrice2-cmsBondPrice2);

             if (error9>tolerance) {
            Assert.Fail("wrong zero spread asset swap price for zero cpn bond:" +
                        "\n  bond's clean price:      " + zeroCpnBondPrice2 +
                        "\n  asset swap fair price:   " + zeroCpnBondAssetSwapPrice2 +
                        "\n  error:                   " + error9 +
                        "\n  tolerance:               " + tolerance);
             }
        }
Exemple #6
0
        public void testZSpreadWithGenericBond()
        {
            // Testing clean and dirty price with null Z-spread against theoretical prices...

             CommonVars vars = new CommonVars();

             Calendar bondCalendar = new TARGET();
             int settlementDays = 3;
             int fixingDays = 2;
             bool inArrears = false;

             // Fixed Underlying bond (Isin: DE0001135275 DBR 4 01/04/37)
             // maturity doesn't occur on a business day

             Date fixedBondStartDate1 = new Date(4,Month.January,2005);
             Date fixedBondMaturityDate1 = new Date(4,Month.January,2037);
             Schedule fixedBondSchedule1= new Schedule(fixedBondStartDate1,
                                    fixedBondMaturityDate1,
                                    new Period(Frequency.Annual), bondCalendar,
                                    BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                    DateGeneration.Rule.Backward, false);
             List<CashFlow> fixedBondLeg1 = new FixedRateLeg(fixedBondSchedule1)
            .withCouponRates(0.04, new ActualActual(ActualActual.Convention.ISDA))
            .withNotionals(vars.faceAmount);
             Date fixedbondRedemption1 = bondCalendar.adjust(fixedBondMaturityDate1,
                                                         BusinessDayConvention.Following);
             fixedBondLeg1.Add(new SimpleCashFlow(100.0, fixedbondRedemption1));
             Bond fixedBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, fixedBondMaturityDate1, fixedBondStartDate1,
                  fixedBondLeg1);
             IPricingEngine bondEngine = new DiscountingBondEngine(vars.termStructure);
             fixedBond1.setPricingEngine(bondEngine);

             double fixedBondImpliedValue1 = fixedBond1.cleanPrice();
             Date fixedBondSettlementDate1= fixedBond1.settlementDate();
             // standard market conventions:
             // bond's frequency + coumpounding and daycounter of the YieldCurve
             double fixedBondCleanPrice1 = BondFunctions.cleanPrice(fixedBond1, vars.termStructure, vars.spread,
            new Actual365Fixed(), vars.compounding, Frequency.Annual, fixedBondSettlementDate1);
             double tolerance = 1.0e-13;
             double error1 = Math.Abs(fixedBondImpliedValue1-fixedBondCleanPrice1);
             if (error1>tolerance) {
            Assert.Fail("wrong clean price for fixed bond:"
                        + "\n  market asset swap spread: "
                        + fixedBondImpliedValue1
                        + "\n  par asset swap spread: " + fixedBondCleanPrice1
                        + "\n  error:                 " + error1
                        + "\n  tolerance:             " + tolerance);
             }

             // Fixed Underlying bond (Isin: IT0006527060 IBRD 5 02/05/19)
             // maturity occurs on a business day

             Date fixedBondStartDate2 = new Date(5,Month.February,2005);
             Date fixedBondMaturityDate2 = new Date(5,Month.February,2019);
             Schedule fixedBondSchedule2= new Schedule(fixedBondStartDate2,
                                    fixedBondMaturityDate2,
                                    new Period(Frequency.Annual), bondCalendar,
                                    BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                    DateGeneration.Rule.Backward, false);
             List<CashFlow> fixedBondLeg2 = new FixedRateLeg(fixedBondSchedule2)
            .withCouponRates(0.05, new Thirty360(Thirty360.Thirty360Convention.BondBasis))
            .withNotionals(vars.faceAmount);
             Date fixedbondRedemption2 = bondCalendar.adjust(fixedBondMaturityDate2, BusinessDayConvention.Following);
             fixedBondLeg2.Add(new SimpleCashFlow(100.0, fixedbondRedemption2));
             Bond fixedBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount,
                  fixedBondMaturityDate2, fixedBondStartDate2, fixedBondLeg2);
             fixedBond2.setPricingEngine(bondEngine);

             double fixedBondImpliedValue2 = fixedBond2.cleanPrice();
             Date fixedBondSettlementDate2= fixedBond2.settlementDate();
             // standard market conventions:
             // bond's frequency + coumpounding and daycounter of the YieldCurve

             double fixedBondCleanPrice2 = BondFunctions.cleanPrice(fixedBond2, vars.termStructure, vars.spread,
            new Actual365Fixed(), vars.compounding, Frequency.Annual, fixedBondSettlementDate2);
             double error3 = Math.Abs(fixedBondImpliedValue2-fixedBondCleanPrice2);
             if (error3>tolerance) {
            Assert.Fail("wrong clean price for fixed bond:"
                        + "\n  market asset swap spread: "
                        + fixedBondImpliedValue2
                        + "\n  par asset swap spread: " + fixedBondCleanPrice2
                        + "\n  error:                 " + error3
                        + "\n  tolerance:             " + tolerance);
             }

             // FRN Underlying bond (Isin: IT0003543847 ISPIM 0 09/29/13)
             // maturity doesn't occur on a business day

             Date floatingBondStartDate1 = new Date(29,Month.September,2003);
             Date floatingBondMaturityDate1 = new Date(29,Month.September,2013);
             Schedule floatingBondSchedule1= new Schedule(floatingBondStartDate1,
                                       floatingBondMaturityDate1,
                                       new Period(Frequency.Semiannual), bondCalendar,
                                       BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                       DateGeneration.Rule.Backward, false);
             List<CashFlow> floatingBondLeg1 = new IborLeg(floatingBondSchedule1, vars.iborIndex)
            .withPaymentDayCounter(new Actual360())
            .withFixingDays(fixingDays)
            .withSpreads(0.0056)
            .inArrears(inArrears)
            .withNotionals(vars.faceAmount);
             Date floatingbondRedemption1 =
            bondCalendar.adjust(floatingBondMaturityDate1, BusinessDayConvention.Following);
             floatingBondLeg1.Add(new SimpleCashFlow(100.0, floatingbondRedemption1));
             Bond floatingBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount,
                  floatingBondMaturityDate1, floatingBondStartDate1,
                  floatingBondLeg1);
             floatingBond1.setPricingEngine(bondEngine);

             Utils.setCouponPricer(floatingBond1.cashflows(), vars.pricer);
             vars.iborIndex.addFixing(new Date(27,Month.March,2007), 0.0402);
             double floatingBondImpliedValue1 = floatingBond1.cleanPrice();
             // standard market conventions:
             // bond's frequency + coumpounding and daycounter of the YieldCurve
             double floatingBondCleanPrice1 = BondFunctions.cleanPrice(floatingBond1, vars.termStructure, vars.spread,
            new Actual365Fixed(), vars.compounding, Frequency.Semiannual, fixedBondSettlementDate1);
             double error5 = Math.Abs(floatingBondImpliedValue1-floatingBondCleanPrice1);
             if (error5>tolerance) {
            Assert.Fail("wrong clean price for fixed bond:"
                        + "\n  market asset swap spread: " +
                        floatingBondImpliedValue1
                        + "\n  par asset swap spread: " + floatingBondCleanPrice1
                        + "\n  error:                 " + error5
                        + "\n  tolerance:             " + tolerance);
             }

             // FRN Underlying bond (Isin: XS0090566539 COE 0 09/24/18)
             // maturity occurs on a business day

             Date floatingBondStartDate2 = new Date(24,Month.September,2004);
             Date floatingBondMaturityDate2 = new Date(24,Month.September,2018);
             Schedule floatingBondSchedule2 = new Schedule(floatingBondStartDate2,
                                       floatingBondMaturityDate2,
                                       new Period(Frequency.Semiannual), bondCalendar,
                                       BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing,
                                       DateGeneration.Rule.Backward, false);
             List<CashFlow> floatingBondLeg2 = new IborLeg(floatingBondSchedule2, vars.iborIndex)
            .withFixingDays(fixingDays)
            .withSpreads(0.0025)
            .withPaymentDayCounter(new Actual360())
            .inArrears(inArrears)
            .withPaymentAdjustment(BusinessDayConvention.ModifiedFollowing)
            .withNotionals(vars.faceAmount);
             Date floatingbondRedemption2 = bondCalendar.adjust(floatingBondMaturityDate2, BusinessDayConvention.ModifiedFollowing);
             floatingBondLeg2.Add(new SimpleCashFlow(100.0, floatingbondRedemption2));
             Bond floatingBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, floatingBondMaturityDate2,
            floatingBondStartDate2, floatingBondLeg2);
             floatingBond2.setPricingEngine(bondEngine);

             Utils.setCouponPricer(floatingBond2.cashflows(), vars.pricer);
             vars.iborIndex.addFixing(new Date(22,Month.March,2007), 0.04013);
             double floatingBondImpliedValue2 = floatingBond2.cleanPrice();
             // standard market conventions:
             // bond's frequency + coumpounding and daycounter of the YieldCurve
             double floatingBondCleanPrice2 = BondFunctions.cleanPrice(floatingBond2, vars.termStructure, vars.spread,
            new Actual365Fixed(), vars.compounding, Frequency.Semiannual,  fixedBondSettlementDate1);
             double error7 = Math.Abs(floatingBondImpliedValue2-floatingBondCleanPrice2);
             if (error7>tolerance) {
            Assert.Fail("wrong clean price for fixed bond:"
                        + "\n  market asset swap spread: " +
                        floatingBondImpliedValue2
                        + "\n  par asset swap spread: " + floatingBondCleanPrice2
                        + "\n  error:                 " + error7
                        + "\n  tolerance:             " + tolerance);
             }

             // CMS Underlying bond (Isin: XS0228052402 CRDIT 0 8/22/20)
             // maturity doesn't occur on a business day

             Date cmsBondStartDate1 = new Date(22,Month.August,2005);
             Date cmsBondMaturityDate1 = new Date(22,Month.August,2020);
             Schedule cmsBondSchedule1= new Schedule(cmsBondStartDate1,
                                 cmsBondMaturityDate1,
                                 new Period(Frequency.Annual), bondCalendar,
                                 BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                 DateGeneration.Rule.Backward, false);
             List<CashFlow> cmsBondLeg1 = new CmsLeg(cmsBondSchedule1, vars.swapIndex)
            .withPaymentDayCounter(new Thirty360())
            .withFixingDays(fixingDays)
            .withCaps(0.055)
            .withFloors(0.025)
            .inArrears(inArrears)
            .withNotionals(vars.faceAmount);
             Date cmsbondRedemption1 = bondCalendar.adjust(cmsBondMaturityDate1, BusinessDayConvention.Following);
             cmsBondLeg1.Add(new SimpleCashFlow(100.0, cmsbondRedemption1));
             Bond cmsBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, cmsBondMaturityDate1, cmsBondStartDate1,
            cmsBondLeg1);
             cmsBond1.setPricingEngine(bondEngine);

             Utils.setCouponPricer(cmsBond1.cashflows(), vars.cmspricer);
             vars.swapIndex.addFixing(new Date(18,Month.August,2006), 0.04158);
             double cmsBondImpliedValue1 = cmsBond1.cleanPrice();
             Date cmsBondSettlementDate1= cmsBond1.settlementDate();
             // standard market conventions:
             // bond's frequency + coumpounding and daycounter of the YieldCurve
             double cmsBondCleanPrice1 = BondFunctions.cleanPrice(cmsBond1, vars.termStructure, vars.spread,
            new Actual365Fixed(), vars.compounding, Frequency.Annual,
            cmsBondSettlementDate1);
             double error9 = Math.Abs(cmsBondImpliedValue1-cmsBondCleanPrice1);
             if (error9>tolerance) {
            Assert.Fail("wrong clean price for fixed bond:"
                        + "\n  market asset swap spread: " + cmsBondImpliedValue1
                        + "\n  par asset swap spread: " + cmsBondCleanPrice1
                        + "\n  error:                 " + error9
                        + "\n  tolerance:             " + tolerance);
             }

             // CMS Underlying bond (Isin: XS0218766664 ISPIM 0 5/6/15)
             // maturity occurs on a business day

             Date cmsBondStartDate2 = new Date(06,Month.May,2005);
             Date cmsBondMaturityDate2 = new Date(06,Month.May,2015);
             Schedule cmsBondSchedule2= new Schedule(cmsBondStartDate2,
                                 cmsBondMaturityDate2,
                                 new Period(Frequency.Annual), bondCalendar,
                                 BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                 DateGeneration.Rule.Backward, false);
             List<CashFlow> cmsBondLeg2 = new CmsLeg(cmsBondSchedule2, vars.swapIndex)
            .withPaymentDayCounter(new Thirty360())
            .withFixingDays(fixingDays)
            .withGearings(0.84)
            .inArrears(inArrears)
            .withNotionals(vars.faceAmount);
             Date cmsbondRedemption2 = bondCalendar.adjust(cmsBondMaturityDate2,  BusinessDayConvention.Following);
             cmsBondLeg2.Add(new SimpleCashFlow(100.0, cmsbondRedemption2));
             Bond cmsBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount,
                  cmsBondMaturityDate2, cmsBondStartDate2, cmsBondLeg2);
             cmsBond2.setPricingEngine(bondEngine);

             Utils.setCouponPricer(cmsBond2.cashflows(), vars.cmspricer);
             vars.swapIndex.addFixing(new Date(04,Month.May,2006), 0.04217);
             double cmsBondImpliedValue2 = cmsBond2.cleanPrice();
             Date cmsBondSettlementDate2= cmsBond2.settlementDate();
             // standard market conventions:
             // bond's frequency + coumpounding and daycounter of the YieldCurve
             double cmsBondCleanPrice2 = BondFunctions.cleanPrice(cmsBond2, vars.termStructure, vars.spread,
            new Actual365Fixed(), vars.compounding, Frequency.Annual,
            cmsBondSettlementDate2);
             double error11 = Math.Abs(cmsBondImpliedValue2-cmsBondCleanPrice2);
             if (error11>tolerance) {
            Assert.Fail("wrong clean price for fixed bond:"
                        + "\n  market asset swap spread: " + cmsBondImpliedValue2
                        + "\n  par asset swap spread: " + cmsBondCleanPrice2
                        + "\n  error:                 " + error11
                        + "\n  tolerance:             " + tolerance);
             }

             // Zero Coupon bond (Isin: DE0004771662 IBRD 0 12/20/15)
             // maturity doesn't occur on a business day

             Date zeroCpnBondStartDate1 = new Date(19,Month.December,1985);
             Date zeroCpnBondMaturityDate1 = new Date(20,Month.December,2015);
             Date zeroCpnBondRedemption1 = bondCalendar.adjust(zeroCpnBondMaturityDate1,
                                                         BusinessDayConvention.Following);
             List<CashFlow> zeroCpnBondLeg1 = new List<CashFlow>{new SimpleCashFlow(100.0, zeroCpnBondRedemption1)};
             Bond zeroCpnBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount,
                  zeroCpnBondMaturityDate1, zeroCpnBondStartDate1, zeroCpnBondLeg1);
             zeroCpnBond1.setPricingEngine(bondEngine);

             double zeroCpnBondImpliedValue1 = zeroCpnBond1.cleanPrice();
             Date zeroCpnBondSettlementDate1= zeroCpnBond1.settlementDate();
             // standard market conventions:
             // bond's frequency + coumpounding and daycounter of the YieldCurve
             double zeroCpnBondCleanPrice1 =
            BondFunctions.cleanPrice(zeroCpnBond1,
                                 vars.termStructure,
                                 vars.spread,
                                 new Actual365Fixed(),
                                 vars.compounding, Frequency.Annual,
                                 zeroCpnBondSettlementDate1);
             double error13 = Math.Abs(zeroCpnBondImpliedValue1-zeroCpnBondCleanPrice1);
             if (error13>tolerance) {
            Assert.Fail("wrong clean price for zero coupon bond:"
                        + "\n  zero cpn implied value: " +
                        zeroCpnBondImpliedValue1
                        + "\n  zero cpn price: " + zeroCpnBondCleanPrice1
                        + "\n  error:                 " + error13
                        + "\n  tolerance:             " + tolerance);
             }

             // Zero Coupon bond (Isin: IT0001200390 ISPIM 0 02/17/28)
             // maturity occurs on a business day

             Date zeroCpnBondStartDate2 = new Date(17,Month.February,1998);
             Date zeroCpnBondMaturityDate2 = new Date(17,Month.February,2028);
             Date zerocpbondRedemption2 = bondCalendar.adjust(zeroCpnBondMaturityDate2,
                                                         BusinessDayConvention.Following);
             List<CashFlow> zeroCpnBondLeg2 = new List<CashFlow>{new SimpleCashFlow(100.0, zerocpbondRedemption2)};
             Bond zeroCpnBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount,
                  zeroCpnBondMaturityDate2, zeroCpnBondStartDate2, zeroCpnBondLeg2);
             zeroCpnBond2.setPricingEngine(bondEngine);

             double zeroCpnBondImpliedValue2 = zeroCpnBond2.cleanPrice();
             Date zeroCpnBondSettlementDate2= zeroCpnBond2.settlementDate();
             // standard market conventions:
             // bond's frequency + coumpounding and daycounter of the YieldCurve
             double zeroCpnBondCleanPrice2 =
            BondFunctions.cleanPrice(zeroCpnBond2,
                                 vars.termStructure,
                                 vars.spread,
                                 new Actual365Fixed(),
                                 vars.compounding, Frequency.Annual,
                                 zeroCpnBondSettlementDate2);
             double error15 = Math.Abs(zeroCpnBondImpliedValue2-zeroCpnBondCleanPrice2);
             if (error15>tolerance) {
            Assert.Fail("wrong clean price for zero coupon bond:"
                        + "\n  zero cpn implied value: " +
                        zeroCpnBondImpliedValue2
                        + "\n  zero cpn price: " + zeroCpnBondCleanPrice2
                        + "\n  error:                 " + error15
                        + "\n  tolerance:             " + tolerance);
             }
        }
Exemple #7
0
        public void testSpecializedBondVsGenericBondUsingAsw()
        {
            // Testing asset-swap prices and spreads for specialized bond against equivalent generic bond...
             CommonVars vars = new CommonVars();

             Calendar bondCalendar = new TARGET();
             int settlementDays = 3;
             int fixingDays = 2;
             bool payFixedRate = true;
             bool parAssetSwap = true;
             bool inArrears = false;

             // Fixed bond (Isin: DE0001135275 DBR 4 01/04/37)
             // maturity doesn't occur on a business day
             Date fixedBondStartDate1 = new Date(4,Month.January,2005);
             Date fixedBondMaturityDate1 = new Date(4,Month.January,2037);
             Schedule fixedBondSchedule1 = new Schedule(fixedBondStartDate1,
                                    fixedBondMaturityDate1,
                                    new Period(Frequency.Annual), bondCalendar,
                                    BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                    DateGeneration.Rule.Backward, false);
             List<CashFlow> fixedBondLeg1 = new FixedRateLeg(fixedBondSchedule1)
            .withCouponRates(0.04, new ActualActual(ActualActual.Convention.ISDA))
            .withNotionals(vars.faceAmount);
             Date fixedbondRedemption1 = bondCalendar.adjust(fixedBondMaturityDate1, BusinessDayConvention.Following);
             fixedBondLeg1.Add(new SimpleCashFlow(100.0, fixedbondRedemption1));
             // generic bond
             Bond fixedBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount,
                  fixedBondMaturityDate1, fixedBondStartDate1, fixedBondLeg1);
             IPricingEngine bondEngine = new DiscountingBondEngine(vars.termStructure);
             IPricingEngine swapEngine = new DiscountingSwapEngine(vars.termStructure);
             fixedBond1.setPricingEngine(bondEngine);

             // equivalent specialized fixed rate bond
             Bond fixedSpecializedBond1 = new FixedRateBond(settlementDays, vars.faceAmount, fixedBondSchedule1,
                           new List<double>{0.04},
                           new ActualActual(ActualActual.Convention.ISDA), BusinessDayConvention.Following,
                           100.0, new Date(4,Month.January,2005));
             fixedSpecializedBond1.setPricingEngine(bondEngine);

             double fixedBondPrice1 = fixedBond1.cleanPrice();
             double fixedSpecializedBondPrice1 = fixedSpecializedBond1.cleanPrice();
             AssetSwap fixedBondAssetSwap1 = new AssetSwap(payFixedRate,
                                       fixedBond1, fixedBondPrice1,
                                       vars.iborIndex, vars.nonnullspread,
                                       null,
                                       vars.iborIndex.dayCounter(),
                                       parAssetSwap);
             fixedBondAssetSwap1.setPricingEngine(swapEngine);
             AssetSwap fixedSpecializedBondAssetSwap1 = new AssetSwap(payFixedRate,
                                                fixedSpecializedBond1,
                                                fixedSpecializedBondPrice1,
                                                vars.iborIndex,
                                                vars.nonnullspread,
                                                null,
                                                vars.iborIndex.dayCounter(),
                                                parAssetSwap);
             fixedSpecializedBondAssetSwap1.setPricingEngine(swapEngine);
             double fixedBondAssetSwapPrice1 = fixedBondAssetSwap1.fairCleanPrice();
             double fixedSpecializedBondAssetSwapPrice1 =
            fixedSpecializedBondAssetSwap1.fairCleanPrice();
             double tolerance = 1.0e-13;
             double error1 =
            Math.Abs(fixedBondAssetSwapPrice1-fixedSpecializedBondAssetSwapPrice1);
             if (error1>tolerance) {
            Assert.Fail("wrong clean price for fixed bond:"
                        + "\n  generic  fixed rate bond's  clean price: "
                        + fixedBondAssetSwapPrice1
                        + "\n  equivalent specialized bond's clean price: "
                        + fixedSpecializedBondAssetSwapPrice1
                        + "\n  error:                 " + error1
                        + "\n  tolerance:             " + tolerance);
             }
             // market executable price as of 4th sept 2007
             double fixedBondMktPrice1= 91.832;
             AssetSwap fixedBondASW1 = new AssetSwap(payFixedRate,
                                 fixedBond1, fixedBondMktPrice1,
                                 vars.iborIndex, vars.spread,
                                 null,
                                 vars.iborIndex.dayCounter(),
                                 parAssetSwap);
             fixedBondASW1.setPricingEngine(swapEngine);
             AssetSwap fixedSpecializedBondASW1 = new AssetSwap(payFixedRate,
                                          fixedSpecializedBond1,
                                          fixedBondMktPrice1,
                                          vars.iborIndex, vars.spread,
                                          null,
                                          vars.iborIndex.dayCounter(),
                                          parAssetSwap);
             fixedSpecializedBondASW1.setPricingEngine(swapEngine);
             double fixedBondASWSpread1 = fixedBondASW1.fairSpread();
             double fixedSpecializedBondASWSpread1 = fixedSpecializedBondASW1.fairSpread();
             double error2 = Math.Abs(fixedBondASWSpread1-fixedSpecializedBondASWSpread1);
             if (error2>tolerance) {
            Assert.Fail("wrong asw spread  for fixed bond:"
                        + "\n  generic  fixed rate bond's  asw spread: "
                        + fixedBondASWSpread1
                        + "\n  equivalent specialized bond's asw spread: "
                        + fixedSpecializedBondASWSpread1
                        + "\n  error:                 " + error2
                        + "\n  tolerance:             " + tolerance);
             }

             //Fixed bond (Isin: IT0006527060 IBRD 5 02/05/19)
             //maturity occurs on a business day

             Date fixedBondStartDate2 = new Date(5,Month.February,2005);
             Date fixedBondMaturityDate2 = new Date(5,Month.February,2019);
             Schedule fixedBondSchedule2= new Schedule(fixedBondStartDate2,
                                    fixedBondMaturityDate2,
                                    new Period(Frequency.Annual), bondCalendar,
                                    BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                    DateGeneration.Rule.Backward, false);
             List<CashFlow> fixedBondLeg2 = new FixedRateLeg(fixedBondSchedule2)
            .withCouponRates(0.05, new Thirty360(Thirty360.Thirty360Convention.BondBasis))
            .withNotionals(vars.faceAmount);
             Date fixedbondRedemption2 = bondCalendar.adjust(fixedBondMaturityDate2, BusinessDayConvention.Following);
             fixedBondLeg2.Add(new SimpleCashFlow(100.0, fixedbondRedemption2));

             // generic bond
             Bond fixedBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount,
                  fixedBondMaturityDate2, fixedBondStartDate2, fixedBondLeg2);
             fixedBond2.setPricingEngine(bondEngine);

             // equivalent specialized fixed rate bond
             Bond fixedSpecializedBond2 = new FixedRateBond(settlementDays, vars.faceAmount, fixedBondSchedule2,
                           new List<double>{ 0.05},
                           new Thirty360(Thirty360.Thirty360Convention.BondBasis), BusinessDayConvention.Following,
                           100.0, new Date(5,Month.February,2005));
             fixedSpecializedBond2.setPricingEngine(bondEngine);

             double fixedBondPrice2 = fixedBond2.cleanPrice();
             double fixedSpecializedBondPrice2 = fixedSpecializedBond2.cleanPrice();
             AssetSwap fixedBondAssetSwap2 = new AssetSwap(payFixedRate,
                                       fixedBond2, fixedBondPrice2,
                                       vars.iborIndex, vars.nonnullspread,
                                       null,
                                       vars.iborIndex.dayCounter(),
                                       parAssetSwap);
             fixedBondAssetSwap2.setPricingEngine(swapEngine);
             AssetSwap fixedSpecializedBondAssetSwap2 = new AssetSwap(payFixedRate,
                                                fixedSpecializedBond2,
                                                fixedSpecializedBondPrice2,
                                                vars.iborIndex,
                                                vars.nonnullspread,
                                                null,
                                                vars.iborIndex.dayCounter(),
                                                parAssetSwap);
             fixedSpecializedBondAssetSwap2.setPricingEngine(swapEngine);
             double fixedBondAssetSwapPrice2 = fixedBondAssetSwap2.fairCleanPrice();
             double fixedSpecializedBondAssetSwapPrice2 = fixedSpecializedBondAssetSwap2.fairCleanPrice();

             double error3 = Math.Abs(fixedBondAssetSwapPrice2-fixedSpecializedBondAssetSwapPrice2);
             if (error3>tolerance) {
            Assert.Fail("wrong clean price for fixed bond:"
                        + "\n  generic  fixed rate bond's clean price: "
                        + fixedBondAssetSwapPrice2
                        + "\n  equivalent specialized  bond's clean price: "
                        + fixedSpecializedBondAssetSwapPrice2
                        + "\n  error:                 " + error3
                        + "\n  tolerance:             " + tolerance);
             }
             // market executable price as of 4th sept 2007
             double fixedBondMktPrice2= 102.178;
             AssetSwap fixedBondASW2 = new AssetSwap(payFixedRate,
                                 fixedBond2, fixedBondMktPrice2,
                                 vars.iborIndex, vars.spread,
                                 null,
                                 vars.iborIndex.dayCounter(),
                                 parAssetSwap);
             fixedBondASW2.setPricingEngine(swapEngine);
             AssetSwap fixedSpecializedBondASW2 = new AssetSwap(payFixedRate,
                                          fixedSpecializedBond2,
                                          fixedBondMktPrice2,
                                          vars.iborIndex, vars.spread,
                                          null,
                                          vars.iborIndex.dayCounter(),
                                          parAssetSwap);
             fixedSpecializedBondASW2.setPricingEngine(swapEngine);
             double fixedBondASWSpread2 = fixedBondASW2.fairSpread();
             double fixedSpecializedBondASWSpread2 = fixedSpecializedBondASW2.fairSpread();
             double error4 = Math.Abs(fixedBondASWSpread2-fixedSpecializedBondASWSpread2);
             if (error4>tolerance) {
            Assert.Fail("wrong asw spread for fixed bond:"
                        + "\n  generic  fixed rate bond's  asw spread: "
                        + fixedBondASWSpread2
                        + "\n  equivalent specialized bond's asw spread: "
                        + fixedSpecializedBondASWSpread2
                        + "\n  error:                 " + error4
                        + "\n  tolerance:             " + tolerance);
             }

             //FRN bond (Isin: IT0003543847 ISPIM 0 09/29/13)
             //maturity doesn't occur on a business day
             Date floatingBondStartDate1 = new Date(29,Month.September,2003);
             Date floatingBondMaturityDate1 = new Date(29,Month.September,2013);
             Schedule floatingBondSchedule1= new Schedule(floatingBondStartDate1,
                                       floatingBondMaturityDate1,
                                       new Period(Frequency.Semiannual), bondCalendar,
                                       BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                       DateGeneration.Rule.Backward, false);
             List<CashFlow> floatingBondLeg1 = new IborLeg(floatingBondSchedule1, vars.iborIndex)
            .withPaymentDayCounter(new Actual360())
            .withFixingDays(fixingDays)
            .withSpreads(0.0056)
            .inArrears(inArrears)
            .withNotionals(vars.faceAmount);
             Date floatingbondRedemption1 = bondCalendar.adjust(floatingBondMaturityDate1, BusinessDayConvention.Following);
             floatingBondLeg1.Add(new SimpleCashFlow(100.0, floatingbondRedemption1));
             // generic bond
             Bond floatingBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount,
                  floatingBondMaturityDate1, floatingBondStartDate1, floatingBondLeg1);
             floatingBond1.setPricingEngine(bondEngine);

             // equivalent specialized floater
             Bond floatingSpecializedBond1 = new FloatingRateBond(settlementDays, vars.faceAmount,
                                 floatingBondSchedule1,
                                 vars.iborIndex, new Actual360(),
                                 BusinessDayConvention.Following, fixingDays,
                                 new List<double>{1},
                                 new List<double>{0.0056},
                                 new List<double>(), new List<double>(),
                                 inArrears,
                                 100.0, new Date(29,Month.September,2003));
             floatingSpecializedBond1.setPricingEngine(bondEngine);

             Utils.setCouponPricer(floatingBond1.cashflows(), vars.pricer);
             Utils.setCouponPricer(floatingSpecializedBond1.cashflows(), vars.pricer);
             vars.iborIndex.addFixing(new Date(27,Month.March,2007), 0.0402);
             double floatingBondPrice1 = floatingBond1.cleanPrice();
             double floatingSpecializedBondPrice1= floatingSpecializedBond1.cleanPrice();
             AssetSwap floatingBondAssetSwap1= new AssetSwap(payFixedRate,
                                          floatingBond1, floatingBondPrice1,
                                          vars.iborIndex, vars.nonnullspread,
                                          null,
                                          vars.iborIndex.dayCounter(),
                                          parAssetSwap);
             floatingBondAssetSwap1.setPricingEngine(swapEngine);
             AssetSwap floatingSpecializedBondAssetSwap1= new AssetSwap(payFixedRate,
                                                   floatingSpecializedBond1,
                                                   floatingSpecializedBondPrice1,
                                                   vars.iborIndex,
                                                   vars.nonnullspread,
                                                   null,
                                                   vars.iborIndex.dayCounter(),
                                                   parAssetSwap);
             floatingSpecializedBondAssetSwap1.setPricingEngine(swapEngine);
             double floatingBondAssetSwapPrice1 = floatingBondAssetSwap1.fairCleanPrice();
             double floatingSpecializedBondAssetSwapPrice1 =
            floatingSpecializedBondAssetSwap1.fairCleanPrice();

             double error5 =
            Math.Abs(floatingBondAssetSwapPrice1-floatingSpecializedBondAssetSwapPrice1);
             if (error5>tolerance) {
            Assert.Fail("wrong clean price for frnbond:"
                        + "\n  generic frn rate bond's clean price: "
                        + floatingBondAssetSwapPrice1
                        + "\n  equivalent specialized  bond's price: "
                        + floatingSpecializedBondAssetSwapPrice1
                        + "\n  error:                 " + error5
                        + "\n  tolerance:             " + tolerance);
             }
             // market executable price as of 4th sept 2007
             double floatingBondMktPrice1= 101.33;
             AssetSwap floatingBondASW1= new AssetSwap(payFixedRate,
                                    floatingBond1, floatingBondMktPrice1,
                                    vars.iborIndex, vars.spread,
                                    null,
                                    vars.iborIndex.dayCounter(),
                                    parAssetSwap);
             floatingBondASW1.setPricingEngine(swapEngine);
             AssetSwap floatingSpecializedBondASW1= new AssetSwap(payFixedRate,
                                             floatingSpecializedBond1,
                                             floatingBondMktPrice1,
                                             vars.iborIndex, vars.spread,
                                             null,
                                             vars.iborIndex.dayCounter(),
                                             parAssetSwap);
             floatingSpecializedBondASW1.setPricingEngine(swapEngine);
             double floatingBondASWSpread1 = floatingBondASW1.fairSpread();
             double floatingSpecializedBondASWSpread1 =
            floatingSpecializedBondASW1.fairSpread();
             double error6 =
            Math.Abs(floatingBondASWSpread1-floatingSpecializedBondASWSpread1);
             if (error6>tolerance) {
            Assert.Fail("wrong asw spread for fixed bond:"
                        + "\n  generic  frn rate bond's  asw spread: "
                        + floatingBondASWSpread1
                        + "\n  equivalent specialized bond's asw spread: "
                        + floatingSpecializedBondASWSpread1
                        + "\n  error:                 " + error6
                        + "\n  tolerance:             " + tolerance);
             }
             //FRN bond (Isin: XS0090566539 COE 0 09/24/18)
             //maturity occurs on a business day
             Date floatingBondStartDate2 = new Date(24,Month.September,2004);
             Date floatingBondMaturityDate2 = new Date(24,Month.September,2018);
             Schedule floatingBondSchedule2= new Schedule(floatingBondStartDate2,
                                       floatingBondMaturityDate2,
                                       new Period(Frequency.Semiannual), bondCalendar,
                                       BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing,
                                       DateGeneration.Rule.Backward, false);
             List<CashFlow> floatingBondLeg2 = new IborLeg(floatingBondSchedule2, vars.iborIndex)
            .withPaymentDayCounter(new Actual360())
            .withFixingDays(fixingDays)
            .withSpreads(0.0025)
            .inArrears(inArrears)
            .withPaymentAdjustment(BusinessDayConvention.ModifiedFollowing)
            .withNotionals(vars.faceAmount);
             Date floatingbondRedemption2 = bondCalendar.adjust(floatingBondMaturityDate2, BusinessDayConvention.ModifiedFollowing);
             floatingBondLeg2.Add(new SimpleCashFlow(100.0, floatingbondRedemption2));
             // generic bond
             Bond floatingBond2 = new  Bond(settlementDays, bondCalendar, vars.faceAmount,
                  floatingBondMaturityDate2, floatingBondStartDate2,floatingBondLeg2);
             floatingBond2.setPricingEngine(bondEngine);

             // equivalent specialized floater
             Bond floatingSpecializedBond2 = new FloatingRateBond(settlementDays, vars.faceAmount,
                              floatingBondSchedule2,
                              vars.iborIndex, new Actual360(),
                              BusinessDayConvention.ModifiedFollowing, fixingDays,
                              new List<double>{1},
                              new List<double>{0.0025},
                              new List<double>(), new List<double>(),
                              inArrears,
                              100.0, new Date(24,Month.September,2004));
             floatingSpecializedBond2.setPricingEngine(bondEngine);

             Utils.setCouponPricer(floatingBond2.cashflows(), vars.pricer);
             Utils.setCouponPricer(floatingSpecializedBond2.cashflows(), vars.pricer);

             vars.iborIndex.addFixing(new Date(22,Month.March,2007), 0.04013);

             double floatingBondPrice2 = floatingBond2.cleanPrice();
             double floatingSpecializedBondPrice2= floatingSpecializedBond2.cleanPrice();
             AssetSwap floatingBondAssetSwap2= new AssetSwap(payFixedRate,
                                          floatingBond2, floatingBondPrice2,
                                          vars.iborIndex, vars.nonnullspread,
                                          null,
                                          vars.iborIndex.dayCounter(),
                                          parAssetSwap);
             floatingBondAssetSwap2.setPricingEngine(swapEngine);
             AssetSwap floatingSpecializedBondAssetSwap2= new AssetSwap(payFixedRate,
                                                   floatingSpecializedBond2,
                                                   floatingSpecializedBondPrice2,
                                                   vars.iborIndex,
                                                   vars.nonnullspread,
                                                   null,
                                                   vars.iborIndex.dayCounter(),
                                                   parAssetSwap);
             floatingSpecializedBondAssetSwap2.setPricingEngine(swapEngine);
             double floatingBondAssetSwapPrice2 = floatingBondAssetSwap2.fairCleanPrice();
             double floatingSpecializedBondAssetSwapPrice2 =
            floatingSpecializedBondAssetSwap2.fairCleanPrice();
             double error7 =
            Math.Abs(floatingBondAssetSwapPrice2-floatingSpecializedBondAssetSwapPrice2);
             if (error7>tolerance) {
            Assert.Fail("wrong clean price for frnbond:"
                        + "\n  generic frn rate bond's clean price: "
                        + floatingBondAssetSwapPrice2
                        + "\n  equivalent specialized frn  bond's price: "
                        + floatingSpecializedBondAssetSwapPrice2
                        + "\n  error:                 " + error7
                        + "\n  tolerance:             " + tolerance);
             }
             // market executable price as of 4th sept 2007
             double floatingBondMktPrice2 = 101.26;
             AssetSwap floatingBondASW2= new AssetSwap(payFixedRate,
                                    floatingBond2, floatingBondMktPrice2,
                                    vars.iborIndex, vars.spread,
                                    null,
                                    vars.iborIndex.dayCounter(),
                                    parAssetSwap);
             floatingBondASW2.setPricingEngine(swapEngine);
             AssetSwap floatingSpecializedBondASW2= new AssetSwap(payFixedRate,
                                             floatingSpecializedBond2,
                                             floatingBondMktPrice2,
                                             vars.iborIndex, vars.spread,
                                             null,
                                             vars.iborIndex.dayCounter(),
                                             parAssetSwap);
             floatingSpecializedBondASW2.setPricingEngine(swapEngine);
             double floatingBondASWSpread2 = floatingBondASW2.fairSpread();
             double floatingSpecializedBondASWSpread2 =
            floatingSpecializedBondASW2.fairSpread();
             double error8 =
            Math.Abs(floatingBondASWSpread2-floatingSpecializedBondASWSpread2);
             if (error8>tolerance) {
            Assert.Fail("wrong asw spread for frn bond:"
                        + "\n  generic  frn rate bond's  asw spread: "
                        + floatingBondASWSpread2
                        + "\n  equivalent specialized bond's asw spread: "
                        + floatingSpecializedBondASWSpread2
                        + "\n  error:                 " + error8
                        + "\n  tolerance:             " + tolerance);
             }

             // CMS bond (Isin: XS0228052402 CRDIT 0 8/22/20)
             // maturity doesn't occur on a business day
             Date cmsBondStartDate1 = new Date(22,Month.August,2005);
             Date cmsBondMaturityDate1 = new Date(22,Month.August,2020);
             Schedule cmsBondSchedule1= new Schedule(cmsBondStartDate1,
                                 cmsBondMaturityDate1,
                                 new Period(Frequency.Annual), bondCalendar,
                                 BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                 DateGeneration.Rule.Backward, false);
             List<CashFlow> cmsBondLeg1 = new CmsLeg(cmsBondSchedule1, vars.swapIndex)
            .withPaymentDayCounter(new Thirty360())
            .withFixingDays(fixingDays)
            .withCaps(0.055)
            .withFloors(0.025)
            .inArrears(inArrears)
            .withNotionals(vars.faceAmount);
             Date cmsbondRedemption1 = bondCalendar.adjust(cmsBondMaturityDate1, BusinessDayConvention.Following);
             cmsBondLeg1.Add(new SimpleCashFlow(100.0, cmsbondRedemption1));
             // generic cms bond
             Bond cmsBond1 = new  Bond(settlementDays, bondCalendar, vars.faceAmount,
                  cmsBondMaturityDate1, cmsBondStartDate1, cmsBondLeg1);
             cmsBond1.setPricingEngine(bondEngine);

             // equivalent specialized cms bond
             Bond cmsSpecializedBond1 = new CmsRateBond(settlementDays, vars.faceAmount, cmsBondSchedule1,
                     vars.swapIndex, new Thirty360(),
                     BusinessDayConvention.Following, fixingDays,
                     new List<double>{1.0}, new List<double>{0.0},
                     new List<double>{0.055}, new List<double>{0.025},
                     inArrears,
                     100.0, new Date(22,Month.August,2005));
             cmsSpecializedBond1.setPricingEngine(bondEngine);

             Utils.setCouponPricer(cmsBond1.cashflows(), vars.cmspricer);
             Utils.setCouponPricer(cmsSpecializedBond1.cashflows(), vars.cmspricer);
             vars.swapIndex.addFixing(new Date(18,Month.August,2006), 0.04158);
             double cmsBondPrice1 = cmsBond1.cleanPrice();
             double cmsSpecializedBondPrice1 = cmsSpecializedBond1.cleanPrice();
             AssetSwap cmsBondAssetSwap1= new AssetSwap(payFixedRate,cmsBond1, cmsBondPrice1,
                                    vars.iborIndex, vars.nonnullspread,
                                    null,vars.iborIndex.dayCounter(),
                                    parAssetSwap);
             cmsBondAssetSwap1.setPricingEngine(swapEngine);
             AssetSwap cmsSpecializedBondAssetSwap1= new AssetSwap(payFixedRate,cmsSpecializedBond1,
                                                cmsSpecializedBondPrice1,
                                                vars.iborIndex,
                                                vars.nonnullspread,
                                                null,
                                                vars.iborIndex.dayCounter(),
                                                parAssetSwap);
             cmsSpecializedBondAssetSwap1.setPricingEngine(swapEngine);
             double cmsBondAssetSwapPrice1 = cmsBondAssetSwap1.fairCleanPrice();
             double cmsSpecializedBondAssetSwapPrice1 =
            cmsSpecializedBondAssetSwap1.fairCleanPrice();
             double error9 =
            Math.Abs(cmsBondAssetSwapPrice1-cmsSpecializedBondAssetSwapPrice1);
             if (error9>tolerance) {
            Assert.Fail("wrong clean price for cmsbond:"
                        + "\n  generic bond's clean price: "
                        + cmsBondAssetSwapPrice1
                        + "\n  equivalent specialized cms rate bond's price: "
                        + cmsSpecializedBondAssetSwapPrice1
                        + "\n  error:                 " + error9
                        + "\n  tolerance:             " + tolerance);
             }
             double cmsBondMktPrice1 = 87.02;// market executable price as of 4th sept 2007
             AssetSwap cmsBondASW1= new AssetSwap(payFixedRate,
                              cmsBond1, cmsBondMktPrice1,
                              vars.iborIndex, vars.spread,
                              null,
                              vars.iborIndex.dayCounter(),
                              parAssetSwap);
             cmsBondASW1.setPricingEngine(swapEngine);
             AssetSwap cmsSpecializedBondASW1= new AssetSwap(payFixedRate,
                                          cmsSpecializedBond1,
                                          cmsBondMktPrice1,
                                          vars.iborIndex, vars.spread,
                                          null,
                                          vars.iborIndex.dayCounter(),
                                          parAssetSwap);
             cmsSpecializedBondASW1.setPricingEngine(swapEngine);
             double cmsBondASWSpread1 = cmsBondASW1.fairSpread();
             double cmsSpecializedBondASWSpread1 = cmsSpecializedBondASW1.fairSpread();
             double error10 = Math.Abs(cmsBondASWSpread1-cmsSpecializedBondASWSpread1);
             if (error10>tolerance) {
            Assert.Fail("wrong asw spread for cm bond:"
                        + "\n  generic cms rate bond's  asw spread: "
                        + cmsBondASWSpread1
                        + "\n  equivalent specialized bond's asw spread: "
                        + cmsSpecializedBondASWSpread1
                        + "\n  error:                 " + error10
                        + "\n  tolerance:             " + tolerance);
             }

             //CMS bond (Isin: XS0218766664 ISPIM 0 5/6/15)
             //maturity occurs on a business day
             Date cmsBondStartDate2 = new Date(06,Month.May,2005);
             Date cmsBondMaturityDate2 = new Date(06,Month.May,2015);
             Schedule cmsBondSchedule2= new Schedule(cmsBondStartDate2,
                                 cmsBondMaturityDate2,
                                 new Period(Frequency.Annual), bondCalendar,
                                 BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                 DateGeneration.Rule.Backward, false);
             List<CashFlow> cmsBondLeg2 = new CmsLeg(cmsBondSchedule2, vars.swapIndex)
            .withPaymentDayCounter(new Thirty360())
            .withFixingDays(fixingDays)
            .withGearings(0.84)
            .inArrears(inArrears)
            .withNotionals(vars.faceAmount);
             Date cmsbondRedemption2 = bondCalendar.adjust(cmsBondMaturityDate2,
                                                      BusinessDayConvention.Following);
             cmsBondLeg2.Add(new SimpleCashFlow(100.0, cmsbondRedemption2));
             // generic bond
             Bond cmsBond2 = new  Bond(settlementDays, bondCalendar, vars.faceAmount,
                  cmsBondMaturityDate2, cmsBondStartDate2, cmsBondLeg2);
             cmsBond2.setPricingEngine(bondEngine);

             // equivalent specialized cms bond
             Bond cmsSpecializedBond2 = new  CmsRateBond(settlementDays, vars.faceAmount, cmsBondSchedule2,
                     vars.swapIndex, new Thirty360(),
                     BusinessDayConvention.Following, fixingDays,
                     new List<double>{0.84}, new List<double>{0.0},
                     new List<double>(), new List<double>(),
                     inArrears,
                     100.0, new Date(06,Month.May,2005));
             cmsSpecializedBond2.setPricingEngine(bondEngine);

             Utils.setCouponPricer(cmsBond2.cashflows(), vars.cmspricer);
             Utils.setCouponPricer(cmsSpecializedBond2.cashflows(), vars.cmspricer);
             vars.swapIndex.addFixing(new Date(04,Month.May,2006), 0.04217);
             double cmsBondPrice2 = cmsBond2.cleanPrice();
             double cmsSpecializedBondPrice2 = cmsSpecializedBond2.cleanPrice();
             AssetSwap cmsBondAssetSwap2= new AssetSwap(payFixedRate,cmsBond2, cmsBondPrice2,
                                    vars.iborIndex, vars.nonnullspread,
                                    null,
                                    vars.iborIndex.dayCounter(),
                                    parAssetSwap);
             cmsBondAssetSwap2.setPricingEngine(swapEngine);
             AssetSwap cmsSpecializedBondAssetSwap2= new AssetSwap(payFixedRate,cmsSpecializedBond2,
                                                cmsSpecializedBondPrice2,
                                                vars.iborIndex,
                                                vars.nonnullspread,
                                                null,
                                                vars.iborIndex.dayCounter(),
                                                parAssetSwap);
             cmsSpecializedBondAssetSwap2.setPricingEngine(swapEngine);
             double cmsBondAssetSwapPrice2 = cmsBondAssetSwap2.fairCleanPrice();
             double cmsSpecializedBondAssetSwapPrice2 =
            cmsSpecializedBondAssetSwap2.fairCleanPrice();
             double error11 =
            Math.Abs(cmsBondAssetSwapPrice2-cmsSpecializedBondAssetSwapPrice2);
             if (error11>tolerance) {
            Assert.Fail("wrong clean price for cmsbond:"
                        + "\n  generic  bond's clean price: "
                        + cmsBondAssetSwapPrice2
                        + "\n  equivalent specialized cms rate bond's price: "
                        + cmsSpecializedBondAssetSwapPrice2
                        + "\n  error:                 " + error11
                        + "\n  tolerance:             " + tolerance);
             }
             double cmsBondMktPrice2 = 94.35;// market executable price as of 4th sept 2007
             AssetSwap cmsBondASW2= new AssetSwap(payFixedRate,
                              cmsBond2, cmsBondMktPrice2,
                              vars.iborIndex, vars.spread,
                              null,
                              vars.iborIndex.dayCounter(),
                              parAssetSwap);
             cmsBondASW2.setPricingEngine(swapEngine);
             AssetSwap cmsSpecializedBondASW2= new AssetSwap(payFixedRate,
                                          cmsSpecializedBond2,
                                          cmsBondMktPrice2,
                                          vars.iborIndex, vars.spread,
                                          null,
                                          vars.iborIndex.dayCounter(),
                                          parAssetSwap);
             cmsSpecializedBondASW2.setPricingEngine(swapEngine);
             double cmsBondASWSpread2 = cmsBondASW2.fairSpread();
             double cmsSpecializedBondASWSpread2 = cmsSpecializedBondASW2.fairSpread();
             double error12 = Math.Abs(cmsBondASWSpread2-cmsSpecializedBondASWSpread2);
             if (error12>tolerance) {
            Assert.Fail("wrong asw spread for cm bond:"
                        + "\n  generic cms rate bond's  asw spread: "
                        + cmsBondASWSpread2
                        + "\n  equivalent specialized bond's asw spread: "
                        + cmsSpecializedBondASWSpread2
                        + "\n  error:                 " + error12
                        + "\n  tolerance:             " + tolerance);
             }

              //  Zero-Coupon bond (Isin: DE0004771662 IBRD 0 12/20/15)
              //  maturity doesn't occur on a business day
             Date zeroCpnBondStartDate1 = new Date(19,Month.December,1985);
             Date zeroCpnBondMaturityDate1 = new Date(20,Month.December,2015);
             Date zeroCpnBondRedemption1 = bondCalendar.adjust(zeroCpnBondMaturityDate1,
                                                         BusinessDayConvention.Following);
             List<CashFlow> zeroCpnBondLeg1 = new List<CashFlow>{new SimpleCashFlow(100.0, zeroCpnBondRedemption1)};
             // generic bond
             Bond zeroCpnBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount,
                  zeroCpnBondMaturityDate1, zeroCpnBondStartDate1, zeroCpnBondLeg1);
             zeroCpnBond1.setPricingEngine(bondEngine);

             // specialized zerocpn bond
             Bond zeroCpnSpecializedBond1= new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount,
                     new Date(20,Month.December,2015),
                     BusinessDayConvention.Following,
                     100.0, new Date(19,Month.December,1985));
             zeroCpnSpecializedBond1.setPricingEngine(bondEngine);

             double zeroCpnBondPrice1 = zeroCpnBond1.cleanPrice();
             double zeroCpnSpecializedBondPrice1 = zeroCpnSpecializedBond1.cleanPrice();
             AssetSwap zeroCpnBondAssetSwap1= new AssetSwap(payFixedRate,zeroCpnBond1,
                                       zeroCpnBondPrice1,
                                       vars.iborIndex, vars.nonnullspread,
                                       null,
                                       vars.iborIndex.dayCounter(),
                                       parAssetSwap);
             zeroCpnBondAssetSwap1.setPricingEngine(swapEngine);
             AssetSwap zeroCpnSpecializedBondAssetSwap1= new AssetSwap(payFixedRate,
                                                   zeroCpnSpecializedBond1,
                                                   zeroCpnSpecializedBondPrice1,
                                                   vars.iborIndex,
                                                   vars.nonnullspread,
                                                   null,
                                                   vars.iborIndex.dayCounter(),
                                                   parAssetSwap);
             zeroCpnSpecializedBondAssetSwap1.setPricingEngine(swapEngine);
             double zeroCpnBondAssetSwapPrice1 = zeroCpnBondAssetSwap1.fairCleanPrice();
             double zeroCpnSpecializedBondAssetSwapPrice1 =
            zeroCpnSpecializedBondAssetSwap1.fairCleanPrice();
             double error13 =
            Math.Abs(zeroCpnBondAssetSwapPrice1-zeroCpnSpecializedBondAssetSwapPrice1);
             if (error13>tolerance) {
            Assert.Fail("wrong clean price for zerocpn bond:"
                        + "\n  generic zero cpn bond's clean price: "
                        + zeroCpnBondAssetSwapPrice1
                        + "\n  specialized equivalent bond's price: "
                        + zeroCpnSpecializedBondAssetSwapPrice1
                        + "\n  error:                 " + error13
                        + "\n  tolerance:             " + tolerance);
             }
             // market executable price as of 4th sept 2007
             double zeroCpnBondMktPrice1 = 72.277;
             AssetSwap zeroCpnBondASW1= new AssetSwap(payFixedRate,
                                 zeroCpnBond1,zeroCpnBondMktPrice1,
                                 vars.iborIndex, vars.spread,
                                 null,
                                 vars.iborIndex.dayCounter(),
                                 parAssetSwap);
             zeroCpnBondASW1.setPricingEngine(swapEngine);
             AssetSwap zeroCpnSpecializedBondASW1= new AssetSwap(payFixedRate,
                                             zeroCpnSpecializedBond1,
                                             zeroCpnBondMktPrice1,
                                             vars.iborIndex, vars.spread,
                                             null,
                                             vars.iborIndex.dayCounter(),
                                             parAssetSwap);
             zeroCpnSpecializedBondASW1.setPricingEngine(swapEngine);
             double zeroCpnBondASWSpread1 = zeroCpnBondASW1.fairSpread();
             double zeroCpnSpecializedBondASWSpread1 =
            zeroCpnSpecializedBondASW1.fairSpread();
             double error14 =
            Math.Abs(zeroCpnBondASWSpread1-zeroCpnSpecializedBondASWSpread1);
             if (error14>tolerance) {
            Assert.Fail("wrong asw spread for zeroCpn bond:"
                        + "\n  generic zeroCpn bond's  asw spread: "
                        + zeroCpnBondASWSpread1
                        + "\n  equivalent specialized bond's asw spread: "
                        + zeroCpnSpecializedBondASWSpread1
                        + "\n  error:                 " + error14
                        + "\n  tolerance:             " + tolerance);
             }

              //  Zero Coupon bond (Isin: IT0001200390 ISPIM 0 02/17/28)
              //  maturity doesn't occur on a business day
             Date zeroCpnBondStartDate2 = new Date(17,Month.February,1998);
             Date zeroCpnBondMaturityDate2 = new Date(17,Month.February,2028);
             Date zerocpbondRedemption2 = bondCalendar.adjust(zeroCpnBondMaturityDate2,
                                                         BusinessDayConvention.Following);
             List<CashFlow> zeroCpnBondLeg2 = new List<CashFlow>{new SimpleCashFlow(100.0, zerocpbondRedemption2)};
             // generic bond
             Bond zeroCpnBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount,
                  zeroCpnBondMaturityDate2, zeroCpnBondStartDate2, zeroCpnBondLeg2);
             zeroCpnBond2.setPricingEngine(bondEngine);

             // specialized zerocpn bond
             Bond zeroCpnSpecializedBond2 = new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount,
                        new Date(17,Month.February,2028),
                        BusinessDayConvention.Following,
                        100.0, new Date(17,Month.February,1998));
             zeroCpnSpecializedBond2.setPricingEngine(bondEngine);

             double zeroCpnBondPrice2 = zeroCpnBond2.cleanPrice();
             double zeroCpnSpecializedBondPrice2 = zeroCpnSpecializedBond2.cleanPrice();

             AssetSwap zeroCpnBondAssetSwap2= new AssetSwap(payFixedRate,zeroCpnBond2,
                                       zeroCpnBondPrice2,
                                       vars.iborIndex, vars.nonnullspread,
                                       null,
                                       vars.iborIndex.dayCounter(),
                                       parAssetSwap);
             zeroCpnBondAssetSwap2.setPricingEngine(swapEngine);
             AssetSwap zeroCpnSpecializedBondAssetSwap2= new AssetSwap(payFixedRate,
                                                   zeroCpnSpecializedBond2,
                                                   zeroCpnSpecializedBondPrice2,
                                                   vars.iborIndex,
                                                   vars.nonnullspread,
                                                   null,
                                                   vars.iborIndex.dayCounter(),
                                                   parAssetSwap);
             zeroCpnSpecializedBondAssetSwap2.setPricingEngine(swapEngine);
             double zeroCpnBondAssetSwapPrice2 = zeroCpnBondAssetSwap2.fairCleanPrice();
             double zeroCpnSpecializedBondAssetSwapPrice2 =
                                    zeroCpnSpecializedBondAssetSwap2.fairCleanPrice();
             double error15 = Math.Abs(zeroCpnBondAssetSwapPrice2
                                 -zeroCpnSpecializedBondAssetSwapPrice2);
             if (error15>tolerance) {
            Assert.Fail("wrong clean price for zerocpn bond:"
                        + "\n  generic zero cpn bond's clean price: "
                        + zeroCpnBondAssetSwapPrice2
                        + "\n  equivalent specialized bond's price: "
                        + zeroCpnSpecializedBondAssetSwapPrice2
                        + "\n  error:                 " + error15
                        + "\n  tolerance:             " + tolerance);
             }
             // market executable price as of 4th sept 2007
             double zeroCpnBondMktPrice2 = 72.277;
             AssetSwap zeroCpnBondASW2= new AssetSwap(payFixedRate,
                                 zeroCpnBond2,zeroCpnBondMktPrice2,
                                 vars.iborIndex, vars.spread,
                                 null,
                                 vars.iborIndex.dayCounter(),
                                 parAssetSwap);
             zeroCpnBondASW2.setPricingEngine(swapEngine);
             AssetSwap zeroCpnSpecializedBondASW2= new AssetSwap(payFixedRate,
                                             zeroCpnSpecializedBond2,
                                             zeroCpnBondMktPrice2,
                                             vars.iborIndex, vars.spread,
                                             null,
                                             vars.iborIndex.dayCounter(),
                                             parAssetSwap);
             zeroCpnSpecializedBondASW2.setPricingEngine(swapEngine);
             double zeroCpnBondASWSpread2 = zeroCpnBondASW2.fairSpread();
             double zeroCpnSpecializedBondASWSpread2 =
            zeroCpnSpecializedBondASW2.fairSpread();
             double error16 =
            Math.Abs(zeroCpnBondASWSpread2-zeroCpnSpecializedBondASWSpread2);
             if (error16>tolerance) {
            Assert.Fail("wrong asw spread for zeroCpn bond:"
                        + "\n  generic zeroCpn bond's  asw spread: "
                        + zeroCpnBondASWSpread2
                        + "\n  equivalent specialized bond's asw spread: "
                        + zeroCpnSpecializedBondASWSpread2
                        + "\n  error:                 " + error16
                        + "\n  tolerance:             " + tolerance);
             }
        }
Exemple #8
0
        public void testMASWWithGenericBond()
        {
            // Testing market asset swap against par asset swap with generic bond...

             CommonVars vars = new CommonVars();

             Calendar bondCalendar = new TARGET();
             int settlementDays = 3;
             int fixingDays = 2;
             bool payFixedRate = true;
             bool parAssetSwap = true;
             bool mktAssetSwap = false;
             bool inArrears = false;

             // Fixed Underlying bond (Isin: DE0001135275 DBR 4 01/04/37)
             // maturity doesn't occur on a business day

             Date fixedBondStartDate1 = new Date(4,Month.January,2005);
             Date fixedBondMaturityDate1 = new Date(4,Month.January,2037);
             Schedule fixedBondSchedule1 = new Schedule(fixedBondStartDate1,
                                    fixedBondMaturityDate1,
                                    new Period(Frequency.Annual), bondCalendar,
                                    BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                    DateGeneration.Rule.Backward, false);
             List<CashFlow> fixedBondLeg1 = new FixedRateLeg(fixedBondSchedule1)
            .withCouponRates(0.04, new ActualActual(ActualActual.Convention.ISDA))
            .withNotionals(vars.faceAmount);
             Date fixedbondRedemption1 = bondCalendar.adjust(fixedBondMaturityDate1,   BusinessDayConvention.Following);
             fixedBondLeg1.Add(new SimpleCashFlow(100.0, fixedbondRedemption1));
             Bond fixedBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, fixedBondMaturityDate1,
            fixedBondStartDate1, fixedBondLeg1);
             IPricingEngine bondEngine = new DiscountingBondEngine(vars.termStructure);
             IPricingEngine swapEngine = new DiscountingSwapEngine(vars.termStructure);
             fixedBond1.setPricingEngine(bondEngine);

             double fixedBondMktPrice1 = 89.22 ; // market price observed on 7th June 2007
             double fixedBondMktFullPrice1=fixedBondMktPrice1+fixedBond1.accruedAmount();
             AssetSwap fixedBondParAssetSwap1= new AssetSwap(payFixedRate,
                                          fixedBond1, fixedBondMktPrice1,
                                          vars.iborIndex, vars.spread,
                                          null,
                                          vars.iborIndex.dayCounter(),
                                          parAssetSwap);
             fixedBondParAssetSwap1.setPricingEngine(swapEngine);
             double fixedBondParAssetSwapSpread1 = fixedBondParAssetSwap1.fairSpread();
             AssetSwap fixedBondMktAssetSwap1 = new AssetSwap(payFixedRate,
                                          fixedBond1, fixedBondMktPrice1,
                                          vars.iborIndex, vars.spread,
                                          null,
                                          vars.iborIndex.dayCounter(),
                                          mktAssetSwap);
             fixedBondMktAssetSwap1.setPricingEngine(swapEngine);
             double fixedBondMktAssetSwapSpread1 = fixedBondMktAssetSwap1.fairSpread();

             double tolerance = 1.0e-13;
             double error1 =
            Math.Abs(fixedBondMktAssetSwapSpread1-
                     100*fixedBondParAssetSwapSpread1/fixedBondMktFullPrice1);

             if (error1>tolerance)
            Assert.Fail("wrong asset swap spreads for fixed bond:" +
                        "\n  market asset swap spread: " + fixedBondMktAssetSwapSpread1 +
                        "\n  par asset swap spread:    " + fixedBondParAssetSwapSpread1 +
                        "\n  error:                    " + error1 +
                        "\n  tolerance:                " + tolerance);

             // Fixed Underlying bond (Isin: IT0006527060 IBRD 5 02/05/19)
             // maturity occurs on a business day

             Date fixedBondStartDate2 = new Date(5,Month.February,2005);
             Date fixedBondMaturityDate2 = new Date(5,Month.February,2019);
             Schedule fixedBondSchedule2 = new Schedule(fixedBondStartDate2,
                                    fixedBondMaturityDate2,
                                    new Period(Frequency.Annual), bondCalendar,
                                    BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                    DateGeneration.Rule.Backward, false);
             List<CashFlow> fixedBondLeg2 = new FixedRateLeg(fixedBondSchedule2)
            .withCouponRates(0.05, new Thirty360(Thirty360.Thirty360Convention.BondBasis))
            .withNotionals(vars.faceAmount);
             Date fixedbondRedemption2 = bondCalendar.adjust(fixedBondMaturityDate2,  BusinessDayConvention.Following);
             fixedBondLeg2.Add(new SimpleCashFlow(100.0, fixedbondRedemption2));
             Bond fixedBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, fixedBondMaturityDate2, fixedBondStartDate2,
            fixedBondLeg2);
             fixedBond2.setPricingEngine(bondEngine);

             double fixedBondMktPrice2 = 99.98 ; // market price observed on 7th June 2007
             double fixedBondMktFullPrice2=fixedBondMktPrice2+fixedBond2.accruedAmount();
             AssetSwap fixedBondParAssetSwap2= new AssetSwap(payFixedRate,
                                          fixedBond2, fixedBondMktPrice2,
                                          vars.iborIndex, vars.spread,
                                          null,
                                          vars.iborIndex.dayCounter(),
                                          parAssetSwap);
             fixedBondParAssetSwap2.setPricingEngine(swapEngine);
             double fixedBondParAssetSwapSpread2 = fixedBondParAssetSwap2.fairSpread();
             AssetSwap fixedBondMktAssetSwap2= new AssetSwap(payFixedRate,
                                          fixedBond2, fixedBondMktPrice2,
                                          vars.iborIndex, vars.spread,
                                          null,
                                          vars.iborIndex.dayCounter(),
                                          mktAssetSwap);
             fixedBondMktAssetSwap2.setPricingEngine(swapEngine);
             double fixedBondMktAssetSwapSpread2 = fixedBondMktAssetSwap2.fairSpread();
             double error2 = Math.Abs(fixedBondMktAssetSwapSpread2-
                     100*fixedBondParAssetSwapSpread2/fixedBondMktFullPrice2);

             if (error2>tolerance)
            Assert.Fail("wrong asset swap spreads for fixed bond:" +
                        "\n  market asset swap spread: " + fixedBondMktAssetSwapSpread2 +
                        "\n  par asset swap spread:    " + fixedBondParAssetSwapSpread2 +
                        "\n  error:                    " + error2 +
                        "\n  tolerance:                " + tolerance);

             // FRN Underlying bond (Isin: IT0003543847 ISPIM 0 09/29/13)
             // maturity doesn't occur on a business day

             Date floatingBondStartDate1 = new Date(29,Month.September,2003);
             Date floatingBondMaturityDate1 = new Date(29,Month.September,2013);
             Schedule floatingBondSchedule1= new Schedule(floatingBondStartDate1,
                                       floatingBondMaturityDate1,
                                       new Period(Frequency.Semiannual), bondCalendar,
                                       BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                       DateGeneration.Rule.Backward, false);
             List<CashFlow> floatingBondLeg1 = new IborLeg(floatingBondSchedule1, vars.iborIndex)
            .withPaymentDayCounter(new Actual360())
            .withFixingDays(fixingDays)
            .withSpreads(0.0056)
            .inArrears(inArrears)
            .withNotionals(vars.faceAmount);
             Date floatingbondRedemption1 =
            bondCalendar.adjust(floatingBondMaturityDate1, BusinessDayConvention.Following);
             floatingBondLeg1.Add(new SimpleCashFlow(100.0, floatingbondRedemption1));
             Bond floatingBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount,  floatingBondMaturityDate1,
            floatingBondStartDate1, floatingBondLeg1);
             floatingBond1.setPricingEngine(bondEngine);

             Utils.setCouponPricer(floatingBond1.cashflows(), vars.pricer);
             vars.iborIndex.addFixing(new Date(27,Month.March,2007), 0.0402);
             // market price observed on 7th June 2007
             double floatingBondMktPrice1 = 101.64 ;
             double floatingBondMktFullPrice1 =
            floatingBondMktPrice1+floatingBond1.accruedAmount();
             AssetSwap floatingBondParAssetSwap1 = new AssetSwap(payFixedRate,
                                             floatingBond1, floatingBondMktPrice1,
                                             vars.iborIndex, vars.spread,
                                             null,
                                             vars.iborIndex.dayCounter(),
                                             parAssetSwap);
             floatingBondParAssetSwap1.setPricingEngine(swapEngine);
             double floatingBondParAssetSwapSpread1 =
            floatingBondParAssetSwap1.fairSpread();
             AssetSwap floatingBondMktAssetSwap1 = new AssetSwap(payFixedRate,
                                             floatingBond1, floatingBondMktPrice1,
                                             vars.iborIndex, vars.spread,
                                             null,
                                             vars.iborIndex.dayCounter(),
                                             mktAssetSwap);
             floatingBondMktAssetSwap1.setPricingEngine(swapEngine);
             double floatingBondMktAssetSwapSpread1 =
            floatingBondMktAssetSwap1.fairSpread();
             double error3 = Math.Abs(floatingBondMktAssetSwapSpread1-
                     100*floatingBondParAssetSwapSpread1/floatingBondMktFullPrice1);

             if (error3>tolerance)
            Assert.Fail("wrong asset swap spreads for floating bond:" +
                        "\n  market asset swap spread: " + floatingBondMktAssetSwapSpread1 +
                        "\n  par asset swap spread:    " + floatingBondParAssetSwapSpread1 +
                        "\n  error:                    " + error3 +
                        "\n  tolerance:                " + tolerance);

             // FRN Underlying bond (Isin: XS0090566539 COE 0 09/24/18)
             // maturity occurs on a business day

             Date floatingBondStartDate2 = new Date(24,Month.September,2004);
             Date floatingBondMaturityDate2 = new Date(24,Month.September,2018);
             Schedule floatingBondSchedule2 = new Schedule(floatingBondStartDate2,
                                       floatingBondMaturityDate2,
                                       new Period(Frequency.Semiannual), bondCalendar,
                                       BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing,
                                       DateGeneration.Rule.Backward, false);
             List<CashFlow> floatingBondLeg2 = new IborLeg(floatingBondSchedule2, vars.iborIndex)
            .withFixingDays(fixingDays)
            .withSpreads(0.0025)
            .inArrears(inArrears)
            .withPaymentDayCounter(new Actual360())
            .withPaymentAdjustment(BusinessDayConvention.ModifiedFollowing)
            .withNotionals(vars.faceAmount);
             Date floatingbondRedemption2 =
            bondCalendar.adjust(floatingBondMaturityDate2, BusinessDayConvention.ModifiedFollowing);
             floatingBondLeg2.Add(new
            SimpleCashFlow(100.0, floatingbondRedemption2));
             Bond floatingBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, floatingBondMaturityDate2,
            floatingBondStartDate2, floatingBondLeg2);
             floatingBond2.setPricingEngine(bondEngine);

             Utils.setCouponPricer(floatingBond2.cashflows(), vars.pricer);
             vars.iborIndex.addFixing(new Date(22,Month.March,2007), 0.04013);
             // market price observed on 7th June 2007
             double floatingBondMktPrice2 = 101.248 ;
             double floatingBondMktFullPrice2 =
            floatingBondMktPrice2+floatingBond2.accruedAmount();
             AssetSwap floatingBondParAssetSwap2 = new AssetSwap(payFixedRate,
                                             floatingBond2, floatingBondMktPrice2,
                                             vars.iborIndex, vars.spread,
                                             null,
                                             vars.iborIndex.dayCounter(),
                                             parAssetSwap);
             floatingBondParAssetSwap2.setPricingEngine(swapEngine);
             double floatingBondParAssetSwapSpread2 = floatingBondParAssetSwap2.fairSpread();
             AssetSwap floatingBondMktAssetSwap2 = new AssetSwap(payFixedRate,
                                             floatingBond2, floatingBondMktPrice2,
                                             vars.iborIndex, vars.spread,
                                             null,
                                             vars.iborIndex.dayCounter(),
                                             mktAssetSwap);
             floatingBondMktAssetSwap2.setPricingEngine(swapEngine);
             double floatingBondMktAssetSwapSpread2 =
            floatingBondMktAssetSwap2.fairSpread();
             double error4 = Math.Abs(floatingBondMktAssetSwapSpread2-
                     100*floatingBondParAssetSwapSpread2/floatingBondMktFullPrice2);

             if (error4>tolerance)
            Assert.Fail("wrong asset swap spreads for floating bond:" +
                        "\n  market asset swap spread: " + floatingBondMktAssetSwapSpread2 +
                        "\n  par asset swap spread:    " + floatingBondParAssetSwapSpread2 +
                        "\n  error:                    " + error4 +
                        "\n  tolerance:                " + tolerance);

             // CMS Underlying bond (Isin: XS0228052402 CRDIT 0 8/22/20)
             // maturity doesn't occur on a business day

             Date cmsBondStartDate1 = new Date(22,Month.August,2005);
             Date cmsBondMaturityDate1 = new Date(22,Month.August,2020);
             Schedule cmsBondSchedule1= new Schedule(cmsBondStartDate1,
                                 cmsBondMaturityDate1,
                                 new Period(Frequency.Annual), bondCalendar,
                                 BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                 DateGeneration.Rule.Backward, false);
             List<CashFlow> cmsBondLeg1 = new CmsLeg(cmsBondSchedule1, vars.swapIndex)
            .withPaymentDayCounter(new Thirty360())
            .withFixingDays(fixingDays)
            .withCaps(0.055)
            .withFloors(0.025)
            .inArrears(inArrears)
            .withNotionals(vars.faceAmount);
             Date cmsbondRedemption1 = bondCalendar.adjust(cmsBondMaturityDate1, BusinessDayConvention.Following);
             cmsBondLeg1.Add(new SimpleCashFlow(100.0, cmsbondRedemption1));
             Bond cmsBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, cmsBondMaturityDate1, cmsBondStartDate1,
            cmsBondLeg1);
             cmsBond1.setPricingEngine(bondEngine);

             Utils.setCouponPricer(cmsBond1.cashflows(), vars.cmspricer);
             vars.swapIndex.addFixing(new Date(18,Month.August,2006), 0.04158);
             double cmsBondMktPrice1 = 88.45 ; // market price observed on 7th June 2007
             double cmsBondMktFullPrice1 = cmsBondMktPrice1+cmsBond1.accruedAmount();
             AssetSwap cmsBondParAssetSwap1 = new AssetSwap(payFixedRate,
                                       cmsBond1, cmsBondMktPrice1,
                                       vars.iborIndex, vars.spread,
                                       null,
                                       vars.iborIndex.dayCounter(),
                                       parAssetSwap);
             cmsBondParAssetSwap1.setPricingEngine(swapEngine);
             double cmsBondParAssetSwapSpread1 = cmsBondParAssetSwap1.fairSpread();
             AssetSwap cmsBondMktAssetSwap1 = new AssetSwap(payFixedRate,
                                       cmsBond1, cmsBondMktPrice1,
                                       vars.iborIndex, vars.spread,
                                       null,
                                       vars.iborIndex.dayCounter(),
                                       mktAssetSwap);
             cmsBondMktAssetSwap1.setPricingEngine(swapEngine);
             double cmsBondMktAssetSwapSpread1 = cmsBondMktAssetSwap1.fairSpread();
             double error5 =
            Math.Abs(cmsBondMktAssetSwapSpread1-
                     100*cmsBondParAssetSwapSpread1/cmsBondMktFullPrice1);

             if (error5>tolerance)
            Assert.Fail("wrong asset swap spreads for cms bond:" +
                        "\n  market asset swap spread: " + cmsBondMktAssetSwapSpread1 +
                        "\n  par asset swap spread:    " + cmsBondParAssetSwapSpread1 +
                        "\n  error:                    " + error5 +
                        "\n  tolerance:                " + tolerance);

             // CMS Underlying bond (Isin: XS0218766664 ISPIM 0 5/6/15)
             // maturity occurs on a business day

             Date cmsBondStartDate2 = new Date(06,Month.May,2005);
             Date cmsBondMaturityDate2 = new Date(06,Month.May,2015);
             Schedule cmsBondSchedule2= new Schedule(cmsBondStartDate2,
                                 cmsBondMaturityDate2,
                                 new Period(Frequency.Annual), bondCalendar,
                                 BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                 DateGeneration.Rule.Backward, false);
             List<CashFlow> cmsBondLeg2 = new CmsLeg(cmsBondSchedule2, vars.swapIndex)
            .withPaymentDayCounter(new Thirty360())
            .withFixingDays(fixingDays)
            .withGearings(0.84)
            .inArrears(inArrears)
            .withNotionals(vars.faceAmount);
             Date cmsbondRedemption2 = bondCalendar.adjust(cmsBondMaturityDate2,  BusinessDayConvention.Following);
             cmsBondLeg2.Add(new SimpleCashFlow(100.0, cmsbondRedemption2));
             Bond cmsBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount,  cmsBondMaturityDate2, cmsBondStartDate2,
            cmsBondLeg2);
             cmsBond2.setPricingEngine(bondEngine);

             Utils.setCouponPricer(cmsBond2.cashflows(), vars.cmspricer);
             vars.swapIndex.addFixing(new Date(04,Month.May,2006), 0.04217);
             double cmsBondMktPrice2 = 94.08 ; // market price observed on 7th June 2007
             double cmsBondMktFullPrice2 = cmsBondMktPrice2+cmsBond2.accruedAmount();
             AssetSwap cmsBondParAssetSwap2 = new AssetSwap(payFixedRate,
                                       cmsBond2, cmsBondMktPrice2,
                                       vars.iborIndex, vars.spread,
                                       null,
                                       vars.iborIndex.dayCounter(),
                                       parAssetSwap);
             cmsBondParAssetSwap2.setPricingEngine(swapEngine);
             double cmsBondParAssetSwapSpread2 = cmsBondParAssetSwap2.fairSpread();
             AssetSwap cmsBondMktAssetSwap2 = new AssetSwap(payFixedRate,
                                       cmsBond2, cmsBondMktPrice2,
                                       vars.iborIndex, vars.spread,
                                       null,
                                       vars.iborIndex.dayCounter(),
                                       mktAssetSwap);
             cmsBondMktAssetSwap2.setPricingEngine(swapEngine);
             double cmsBondMktAssetSwapSpread2 = cmsBondMktAssetSwap2.fairSpread();
             double error6 =
            Math.Abs(cmsBondMktAssetSwapSpread2-
                     100*cmsBondParAssetSwapSpread2/cmsBondMktFullPrice2);

             if (error6>tolerance)
            Assert.Fail("wrong asset swap spreads for cms bond:" +
                        "\n  market asset swap spread: " + cmsBondMktAssetSwapSpread2 +
                        "\n  par asset swap spread:    " + cmsBondParAssetSwapSpread2 +
                        "\n  error:                    " + error6 +
                        "\n  tolerance:                " + tolerance);

             // Zero Coupon bond (Isin: DE0004771662 IBRD 0 12/20/15)
             // maturity doesn't occur on a business day

             Date zeroCpnBondStartDate1 = new Date(19,Month.December,1985);
             Date zeroCpnBondMaturityDate1 = new Date(20,Month.December,2015);
             Date zeroCpnBondRedemption1 = bondCalendar.adjust(zeroCpnBondMaturityDate1,
                                                         BusinessDayConvention.Following);
             List<CashFlow> zeroCpnBondLeg1 = new List<CashFlow>{new SimpleCashFlow(100.0, zeroCpnBondRedemption1)};
             Bond zeroCpnBond1 = new  Bond(settlementDays, bondCalendar, vars.faceAmount, zeroCpnBondMaturityDate1,
            zeroCpnBondStartDate1, zeroCpnBondLeg1);
             zeroCpnBond1.setPricingEngine(bondEngine);

             // market price observed on 12th June 2007
             double zeroCpnBondMktPrice1 = 70.436 ;
             double zeroCpnBondMktFullPrice1 =
            zeroCpnBondMktPrice1+zeroCpnBond1.accruedAmount();
             AssetSwap zeroCpnBondParAssetSwap1 = new AssetSwap(payFixedRate,zeroCpnBond1,
                                          zeroCpnBondMktPrice1,
                                          vars.iborIndex, vars.spread,
                                          null,
                                          vars.iborIndex.dayCounter(),
                                          parAssetSwap);
             zeroCpnBondParAssetSwap1.setPricingEngine(swapEngine);
             double zeroCpnBondParAssetSwapSpread1 = zeroCpnBondParAssetSwap1.fairSpread();
             AssetSwap zeroCpnBondMktAssetSwap1 = new AssetSwap(payFixedRate,zeroCpnBond1,
                                          zeroCpnBondMktPrice1,
                                          vars.iborIndex, vars.spread,
                                          null,
                                          vars.iborIndex.dayCounter(),
                                          mktAssetSwap);
             zeroCpnBondMktAssetSwap1.setPricingEngine(swapEngine);
             double zeroCpnBondMktAssetSwapSpread1 = zeroCpnBondMktAssetSwap1.fairSpread();
             double error7 =
            Math.Abs(zeroCpnBondMktAssetSwapSpread1-
                     100*zeroCpnBondParAssetSwapSpread1/zeroCpnBondMktFullPrice1);

             if (error7>tolerance)
            Assert.Fail("wrong asset swap spreads for zero cpn bond:" +
                        "\n  market asset swap spread: " + zeroCpnBondMktAssetSwapSpread1 +
                        "\n  par asset swap spread:    " + zeroCpnBondParAssetSwapSpread1 +
                        "\n  error:                    " + error7 +
                        "\n  tolerance:                " + tolerance);

             // Zero Coupon bond (Isin: IT0001200390 ISPIM 0 02/17/28)
             // maturity occurs on a business day

             Date zeroCpnBondStartDate2 = new Date(17,Month.February,1998);
             Date zeroCpnBondMaturityDate2 = new Date(17,Month.February,2028);
             Date zerocpbondRedemption2 = bondCalendar.adjust(zeroCpnBondMaturityDate2,
                                                         BusinessDayConvention.Following);
             List<CashFlow> zeroCpnBondLeg2 = new List<CashFlow>{new SimpleCashFlow(100.0, zerocpbondRedemption2)};
             Bond zeroCpnBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount,
                  zeroCpnBondMaturityDate2, zeroCpnBondStartDate2, zeroCpnBondLeg2);
             zeroCpnBond2.setPricingEngine(bondEngine);

             // double zeroCpnBondPrice2 = zeroCpnBond2.cleanPrice();
             // market price observed on 12th June 2007
             double zeroCpnBondMktPrice2 = 35.160 ;
             double zeroCpnBondMktFullPrice2 =
            zeroCpnBondMktPrice2+zeroCpnBond2.accruedAmount();
             AssetSwap zeroCpnBondParAssetSwap2 = new AssetSwap(payFixedRate,zeroCpnBond2,
                                          zeroCpnBondMktPrice2,
                                          vars.iborIndex, vars.spread,
                                          null,
                                          vars.iborIndex.dayCounter(),
                                          parAssetSwap);
             zeroCpnBondParAssetSwap2.setPricingEngine(swapEngine);
             double zeroCpnBondParAssetSwapSpread2 = zeroCpnBondParAssetSwap2.fairSpread();
             AssetSwap zeroCpnBondMktAssetSwap2 = new AssetSwap(payFixedRate,zeroCpnBond2,
                                          zeroCpnBondMktPrice2,
                                          vars.iborIndex, vars.spread,
                                          null,
                                          vars.iborIndex.dayCounter(),
                                          mktAssetSwap);
             zeroCpnBondMktAssetSwap2.setPricingEngine(swapEngine);
             double zeroCpnBondMktAssetSwapSpread2 = zeroCpnBondMktAssetSwap2.fairSpread();
             double error8 =
            Math.Abs(zeroCpnBondMktAssetSwapSpread2-
                     100*zeroCpnBondParAssetSwapSpread2/zeroCpnBondMktFullPrice2);

             if (error8>tolerance)
            Assert.Fail("wrong asset swap spreads for zero cpn bond:" +
                        "\n  market asset swap spread: " + zeroCpnBondMktAssetSwapSpread2 +
                        "\n  par asset swap spread:    " + zeroCpnBondParAssetSwapSpread2 +
                        "\n  error:                    " + error8 +
                        "\n  tolerance:                " + tolerance);
        }
Exemple #9
0
        public void testMBSFixedBondCached()
        {
            // Test MBS Bond against cached values
             // from Fabozzi MBS Products Structuring and Analytical Techniques
             // Second Edition - WILEY ISBN 978-1-118-00469-2
             // pag 58,61,63

             #region Cached Values
             double[] OutstandingBalance = {400000000,399396651,398724866,397984841,397176808,396301034,395357823,394347512,393270474,
                                        392127117,390917882,389643247,388303720,386899847,385432204,383901402,382308084,380652925,
                                        378936631,377159941,375323622,373428474,371475324,369465030,367398478,365276580,363100276,
                                        360870534,358588346,356317966,354059336,351812393,349577078,347353331,345141093,342940305,
                                        340750907,338572840,336406048,334250471,332106052,329972733,327850458,325739170,323638812,
                                        321549327,319470661,317402757,315345560,313299014,311263066,309237660,307222743,305218260,
                                        303224158,301240383,299266882,297303602,295350492,293407497,291474567,289551650,287638694,
                                        285735647,283842460,281959081,280085459,278221545,276367288,274522640,272687550,270861969,
                                        269045848,267239140,265441794,263653764,261875001,260105457,258345086,256593839,254851671,
                                        253118533,251394381,249679167,247972846,246275371,244586698,242906782,241235576,239573036,
                                        237919118,236273777,234636970,233008651,231388779,229777308,228174197,226579401,224992878,
                                        223414586,221844483,220282525,218728672,217182881,215645111,214115321,212593469,211079516,
                                        209573419,208075140,206584637,205101871,203626802,202159389,200699595,199247379,197802703,
                                        196365528,194935815,193513525,192098622,190691066,189290820,187897846,186512107,185133566,
                                        183762186,182397929,181040759,179690640,178347535,177011409,175682225,174359947,173044541,
                                        171735971,170434201,169139197,167850924,166569347,165294431,164026143,162764449,161509314,
                                        160260704,159018587,157782929,156553696,155330855,154114374,152904220,151700360,150502762,
                                        149311394,148126224,146947219,145774348,144607580,143446882,142292225,141143576,140000905,
                                        138864182,137733374,136608453,135489388,134376148,133268704,132167026,131071083,129980848,
                                        128896290,127817380,126744089,125676388,124614249,123557642,122506539,121460913,120420734,
                                        119385975,118356608,117332605,116313939,115300582,114292506,113289685,112292092,111299699,
                                        110312480,109330408,108353458,107381601,106414813,105453067,104496337,103544598,102597823,
                                        101655987,100719066,99787032 ,98859862 ,97937530 ,97020012 ,96107282 ,95199317 ,94296091 ,
                                        93397579 ,92503759 ,91614606 ,90730095 ,89850202 ,88974905 ,88104180 ,87238002 ,86376348 ,
                                        85519196 ,84666522 ,83818303 ,82974516 ,82135138 ,81300146 ,80469519 ,79643233 ,78821266 ,
                                        78003597 ,77190202 ,76381060 ,75576149 ,74775447 ,73978932 ,73186584 ,72398380 ,71614300 ,
                                        70834321 ,70058424 ,69286586 ,68518787 ,67755007 ,66995224 ,66239418 ,65487568 ,64739655 ,
                                        63995657 ,63255556 ,62519330 ,61786959 ,61058425 ,60333707 ,59612785 ,58895641 ,58182253 ,
                                        57472605 ,56766675 ,56064445 ,55365895 ,54671008 ,53979764 ,53292143 ,52608129 ,51927702 ,
                                        51250843 ,50577534 ,49907758 ,49241495 ,48578728 ,47919438 ,47263609 ,46611221 ,45962258 ,
                                        45316701 ,44674534 ,44035738 ,43400297 ,42768192 ,42139408 ,41513926 ,40891731 ,40272804 ,
                                        39657129 ,39044690 ,38435469 ,37829450 ,37226618 ,36626954 ,36030443 ,35437069 ,34846816 ,
                                        34259667 ,33675607 ,33094619 ,32516689 ,31941799 ,31369935 ,30801080 ,30235220 ,29672339 ,
                                        29112422 ,28555453 ,28001417 ,27450300 ,26902085 ,26356759 ,25814305 ,25274711 ,24737960 ,
                                        24204038 ,23672931 ,23144624 ,22619103 ,22096353 ,21576360 ,21059110 ,20544589 ,20032782 ,
                                        19523677 ,19017258 ,18513512 ,18012425 ,17513984 ,17018175 ,16524985 ,16034399 ,15546405 ,
                                        15060989 ,14578138 ,14097838 ,13620077 ,13144842 ,12672119 ,12201896 ,11734160 ,11268897 ,
                                        10806096 ,10345743 ,9887826  ,9432332  ,8979249  ,8528565  ,8080267  ,7634342  ,7190780  ,
                                        6749566  ,6310691  ,5874140  ,5439903  ,5007967  ,4578321  ,4150953  ,3725851  ,3303003  ,
                                        2882398  ,2464024  ,2047870  ,1633925  ,1222176  ,812614   ,405225   };
             double[] Prepayments = { 200350,266975,333463,399780,465892,531764,597362,662652,727600,792172,856336,920057,983303,
                                  1046041,1108239,1169864,1230887,1291274,1350996,1410023,1468325,1525872,1582637,1638590,1693706,1747956,
                                  1801315,1853758,1842021,1830345,1818729,1807174,1795678,1784241,1772864,1761546,1750286,1739085,1727941,
                                  1716855,1705827,1694856,1683941,1673083,1662281,1651536,1640845,1630210,1619631,1609106,1598635,1588219,
                                  1577856,1567548,1557292,1547090,1536941,1526844,1516799,1506807,1496866,1486977,1477139,1467352,1457616,
                                  1447930,1438294,1428708,1419172,1409686,1400248,1390859,1381519,1372228,1362985,1353789,1344641,1335541,
                                  1326488,1317481,1308522,1299608,1290741,1281920,1273145,1264415,1255731,1247091,1238497,1229947,1221441,
                                  1212979,1204562,1196187,1187857,1179569,1171325,1163123,1154964,1146847,1138773,1130740,1122749,1114799,
                                  1106891,1099023,1091197,1083411,1075665,1067960,1060295,1052669,1045083,1037537,1030029,1022561,1015131,
                                  1007740,1000388,993073,985797,978558,971357,964193,957067,949977,942924,935908,928929,921985,915078,
                                  908207,901371,894571,887806,881077,874382,867722,861097,854506,847950,841427,834939,828484,822063,
                                  815675,809320,802998,796710,790454,784230,778039,771880,765753,759658,753595,747563,741563,735594,
                                  729656,723749,717872,712026,706211,700426,694671,688946,683251,677585,671949,666342,660765,655216,
                                  649697,644206,638744,633310,627904,622527,617178,611856,606563,601297,596058,590847,585662,580505,
                                  575375,570271,565194,560144,555120,550122,545150,540204,535284,530390,525521,520677,515859,511066,
                                  506298,501555,496836,492142,487473,482828,478207,473611,469038,464490,459965,455463,450986,446531,
                                  442100,437692,433307,428945,424606,420289,415995,411724,407474,403247,399042,394860,390698,386559,
                                  382442,378345,374271,370217,366185,362174,358184,354215,350266,346339,342431,338545,334678,330832,
                                  327006,323200,319414,315648,311901,308174,304467,300779,297110,293461,289831,286220,282627,279054,
                                  275499,271963,268445,264946,261466,258003,254559,251133,247724,244334,240961,237606,234269,230949,
                                  227647,224362,221094,217844,214610,211394,208194,205012,201845,198696,195563,192447,189347,186263,
                                  183195,180144,177109,174089,171086,168098,165126,162170,159229,156304,153394,150500,147620,144756,
                                  141907,139073,136254,133450,130660,127885,125125,122380,119648,116932,114229,111541,108867,106207,
                                  103561,100930,98312,95707,93117,90540,87977,85428,82891,80369,77859,75363,72880,70410,67954,65510,
                                  63079,60661,58256,55863,53483,51116,48761,46419,44089,41772,39466,37173,34893,32624,30367,28122,
                                  25889,23668,21459,19261,17075,14901,12738,10587,8447,6318,4201,2095,0};
             double[] NetInterest = { 1833333,1830568,1827489,1824097,1820394,1816380,1812057,1807426,1802490,1797249,1791707,1785865,
                                  1779725,1773291,1766564,1759548,1752245,1744659,1736793,1728650,1720233,1711547,1702595,1693381,
                                  1683910,1674184,1664210,1653990,1643530,1633124,1622772,1612473,1602228,1592036,1581897,1571810,
                                  1561775,1551792,1541861,1531981,1522153,1512375,1502648,1492971,1483345,1473768,1464241,1454763,
                                  1445334,1435954,1426622,1417339,1408104,1398917,1389777,1380685,1371640,1362642,1353690,1344784,
                                  1335925,1327112,1318344,1309622,1300945,1292312,1283725,1275182,1266683,1258229,1249818,1241451,
                                  1233127,1224846,1216608,1208413,1200260,1192150,1184082,1176055,1168070,1160127,1152224,1144363,
                                  1136542,1128762,1121022,1113323,1105663,1098043,1090463,1082921,1075419,1067956,1060532,1053146,
                                  1045798,1038489,1031217,1023984,1016787,1009628,1002506,995422,988373,981362,974387,967448,960545,
                                  953678,946846,940050,933290,926564,919873,913217,906596,900009,893456,886937,880452,874001,867583,
                                  861198,854847,848529,842243,835991,829770,823582,817426,811302,805210,799150,793121,787123,781157,
                                  775221,769317,763443,757599,751786,746004,740251,734528,728835,723172,717538,711933,706358,700811,
                                  695293,689804,684344,678912,673508,668132,662785,657465,652173,646908,641671,636461,631278,626122,
                                  620993,615891,610815,605766,600742,595746,590775,585830,580910,576017,571149,566306,561488,556696,
                                  551928,547186,542468,537774,533106,528461,523841,519244,514672,510124,505599,501098,496620,492166,
                                  487735,483327,478942,474579,470240,465923,461629,457357,453108,448880,444675,440492,436330,432190,
                                  428072,423976,419900,415846,411813,407802,403811,399841,395892,391963,388055,384167,380300,376453,
                                  372626,368819,365031,361264,357516,353788,350080,346391,342721,339070,335439,331826,328232,324657,
                                  321101,317564,314044,310544,307061,303597,300151,296723,293313,289921,286547,283190,279851,276529,
                                  273225,269938,266669,263416,260181,256962,253760,250575,247407,244256,241121,238002,234900,231814,
                                  228744,225690,222653,219631,216625,213635,210660,207702,204758,201830,198918,196021,193139,190272,
                                  187420,184584,181762,178955,176163,173385,170622,167874,165140,162420,159715,157023,154347,151684,
                                  149035,146400,143779,141172,138578,135998,133432,130879,128340,125814,123301,120802,118316,115842,
                                  113382,110935,108501,106080,103671,101275,98892,96521,94163,91817,89484,87162,84854,82557,80272,
                                  78000,75740,73491,71254,69030,66816,64615,62425,60247,58081,55925,53782,51649,49528,47418,45319,
                                  43232,41155,39089,37035,34991,32958,30936,28924,26923,24933,22953,20984,19025,17077,15139,13211,
                                  11293,9386,7489,5602,3724,1857};
             double[] ScheduledPrincipal = { 402998,404810,406562,408253,409882,411447,412949,414386,415758,417063,418300,419470,420571,
                                         421602,422563,423454,424273,425020,425694,426296,426824,427278,427657,427962,428192,428347,
                                         428427,428430,428358,428286,428213,428141,428069,427997,427924,427852,427780,427708,427636,
                                         427564,427491,427419,427347,427275,427203,427131,427059,426987,426915,426843,426771,426699,
                                         426627,426555,426483,426411,426339,426267,426195,426123,426051,425979,425907,425835,425764,
                                         425692,425620,425548,425476,425405,425333,425261,425189,425118,425046,424974,424902,424831,
                                         424759,424687,424616,424544,424472,424401,424329,424258,424186,424114,424043,423971,423900,
                                         423828,423757,423685,423614,423542,423471,423399,423328,423256,423185,423114,423042,422971,
                                         422900,422828,422757,422685,422614,422543,422472,422400,422329,422258,422187,422115,422044,
                                         421973,421902,421830,421759,421688,421617,421546,421475,421404,421332,421261,421190,421119,
                                         421048,420977,420906,420835,420764,420693,420622,420551,420480,420409,420338,420267,420196,
                                         420126,420055,419984,419913,419842,419771,419700,419630,419559,419488,419417,419346,419276,
                                         419205,419134,419064,418993,418922,418851,418781,418710,418639,418569,418498,418428,418357,
                                         418286,418216,418145,418075,418004,417934,417863,417793,417722,417652,417581,417511,417440,
                                         417370,417299,417229,417159,417088,417018,416947,416877,416807,416736,416666,416596,416526,
                                         416455,416385,416315,416245,416174,416104,416034,415964,415893,415823,415753,415683,415613,
                                         415543,415473,415403,415332,415262,415192,415122,415052,414982,414912,414842,414772,414702,
                                         414632,414562,414492,414422,414352,414282,414213,414143,414073,414003,413933,413863,413793,
                                         413724,413654,413584,413514,413444,413375,413305,413235,413165,413096,413026,412956,412887,
                                         412817,412747,412678,412608,412538,412469,412399,412330,412260,412191,412121,412051,411982,
                                         411912,411843,411773,411704,411635,411565,411496,411426,411357,411287,411218,411149,411079,
                                         411010,410941,410871,410802,410733,410663,410594,410525,410455,410386,410317,410248,410178,
                                         410109,410040,409971,409902,409833,409763,409694,409625,409556,409487,409418,409349,409280,
                                         409211,409142,409073,409003,408934,408865,408796,408728,408659,408590,408521,408452,408383,
                                         408314,408245,408176,408107,408038,407970,407901,407832,407763,407694,407625,407557,407488,
                                         407419,407350,407282,407213,407144,407076,407007,406938,406870,406801,406732,406664,406595,
                                         406526,406458,406389,406321,406252,406184,406115,406047,405978,405910,405841,405773,405704,
                                         405636,405567,405499,405430,405362,405294,405225};
             #endregion

             Date startDate = new Date(1, 2, 2007);
             Settings.setEvaluationDate(startDate);

             Period bondLength = new Period(358, TimeUnit.Months);
             Period originalLenght = new Period(360, TimeUnit.Months);
             DayCounter dCounter = new Thirty360();
             Frequency payFrequency = Frequency.Monthly;
             double amount = 400000000;
             double WACrate = 0.06;
             double PassThroughRate = 0.055;
             PSACurve psa100 = new PSACurve(startDate);

             var discountCurve = new Handle<YieldTermStructure>(Utilities.flatRate(startDate, new SimpleQuote(WACrate), new Thirty360()));

             // 400 Million Pass-Through with a 5.5% Pass-through Rate, a WAC of 6.0%, and a WAM of 358 Months,
             // Assuming 100% PSA
             MBSFixedRateBond bond = BondFactory.makeMBSFixedBond(startDate,
                                                               bondLength,
                                                               originalLenght,
                                                               dCounter,
                                                               payFrequency,
                                                               amount,
                                                               WACrate,
                                                               PassThroughRate,
                                                               psa100);

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

             // Calculate Monthly Expecting Cashflow
             List<CashFlow> cf = bond.expectedCashflows();

             // Outstanding Balance
             int i = 0;
             foreach (CashFlow c in cf)
             {
            if (c is QLNet.FixedRateCoupon)
            {
               FixedRateCoupon frc = c as FixedRateCoupon;
               Assert.AreEqual(OutstandingBalance[i], frc.nominal(), 1, "Outstanding Balance " + i++ + "is different");
            }
             }

             // Prepayments
             i = 0;
             foreach (CashFlow c in cf)
             {
            if (c is QLNet.VoluntaryPrepay)
            {
               Assert.AreEqual(Prepayments[i], c.amount(), 1, "Prepayments " + i++ + "is different");
            }
             }

             // Net Interest
             i = 0;
             foreach (CashFlow c in cf)
             {
            if (c is QLNet.FixedRateCoupon)
            {
               FixedRateCoupon frc = c as FixedRateCoupon;
               Assert.AreEqual(NetInterest[i], frc.amount(), 1, "Net Interest " + i++ + "is different");
            }
             }

             // Scheduled Principal
             i = 0;
             foreach (CashFlow c in cf)
             {
            if (c is QLNet.AmortizingPayment)
            {
               Assert.AreEqual(ScheduledPrincipal[i], c.amount(), 1, "Scheduled Principal " + i++ + "is different");
            }
             }

             // Monthly Yield
             Assert.AreEqual(0.00458333333333381, bond.MonthlyYield(), 0.000000001, "MonthlyYield is different");

             // Bond Equivalent Yield
             Assert.AreEqual(0.0556, bond.BondEquivalentYield(), 0.0001, " Bond Equivalent Yield is different");
        }
Exemple #10
0
        public void testCachedZero()
        {
            Console.WriteLine("Testing zero-coupon bond prices against cached values...");

             CommonVars vars = new CommonVars();

             Date today = new Date(22, Month.November, 2004);
             Settings.setEvaluationDate(today);

             int settlementDays = 1;

             var discountCurve = new Handle<YieldTermStructure>(Utilities.flatRate(today, 0.03, new Actual360()));

             double tolerance = 1.0e-6;

             // plain
             ZeroCouponBond bond1 = new ZeroCouponBond(settlementDays, new UnitedStates(UnitedStates.Market.GovernmentBond),
                              vars.faceAmount, new Date(30, Month.November, 2008), BusinessDayConvention.ModifiedFollowing,
                              100.0, new Date(30, Month.November, 2004));

             IPricingEngine bondEngine = new DiscountingBondEngine(discountCurve);
             bond1.setPricingEngine(bondEngine);

             double cachedPrice1 = 88.551726;

             double price = bond1.cleanPrice();
             if (Math.Abs(price - cachedPrice1) > tolerance)
             {
            Console.WriteLine("failed to reproduce cached price:\n"
                       + "    calculated: " + price + "\n"
                       + "    expected:   " + cachedPrice1 + "\n"
                       + "    error:      " + (price - cachedPrice1));
             }

             ZeroCouponBond bond2 = new ZeroCouponBond(settlementDays, new UnitedStates(UnitedStates.Market.GovernmentBond),
                              vars.faceAmount, new Date(30, Month.November, 2007), BusinessDayConvention.ModifiedFollowing,
                              100.0, new Date(30, Month.November, 2004));

             bond2.setPricingEngine(bondEngine);

             double cachedPrice2 = 91.278949;

             price = bond2.cleanPrice();
             if (Math.Abs(price - cachedPrice2) > tolerance)
             {
            Console.WriteLine("failed to reproduce cached price:\n"
                       + "    calculated: " + price + "\n"
                       + "    expected:   " + cachedPrice2 + "\n"
                       + "    error:      " + (price - cachedPrice2));
             }

             ZeroCouponBond bond3 = new ZeroCouponBond(settlementDays, new UnitedStates(UnitedStates.Market.GovernmentBond),
                              vars.faceAmount, new Date(30, Month.November, 2006), BusinessDayConvention.ModifiedFollowing,
                              100.0, new Date(30, Month.November, 2004));

             bond3.setPricingEngine(bondEngine);

             double cachedPrice3 = 94.098006;

             price = bond3.cleanPrice();
             if (Math.Abs(price - cachedPrice3) > tolerance)
             {
            Console.WriteLine("failed to reproduce cached price:\n"
                       + "    calculated: " + price + "\n"
                       + "    expected:   " + cachedPrice3 + "\n"
                       + "    error:      " + (price - cachedPrice3));
             }
        }
Exemple #11
0
        public void testCachedFixed()
        {
            // "Testing fixed-coupon bond prices against cached values...");

             CommonVars vars = new CommonVars();

             Date today = new Date(22, Month.November, 2004);
             Settings.setEvaluationDate(today);

             int settlementDays = 1;

             var discountCurve = new Handle<YieldTermStructure>(Utilities.flatRate(today, 0.03, new Actual360()));

             double tolerance = 1.0e-6;

             // plain
             Schedule sch = new Schedule(new Date(30, Month.November, 2004),
                      new Date(30, Month.November, 2008), new Period(Frequency.Semiannual),
                      new UnitedStates(UnitedStates.Market.GovernmentBond),
                      BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false);

             FixedRateBond bond1 = new FixedRateBond(settlementDays, vars.faceAmount, sch, new List<double>() { 0.02875 },
                             new ActualActual(ActualActual.Convention.ISMA), BusinessDayConvention.ModifiedFollowing,
                             100.0, new Date(30, Month.November, 2004));

             IPricingEngine bondEngine = new DiscountingBondEngine(discountCurve);
             bond1.setPricingEngine(bondEngine);

             double cachedPrice1 = 99.298100;

             double price = bond1.cleanPrice();
             if (Math.Abs(price - cachedPrice1) > tolerance)
             {
            Console.WriteLine("failed to reproduce cached price:\n"
                       + "    calculated: " + price + "\n"
                       + "    expected:   " + cachedPrice1 + "\n"
                       + "    error:      " + (price - cachedPrice1));
             }

             // varying coupons
             InitializedList<double> couponRates = new InitializedList<double>(4);
             couponRates[0] = 0.02875;
             couponRates[1] = 0.03;
             couponRates[2] = 0.03125;
             couponRates[3] = 0.0325;

             FixedRateBond bond2 = new FixedRateBond(settlementDays, vars.faceAmount, sch, couponRates,
                               new ActualActual(ActualActual.Convention.ISMA),
                               BusinessDayConvention.ModifiedFollowing,
                               100.0, new Date(30, Month.November, 2004));

             bond2.setPricingEngine(bondEngine);

             double cachedPrice2 = 100.334149;

             price = bond2.cleanPrice();
             if (Math.Abs(price - cachedPrice2) > tolerance)
             {
            Console.WriteLine("failed to reproduce cached price:\n"
                       + "    calculated: " + price + "\n"
                       + "    expected:   " + cachedPrice2 + "\n"
                       + "    error:      " + (price - cachedPrice2));
             }

             // stub date
             Schedule sch3 = new Schedule(new Date(30, Month.November, 2004),
                       new Date(30, Month.March, 2009), new Period(Frequency.Semiannual),
                       new UnitedStates(UnitedStates.Market.GovernmentBond),
                       BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false,
                       null, new Date(30, Month.November, 2008));

             FixedRateBond bond3 = new FixedRateBond(settlementDays, vars.faceAmount, sch3,
                               couponRates, new ActualActual(ActualActual.Convention.ISMA),
                               BusinessDayConvention.ModifiedFollowing,
                               100.0, new Date(30, Month.November, 2004));

             bond3.setPricingEngine(bondEngine);

             double cachedPrice3 = 100.382794;

             price = bond3.cleanPrice();
             if (Math.Abs(price - cachedPrice3) > tolerance)
             {
            Assert.Fail("failed to reproduce cached price:\n"
                       + "    calculated: " + price + "\n"
                       + "    expected:   " + cachedPrice3 + "\n"
                       + "    error:      " + (price - cachedPrice3));
             }
        }
Exemple #12
0
        public void testCached()
        {
            // ("Testing bond price/yield calculation against cached values...");

             CommonVars vars = new CommonVars();

             // with implicit settlement calculation:
             Date today = new Date(22, Month.November, 2004);
             Settings.setEvaluationDate(today);

             Calendar bondCalendar = new NullCalendar();
             DayCounter bondDayCount = new ActualActual(ActualActual.Convention.ISMA);
             int settlementDays = 1;

             var discountCurve = new Handle<YieldTermStructure>(Utilities.flatRate(today, new SimpleQuote(0.03), new Actual360()));

             // actual market values from the evaluation date
             Frequency freq = Frequency.Semiannual;
             Schedule sch1 = new Schedule(new Date(31, Month.October, 2004), new Date(31, Month.October, 2006), new Period(freq),
                                      bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                      DateGeneration.Rule.Backward, false);

             FixedRateBond bond1 = new FixedRateBond(settlementDays, vars.faceAmount, sch1, new List<double>() { 0.025 },
                                 bondDayCount, BusinessDayConvention.ModifiedFollowing, 100.0, new Date(1, Month.November, 2004));

             IPricingEngine bondEngine = new DiscountingBondEngine(discountCurve);
             bond1.setPricingEngine(bondEngine);

             double marketPrice1 = 99.203125;
             double marketYield1 = 0.02925;

             Schedule sch2 = new Schedule(new Date(15, Month.November, 2004), new Date(15, Month.November, 2009), new Period(freq),
                                      bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                      DateGeneration.Rule.Backward, false);

             FixedRateBond bond2 = new FixedRateBond(settlementDays, vars.faceAmount, sch2, new List<double>() { 0.035 },
                                      bondDayCount, BusinessDayConvention.ModifiedFollowing,
                                      100.0, new Date(15, Month.November, 2004));

             bond2.setPricingEngine(bondEngine);

             double marketPrice2 = 99.6875;
             double marketYield2 = 0.03569;

             // calculated values
             double cachedPrice1a = 99.204505, cachedPrice2a = 99.687192;
             double cachedPrice1b = 98.943393, cachedPrice2b = 101.986794;
             double cachedYield1a = 0.029257, cachedYield2a = 0.035689;
             double cachedYield1b = 0.029045, cachedYield2b = 0.035375;
             double cachedYield1c = 0.030423, cachedYield2c = 0.030432;

             // check
             double tolerance = 1.0e-6;
             double price, yield;

             price = bond1.cleanPrice(marketYield1, bondDayCount, Compounding.Compounded, freq);
             if (Math.Abs(price - cachedPrice1a) > tolerance)
             {
            Assert.Fail("failed to reproduce cached price:"
                       + "\n    calculated: " + price
                       + "\n    expected:   " + cachedPrice1a
                       + "\n    tolerance:  " + tolerance
                       + "\n    error:      " + (price - cachedPrice1a));
             }

             price = bond1.cleanPrice();
             if (Math.Abs(price - cachedPrice1b) > tolerance)
             {
            Assert.Fail("failed to reproduce cached price:"
                       + "\n    calculated: " + price
                       + "\n    expected:   " + cachedPrice1b
                       + "\n    tolerance:  " + tolerance
                       + "\n    error:      " + (price - cachedPrice1b));
             }

             yield = bond1.yield(marketPrice1, bondDayCount, Compounding.Compounded, freq);
             if (Math.Abs(yield - cachedYield1a) > tolerance)
             {
            Assert.Fail("failed to reproduce cached compounded yield:"
                       + "\n    calculated: " + yield
                       + "\n    expected:   " + cachedYield1a
                       + "\n    tolerance:  " + tolerance
                       + "\n    error:      " + (yield - cachedYield1a));
             }

             yield = bond1.yield(marketPrice1, bondDayCount, Compounding.Continuous, freq);
             if (Math.Abs(yield - cachedYield1b) > tolerance)
             {
            Assert.Fail("failed to reproduce cached continuous yield:"
                       + "\n    calculated: " + yield
                       + "\n    expected:   " + cachedYield1b
                       + "\n    tolerance:  " + tolerance
                       + "\n    error:      " + (yield - cachedYield1b));
             }

             yield = bond1.yield(bondDayCount, Compounding.Continuous, freq);
             if (Math.Abs(yield - cachedYield1c) > tolerance)
             {
            Assert.Fail("failed to reproduce cached continuous yield:"
                       + "\n    calculated: " + yield
                       + "\n    expected:   " + cachedYield1c
                       + "\n    tolerance:  " + tolerance
                       + "\n    error:      " + (yield - cachedYield1c));
             }

             price = bond2.cleanPrice(marketYield2, bondDayCount, Compounding.Compounded, freq);
             if (Math.Abs(price - cachedPrice2a) > tolerance)
             {
            Assert.Fail("failed to reproduce cached price:"
                       + "\n    calculated: " + price
                       + "\n    expected:   " + cachedPrice2a
                       + "\n    tolerance:  " + tolerance
                       + "\n    error:      " + (price - cachedPrice2a));
             }

             price = bond2.cleanPrice();
             if (Math.Abs(price - cachedPrice2b) > tolerance)
             {
            Assert.Fail("failed to reproduce cached price:"
                       + "\n    calculated: " + price
                       + "\n    expected:   " + cachedPrice2b
                       + "\n    tolerance:  " + tolerance
                       + "\n    error:      " + (price - cachedPrice2b));
             }

             yield = bond2.yield(marketPrice2, bondDayCount, Compounding.Compounded, freq);
             if (Math.Abs(yield - cachedYield2a) > tolerance)
             {
            Assert.Fail("failed to reproduce cached compounded yield:"
                       + "\n    calculated: " + yield
                       + "\n    expected:   " + cachedYield2a
                       + "\n    tolerance:  " + tolerance
                       + "\n    error:      " + (yield - cachedYield2a));
             }

             yield = bond2.yield(marketPrice2, bondDayCount, Compounding.Continuous, freq);
             if (Math.Abs(yield - cachedYield2b) > tolerance)
             {
            Assert.Fail("failed to reproduce cached continuous yield:"
                       + "\n    calculated: " + yield
                       + "\n    expected:   " + cachedYield2b
                       + "\n    tolerance:  " + tolerance
                       + "\n    error:      " + (yield - cachedYield2b));
             }

             yield = bond2.yield(bondDayCount, Compounding.Continuous, freq);
             if (Math.Abs(yield - cachedYield2c) > tolerance)
             {
            Assert.Fail("failed to reproduce cached continuous yield:"
                       + "\n    calculated: " + yield
                       + "\n    expected:   " + cachedYield2c
                       + "\n    tolerance:  " + tolerance
                       + "\n    error:      " + (yield - cachedYield2c));
             }

             // with explicit settlement date:
             Schedule sch3 = new Schedule(new Date(30, Month.November, 2004), new Date(30, Month.November, 2006), new Period(freq),
                                      new UnitedStates(UnitedStates.Market.GovernmentBond), BusinessDayConvention.Unadjusted,
                                      BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false);

             FixedRateBond bond3 = new FixedRateBond(settlementDays, vars.faceAmount, sch3, new List<double>() { 0.02875 },
                             new ActualActual(ActualActual.Convention.ISMA),
                             BusinessDayConvention.ModifiedFollowing, 100.0, new Date(30, Month.November, 2004));

             bond3.setPricingEngine(bondEngine);

             double marketYield3 = 0.02997;

             Date settlementDate = new Date(30, Month.November, 2004);
             double cachedPrice3 = 99.764759;

             price = bond3.cleanPrice(marketYield3, bondDayCount, Compounding.Compounded, freq, settlementDate);
             if (Math.Abs(price - cachedPrice3) > tolerance)
             {
            Assert.Fail("failed to reproduce cached price:"
                       + "\n    calculated: " + price + ""
                       + "\n    expected:   " + cachedPrice3 + ""
                       + "\n    error:      " + (price - cachedPrice3));
             }

             // this should give the same result since the issue date is the
             // earliest possible settlement date
             Settings.setEvaluationDate(new Date(22, Month.November, 2004));

             price = bond3.cleanPrice(marketYield3, bondDayCount, Compounding.Compounded, freq);
             if (Math.Abs(price - cachedPrice3) > tolerance)
             {
            Assert.Fail("failed to reproduce cached price:"
                       + "\n    calculated: " + price + ""
                       + "\n    expected:   " + cachedPrice3 + ""
                       + "\n    error:      " + (price - cachedPrice3));
             }
        }
Exemple #13
0
        public void testAmortizingFixedBond()
        {
            Date startDate = new Date(2, 1, 2007);
             Settings.setEvaluationDate(startDate);

             Period bondLength = new Period(12, TimeUnit.Months);
             DayCounter dCounter = new Thirty360();
             Frequency payFrequency = Frequency.Monthly;
             double amount = 400000000;
             double rate = 0.06;
             var discountCurve = new Handle<YieldTermStructure>(Utilities.flatRate(startDate, new SimpleQuote(rate), new Thirty360()));

             AmortizingFixedRateBond bond = BondFactory.makeAmortizingFixedBond(startDate, bondLength, dCounter, payFrequency, amount, rate);
             IPricingEngine bondEngine = new DiscountingBondEngine(discountCurve);
             bond.setPricingEngine(bondEngine);

             // cached values
             int totCashflow = 24;
             int totNotionals = 13;
             double PVDifference = 13118862.59;
             double[] notionals = {400000000,367573428,334984723,302233075,269317669,236237685,202992302,169580691,136002023,
                               102255461,68340166,34255295,0 };

             // test total cashflow count
             Assert.AreEqual(bond.cashflows().Count, totCashflow, "Cashflow size different");

             // test notional cashflow count
             Assert.AreEqual(bond.notionals().Count, totNotionals, "Notionals size different");

             // test notional amortization values
             for (int i = 0; i < totNotionals; i++)
             {
            Assert.AreEqual(bond.notionals()[i], notionals[i], 1, "Notionals " + i + "is different");
             }

             // test PV difference
             double cash = bond.CASH();
             Assert.AreEqual(cash - amount, PVDifference, 0.1, "PV Difference wrong");
        }
Exemple #14
0
        public void testTheoretical()
        {
            // "Testing theoretical bond price/yield calculation...");

             CommonVars vars = new CommonVars();

             double tolerance = 1.0e-7;
             int maxEvaluations = 100;

             int[] lengths = new int[] { 3, 5, 10, 15, 20 };
             int settlementDays = 3;
             double[] coupons = new double[] { 0.02, 0.05, 0.08 };
             Frequency[] frequencies = new Frequency[] { Frequency.Semiannual, Frequency.Annual };
             DayCounter bondDayCount = new Actual360();
             BusinessDayConvention accrualConvention = BusinessDayConvention.Unadjusted;
             BusinessDayConvention paymentConvention = BusinessDayConvention.ModifiedFollowing;
             double redemption = 100.0;

             double[] yields = new double[] { 0.03, 0.04, 0.05, 0.06, 0.07 };

             for (int j = 0; j < lengths.Length; j++)
             {
            for (int k = 0; k < coupons.Length; k++)
            {
               for (int l = 0; l < frequencies.Length; l++)
               {

                  Date dated = vars.today;
                  Date issue = dated;
                  Date maturity = vars.calendar.advance(issue, lengths[j], TimeUnit.Years);

                  SimpleQuote rate = new SimpleQuote(0.0);
                  var discountCurve = new Handle<YieldTermStructure>(Utilities.flatRate(vars.today, rate, bondDayCount));

                  Schedule sch = new Schedule(dated, maturity, new Period(frequencies[l]), vars.calendar,
                                              accrualConvention, accrualConvention, DateGeneration.Rule.Backward, false);

                  FixedRateBond bond = new FixedRateBond(settlementDays, vars.faceAmount, sch, new List<double>() { coupons[k] },
                                                         bondDayCount, paymentConvention, redemption, issue);

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

                  for (int m = 0; m < yields.Length; m++)
                  {

                     rate.setValue(yields[m]);

                     double price = bond.cleanPrice(yields[m], bondDayCount, Compounding.Continuous, frequencies[l]);
                     double calculatedPrice = bond.cleanPrice();

                     if (Math.Abs(price - calculatedPrice) > tolerance)
                     {
                        Assert.Fail("price calculation failed:"
                            + "\n    issue:     " + issue
                            + "\n    maturity:  " + maturity
                            + "\n    coupon:    " + coupons[k]
                            + "\n    frequency: " + frequencies[l] + "\n"
                            + "\n    yield:     " + yields[m]
                            + "\n    expected:    " + price
                            + "\n    calculated': " + calculatedPrice
                            + "\n    error':      " + (price - calculatedPrice));
                     }

                     double calculatedYield = bond.yield(bondDayCount, Compounding.Continuous, frequencies[l],
                                              tolerance, maxEvaluations);
                     if (Math.Abs(yields[m] - calculatedYield) > tolerance)
                     {
                        Assert.Fail("yield calculation failed:"
                            + "\n    issue:     " + issue
                            + "\n    maturity:  " + maturity
                            + "\n    coupon:    " + coupons[k]
                            + "\n    frequency: " + frequencies[l] + "\n"
                            + "\n    yield:  " + yields[m]
                            + "\n    price:  " + price
                            + "\n    yield': " + calculatedYield);
                     }
                  }
               }
            }
             }
        }
Exemple #15
0
        public void testMarketASWSpread()
        {
            // Testing relationship between market asset swap and par asset swap...
             CommonVars vars = new CommonVars();

             Calendar bondCalendar = new TARGET();
             int settlementDays = 3;
             int fixingDays = 2;
             bool payFixedRate = true;
             bool parAssetSwap = true;
             bool mktAssetSwap = false;
             bool inArrears = false;

             // Fixed Underlying bond (Isin: DE0001135275 DBR 4 01/04/37)
             // maturity doesn't occur on a business day

             Schedule fixedBondSchedule1 = new Schedule(new Date(4,Month.January,2005),
                                    new Date(4,Month.January,2037),
                                    new Period(Frequency.Annual), bondCalendar,
                                    BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                    DateGeneration.Rule.Backward, false);
             Bond fixedBond1 = new FixedRateBond(settlementDays, vars.faceAmount, fixedBondSchedule1,
                           new List<double>{0.04},
                           new ActualActual(ActualActual.Convention.ISDA),BusinessDayConvention.Following,
                           100.0, new Date(4,Month.January,2005));

             IPricingEngine bondEngine = new DiscountingBondEngine(vars.termStructure);
             IPricingEngine swapEngine = new DiscountingSwapEngine(vars.termStructure);
             fixedBond1.setPricingEngine(bondEngine);

             double fixedBondMktPrice1 = 89.22 ; // market price observed on 7th June 2007
             double fixedBondMktFullPrice1=fixedBondMktPrice1+fixedBond1.accruedAmount();
             AssetSwap fixedBondParAssetSwap1 = new AssetSwap(payFixedRate,
                                          fixedBond1, fixedBondMktPrice1,
                                          vars.iborIndex, vars.spread,
                                          null,
                                          vars.iborIndex.dayCounter(),
                                          parAssetSwap);
             fixedBondParAssetSwap1.setPricingEngine(swapEngine);
             double fixedBondParAssetSwapSpread1 = fixedBondParAssetSwap1.fairSpread();
             AssetSwap fixedBondMktAssetSwap1 = new AssetSwap(payFixedRate,
                                          fixedBond1, fixedBondMktPrice1,
                                          vars.iborIndex, vars.spread,
                                          null,
                                          vars.iborIndex.dayCounter(),
                                          mktAssetSwap);
             fixedBondMktAssetSwap1.setPricingEngine(swapEngine);
             double fixedBondMktAssetSwapSpread1 = fixedBondMktAssetSwap1.fairSpread();

             double tolerance = 1.0e-13;
             double error1 = Math.Abs(fixedBondMktAssetSwapSpread1- 100*fixedBondParAssetSwapSpread1/fixedBondMktFullPrice1);

             if (error1>tolerance) {
            Assert.Fail("wrong asset swap spreads for fixed bond:" +
                        "\n  market ASW spread: " + fixedBondMktAssetSwapSpread1 +
                        "\n  par ASW spread:    " + fixedBondParAssetSwapSpread1 +
                        "\n  error:             " + error1 +
                        "\n  tolerance:         " + tolerance);
             }

             // Fixed Underlying bond (Isin: IT0006527060 IBRD 5 02/05/19)
             // maturity occurs on a business day

             Schedule fixedBondSchedule2 = new Schedule(new Date(5,Month.February,2005),
                                    new Date(5,Month.February,2019),
                                    new Period(Frequency.Annual), bondCalendar,
                                    BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                    DateGeneration.Rule.Backward, false);
             Bond fixedBond2 = new FixedRateBond(settlementDays, vars.faceAmount, fixedBondSchedule2,
                           new List<double>{ 0.05},
                           new Thirty360(Thirty360.Thirty360Convention.BondBasis), BusinessDayConvention.Following,
                           100.0, new Date(5,Month.February,2005));

             fixedBond2.setPricingEngine(bondEngine);

             double fixedBondMktPrice2 = 99.98 ; // market price observed on 7th June 2007
             double fixedBondMktFullPrice2=fixedBondMktPrice2+fixedBond2.accruedAmount();
             AssetSwap fixedBondParAssetSwap2 = new AssetSwap(payFixedRate,
                                          fixedBond2, fixedBondMktPrice2,
                                          vars.iborIndex, vars.spread,
                                          null,
                                          vars.iborIndex.dayCounter(),
                                          parAssetSwap);
             fixedBondParAssetSwap2.setPricingEngine(swapEngine);
             double fixedBondParAssetSwapSpread2 = fixedBondParAssetSwap2.fairSpread();
             AssetSwap fixedBondMktAssetSwap2 = new AssetSwap(payFixedRate,
                                          fixedBond2, fixedBondMktPrice2,
                                          vars.iborIndex, vars.spread,
                                          null,
                                          vars.iborIndex.dayCounter(),
                                          mktAssetSwap);
             fixedBondMktAssetSwap2.setPricingEngine(swapEngine);
             double fixedBondMktAssetSwapSpread2 = fixedBondMktAssetSwap2.fairSpread();
             double error2 = Math.Abs(fixedBondMktAssetSwapSpread2-
                     100*fixedBondParAssetSwapSpread2/fixedBondMktFullPrice2);

             if (error2>tolerance) {
            Assert.Fail("wrong asset swap spreads for fixed bond:" +
                        "\n  market ASW spread: " + fixedBondMktAssetSwapSpread2 +
                        "\n  par ASW spread:    " + fixedBondParAssetSwapSpread2 +
                        "\n  error:             " + error2 +
                        "\n  tolerance:         " + tolerance);
             }

             // FRN Underlying bond (Isin: IT0003543847 ISPIM 0 09/29/13)
             // maturity doesn't occur on a business day

             Schedule floatingBondSchedule1 = new Schedule( new Date(29,Month.September,2003),
                                       new Date(29,Month.September,2013),
                                       new Period(Frequency.Semiannual), bondCalendar,
                                       BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                       DateGeneration.Rule.Backward, false);

             Bond floatingBond1 = new FloatingRateBond(settlementDays, vars.faceAmount,
                              floatingBondSchedule1,
                              vars.iborIndex, new Actual360(),
                              BusinessDayConvention.Following, fixingDays,
                              new List<double>{1}, new List<double>{0.0056},
                              new List<double>(), new List<double>(),
                              inArrears,
                              100.0, new Date(29,Month.September,2003));

             floatingBond1.setPricingEngine(bondEngine);

             Utils.setCouponPricer(floatingBond1.cashflows(), vars.pricer);
             vars.iborIndex.addFixing(new Date(27,Month.March,2007), 0.0402);
             // market price observed on 7th June 2007
             double floatingBondMktPrice1 = 101.64 ;
             double floatingBondMktFullPrice1 = floatingBondMktPrice1+floatingBond1.accruedAmount();
             AssetSwap floatingBondParAssetSwap1 = new AssetSwap(payFixedRate,
                                             floatingBond1, floatingBondMktPrice1,
                                             vars.iborIndex, vars.spread,
                                             null,
                                             vars.iborIndex.dayCounter(),
                                             parAssetSwap);
             floatingBondParAssetSwap1.setPricingEngine(swapEngine);
             double floatingBondParAssetSwapSpread1 = floatingBondParAssetSwap1.fairSpread();
             AssetSwap floatingBondMktAssetSwap1= new AssetSwap(payFixedRate,
                                             floatingBond1, floatingBondMktPrice1,
                                             vars.iborIndex, vars.spread,
                                             null,
                                             vars.iborIndex.dayCounter(),
                                             mktAssetSwap);
             floatingBondMktAssetSwap1.setPricingEngine(swapEngine);
             double floatingBondMktAssetSwapSpread1 = floatingBondMktAssetSwap1.fairSpread();
             double error3 = Math.Abs(floatingBondMktAssetSwapSpread1-
                     100*floatingBondParAssetSwapSpread1/floatingBondMktFullPrice1);

             if (error3>tolerance) {
            Assert.Fail("wrong asset swap spreads for floating bond:" +
                        "\n  market ASW spread: " + floatingBondMktAssetSwapSpread1 +
                        "\n  par ASW spread:    " + floatingBondParAssetSwapSpread1 +
                        "\n  error:             " + error3 +
                        "\n  tolerance:         " + tolerance);
             }

             // FRN Underlying bond (Isin: XS0090566539 COE 0 09/24/18)
             // maturity occurs on a business day

             Schedule floatingBondSchedule2 = new Schedule( new Date(24,Month.September,2004),
                                       new Date(24,Month.September,2018),
                                       new Period(Frequency.Semiannual), bondCalendar,
                                       BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing,
                                       DateGeneration.Rule.Backward, false);
             Bond floatingBond2 = new FloatingRateBond(settlementDays, vars.faceAmount,
                              floatingBondSchedule2,
                              vars.iborIndex, new Actual360(),
                              BusinessDayConvention.ModifiedFollowing, fixingDays,
                              new List<double>{1}, new List<double>{0.0025},
                              new List<double>(), new List<double>(),
                              inArrears,
                              100.0, new Date(24,Month.September,2004));

             floatingBond2.setPricingEngine(bondEngine);

             Utils.setCouponPricer(floatingBond2.cashflows(), vars.pricer);
             vars.iborIndex.addFixing(new Date(22,Month.March,2007), 0.04013);
             // market price observed on 7th June 2007
             double floatingBondMktPrice2 = 101.248 ;
             double floatingBondMktFullPrice2 = floatingBondMktPrice2+floatingBond2.accruedAmount();
             AssetSwap floatingBondParAssetSwap2= new AssetSwap(payFixedRate,
                                             floatingBond2, floatingBondMktPrice2,
                                             vars.iborIndex, vars.spread,
                                             null,
                                             vars.iborIndex.dayCounter(),
                                             parAssetSwap);
             floatingBondParAssetSwap2.setPricingEngine(swapEngine);
             double floatingBondParAssetSwapSpread2 = floatingBondParAssetSwap2.fairSpread();
             AssetSwap floatingBondMktAssetSwap2 = new AssetSwap(payFixedRate,
                                             floatingBond2, floatingBondMktPrice2,
                                             vars.iborIndex, vars.spread,
                                             null,
                                             vars.iborIndex.dayCounter(),
                                             mktAssetSwap);
             floatingBondMktAssetSwap2.setPricingEngine(swapEngine);
             double floatingBondMktAssetSwapSpread2 = floatingBondMktAssetSwap2.fairSpread();
             double error4 = Math.Abs(floatingBondMktAssetSwapSpread2-
                     100*floatingBondParAssetSwapSpread2/floatingBondMktFullPrice2);

             if (error4>tolerance) {
            Assert.Fail("wrong asset swap spreads for floating bond:" +
                        "\n  market ASW spread: " + floatingBondMktAssetSwapSpread2 +
                        "\n  par ASW spread:    " + floatingBondParAssetSwapSpread2 +
                        "\n  error:             " + error4 +
                        "\n  tolerance:         " + tolerance);
             }

             // CMS Underlying bond (Isin: XS0228052402 CRDIT 0 8/22/20)
             // maturity doesn't occur on a business day

             Schedule cmsBondSchedule1 = new Schedule( new Date(22,Month.August,2005),
                                 new Date(22,Month.August,2020),
                                 new Period(Frequency.Annual), bondCalendar,
                                 BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                 DateGeneration.Rule.Backward, false);
             Bond cmsBond1 = new CmsRateBond(settlementDays, vars.faceAmount, cmsBondSchedule1,
                        vars.swapIndex, new Thirty360(),
                        BusinessDayConvention.Following, fixingDays,
                        new List<double>{1.0}, new List<double>{0.0},
                        new List<double>{0.055}, new List<double>{0.025},
                        inArrears,
                        100.0, new Date(22,Month.August,2005));

             cmsBond1.setPricingEngine(bondEngine);

             Utils.setCouponPricer(cmsBond1.cashflows(), vars.cmspricer);
             vars.swapIndex.addFixing(new Date(18,Month.August,2006), 0.04158);
             double cmsBondMktPrice1 = 88.45 ; // market price observed on 7th June 2007
             double cmsBondMktFullPrice1 = cmsBondMktPrice1+cmsBond1.accruedAmount();
             AssetSwap cmsBondParAssetSwap1 = new AssetSwap(payFixedRate,
                                       cmsBond1, cmsBondMktPrice1,
                                       vars.iborIndex, vars.spread,
                                       null,
                                       vars.iborIndex.dayCounter(),
                                       parAssetSwap);
             cmsBondParAssetSwap1.setPricingEngine(swapEngine);
             double cmsBondParAssetSwapSpread1 = cmsBondParAssetSwap1.fairSpread();
             AssetSwap cmsBondMktAssetSwap1 = new AssetSwap(payFixedRate,
                                       cmsBond1, cmsBondMktPrice1,
                                       vars.iborIndex, vars.spread,
                                       null,
                                       vars.iborIndex.dayCounter(),
                                       mktAssetSwap);
             cmsBondMktAssetSwap1.setPricingEngine(swapEngine);
             double cmsBondMktAssetSwapSpread1 = cmsBondMktAssetSwap1.fairSpread();
             double error5 = Math.Abs(cmsBondMktAssetSwapSpread1-
                     100*cmsBondParAssetSwapSpread1/cmsBondMktFullPrice1);

             if (error5>tolerance) {
            Assert.Fail("wrong asset swap spreads for cms bond:" +
                        "\n  market ASW spread: " + cmsBondMktAssetSwapSpread1 +
                        "\n  par ASW spread:    " + cmsBondParAssetSwapSpread1 +
                        "\n  error:             " + error5 +
                        "\n  tolerance:         " + tolerance);
             }

             // CMS Underlying bond (Isin: XS0218766664 ISPIM 0 5/6/15)
             // maturity occurs on a business day

             Schedule cmsBondSchedule2 = new Schedule(new Date(06,Month.May,2005),
                                 new Date(06,Month.May,2015),
                                 new Period(Frequency.Annual), bondCalendar,
                                 BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted,
                                 DateGeneration.Rule.Backward, false);
             Bond cmsBond2 = new CmsRateBond(settlementDays, vars.faceAmount, cmsBondSchedule2,
                        vars.swapIndex, new Thirty360(),
                        BusinessDayConvention.Following, fixingDays,
                        new List<double>{0.84}, new List<double>{0.0},
                        new List<double>(), new List<double>(),
                        inArrears,
                        100.0, new Date(06,Month.May,2005));

             cmsBond2.setPricingEngine(bondEngine);

             Utils.setCouponPricer(cmsBond2.cashflows(), vars.cmspricer);
             vars.swapIndex.addFixing(new Date(04,Month.May,2006), 0.04217);
             double cmsBondMktPrice2 = 94.08 ; // market price observed on 7th June 2007
             double cmsBondMktFullPrice2 = cmsBondMktPrice2+cmsBond2.accruedAmount();
             AssetSwap cmsBondParAssetSwap2 = new AssetSwap(payFixedRate,
                                       cmsBond2, cmsBondMktPrice2,
                                       vars.iborIndex, vars.spread,
                                       null,
                                       vars.iborIndex.dayCounter(),
                                       parAssetSwap);
             cmsBondParAssetSwap2.setPricingEngine(swapEngine);
             double cmsBondParAssetSwapSpread2 = cmsBondParAssetSwap2.fairSpread();
             AssetSwap cmsBondMktAssetSwap2 = new AssetSwap(payFixedRate,
                                       cmsBond2, cmsBondMktPrice2,
                                       vars.iborIndex, vars.spread,
                                       null,
                                       vars.iborIndex.dayCounter(),
                                       mktAssetSwap);
             cmsBondMktAssetSwap2.setPricingEngine(swapEngine);
             double cmsBondMktAssetSwapSpread2 = cmsBondMktAssetSwap2.fairSpread();
             double error6 = Math.Abs(cmsBondMktAssetSwapSpread2-
                     100*cmsBondParAssetSwapSpread2/cmsBondMktFullPrice2);

             if (error6>tolerance) {
            Assert.Fail("wrong asset swap spreads for cms bond:" +
                        "\n  market ASW spread: " + cmsBondMktAssetSwapSpread2 +
                        "\n  par ASW spread:    " + cmsBondParAssetSwapSpread2 +
                        "\n  error:             " + error6 +
                        "\n  tolerance:         " + tolerance);
             }

             // Zero Coupon bond (Isin: DE0004771662 IBRD 0 12/20/15)
             // maturity doesn't occur on a business day

             Bond zeroCpnBond1 = new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount,
                          new  Date(20,Month.December,2015), BusinessDayConvention.Following,
                           100.0, new Date(19,Month.December,1985));

             zeroCpnBond1.setPricingEngine(bondEngine);

             // market price observed on 12th June 2007
             double zeroCpnBondMktPrice1 = 70.436 ;
             double zeroCpnBondMktFullPrice1 = zeroCpnBondMktPrice1+zeroCpnBond1.accruedAmount();
             AssetSwap zeroCpnBondParAssetSwap1 = new AssetSwap(payFixedRate,zeroCpnBond1,
                                          zeroCpnBondMktPrice1,
                                          vars.iborIndex, vars.spread,
                                          null,
                                          vars.iborIndex.dayCounter(),
                                          parAssetSwap);
             zeroCpnBondParAssetSwap1.setPricingEngine(swapEngine);
             double zeroCpnBondParAssetSwapSpread1 = zeroCpnBondParAssetSwap1.fairSpread();
             AssetSwap zeroCpnBondMktAssetSwap1 = new AssetSwap(payFixedRate,zeroCpnBond1,
                                          zeroCpnBondMktPrice1,
                                          vars.iborIndex, vars.spread,
                                          null,
                                          vars.iborIndex.dayCounter(),
                                          mktAssetSwap);
             zeroCpnBondMktAssetSwap1.setPricingEngine(swapEngine);
             double zeroCpnBondMktAssetSwapSpread1 = zeroCpnBondMktAssetSwap1.fairSpread();
             double error7 = Math.Abs(zeroCpnBondMktAssetSwapSpread1-
                     100*zeroCpnBondParAssetSwapSpread1/zeroCpnBondMktFullPrice1);

             if (error7>tolerance) {
            Assert.Fail("wrong asset swap spreads for zero cpn bond:" +
                        "\n  market ASW spread: " + zeroCpnBondMktAssetSwapSpread1 +
                        "\n  par ASW spread:    " + zeroCpnBondParAssetSwapSpread1 +
                        "\n  error:             " + error7 +
                        "\n  tolerance:         " + tolerance);
             }

             // Zero Coupon bond (Isin: IT0001200390 ISPIM 0 02/17/28)
             // maturity occurs on a business day

             Bond zeroCpnBond2 = new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount,
                           new Date(17,Month.February,2028),
                           BusinessDayConvention.Following,
                           100.0, new Date(17,Month.February,1998));

             zeroCpnBond2.setPricingEngine(bondEngine);

             // Real zeroCpnBondPrice2 = zeroCpnBond2->cleanPrice();

             // market price observed on 12th June 2007
             double zeroCpnBondMktPrice2 = 35.160 ;
             double zeroCpnBondMktFullPrice2 = zeroCpnBondMktPrice2+zeroCpnBond2.accruedAmount();
             AssetSwap zeroCpnBondParAssetSwap2 = new AssetSwap(payFixedRate,zeroCpnBond2,
                                          zeroCpnBondMktPrice2,
                                          vars.iborIndex, vars.spread,
                                          null,
                                          vars.iborIndex.dayCounter(),
                                          parAssetSwap);
             zeroCpnBondParAssetSwap2.setPricingEngine(swapEngine);
             double zeroCpnBondParAssetSwapSpread2 = zeroCpnBondParAssetSwap2.fairSpread();
             AssetSwap zeroCpnBondMktAssetSwap2 = new AssetSwap(payFixedRate,zeroCpnBond2,
                                          zeroCpnBondMktPrice2,
                                          vars.iborIndex, vars.spread,
                                          null,
                                          vars.iborIndex.dayCounter(),
                                          mktAssetSwap);
             zeroCpnBondMktAssetSwap2.setPricingEngine(swapEngine);
             double zeroCpnBondMktAssetSwapSpread2 = zeroCpnBondMktAssetSwap2.fairSpread();
             double error8 = Math.Abs(zeroCpnBondMktAssetSwapSpread2-
                     100*zeroCpnBondParAssetSwapSpread2/zeroCpnBondMktFullPrice2);

             if (error8>tolerance) {
            Assert.Fail("wrong asset swap spreads for zero cpn bond:" +
                        "\n  market ASW spread: " + zeroCpnBondMktAssetSwapSpread2 +
                        "\n  par ASW spread:    " + zeroCpnBondParAssetSwapSpread2 +
                        "\n  error:             " + error8 +
                        "\n  tolerance:         " + tolerance);
             }
        }
        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();
        }
Exemple #17
0
        public void testCachedFloating()
        {
            // "Testing floating-rate bond prices against cached values...");

             CommonVars vars = new CommonVars();

             Date today = new Date(22, Month.November, 2004);
             Settings.setEvaluationDate(today);

             int settlementDays = 1;

             var riskFreeRate = new Handle<YieldTermStructure>(Utilities.flatRate(today, 0.025, new Actual360()));
             var discountCurve = new Handle<YieldTermStructure>(Utilities.flatRate(today, 0.03, new Actual360()));

             IborIndex index = new USDLibor(new Period(6, TimeUnit.Months), riskFreeRate);
             int fixingDays = 1;

             double tolerance = 1.0e-6;

             IborCouponPricer pricer = new BlackIborCouponPricer(new Handle<OptionletVolatilityStructure>());

             // plain
             Schedule sch = new Schedule(new Date(30, Month.November, 2004), new Date(30, Month.November, 2008),
                                     new Period(Frequency.Semiannual), new UnitedStates(UnitedStates.Market.GovernmentBond),
                                     BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing,
                                     DateGeneration.Rule.Backward, false);

             FloatingRateBond bond1 = new FloatingRateBond(settlementDays, vars.faceAmount, sch,
                                index, new ActualActual(ActualActual.Convention.ISMA),
                                BusinessDayConvention.ModifiedFollowing, fixingDays,
                                new List<double>(), new List<double>(),
                                new List<double>(), new List<double>(),
                                false,
                                100.0, new Date(30, Month.November, 2004));

             IPricingEngine bondEngine = new DiscountingBondEngine(riskFreeRate);
             bond1.setPricingEngine(bondEngine);

             Utils.setCouponPricer(bond1.cashflows(), pricer);

            #if QL_USE_INDEXED_COUPON
            double cachedPrice1 = 99.874645;
            #else
             double cachedPrice1 = 99.874646;
            #endif

             double price = bond1.cleanPrice();
             if (Math.Abs(price - cachedPrice1) > tolerance)
             {
            Assert.Fail("failed to reproduce cached price:\n"
                       + "    calculated: " + price + "\n"
                       + "    expected:   " + cachedPrice1 + "\n"
                       + "    error:      " + (price - cachedPrice1));
             }

             // different risk-free and discount curve
             FloatingRateBond bond2 = new FloatingRateBond(settlementDays, vars.faceAmount, sch,
                                index, new ActualActual(ActualActual.Convention.ISMA),
                                BusinessDayConvention.ModifiedFollowing, fixingDays,
                                new List<double>(), new List<double>(),
                                new List<double>(), new List<double>(),
                                false,
                                100.0, new Date(30, Month.November, 2004));

             IPricingEngine bondEngine2 = new DiscountingBondEngine(discountCurve);
             bond2.setPricingEngine(bondEngine2);

             Utils.setCouponPricer(bond2.cashflows(), pricer);

            #if QL_USE_INDEXED_COUPON
            double cachedPrice2 = 97.955904;
            #else
             double cachedPrice2 = 97.955904;
            #endif

             price = bond2.cleanPrice();
             if (Math.Abs(price - cachedPrice2) > tolerance)
             {
            Assert.Fail("failed to reproduce cached price:\n"
                       + "    calculated: " + price + "\n"
                       + "    expected:   " + cachedPrice2 + "\n"
                       + "    error:      " + (price - cachedPrice2));
             }

             // varying spread
             InitializedList<double> spreads = new InitializedList<double>(4);
             spreads[0] = 0.001;
             spreads[1] = 0.0012;
             spreads[2] = 0.0014;
             spreads[3] = 0.0016;

             FloatingRateBond bond3 = new FloatingRateBond(settlementDays, vars.faceAmount, sch,
                                index, new ActualActual(ActualActual.Convention.ISMA),
                                BusinessDayConvention.ModifiedFollowing, fixingDays,
                                new List<double>(), spreads,
                                new List<double>(), new List<double>(),
                                false,
                                100.0, new Date(30, Month.November, 2004));

             bond3.setPricingEngine(bondEngine2);

             Utils.setCouponPricer(bond3.cashflows(), pricer);

            #if QL_USE_INDEXED_COUPON
            double cachedPrice3 = 98.495458;
            #else
             double cachedPrice3 = 98.495459;
            #endif

             price = bond3.cleanPrice();
             if (Math.Abs(price - cachedPrice3) > tolerance)
             {
            Assert.Fail("failed to reproduce cached price:\n"
                       + "    calculated: " + price + "\n"
                       + "    expected:   " + cachedPrice3 + "\n"
                       + "    error:      " + (price - cachedPrice3));
             }
        }