//public FixedRateBondHelper(Quote cleanPrice, int settlementDays, double faceAmount, Schedule schedule, // List<double> coupons, DayCounter dayCounter, // BusinessDayConvention paymentConv = Following, // double redemption = 100.0, // Date issueDate = null); public FixedRateBondHelper(Handle <Quote> cleanPrice, int settlementDays, double faceAmount, Schedule schedule, List <double> coupons, DayCounter dayCounter, BusinessDayConvention paymentConvention, double redemption, Date issueDate) : base(cleanPrice, new FixedRateBond(settlementDays, faceAmount, schedule, coupons, dayCounter, paymentConvention, redemption, issueDate)) { fixedRateBond_ = bond_ as FixedRateBond; }
//! \name Constructors /*! If strike is given in the constructor, can calculate the NPV of the contract via NPV(). If strike/forward price is desired, it can be obtained via forwardPrice(). In this case, the strike variable in the constructor is irrelevant and will be ignored. */ //@{ //Handle<YieldTermStructure> discountCurve = Handle<YieldTermStructure>(), //Handle<YieldTermStructure> incomeDiscountCurve = Handle<YieldTermStructure>()); public FixedRateBondForward(Date valueDate, Date maturityDate, Position.Type type, double strike, int settlementDays, DayCounter dayCounter, Calendar calendar, BusinessDayConvention businessDayConvention, FixedRateBond fixedCouponBond, Handle<YieldTermStructure> discountCurve, Handle<YieldTermStructure> incomeDiscountCurve) : base(dayCounter, calendar, businessDayConvention, settlementDays, new ForwardTypePayoff(type, strike), valueDate, maturityDate, discountCurve) { fixedCouponBond_ = fixedCouponBond; incomeDiscountCurve_ = incomeDiscountCurve; incomeDiscountCurve_.registerWith(update); }
//! \name Constructors /*! If strike is given in the constructor, can calculate the * NPV of the contract via NPV(). * * If strike/forward price is desired, it can be obtained via * forwardPrice(). In this case, the strike variable in the * constructor is irrelevant and will be ignored. */ //@{ //Handle<YieldTermStructure> discountCurve = Handle<YieldTermStructure>(), //Handle<YieldTermStructure> incomeDiscountCurve = Handle<YieldTermStructure>()); public FixedRateBondForward(Date valueDate, Date maturityDate, Position.Type type, double strike, int settlementDays, DayCounter dayCounter, Calendar calendar, BusinessDayConvention businessDayConvention, FixedRateBond fixedCouponBond, Handle <YieldTermStructure> discountCurve, Handle <YieldTermStructure> incomeDiscountCurve) : base(dayCounter, calendar, businessDayConvention, settlementDays, new ForwardTypePayoff(type, strike), valueDate, maturityDate, discountCurve) { fixedCouponBond_ = fixedCouponBond; incomeDiscountCurve_ = incomeDiscountCurve; incomeDiscountCurve_.registerWith(update); }
//public FixedRateBondHelper(Quote cleanPrice, int settlementDays, double faceAmount, Schedule schedule, // List<double> coupons, DayCounter dayCounter, // BusinessDayConvention paymentConv = Following, // double redemption = 100.0, // Date issueDate = null); public FixedRateBondHelper(Handle <Quote> price, int settlementDays, double faceAmount, Schedule schedule, List <double> coupons, DayCounter dayCounter, BusinessDayConvention paymentConvention, double redemption, Date issueDate, Calendar paymentCalendar = null, Period exCouponPeriod = null, Calendar exCouponCalendar = null, BusinessDayConvention exCouponConvention = BusinessDayConvention.Unadjusted, bool exCouponEndOfMonth = false, bool useCleanPrice = true) : base(price, new FixedRateBond(settlementDays, faceAmount, schedule, coupons, dayCounter, paymentConvention, redemption, issueDate, paymentCalendar, exCouponPeriod, exCouponCalendar, exCouponConvention, exCouponEndOfMonth), useCleanPrice) { fixedRateBond_ = bond_ as FixedRateBond; }
public override void Update() { var faceValue = GetInputNode<double>("FaceValue"); var couponRate = GetInputNode<double>("CouponRate"); var schedule = GetInputNode<Schedule>("Schedule"); var issueDate = schedule.dates()[0]; Value = new FixedRateBond( QLHelpers.SettlementDays, faceValue, schedule, new List<double> { couponRate }, QLHelpers.DayCounter, BusinessDayConvention.Following, 100.0, issueDate); }
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); } }
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)); } }
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)); } }
public void testBrazilianCached() { //("Testing Brazilian public bond prices against cached values..."); CommonVars vars = new CommonVars(); double faceAmount = 1000.0; double redemption = 100.0; Date issueDate = new Date(1, Month.January, 2007); Date today = new Date(6, Month.June, 2007); Settings.setEvaluationDate(today); // NTN-F maturity dates InitializedList<Date> maturityDates = new InitializedList<Date>(6); maturityDates[0] = new Date(1, Month.January, 2008); maturityDates[1] = new Date(1, Month.January, 2010); maturityDates[2] = new Date(1, Month.July, 2010); maturityDates[3] = new Date(1, Month.January, 2012); maturityDates[4] = new Date(1, Month.January, 2014); maturityDates[5] = new Date(1, Month.January, 2017); // NTN-F yields InitializedList<double> yields = new InitializedList<double>(6); yields[0] = 0.114614; yields[1] = 0.105726; yields[2] = 0.105328; yields[3] = 0.104283; yields[4] = 0.103218; yields[5] = 0.102948; // NTN-F prices InitializedList<double> prices = new InitializedList<double>(6); prices[0] = 1034.63031372; prices[1] = 1030.09919487; prices[2] = 1029.98307160; prices[3] = 1028.13585068; prices[4] = 1028.33383817; prices[5] = 1026.19716497; int settlementDays = 1; vars.faceAmount = 1000.0; // The tolerance is high because Andima truncate yields double tolerance = 1.0e-4; InitializedList<InterestRate> couponRates = new InitializedList<InterestRate>(1); couponRates[0] = new InterestRate(0.1, new Thirty360(), Compounding.Compounded, Frequency.Annual); for (int bondIndex = 0; bondIndex < maturityDates.Count; bondIndex++) { // plain InterestRate yield = new InterestRate(yields[bondIndex], new Business252(new Brazil()), Compounding.Compounded, Frequency.Annual); Schedule schedule = new Schedule(new Date(1, Month.January, 2007), maturityDates[bondIndex], new Period(Frequency.Semiannual), new Brazil(Brazil.Market.Settlement), BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); FixedRateBond bond = new FixedRateBond(settlementDays, faceAmount, schedule, couponRates, BusinessDayConvention.Following, redemption, issueDate); double cachedPrice = prices[bondIndex]; double price = vars.faceAmount * (bond.cleanPrice(yield.rate(), yield.dayCounter(), yield.compounding(), yield.frequency(), today) + bond.accruedAmount(today)) / 100; if (Math.Abs(price - cachedPrice) > tolerance) { Assert.Fail("failed to reproduce cached price:\n" + " calculated: " + price + "\n" + " expected: " + cachedPrice + "\n" + " error: " + (price - cachedPrice) + "\n" ); } } }
protected override void performCalculations() { List<BTP> btps = basket_.btps(); List<Handle<Quote> > quotes = basket_.cleanPriceQuotes(); Date bondSettlementDate = btps[0].settlementDate(); for (int i=0; i<basket_.size(); ++i) { yields_[i] = BondFunctions.yield(btps[i], quotes[i].link.value(), new ActualActual(ActualActual.Convention.ISMA), Compounding.Compounded, Frequency.Annual, bondSettlementDate, // accuracy, maxIterations, guess 1.0e-10, 100, yields_[i]); durations_[i] = BondFunctions.duration(btps[i], yields_[i],new ActualActual(ActualActual.Convention.ISMA), Compounding.Compounded, Frequency.Annual,Duration.Type.Modified, bondSettlementDate); } duration_ = 0; basket_.weights().ForEach((ii, vv) => duration_ += vv * yields()[ii]); //duration_ = std::inner_product(basket_->weights().begin(), // basket_->weights().end(), // durations_.begin(), 0.0); int settlDays = 3; DayCounter fixedDayCount = swaps_[0].fixedDayCount(); equivalentSwapIndex_ = nSwaps_-1; swapRates_[0]= swaps_[0].fairRate(); FixedRateBond swapBond = new FixedRateBond(settlDays, 100.0, // faceAmount swaps_[0].fixedSchedule(), new List<double>() { swapRates_[0].Value }, fixedDayCount, BusinessDayConvention.Following, // paymentConvention 100.0); // redemption swapBondYields_[0] = BondFunctions.yield(swapBond, 100.0, // floating leg NPV including end payment new ActualActual(ActualActual.Convention.ISMA), Compounding.Compounded, Frequency.Annual, bondSettlementDate, // accuracy, maxIterations, guess 1.0e-10, 100, swapBondYields_[0].Value); swapBondDurations_[0] = BondFunctions.duration(swapBond, swapBondYields_[0].Value, new ActualActual(ActualActual.Convention.ISMA), Compounding.Compounded, Frequency.Annual, Duration.Type.Modified, bondSettlementDate); for (int i=1; i<nSwaps_; ++i) { swapRates_[i]= swaps_[i].fairRate(); FixedRateBond swapBond2 = new FixedRateBond(settlDays, 100.0, // faceAmount swaps_[i].fixedSchedule(), new List<double>(){swapRates_[i].Value}, fixedDayCount, BusinessDayConvention.Following, // paymentConvention 100.0); // redemption swapBondYields_[i] = BondFunctions.yield(swapBond2, 100.0, // floating leg NPV including end payment new ActualActual(ActualActual.Convention.ISMA), Compounding.Compounded, Frequency.Annual, bondSettlementDate, // accuracy, maxIterations, guess 1.0e-10, 100, swapBondYields_[i].Value); swapBondDurations_[i] = BondFunctions.duration(swapBond2, swapBondYields_[i].Value, new ActualActual(ActualActual.Convention.ISMA), Compounding.Compounded, Frequency.Annual, Duration.Type.Modified, bondSettlementDate); if (swapBondDurations_[i] > duration_) { equivalentSwapIndex_ = i-1; break; // exit the loop } } return; }
protected override void performCalculations() { List <BTP> btps = basket_.btps(); List <Handle <Quote> > quotes = basket_.cleanPriceQuotes(); Date bondSettlementDate = btps[0].settlementDate(); for (int i = 0; i < basket_.size(); ++i) { yields_[i] = BondFunctions.yield(btps[i], quotes[i].link.value(), new ActualActual(ActualActual.Convention.ISMA), Compounding.Compounded, Frequency.Annual, bondSettlementDate, // accuracy, maxIterations, guess 1.0e-10, 100, yields_[i]); durations_[i] = BondFunctions.duration(btps[i], yields_[i], new ActualActual(ActualActual.Convention.ISMA), Compounding.Compounded, Frequency.Annual, Duration.Type.Modified, bondSettlementDate); } duration_ = 0; basket_.weights().ForEach((ii, vv) => duration_ += vv * yields()[ii]); int settlDays = 2; DayCounter fixedDayCount = swaps_[0].fixedDayCount(); equivalentSwapIndex_ = nSwaps_ - 1; swapRates_[0] = swaps_[0].fairRate(); FixedRateBond swapBond = new FixedRateBond(settlDays, 100.0, // faceAmount swaps_[0].fixedSchedule(), new List <double>() { swapRates_[0].Value }, fixedDayCount, BusinessDayConvention.Following, // paymentConvention 100.0); // redemption swapBondYields_[0] = BondFunctions.yield(swapBond, 100.0, // floating leg NPV including end payment new ActualActual(ActualActual.Convention.ISMA), Compounding.Compounded, Frequency.Annual, bondSettlementDate, // accuracy, maxIterations, guess 1.0e-10, 100, swapBondYields_[0].Value); swapBondDurations_[0] = BondFunctions.duration(swapBond, swapBondYields_[0].Value, new ActualActual(ActualActual.Convention.ISMA), Compounding.Compounded, Frequency.Annual, Duration.Type.Modified, bondSettlementDate); for (int i = 1; i < nSwaps_; ++i) { swapRates_[i] = swaps_[i].fairRate(); FixedRateBond swapBond2 = new FixedRateBond(settlDays, 100.0, // faceAmount swaps_[i].fixedSchedule(), new List <double>() { swapRates_[i].Value }, fixedDayCount, BusinessDayConvention.Following, // paymentConvention 100.0); // redemption swapBondYields_[i] = BondFunctions.yield(swapBond2, 100.0, // floating leg NPV including end payment new ActualActual(ActualActual.Convention.ISMA), Compounding.Compounded, Frequency.Annual, bondSettlementDate, // accuracy, maxIterations, guess 1.0e-10, 100, swapBondYields_[i].Value); swapBondDurations_[i] = BondFunctions.duration(swapBond2, swapBondYields_[i].Value, new ActualActual(ActualActual.Convention.ISMA), Compounding.Compounded, Frequency.Annual, Duration.Type.Modified, bondSettlementDate); if (swapBondDurations_[i] > duration_) { equivalentSwapIndex_ = i - 1; break; // exit the loop } } return; }
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); } }
//public FixedRateBondHelper(Quote cleanPrice, int settlementDays, double faceAmount, Schedule schedule, // List<double> coupons, DayCounter dayCounter, // BusinessDayConvention paymentConv = Following, // double redemption = 100.0, // Date issueDate = null); public FixedRateBondHelper(Handle<Quote> price, int settlementDays, double faceAmount, Schedule schedule, List<double> coupons, DayCounter dayCounter, BusinessDayConvention paymentConvention, double redemption, Date issueDate, Calendar paymentCalendar = null, Period exCouponPeriod = null, Calendar exCouponCalendar = null, BusinessDayConvention exCouponConvention = BusinessDayConvention.Unadjusted, bool exCouponEndOfMonth = false, bool useCleanPrice = true) : base(price, new FixedRateBond(settlementDays, faceAmount, schedule, coupons, dayCounter, paymentConvention, redemption, issueDate, paymentCalendar, exCouponPeriod, exCouponCalendar, exCouponConvention, exCouponEndOfMonth), useCleanPrice) { fixedRateBond_ = bond_ as FixedRateBond; }
static void Main(string[] args) { DateTime timer = DateTime.Now; Date repoSettlementDate = new Date(14,Month.February,2000);; Date repoDeliveryDate = new Date(15,Month.August,2000); double repoRate = 0.05; DayCounter repoDayCountConvention = new Actual360(); int repoSettlementDays = 0; Compounding repoCompounding = Compounding.Simple; Frequency repoCompoundFreq = Frequency.Annual; // assume a ten year bond- this is irrelevant Date bondIssueDate = new Date(15,Month.September,1995); Date bondDatedDate = new Date(15,Month.September,1995); Date bondMaturityDate = new Date(15,Month.September,2005); double bondCoupon = 0.08; Frequency bondCouponFrequency = Frequency.Semiannual; // unknown what calendar fincad is using Calendar bondCalendar = new NullCalendar(); DayCounter bondDayCountConvention = new Thirty360(Thirty360.Thirty360Convention.BondBasis); // unknown what fincad is using. this may affect accrued calculation int bondSettlementDays = 0; BusinessDayConvention bondBusinessDayConvention = BusinessDayConvention.Unadjusted; double bondCleanPrice = 89.97693786; double bondRedemption = 100.0; double faceAmount = 100.0; Settings.setEvaluationDate(repoSettlementDate); RelinkableHandle<YieldTermStructure> bondCurve = new RelinkableHandle<YieldTermStructure>(); bondCurve.linkTo(new FlatForward(repoSettlementDate, .01, // dummy rate bondDayCountConvention, Compounding.Compounded, bondCouponFrequency)); /* boost::shared_ptr<FixedRateBond> bond( new FixedRateBond(faceAmount, bondIssueDate, bondDatedDate, bondMaturityDate, bondSettlementDays, std::vector<Rate>(1,bondCoupon), bondCouponFrequency, bondCalendar, bondDayCountConvention, bondBusinessDayConvention, bondBusinessDayConvention, bondRedemption, bondCurve)); */ Schedule bondSchedule = new Schedule(bondDatedDate, bondMaturityDate, new Period(bondCouponFrequency), bondCalendar,bondBusinessDayConvention, bondBusinessDayConvention, DateGeneration.Rule.Backward,false); FixedRateBond bond = new FixedRateBond(bondSettlementDays, faceAmount, bondSchedule, new List<double>() { bondCoupon }, bondDayCountConvention, bondBusinessDayConvention, bondRedemption, bondIssueDate); bond.setPricingEngine(new DiscountingBondEngine(bondCurve)); bondCurve.linkTo(new FlatForward(repoSettlementDate, bond.yield(bondCleanPrice, bondDayCountConvention, Compounding.Compounded, bondCouponFrequency), bondDayCountConvention, Compounding.Compounded, bondCouponFrequency)); Position.Type fwdType = Position.Type.Long; double dummyStrike = 91.5745; RelinkableHandle<YieldTermStructure> repoCurve = new RelinkableHandle<YieldTermStructure>(); repoCurve.linkTo(new FlatForward(repoSettlementDate, repoRate, repoDayCountConvention, repoCompounding, repoCompoundFreq)); FixedRateBondForward bondFwd = new FixedRateBondForward(repoSettlementDate, repoDeliveryDate, fwdType, dummyStrike, repoSettlementDays, repoDayCountConvention, bondCalendar, bondBusinessDayConvention, bond, repoCurve, repoCurve); Console.WriteLine("Underlying bond clean price: " + bond.cleanPrice()); Console.WriteLine("Underlying bond dirty price: " + bond.dirtyPrice()); Console.WriteLine("Underlying bond accrued at settlement: " + bond.accruedAmount(repoSettlementDate)); Console.WriteLine("Underlying bond accrued at delivery: " + bond.accruedAmount(repoDeliveryDate)); Console.WriteLine("Underlying bond spot income: " + bondFwd.spotIncome(repoCurve)); Console.WriteLine("Underlying bond fwd income: " + bondFwd.spotIncome(repoCurve)/ repoCurve.link.discount(repoDeliveryDate)); Console.WriteLine("Repo strike: " + dummyStrike); Console.WriteLine("Repo NPV: " + bondFwd.NPV()); Console.WriteLine("Repo clean forward price: " + bondFwd.cleanForwardPrice()); Console.WriteLine("Repo dirty forward price: " + bondFwd.forwardPrice()); Console.WriteLine("Repo implied yield: " + bondFwd.impliedYield(bond.dirtyPrice(), dummyStrike, repoSettlementDate, repoCompounding, repoDayCountConvention)); Console.WriteLine("Market repo rate: " + repoCurve.link.zeroRate(repoDeliveryDate, repoDayCountConvention, repoCompounding, repoCompoundFreq)); Console.WriteLine("\nCompare with example given at \n" + "http://www.fincad.com/support/developerFunc/mathref/BFWD.htm"); Console.WriteLine("Clean forward price = 88.2408"); Console.WriteLine("\nIn that example, it is unknown what bond calendar they are\n" + "using, as well as settlement Days. For that reason, I have\n" + "made the simplest possible assumptions here: NullCalendar\n" + "and 0 settlement days.\n"); Console.WriteLine("nRun completed in {0}", DateTime.Now - timer); Console.Write("Press any key to continue ..."); Console.ReadKey(); }
public void testZSpread() { // 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 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); fixedBond1.setPricingEngine(bondEngine); double fixedBondImpliedValue1 = fixedBond1.cleanPrice(); Date fixedBondSettlementDate1= fixedBond1.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YC... 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 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 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 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 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 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 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 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 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 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 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 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 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 doesn't occur 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 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); } }
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); } } } } } }
public void testConsistency() { // Testing consistency between fair price and fair spread..."); CommonVars vars = new CommonVars(); Calendar bondCalendar = new TARGET(); int settlementDays = 3; // Fixed Underlying bond (Isin: DE0001135275 DBR 4 01/04/37) // maturity doesn't occur on a business day Schedule bondSchedule = 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 bond = new FixedRateBond(settlementDays, vars.faceAmount, bondSchedule, new List<double>() { 0.04 }, new ActualActual(ActualActual.Convention.ISDA), BusinessDayConvention.Following, 100.0, new Date(4, Month.January, 2005)); bool payFixedRate = true; double bondPrice = 95.0; bool isPar = true; AssetSwap parAssetSwap = new AssetSwap(payFixedRate, bond, bondPrice, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), isPar); IPricingEngine swapEngine = new DiscountingSwapEngine(vars.termStructure, true, bond.settlementDate(), Settings.evaluationDate()); parAssetSwap.setPricingEngine(swapEngine); double fairCleanPrice = parAssetSwap.fairCleanPrice(); double fairSpread = parAssetSwap.fairSpread(); double tolerance = 1.0e-13; AssetSwap assetSwap2 = new AssetSwap(payFixedRate, bond, fairCleanPrice, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), isPar); assetSwap2.setPricingEngine(swapEngine); if (Math.Abs(assetSwap2.NPV()) > tolerance) { Assert.Fail("npar asset swap fair clean price doesn't zero the NPV: " + "\n clean price: " + bondPrice + "\n fair clean price: " + fairCleanPrice + "\n NPV: " + assetSwap2.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap2.fairCleanPrice() - fairCleanPrice) > tolerance) { Assert.Fail("\npar asset swap fair clean price doesn't equal input clean price at zero NPV: " + "\n input clean price: " + fairCleanPrice + "\n fair clean price: " + assetSwap2.fairCleanPrice() + "\n NPV: " + assetSwap2.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap2.fairSpread() - vars.spread) > tolerance) { Assert.Fail("\npar asset swap fair spread doesn't equal input spread at zero NPV: " + "\n input spread: " + vars.spread + "\n fair spread: " + assetSwap2.fairSpread() + "\n NPV: " + assetSwap2.NPV() + "\n tolerance: " + tolerance); } AssetSwap assetSwap3 = new AssetSwap(payFixedRate, bond, bondPrice, vars.iborIndex, fairSpread, null, vars.iborIndex.dayCounter(), isPar); assetSwap3.setPricingEngine(swapEngine); if (Math.Abs(assetSwap3.NPV()) > tolerance) { Assert.Fail("\npar asset swap fair spread doesn't zero the NPV: " + "\n spread: " + vars.spread + "\n fair spread: " + fairSpread + "\n NPV: " + assetSwap3.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap3.fairCleanPrice() - bondPrice) > tolerance) { Assert.Fail("\npar asset swap fair clean price doesn't equal input clean price at zero NPV: " + "\n input clean price: " + bondPrice + "\n fair clean price: " + assetSwap3.fairCleanPrice() + "\n NPV: " + assetSwap3.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap3.fairSpread() - fairSpread) > tolerance) { Assert.Fail("\npar asset swap fair spread doesn't equal input spread at zero NPV: " + "\n input spread: " + fairSpread + "\n fair spread: " + assetSwap3.fairSpread() + "\n NPV: " + assetSwap3.NPV() + "\n tolerance: " + tolerance); } // let's change the npv date swapEngine = new DiscountingSwapEngine(vars.termStructure, true, bond.settlementDate(), bond.settlementDate()); parAssetSwap.setPricingEngine(swapEngine); // fair clean price and fair spread should not change if (Math.Abs(parAssetSwap.fairCleanPrice() - fairCleanPrice) > tolerance) { Assert.Fail("\npar asset swap fair clean price changed with NpvDate:" + "\n expected clean price: " + fairCleanPrice + "\n fair clean price: " + parAssetSwap.fairCleanPrice() + "\n tolerance: " + tolerance); } if (Math.Abs(parAssetSwap.fairSpread() - fairSpread) > tolerance) { Assert.Fail("\npar asset swap fair spread changed with NpvDate:" + "\n expected spread: " + fairSpread + "\n fair spread: " + parAssetSwap.fairSpread() + "\n tolerance: " + tolerance); } assetSwap2 = new AssetSwap(payFixedRate, bond, fairCleanPrice, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), isPar); assetSwap2.setPricingEngine(swapEngine); if (Math.Abs(assetSwap2.NPV()) > tolerance) { Assert.Fail("\npar asset swap fair clean price doesn't zero the NPV: " + "\n clean price: " + bondPrice + "\n fair clean price: " + fairCleanPrice + "\n NPV: " + assetSwap2.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap2.fairCleanPrice() - fairCleanPrice) > tolerance) { Assert.Fail("\npar asset swap fair clean price doesn't equal input clean price at zero NPV: " + "\n input clean price: " + fairCleanPrice + "\n fair clean price: " + assetSwap2.fairCleanPrice() + "\n NPV: " + assetSwap2.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap2.fairSpread() - vars.spread) > tolerance) { Assert.Fail("\npar asset swap fair spread doesn't equal input spread at zero NPV: " + "\n input spread: " + vars.spread + "\n fair spread: " + assetSwap2.fairSpread() + "\n NPV: " + assetSwap2.NPV() + "\n tolerance: " + tolerance); } assetSwap3 = new AssetSwap(payFixedRate, bond, bondPrice, vars.iborIndex, fairSpread, null, vars.iborIndex.dayCounter(), isPar); assetSwap3.setPricingEngine(swapEngine); if (Math.Abs(assetSwap3.NPV()) > tolerance) { Assert.Fail("\npar asset swap fair spread doesn't zero the NPV: " + "\n spread: " + vars.spread + "\n fair spread: " + fairSpread + "\n NPV: " + assetSwap3.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap3.fairCleanPrice() - bondPrice) > tolerance) { Assert.Fail("\npar asset swap fair clean price doesn't equal input clean price at zero NPV: " + "\n input clean price: " + bondPrice + "\n fair clean price: " + assetSwap3.fairCleanPrice() + "\n NPV: " + assetSwap3.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap3.fairSpread() - fairSpread) > tolerance) { Assert.Fail("\npar asset swap fair spread doesn't equal input spread at zero NPV: " + "\n input spread: " + fairSpread + "\n fair spread: " + assetSwap3.fairSpread() + "\n NPV: " + assetSwap3.NPV() + "\n tolerance: " + tolerance); } // now market asset swap isPar = false; AssetSwap mktAssetSwap = new AssetSwap(payFixedRate, bond, bondPrice, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), isPar); swapEngine = new DiscountingSwapEngine(vars.termStructure, true, bond.settlementDate(), Settings.evaluationDate()); mktAssetSwap.setPricingEngine(swapEngine); fairCleanPrice = mktAssetSwap.fairCleanPrice(); fairSpread = mktAssetSwap.fairSpread(); AssetSwap assetSwap4 = new AssetSwap(payFixedRate, bond, fairCleanPrice, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), isPar); assetSwap4.setPricingEngine(swapEngine); if (Math.Abs(assetSwap4.NPV()) > tolerance) { Assert.Fail("\nmarket asset swap fair clean price doesn't zero the NPV: " + "\n clean price: " + bondPrice + "\n fair clean price: " + fairCleanPrice + "\n NPV: " + assetSwap4.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap4.fairCleanPrice() - fairCleanPrice) > tolerance) { Assert.Fail("\nmarket asset swap fair clean price doesn't equal input clean price at zero NPV: " + "\n input clean price: " + fairCleanPrice + "\n fair clean price: " + assetSwap4.fairCleanPrice() + "\n NPV: " + assetSwap4.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap4.fairSpread() - vars.spread) > tolerance) { Assert.Fail("\nmarket asset swap fair spread doesn't equal input spread at zero NPV: " + "\n input spread: " + vars.spread + "\n fair spread: " + assetSwap4.fairSpread() + "\n NPV: " + assetSwap4.NPV() + "\n tolerance: " + tolerance); } AssetSwap assetSwap5 = new AssetSwap(payFixedRate, bond, bondPrice, vars.iborIndex, fairSpread, null, vars.iborIndex.dayCounter(), isPar); assetSwap5.setPricingEngine(swapEngine); if (Math.Abs(assetSwap5.NPV()) > tolerance) { Assert.Fail("\nmarket asset swap fair spread doesn't zero the NPV: " + "\n spread: " + vars.spread + "\n fair spread: " + fairSpread + "\n NPV: " + assetSwap5.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap5.fairCleanPrice() - bondPrice) > tolerance) { Assert.Fail("\nmarket asset swap fair clean price doesn't equal input clean price at zero NPV: " + "\n input clean price: " + bondPrice + "\n fair clean price: " + assetSwap5.fairCleanPrice() + "\n NPV: " + assetSwap5.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap5.fairSpread() - fairSpread) > tolerance) { Assert.Fail("\nmarket asset swap fair spread doesn't equal input spread at zero NPV: " + "\n input spread: " + fairSpread + "\n fair spread: " + assetSwap5.fairSpread() + "\n NPV: " + assetSwap5.NPV() + "\n tolerance: " + tolerance); } // let's change the npv date swapEngine = new DiscountingSwapEngine(vars.termStructure, true, bond.settlementDate(), bond.settlementDate()); mktAssetSwap.setPricingEngine(swapEngine); // fair clean price and fair spread should not change if (Math.Abs(mktAssetSwap.fairCleanPrice() - fairCleanPrice) > tolerance) { Assert.Fail("\nmarket asset swap fair clean price changed with NpvDate:" + "\n expected clean price: " + fairCleanPrice + "\n fair clean price: " + mktAssetSwap.fairCleanPrice() + "\n tolerance: " + tolerance); } if (Math.Abs(mktAssetSwap.fairSpread() - fairSpread) > tolerance) { Assert.Fail("\nmarket asset swap fair spread changed with NpvDate:" + "\n expected spread: " + fairSpread + "\n fair spread: " + mktAssetSwap.fairSpread() + "\n tolerance: " + tolerance); } assetSwap4 = new AssetSwap(payFixedRate, bond, fairCleanPrice, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), isPar); assetSwap4.setPricingEngine(swapEngine); if (Math.Abs(assetSwap4.NPV()) > tolerance) { Assert.Fail("\nmarket asset swap fair clean price doesn't zero the NPV: " + "\n clean price: " + bondPrice + "\n fair clean price: " + fairCleanPrice + "\n NPV: " + assetSwap4.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap4.fairCleanPrice() - fairCleanPrice) > tolerance) { Assert.Fail("\nmarket asset swap fair clean price doesn't equal input clean price at zero NPV: " + "\n input clean price: " + fairCleanPrice + "\n fair clean price: " + assetSwap4.fairCleanPrice() + "\n NPV: " + assetSwap4.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap4.fairSpread() - vars.spread) > tolerance) { Assert.Fail("\nmarket asset swap fair spread doesn't equal input spread at zero NPV: " + "\n input spread: " + vars.spread + "\n fair spread: " + assetSwap4.fairSpread() + "\n NPV: " + assetSwap4.NPV() + "\n tolerance: " + tolerance); } assetSwap5 = new AssetSwap(payFixedRate, bond, bondPrice, vars.iborIndex, fairSpread, null, vars.iborIndex.dayCounter(), isPar); assetSwap5.setPricingEngine(swapEngine); if (Math.Abs(assetSwap5.NPV()) > tolerance) { Assert.Fail("\nmarket asset swap fair spread doesn't zero the NPV: " + "\n spread: " + vars.spread + "\n fair spread: " + fairSpread + "\n NPV: " + assetSwap5.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap5.fairCleanPrice() - bondPrice) > tolerance) { Assert.Fail("\nmarket asset swap fair clean price doesn't equal input clean price at zero NPV: " + "\n input clean price: " + bondPrice + "\n fair clean price: " + assetSwap5.fairCleanPrice() + "\n NPV: " + assetSwap5.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap5.fairSpread() - fairSpread) > tolerance) { Assert.Fail("\nmarket asset swap fair spread doesn't equal input spread at zero NPV: " + "\n input spread: " + fairSpread + "\n fair spread: " + assetSwap5.fairSpread() + "\n NPV: " + assetSwap5.NPV() + "\n tolerance: " + tolerance); } }
public void testYield() { //"Testing consistency of bond price/yield calculation..."); CommonVars vars = new CommonVars(); double tolerance = 1.0e-7; int maxEvaluations = 100; int[] issueMonths = new int[] { -24, -18, -12, -6, 0, 6, 12, 18, 24 }; 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 Thirty360(); 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 }; Compounding[] compounding = new Compounding[] { Compounding.Compounded, Compounding.Continuous }; for (int i = 0; i < issueMonths.Length; i++) { for (int j = 0; j < lengths.Length; j++) { for (int k = 0; k < coupons.Length; k++) { for (int l = 0; l < frequencies.Length; l++) { for (int n = 0; n < compounding.Length; n++) { Date dated = vars.calendar.advance(vars.today, issueMonths[i], TimeUnit.Months); Date issue = dated; Date maturity = vars.calendar.advance(issue, lengths[j], TimeUnit.Years); 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); for (int m = 0; m < yields.Length; m++) { double price = bond.cleanPrice(yields[m], bondDayCount, compounding[n], frequencies[l]); double calculated = bond.yield(price, bondDayCount, compounding[n], frequencies[l], null, tolerance, maxEvaluations); if (Math.Abs(yields[m] - calculated) > tolerance) { // the difference might not matter double price2 = bond.cleanPrice(calculated, bondDayCount, compounding[n], frequencies[l]); if (Math.Abs(price - price2) / price > tolerance) { Assert.Fail("yield recalculation failed:\n" + " issue: " + issue + "\n" + " maturity: " + maturity + "\n" + " coupon: " + coupons[k] + "\n" + " frequency: " + frequencies[l] + "\n\n" + " yield: " + yields[m] + " " + (compounding[n] == Compounding.Compounded ? "compounded" : "continuous") + "\n" + " price: " + price + "\n" + " yield': " + calculated + "\n" + " price': " + price2); } } } } } } } } }
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); } }
public void testBondFromScheduleWithDateVector() { // Testing South African R2048 bond price using Schedule constructor with Date vector SavedSettings backup = new SavedSettings(); //When pricing bond from Yield To Maturity, use NullCalendar() Calendar calendar = new NullCalendar(); int settlementDays = 3; Date issueDate = new Date(29, Month.June, 2012); Date today = new Date(7, Month.September, 2015); Date evaluationDate = calendar.adjust(today); Date settlementDate = calendar.advance(evaluationDate, new Period(settlementDays, TimeUnit.Days)); Settings.setEvaluationDate(evaluationDate); // For the schedule to generate correctly for Feb-28's, make maturity date on Feb 29 Date maturityDate = new Date(29, Month.February, 2048); double coupon = 0.0875; Compounding comp = Compounding.Compounded; Frequency freq = Frequency.Semiannual; DayCounter dc = new ActualActual(ActualActual.Convention.Bond); // Yield as quoted in market InterestRate yield = new InterestRate(0.09185, dc, comp, freq); Period tenor = new Period(6, TimeUnit.Months); Period exCouponPeriod = new Period(10, TimeUnit.Days); // Generate coupon dates for 31 Aug and end of Feb each year // For leap years, this will generate 29 Feb, but the bond // actually pays coupons on 28 Feb, regardsless of whether // it is a leap year or not. Schedule schedule = new Schedule(issueDate, maturityDate, tenor, new NullCalendar(), BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, true); // Adjust the 29 Feb's to 28 Feb List<Date> dates = new List<Date>(); for (int i = 0; i < schedule.Count; ++i) { Date d = schedule.date(i); if (d.Month == 2 && d.Day == 29) dates.Add(new Date(28, Month.February, d.Year)); else dates.Add(d); } schedule = new Schedule(dates, schedule.calendar(), schedule.businessDayConvention(), schedule.terminationDateBusinessDayConvention(), schedule.tenor(), schedule.rule(), schedule.endOfMonth(), schedule.isRegular()); FixedRateBond bond = new FixedRateBond( 0, 100.0, schedule, new List<double>() { coupon }, dc, BusinessDayConvention.Following, 100.0, issueDate, calendar, exCouponPeriod, calendar, BusinessDayConvention.Unadjusted, false); double calculatedPrice = BondFunctions.dirtyPrice(bond, yield, settlementDate); double expectedPrice = 95.75706; double tolerance = 1e-5; if (Math.Abs(calculatedPrice - expectedPrice) > tolerance) { Assert.Fail(string.Format("failed to reproduce R2048 dirty price\nexpected: {0}\ncalculated: {1}", expectedPrice, calculatedPrice)); } }
static void Main(string[] args) { DateTime timer = DateTime.Now; /********************* *** MARKET DATA *** *********************/ Calendar calendar = new TARGET(); Date settlementDate = new Date(18, Month.September, 2008); // must be a business day settlementDate = calendar.adjust(settlementDate); int fixingDays = 3; int settlementDays = 3; Date todaysDate = calendar.advance(settlementDate, -fixingDays, TimeUnit.Days); // nothing to do with Date::todaysDate Settings.setEvaluationDate(todaysDate); Console.WriteLine("Today: {0}, {1}", todaysDate.DayOfWeek, todaysDate); Console.WriteLine("Settlement date: {0}, {1}", settlementDate.DayOfWeek, settlementDate); // Building of the bonds discounting yield curve /********************* *** RATE HELPERS *** *********************/ // RateHelpers are built from the above quotes together with // other instrument dependant infos. Quotes are passed in // relinkable handles which could be relinked to some other // data source later. // Common data // ZC rates for the short end double zc3mQuote=0.0096; double zc6mQuote=0.0145; double zc1yQuote=0.0194; Quote zc3mRate = new SimpleQuote(zc3mQuote); Quote zc6mRate = new SimpleQuote(zc6mQuote); Quote zc1yRate = new SimpleQuote(zc1yQuote); DayCounter zcBondsDayCounter = new Actual365Fixed(); RateHelper zc3m = new DepositRateHelper(new Handle<Quote>(zc3mRate), new Period(3, TimeUnit.Months), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, zcBondsDayCounter); RateHelper zc6m = new DepositRateHelper(new Handle<Quote>(zc6mRate), new Period(6, TimeUnit.Months), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, zcBondsDayCounter); RateHelper zc1y = new DepositRateHelper(new Handle<Quote>(zc1yRate), new Period(1, TimeUnit.Years), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, zcBondsDayCounter); // setup bonds double redemption = 100.0; const int numberOfBonds = 5; Date[] issueDates = { new Date (15, Month.March, 2005), new Date (15, Month.June, 2005), new Date (30, Month.June, 2006), new Date (15, Month.November, 2002), new Date (15, Month.May, 1987) }; Date[] maturities = { new Date (31, Month.August, 2010), new Date (31, Month.August, 2011), new Date (31, Month.August, 2013), new Date (15, Month.August, 2018), new Date (15, Month.May, 2038) }; double[] couponRates = { 0.02375, 0.04625, 0.03125, 0.04000, 0.04500 }; double[] marketQuotes = { 100.390625, 106.21875, 100.59375, 101.6875, 102.140625 }; List<SimpleQuote> quote = new List<SimpleQuote>(); for (int i=0; i<numberOfBonds; i++) { SimpleQuote cp = new SimpleQuote(marketQuotes[i]); quote.Add(cp); } List<RelinkableHandle<Quote>> quoteHandle = new InitializedList<RelinkableHandle<Quote>>(numberOfBonds); for (int i=0; i<numberOfBonds; i++) { quoteHandle[i].linkTo(quote[i]); } // Definition of the rate helpers List<FixedRateBondHelper> bondsHelpers = new List<FixedRateBondHelper>(); for (int i=0; i<numberOfBonds; i++) { Schedule schedule = new Schedule(issueDates[i], maturities[i], new Period(Frequency.Semiannual), new UnitedStates(UnitedStates.Market.GovernmentBond), BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); FixedRateBondHelper bondHelper = new FixedRateBondHelper(quoteHandle[i], settlementDays, 100.0, schedule, new List<double>() { couponRates[i] }, new ActualActual(ActualActual.Convention.Bond), BusinessDayConvention.Unadjusted, redemption, issueDates[i]); bondsHelpers.Add(bondHelper); } /********************* ** CURVE BUILDING ** *********************/ // Any DayCounter would be fine. // ActualActual::ISDA ensures that 30 years is 30.0 DayCounter termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA); double tolerance = 1.0e-15; // A depo-bond curve List<RateHelper> bondInstruments = new List<RateHelper>(); // Adding the ZC bonds to the curve for the short end bondInstruments.Add(zc3m); bondInstruments.Add(zc6m); bondInstruments.Add(zc1y); // Adding the Fixed rate bonds to the curve for the long end for (int i=0; i<numberOfBonds; i++) { bondInstruments.Add(bondsHelpers[i]); } YieldTermStructure bondDiscountingTermStructure = new PiecewiseYieldCurve<Discount,LogLinear>( settlementDate, bondInstruments, termStructureDayCounter, new List<Handle<Quote>>(), new List<Date>(), tolerance); // Building of the Libor forecasting curve // deposits double d1wQuote=0.043375; double d1mQuote=0.031875; double d3mQuote=0.0320375; double d6mQuote=0.03385; double d9mQuote=0.0338125; double d1yQuote=0.0335125; // swaps double s2yQuote=0.0295; double s3yQuote=0.0323; double s5yQuote=0.0359; double s10yQuote=0.0412; double s15yQuote=0.0433; /******************** *** QUOTES *** ********************/ // SimpleQuote stores a value which can be manually changed; // other Quote subclasses could read the value from a database // or some kind of data feed. // deposits Quote d1wRate = new SimpleQuote(d1wQuote); Quote d1mRate = new SimpleQuote(d1mQuote); Quote d3mRate = new SimpleQuote(d3mQuote); Quote d6mRate = new SimpleQuote(d6mQuote); Quote d9mRate = new SimpleQuote(d9mQuote); Quote d1yRate = new SimpleQuote(d1yQuote); // swaps Quote s2yRate = new SimpleQuote(s2yQuote); Quote s3yRate = new SimpleQuote(s3yQuote); Quote s5yRate = new SimpleQuote(s5yQuote); Quote s10yRate = new SimpleQuote(s10yQuote); Quote s15yRate = new SimpleQuote(s15yQuote); /********************* *** RATE HELPERS *** *********************/ // RateHelpers are built from the above quotes together with // other instrument dependant infos. Quotes are passed in // relinkable handles which could be relinked to some other // data source later. // deposits DayCounter depositDayCounter = new Actual360(); RateHelper d1w = new DepositRateHelper( new Handle<Quote>(d1wRate), new Period(1, TimeUnit.Weeks), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); RateHelper d1m = new DepositRateHelper( new Handle<Quote>(d1mRate), new Period(1, TimeUnit.Months), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); RateHelper d3m = new DepositRateHelper( new Handle<Quote>(d3mRate), new Period(3, TimeUnit.Months), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); RateHelper d6m = new DepositRateHelper( new Handle<Quote>(d6mRate), new Period(6, TimeUnit.Months), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); RateHelper d9m = new DepositRateHelper( new Handle<Quote>(d9mRate), new Period(9, TimeUnit.Months), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); RateHelper d1y = new DepositRateHelper( new Handle<Quote>(d1yRate), new Period(1, TimeUnit.Years), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); // setup swaps Frequency swFixedLegFrequency =Frequency.Annual; BusinessDayConvention swFixedLegConvention = BusinessDayConvention.Unadjusted; DayCounter swFixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European); IborIndex swFloatingLegIndex = new Euribor6M(); Period forwardStart = new Period(1, TimeUnit.Days); RateHelper s2y = new SwapRateHelper( new Handle<Quote>(s2yRate), new Period(2, TimeUnit.Years), calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex, new Handle<Quote>(),forwardStart); RateHelper s3y = new SwapRateHelper( new Handle<Quote>(s3yRate), new Period(3, TimeUnit.Years), calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex, new Handle<Quote>(),forwardStart); RateHelper s5y = new SwapRateHelper( new Handle<Quote>(s5yRate), new Period(5, TimeUnit.Years), calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex, new Handle<Quote>(),forwardStart); RateHelper s10y = new SwapRateHelper( new Handle<Quote>(s10yRate), new Period(10, TimeUnit.Years), calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex, new Handle<Quote>(),forwardStart); RateHelper s15y = new SwapRateHelper( new Handle<Quote>(s15yRate), new Period(15, TimeUnit.Years), calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex, new Handle<Quote>(),forwardStart); /********************* ** CURVE BUILDING ** *********************/ // Any DayCounter would be fine. // ActualActual::ISDA ensures that 30 years is 30.0 // A depo-swap curve List<RateHelper> depoSwapInstruments = new List<RateHelper>(); depoSwapInstruments.Add(d1w); depoSwapInstruments.Add(d1m); depoSwapInstruments.Add(d3m); depoSwapInstruments.Add(d6m); depoSwapInstruments.Add(d9m); depoSwapInstruments.Add(d1y); depoSwapInstruments.Add(s2y); depoSwapInstruments.Add(s3y); depoSwapInstruments.Add(s5y); depoSwapInstruments.Add(s10y); depoSwapInstruments.Add(s15y); YieldTermStructure depoSwapTermStructure = new PiecewiseYieldCurve<Discount,LogLinear>( settlementDate, depoSwapInstruments, termStructureDayCounter, new List<Handle<Quote> >(), new List<Date>(), tolerance); // Term structures that will be used for pricing: // the one used for discounting cash flows RelinkableHandle<YieldTermStructure> discountingTermStructure = new RelinkableHandle<YieldTermStructure>(); // the one used for forward rate forecasting RelinkableHandle<YieldTermStructure> forecastingTermStructure = new RelinkableHandle<YieldTermStructure>(); /********************* * BONDS TO BE PRICED * **********************/ // Common data double faceAmount = 100; // Pricing engine IPricingEngine bondEngine = new DiscountingBondEngine(discountingTermStructure); // Zero coupon bond ZeroCouponBond zeroCouponBond = new ZeroCouponBond( settlementDays, new UnitedStates(UnitedStates.Market.GovernmentBond), faceAmount, new Date(15, Month.August,2013), BusinessDayConvention.Following, 116.92, new Date(15, Month.August,2003)); zeroCouponBond.setPricingEngine(bondEngine); // Fixed 4.5% US Treasury Note Schedule fixedBondSchedule = new Schedule(new Date(15, Month.May, 2007), new Date(15,Month.May,2017), new Period(Frequency.Semiannual), new UnitedStates(UnitedStates.Market.GovernmentBond), BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); FixedRateBond fixedRateBond = new FixedRateBond( settlementDays, faceAmount, fixedBondSchedule, new List<double>() { 0.045 }, new ActualActual(ActualActual.Convention.Bond), BusinessDayConvention.ModifiedFollowing, 100.0, new Date(15, Month.May, 2007)); fixedRateBond.setPricingEngine(bondEngine); // Floating rate bond (3M USD Libor + 0.1%) // Should and will be priced on another curve later... RelinkableHandle<YieldTermStructure> liborTermStructure = new RelinkableHandle<YieldTermStructure>(); IborIndex libor3m = new USDLibor(new Period(3, TimeUnit.Months), liborTermStructure); libor3m.addFixing(new Date(17, Month.July, 2008),0.0278625); Schedule floatingBondSchedule = new Schedule(new Date(21, Month.October, 2005), new Date(21, Month.October, 2010), new Period(Frequency.Quarterly), new UnitedStates(UnitedStates.Market.NYSE), BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, true); FloatingRateBond floatingRateBond = new FloatingRateBond( settlementDays, faceAmount, floatingBondSchedule, libor3m, new Actual360(), BusinessDayConvention.ModifiedFollowing, 2, // Gearings new List<double>() { 1.0 }, // Spreads new List<double>() { 0.001 }, // Caps new List<double>(), // Floors new List<double>(), // Fixing in arrears true, 100.0, new Date(21, Month.October, 2005)); floatingRateBond.setPricingEngine(bondEngine); // Coupon pricers IborCouponPricer pricer = new BlackIborCouponPricer(); // optionLet volatilities double volatility = 0.0; Handle<OptionletVolatilityStructure> vol; vol = new Handle<OptionletVolatilityStructure>( new ConstantOptionletVolatility( settlementDays, calendar, BusinessDayConvention.ModifiedFollowing, volatility, new Actual365Fixed())); pricer.setCapletVolatility(vol); Utils.setCouponPricer(floatingRateBond.cashflows(),pricer); // Yield curve bootstrapping forecastingTermStructure.linkTo(depoSwapTermStructure); discountingTermStructure.linkTo(bondDiscountingTermStructure); // We are using the depo & swap curve to estimate the future Libor rates liborTermStructure.linkTo(depoSwapTermStructure); /*************** * BOND PRICING * ****************/ // write column headings int[] widths = { 18, 10, 10, 10 }; Console.WriteLine("{0,18}{1,10}{2,10}{3,10}", "", "ZC", "Fixed", "Floating"); string separator = " | "; int width = widths[0] + widths[1] + widths[2] + widths[3]; string rule = "".PadLeft(width, '-'), dblrule = "".PadLeft(width, '='); string tab = "".PadLeft(8, ' '); Console.WriteLine(rule); Console.WriteLine("Net present value".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}", zeroCouponBond.NPV(), fixedRateBond.NPV(), floatingRateBond.NPV()); Console.WriteLine("Clean price".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}", zeroCouponBond.cleanPrice(), fixedRateBond.cleanPrice(), floatingRateBond.cleanPrice()); Console.WriteLine("Dirty price".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}", zeroCouponBond.dirtyPrice(), fixedRateBond.dirtyPrice(), floatingRateBond.dirtyPrice()); Console.WriteLine("Accrued coupon".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}", zeroCouponBond.accruedAmount(), fixedRateBond.accruedAmount(), floatingRateBond.accruedAmount()); Console.WriteLine("Previous coupon".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}", "N/A", fixedRateBond.previousCoupon(), floatingRateBond.previousCoupon()); Console.WriteLine("Next coupon".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}", "N/A", fixedRateBond.nextCoupon(), floatingRateBond.nextCoupon()); Console.WriteLine("Yield".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}", zeroCouponBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual), fixedRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual), floatingRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual)); Console.WriteLine(); // Other computations Console.WriteLine("Sample indirect computations (for the floating rate bond): "); Console.WriteLine(rule); Console.WriteLine("Yield to Clean Price: {0:n2}", floatingRateBond.cleanPrice(floatingRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual), new Actual360(), Compounding.Compounded, Frequency.Annual, settlementDate)); Console.WriteLine("Clean Price to Yield: {0:0.00%}", floatingRateBond.yield(floatingRateBond.cleanPrice(),new Actual360(), Compounding.Compounded, Frequency.Annual, settlementDate)); /* "Yield to Price" "Price to Yield" */ Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer); Console.WriteLine(); Console.Write("Press any key to continue ..."); Console.ReadKey(); }
//public FixedRateBondHelper(Quote cleanPrice, int settlementDays, double faceAmount, Schedule schedule, // List<double> coupons, DayCounter dayCounter, // BusinessDayConvention paymentConv = Following, // double redemption = 100.0, // Date issueDate = null); public FixedRateBondHelper(Handle<Quote> cleanPrice, int settlementDays, double faceAmount, Schedule schedule, List<double> coupons, DayCounter dayCounter, BusinessDayConvention paymentConvention, double redemption, Date issueDate) : base(cleanPrice, new FixedRateBond(settlementDays, faceAmount, schedule, coupons, dayCounter, paymentConvention, redemption, issueDate)) { fixedRateBond_ = bond_ as FixedRateBond; }