public void testCashedValues() { Date startDate = new Date(01, 03, 2007); Period period = new Period(360, TimeUnit.Months); Calendar calendar = new TARGET(); Date endDate = calendar.advance(startDate,period,BusinessDayConvention.Unadjusted); Schedule schedule = new Schedule( startDate, endDate, new Period(1,TimeUnit.Months), calendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); // PSA 100% PSACurve psa100 = new PSACurve(startDate); double[] listCPR = {0.2000,0.4000,0.6000,0.8000,1.0000,1.2000,1.4000,1.6000,1.8000,2.0000,2.2000,2.4000,2.6000,2.8000, 3.0000,3.2000,3.4000,3.6000,3.8000,4.0000,4.2000,4.4000,4.6000,4.8000,5.0000,5.2000,5.4000,5.6000, 5.8000,6.0000}; for (int i = 0; i < schedule.Count; i++) { if ( i <= 29 ) Assert.AreEqual(listCPR[i], psa100.getCPR(schedule[i])*100,0.001); else Assert.AreEqual(6.0000, psa100.getCPR(schedule[i])*100); } }
public void testFairRate() { Calendar calendar = new TARGET(); Date settlementDate = new Date(10, Month.Mar, 2010); /********************* * LOAN TO BE PRICED * **********************/ // constant nominal 1,000,000 Euro double nominal = 1000000.0; // fixed leg Frequency fixedLegFrequency = Frequency.Monthly; BusinessDayConvention fixedLegConvention = BusinessDayConvention.Unadjusted; BusinessDayConvention principalLegConvention = BusinessDayConvention.ModifiedFollowing; DayCounter fixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European); double fixedRate = 0.04; // Principal leg Frequency pricipalLegFrequency = Frequency.Annual; int lenghtInMonths = 3; Loan.Type loanType = Loan.Type.Payer; Date maturity = settlementDate + new Period(lenghtInMonths, TimeUnit.Years); Schedule fixedSchedule = new Schedule(settlementDate, maturity, new Period(fixedLegFrequency), calendar, fixedLegConvention, fixedLegConvention, DateGeneration.Rule.Forward, false); Schedule principalSchedule = new Schedule(settlementDate, maturity, new Period(pricipalLegFrequency), calendar, principalLegConvention, principalLegConvention, DateGeneration.Rule.Forward, false); Loan testLoan = new FixedLoan(loanType, nominal, fixedSchedule, fixedRate, fixedLegDayCounter, principalSchedule, principalLegConvention); }
public void testDefaultProbability() { // Testing default-probability structure... double hazardRate = 0.0100; Handle<Quote> hazardRateQuote = new Handle<Quote>(new SimpleQuote(hazardRate)); DayCounter dayCounter = new Actual360(); Calendar calendar = new TARGET(); int n = 20; double tolerance = 1.0e-10; Date today = Settings.evaluationDate(); Date startDate = today; Date endDate = startDate; FlatHazardRate flatHazardRate = new FlatHazardRate(startDate, hazardRateQuote, dayCounter); for(int i=0; i<n; i++) { startDate = endDate; endDate = calendar.advance(endDate, 1, TimeUnit.Years); double pStart = flatHazardRate.defaultProbability(startDate); double pEnd = flatHazardRate.defaultProbability(endDate); double pBetweenComputed = flatHazardRate.defaultProbability(startDate, endDate); double pBetween = pEnd - pStart; if (Math.Abs(pBetween - pBetweenComputed) > tolerance) Assert.Fail( "Failed to reproduce probability(d1, d2) " + "for default probability structure\n" + " calculated probability: " + pBetweenComputed + "\n" + " expected probability: " + pBetween); double t2 = dayCounter.yearFraction(today, endDate); double timeProbability = flatHazardRate.defaultProbability(t2); double dateProbability = flatHazardRate.defaultProbability(endDate); if (Math.Abs(timeProbability - dateProbability) > tolerance) Assert.Fail( "single-time probability and single-date probability do not match\n" + " time probability: " + timeProbability + "\n" + " date probability: " + dateProbability); double t1 = dayCounter.yearFraction(today, startDate); timeProbability = flatHazardRate.defaultProbability(t1, t2); dateProbability = flatHazardRate.defaultProbability(startDate, endDate); if (Math.Abs(timeProbability - dateProbability) > tolerance) Assert.Fail( "double-time probability and double-date probability do not match\n" + " time probability: " + timeProbability + "\n" + " date probability: " + dateProbability); } }
public CreditDefaultSwapHelper(double cdsSpread, Period cdsTenor, Handle <YieldTermStructure> discount, Handle <DefaultProbabilityTermStructure> HazardHandle = null) : base(cdsSpread) { cdsTenor_ = cdsTenor; cdsSpread_ = cdsSpread; calendar_ = new TARGET(); dayCount_ = new Actual365Fixed(); discountHandle_ = discount ?? new Handle <YieldTermStructure>(); HazardHandle_ = HazardHandle ?? new Handle <DefaultProbabilityTermStructure>(); discountHandle_.registerWith(update); initializeDates(); }
public void testAccessViolation() { // Testing dynamic cast of coupon in Black pricer... SavedSettings backup = new SavedSettings(); Date todaysDate = new Date(7, Month.April, 2010); Date settlementDate = new Date(9, Month.April, 2010); Settings.setEvaluationDate(todaysDate); Calendar calendar = new TARGET(); Handle<YieldTermStructure> rhTermStructure = new Handle<YieldTermStructure>( Utilities.flatRate(settlementDate, 0.04875825, new Actual365Fixed())); double volatility = 0.10; Handle<OptionletVolatilityStructure> vol= new Handle<OptionletVolatilityStructure>( new ConstantOptionletVolatility(2, calendar, BusinessDayConvention.ModifiedFollowing, volatility, new Actual365Fixed())); IborIndex index3m =new USDLibor(new Period(3,TimeUnit.Months), rhTermStructure); Date payDate = new Date(20, Month.December, 2013); Date startDate = new Date(20, Month.September, 2013); Date endDate = new Date(20, Month.December, 2013); double spread = 0.0115; IborCouponPricer pricer = new BlackIborCouponPricer(vol); FloatingRateCoupon coupon = new FloatingRateCoupon(100,payDate, startDate, endDate, 2, index3m, 1.0 , spread / 100); coupon.setPricer(pricer); try { // this caused an access violation in version 1.0 coupon.amount(); } catch (Exception ) { // ok; proper exception thrown } }
static void Main(string[] args) { Calendar calendar = new TARGET(); Date todaysDate = new Date(22, 7, 2014); Date settlementDate = new Date(3, 6, 2014); Settings.setEvaluationDate(todaysDate); DayCounter dayCounter = new Actual365Fixed(); double dividendYield = 0.0117; double volatility = 0.15517; Barrier.Type type = Barrier.Type.UpOut; QLNet.PlainVanillaPayoff payoff = new PlainVanillaPayoff(Option.Type.Call,261.4); QLNet.EuropeanExercise ex = new EuropeanExercise(new Date(30,11,2015)); //QLNet.BarrierOption barrierOption = new BarrierOption(type, 1.2,1.0, 0.0, payoff, ex); //QLNet.BarrierOption barrierOption = new BarrierOption(type, 313.68, 0.0, payoff, ex); QLNet.BarrierOption barrierOption = new BarrierOption(type, 313.68, 0.32,0.0, payoff, ex); double underlying = 262.86; double riskFreeRate = 0.0243; Handle<Quote> underlyingH = new Handle<Quote>(new SimpleQuote(underlying)); // bootstrap the yield/dividend/vol curves var flatTermStructure = new Handle<YieldTermStructure>(new FlatForward(settlementDate, riskFreeRate, dayCounter)); var flatDividendTS = new Handle<YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter)); var flatVolTS = new Handle<BlackVolTermStructure>(new BlackConstantVol(settlementDate, calendar, volatility, dayCounter)); var bsmProcess = new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS); QLNet.AnalyticBarrierWithPartiRateEngine engine = new AnalyticBarrierWithPartiRateEngine(bsmProcess); barrierOption.setPricingEngine(engine); double kk = barrierOption.NPV(); Console.WriteLine(kk); Console.WriteLine(kk / 261.4); }
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 calculate(GBMParaViewModel para) { // set up dates Calendar calendar = new TARGET(); //Date todaysDate = new Date(DateTime.Now); Date settlementDate = new Date(para.ReferenceDate_); Settings.setEvaluationDate(settlementDate); // our options Option.Type type = this.callPutEnum_; double underlying = para.CurrentPrice_; double strike = this.strike_; double dividendYield = para.Dividend_ / 100; double riskFreeRate = para.Drift_ / 100; double volatility = 0.0; if (this.callPutEnum_ == Option.Type.Call) { try { volatility = para.Call_Interpolation_.value(this.strike_) / 100; this.imVolCal_ = Math.Round(para.Call_Interpolation_.value(this.strike_), 1); } catch (Exception) { volatility = para.Call_Interpolation_.value(this.strike_, true) / 100; this.imVolCal_ = Math.Round(para.Call_Interpolation_.value(this.strike_,true), 1); } } else if (this.callPutEnum_ == Option.Type.Put) { try { volatility = para.Call_Interpolation_.value(this.strike_) / 100; this.imVolCal_ = Math.Round(para.Put_Interpolation_.value(this.strike_), 1); } catch (Exception) { volatility = para.Call_Interpolation_.value(this.strike_, true) / 100; this.imVolCal_ = Math.Round(para.Put_Interpolation_.value(this.strike_,true), 1); } } Date maturity = new Date(this.maturiry_); DayCounter dayCounter = new Actual365Fixed(); //// write column headings //int[] widths = new int[] { 35, 14, 14, 14 }; //Console.Write("{0,-" + widths[0] + "}", "Method"); //Console.Write("{0,-" + widths[1] + "}", "European"); //Console.Write("{0,-" + widths[2] + "}", "Bermudan"); //Console.WriteLine("{0,-" + widths[3] + "}", "American"); //List<Date> exerciseDates = new List<Date>(); ; //for (int i = 1; i <= 4; i++) // exerciseDates.Add(settlementDate + new Period(3 * i, TimeUnit.Months)); Exercise europeanExercise = new EuropeanExercise(maturity); //Exercise bermudanExercise = new BermudanExercise(exerciseDates); //Exercise americanExercise = new AmericanExercise(settlementDate, maturity); Handle<Quote> underlyingH = new Handle<Quote>(new SimpleQuote(underlying)); // bootstrap the yield/dividend/vol curves var flatTermStructure = new Handle<YieldTermStructure>(new FlatForward(settlementDate, riskFreeRate, dayCounter)); var flatDividendTS = new Handle<YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter)); var flatVolTS = new Handle<BlackVolTermStructure>(new BlackConstantVol(settlementDate, calendar, volatility, dayCounter)); StrikedTypePayoff payoff = new PlainVanillaPayoff(type, strike); var bsmProcess = new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS); // options VanillaOption europeanOption = new VanillaOption(payoff, europeanExercise); // Analytic formulas: // Black-Scholes for European europeanOption.setPricingEngine(new AnalyticEuropeanEngine(bsmProcess)); this.npv_ = Math.Round(europeanOption.NPV(),6); this.deltaCal_ = Math.Round(europeanOption.delta(),6); this.gammaCal_= Math.Round(europeanOption.gamma(),6); this.vegaCal_ = Math.Round(europeanOption.vega()/ 100, 6); this.thetaCal_= Math.Round(europeanOption.theta()/ 365,6) ; this.rhoCal_ = Math.Round(europeanOption.rho() / 100, 6); }
static void Main(string[] args) { DateTime timer = DateTime.Now; /********************* *** MARKET DATA *** *********************/ Calendar calendar = new TARGET(); Date settlementDate = new Date(22, Month.September, 2004); // must be a business day settlementDate = calendar.adjust(settlementDate); int fixingDays = 2; Date todaysDate = calendar.advance(settlementDate, -fixingDays, TimeUnit.Days); // nothing to do with Date::todaysDate Settings.setEvaluationDate(todaysDate); todaysDate = Settings.evaluationDate(); Console.WriteLine("Today: {0}, {1}", todaysDate.DayOfWeek, todaysDate); Console.WriteLine("Settlement date: {0}, {1}", settlementDate.DayOfWeek, settlementDate); // deposits double d1wQuote = 0.0382; double d1mQuote = 0.0372; double d3mQuote = 0.0363; double d6mQuote = 0.0353; double d9mQuote = 0.0348; double d1yQuote = 0.0345; // FRAs double fra3x6Quote = 0.037125; double fra6x9Quote = 0.037125; double fra6x12Quote = 0.037125; // futures double fut1Quote = 96.2875; double fut2Quote = 96.7875; double fut3Quote = 96.9875; double fut4Quote = 96.6875; double fut5Quote = 96.4875; double fut6Quote = 96.3875; double fut7Quote = 96.2875; double fut8Quote = 96.0875; // swaps double s2yQuote = 0.037125; double s3yQuote = 0.0398; double s5yQuote = 0.0443; double s10yQuote = 0.05165; double s15yQuote = 0.055175; /******************** *** QUOTES *** ********************/ // SimpleQuote stores a value which can be manually changed; // other Quote subclasses could read the value from a database // or some kind of data feed. // deposits Quote d1wRate = new SimpleQuote(d1wQuote); Quote d1mRate = new SimpleQuote(d1mQuote); Quote d3mRate = new SimpleQuote(d3mQuote); Quote d6mRate = new SimpleQuote(d6mQuote); Quote d9mRate = new SimpleQuote(d9mQuote); Quote d1yRate = new SimpleQuote(d1yQuote); // FRAs Quote fra3x6Rate = new SimpleQuote(fra3x6Quote); Quote fra6x9Rate = new SimpleQuote(fra6x9Quote); Quote fra6x12Rate = new SimpleQuote(fra6x12Quote); // futures Quote fut1Price = new SimpleQuote(fut1Quote); Quote fut2Price = new SimpleQuote(fut2Quote); Quote fut3Price = new SimpleQuote(fut3Quote); Quote fut4Price = new SimpleQuote(fut4Quote); Quote fut5Price = new SimpleQuote(fut5Quote); Quote fut6Price = new SimpleQuote(fut6Quote); Quote fut7Price = new SimpleQuote(fut7Quote); Quote fut8Price = new SimpleQuote(fut8Quote); // swaps Quote s2yRate = new SimpleQuote(s2yQuote); Quote s3yRate = new SimpleQuote(s3yQuote); Quote s5yRate = new SimpleQuote(s5yQuote); Quote s10yRate = new SimpleQuote(s10yQuote); Quote s15yRate = new SimpleQuote(s15yQuote); /********************* *** RATE HELPERS *** *********************/ // RateHelpers are built from the above quotes together with // other instrument dependant infos. Quotes are passed in // relinkable handles which could be relinked to some other // data source later. // deposits DayCounter depositDayCounter = new Actual360(); RateHelper d1w = new DepositRateHelper(new Handle<Quote>(d1wRate), new Period(1, TimeUnit.Weeks), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); RateHelper d1m = new DepositRateHelper(new Handle<Quote>(d1mRate), new Period(1, TimeUnit.Months), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); RateHelper d3m = new DepositRateHelper(new Handle<Quote>(d3mRate), new Period(3, TimeUnit.Months), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); RateHelper d6m = new DepositRateHelper(new Handle<Quote>(d6mRate), new Period(6, TimeUnit.Months), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); RateHelper d9m = new DepositRateHelper(new Handle<Quote>(d9mRate), new Period(9, TimeUnit.Months), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); RateHelper d1y = new DepositRateHelper(new Handle<Quote>(d1yRate), new Period(1, TimeUnit.Years), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); // setup FRAs RateHelper fra3x6 = new FraRateHelper(new Handle<Quote>(fra3x6Rate), 3, 6, fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); RateHelper fra6x9 = new FraRateHelper(new Handle<Quote>(fra6x9Rate), 6, 9, fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); RateHelper fra6x12 = new FraRateHelper(new Handle<Quote>(fra6x12Rate), 6, 12, fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); // setup futures // Handle<Quote> convexityAdjustment = new Handle<Quote>(new SimpleQuote(0.0)); int futMonths = 3; Date imm = IMM.nextDate(settlementDate); RateHelper fut1 = new FuturesRateHelper(new Handle<Quote>(fut1Price), imm, futMonths, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); imm = IMM.nextDate(imm + 1); RateHelper fut2 = new FuturesRateHelper(new Handle<Quote>(fut2Price), imm, futMonths, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); imm = IMM.nextDate(imm + 1); RateHelper fut3 = new FuturesRateHelper(new Handle<Quote>(fut3Price), imm, futMonths, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); imm = IMM.nextDate(imm + 1); RateHelper fut4 = new FuturesRateHelper(new Handle<Quote>(fut4Price), imm, futMonths, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); imm = IMM.nextDate(imm + 1); RateHelper fut5 = new FuturesRateHelper(new Handle<Quote>(fut5Price), imm, futMonths, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); imm = IMM.nextDate(imm + 1); RateHelper fut6 = new FuturesRateHelper(new Handle<Quote>(fut6Price), imm, futMonths, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); imm = IMM.nextDate(imm + 1); RateHelper fut7 = new FuturesRateHelper(new Handle<Quote>(fut7Price), imm, futMonths, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); imm = IMM.nextDate(imm + 1); RateHelper fut8 = new FuturesRateHelper(new Handle<Quote>(fut8Price), imm, futMonths, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); // setup swaps Frequency swFixedLegFrequency = Frequency.Annual; BusinessDayConvention swFixedLegConvention = BusinessDayConvention.Unadjusted; DayCounter swFixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European); IborIndex swFloatingLegIndex = new Euribor6M(); RateHelper s2y = new SwapRateHelper(new Handle<Quote>(s2yRate), new Period(2, TimeUnit.Years), calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex); RateHelper s3y = new SwapRateHelper(new Handle<Quote>(s3yRate), new Period(3, TimeUnit.Years), calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex); RateHelper s5y = new SwapRateHelper(new Handle<Quote>(s5yRate), new Period(5, TimeUnit.Years), calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex); RateHelper s10y = new SwapRateHelper(new Handle<Quote>(s10yRate), new Period(10, TimeUnit.Years), calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex); RateHelper s15y = new SwapRateHelper(new Handle<Quote>(s15yRate), new Period(15, TimeUnit.Years), calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex); /********************* ** CURVE BUILDING ** *********************/ // Any DayCounter would be fine. // ActualActual::ISDA ensures that 30 years is 30.0 DayCounter termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA); double tolerance = 1.0e-15; // A depo-swap curve List<RateHelper> depoSwapInstruments = new List<RateHelper>(); depoSwapInstruments.Add(d1w); depoSwapInstruments.Add(d1m); depoSwapInstruments.Add(d3m); depoSwapInstruments.Add(d6m); depoSwapInstruments.Add(d9m); depoSwapInstruments.Add(d1y); depoSwapInstruments.Add(s2y); depoSwapInstruments.Add(s3y); depoSwapInstruments.Add(s5y); depoSwapInstruments.Add(s10y); depoSwapInstruments.Add(s15y); YieldTermStructure depoSwapTermStructure = new PiecewiseYieldCurve<Discount,LogLinear>( settlementDate, depoSwapInstruments, termStructureDayCounter, new List<Handle<Quote>>(), new List<Date>(), tolerance); // A depo-futures-swap curve List<RateHelper> depoFutSwapInstruments = new List<RateHelper>(); depoFutSwapInstruments.Add(d1w); depoFutSwapInstruments.Add(d1m); depoFutSwapInstruments.Add(fut1); depoFutSwapInstruments.Add(fut2); depoFutSwapInstruments.Add(fut3); depoFutSwapInstruments.Add(fut4); depoFutSwapInstruments.Add(fut5); depoFutSwapInstruments.Add(fut6); depoFutSwapInstruments.Add(fut7); depoFutSwapInstruments.Add(fut8); depoFutSwapInstruments.Add(s3y); depoFutSwapInstruments.Add(s5y); depoFutSwapInstruments.Add(s10y); depoFutSwapInstruments.Add(s15y); YieldTermStructure depoFutSwapTermStructure = new PiecewiseYieldCurve<Discount,LogLinear>( settlementDate, depoFutSwapInstruments, termStructureDayCounter, new List<Handle<Quote>>(), new List<Date>(), tolerance); // A depo-FRA-swap curve List<RateHelper> depoFRASwapInstruments = new List<RateHelper>(); depoFRASwapInstruments.Add(d1w); depoFRASwapInstruments.Add(d1m); depoFRASwapInstruments.Add(d3m); depoFRASwapInstruments.Add(fra3x6); depoFRASwapInstruments.Add(fra6x9); depoFRASwapInstruments.Add(fra6x12); depoFRASwapInstruments.Add(s2y); depoFRASwapInstruments.Add(s3y); depoFRASwapInstruments.Add(s5y); depoFRASwapInstruments.Add(s10y); depoFRASwapInstruments.Add(s15y); YieldTermStructure depoFRASwapTermStructure = new PiecewiseYieldCurve<Discount,LogLinear>( settlementDate, depoFRASwapInstruments, termStructureDayCounter, new List<Handle<Quote>>(), new List<Date>(), tolerance); // Term structures that will be used for pricing: // the one used for discounting cash flows RelinkableHandle<YieldTermStructure> discountingTermStructure = new RelinkableHandle<YieldTermStructure>(); // the one used for forward rate forecasting RelinkableHandle<YieldTermStructure> forecastingTermStructure = new RelinkableHandle<YieldTermStructure>(); /********************* * SWAPS TO BE PRICED * **********************/ // constant nominal 1,000,000 Euro double nominal = 1000000.0; // fixed leg Frequency fixedLegFrequency = Frequency.Annual; BusinessDayConvention fixedLegConvention = BusinessDayConvention.Unadjusted; BusinessDayConvention floatingLegConvention = BusinessDayConvention.ModifiedFollowing; DayCounter fixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European); double fixedRate = 0.04; DayCounter floatingLegDayCounter = new Actual360(); // floating leg Frequency floatingLegFrequency = Frequency.Semiannual; IborIndex euriborIndex = new Euribor6M(forecastingTermStructure); double spread = 0.0; int lenghtInYears = 5; VanillaSwap.Type swapType = VanillaSwap.Type.Payer; Date maturity = settlementDate + new Period(lenghtInYears, TimeUnit.Years); Schedule fixedSchedule = new Schedule(settlementDate, maturity, new Period(fixedLegFrequency), calendar, fixedLegConvention, fixedLegConvention, DateGeneration.Rule.Forward, false); Schedule floatSchedule = new Schedule(settlementDate, maturity, new Period(floatingLegFrequency), calendar, floatingLegConvention, floatingLegConvention, DateGeneration.Rule.Forward, false); VanillaSwap spot5YearSwap = new VanillaSwap(swapType, nominal, fixedSchedule, fixedRate, fixedLegDayCounter, floatSchedule, euriborIndex, spread, floatingLegDayCounter); Date fwdStart = calendar.advance(settlementDate, 1, TimeUnit.Years); Date fwdMaturity = fwdStart + new Period(lenghtInYears, TimeUnit.Years); Schedule fwdFixedSchedule = new Schedule(fwdStart, fwdMaturity, new Period(fixedLegFrequency), calendar, fixedLegConvention, fixedLegConvention, DateGeneration.Rule.Forward, false); Schedule fwdFloatSchedule = new Schedule(fwdStart, fwdMaturity, new Period(floatingLegFrequency), calendar, floatingLegConvention, floatingLegConvention, DateGeneration.Rule.Forward, false); VanillaSwap oneYearForward5YearSwap = new VanillaSwap(swapType, nominal, fwdFixedSchedule, fixedRate, fixedLegDayCounter, fwdFloatSchedule, euriborIndex, spread, floatingLegDayCounter); /*************** * SWAP PRICING * ****************/ // utilities for reporting List<string> headers = new List<string>(); headers.Add("term structure"); headers.Add("net present value"); headers.Add("fair spread"); headers.Add("fair fixed rate"); string separator = " | "; int width = headers[0].Length + separator.Length + headers[1].Length + separator.Length + headers[2].Length + separator.Length + headers[3].Length + separator.Length - 1; string rule = string.Format("").PadLeft(width, '-'), dblrule = string.Format("").PadLeft(width, '='); string tab = string.Format("").PadLeft(8, ' '); // calculations Console.WriteLine(dblrule); Console.WriteLine("5-year market swap-rate = {0:0.00%}", s5yRate.value()); Console.WriteLine(dblrule); Console.WriteLine(tab + "5-years swap paying {0:0.00%}", fixedRate); Console.WriteLine(headers[0] + separator + headers[1] + separator + headers[2] + separator + headers[3] + separator); Console.WriteLine(rule); double NPV; double fairRate; double fairSpread; IPricingEngine swapEngine = new DiscountingSwapEngine(discountingTermStructure); spot5YearSwap.setPricingEngine(swapEngine); oneYearForward5YearSwap.setPricingEngine(swapEngine); // Of course, you're not forced to really use different curves forecastingTermStructure.linkTo(depoSwapTermStructure); discountingTermStructure.linkTo(depoSwapTermStructure); NPV = spot5YearSwap.NPV(); fairSpread = spot5YearSwap.fairSpread(); fairRate = spot5YearSwap.fairRate(); Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap"); Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); // let's check that the 5 years swap has been correctly re-priced if (!(Math.Abs(fairRate-s5yQuote)<1e-8)) throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate-s5yQuote)); forecastingTermStructure.linkTo(depoFutSwapTermStructure); discountingTermStructure.linkTo(depoFutSwapTermStructure); NPV = spot5YearSwap.NPV(); fairSpread = spot5YearSwap.fairSpread(); fairRate = spot5YearSwap.fairRate(); Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap"); Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); if (!(Math.Abs(fairRate-s5yQuote)<1e-8)) throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate-s5yQuote)); forecastingTermStructure.linkTo(depoFRASwapTermStructure); discountingTermStructure.linkTo(depoFRASwapTermStructure); NPV = spot5YearSwap.NPV(); fairSpread = spot5YearSwap.fairSpread(); fairRate = spot5YearSwap.fairRate(); Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap"); Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); if (!(Math.Abs(fairRate-s5yQuote)<1e-8)) throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate-s5yQuote)); Console.WriteLine(rule); // now let's price the 1Y forward 5Y swap Console.WriteLine(tab + "5-years, 1-year forward swap paying {0:0.00%}", fixedRate); Console.WriteLine(headers[0] + separator + headers[1] + separator + headers[2] + separator + headers[3] + separator); Console.WriteLine(rule); forecastingTermStructure.linkTo(depoSwapTermStructure); discountingTermStructure.linkTo(depoSwapTermStructure); NPV = oneYearForward5YearSwap.NPV(); fairSpread = oneYearForward5YearSwap.fairSpread(); fairRate = oneYearForward5YearSwap.fairRate(); Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap"); Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); forecastingTermStructure.linkTo(depoFutSwapTermStructure); discountingTermStructure.linkTo(depoFutSwapTermStructure); NPV = oneYearForward5YearSwap.NPV(); fairSpread = oneYearForward5YearSwap.fairSpread(); fairRate = oneYearForward5YearSwap.fairRate(); Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap"); Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); forecastingTermStructure.linkTo(depoFRASwapTermStructure); discountingTermStructure.linkTo(depoFRASwapTermStructure); NPV = oneYearForward5YearSwap.NPV(); fairSpread = oneYearForward5YearSwap.fairSpread(); fairRate = oneYearForward5YearSwap.fairRate(); Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap"); Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); // now let's say that the 5-years swap rate goes up to 4.60%. // A smarter market element--say, connected to a data source-- would // notice the change itself. Since we're using SimpleQuotes, // we'll have to change the value manually--which forces us to // downcast the handle and use the SimpleQuote // interface. In any case, the point here is that a change in the // value contained in the Quote triggers a new bootstrapping // of the curve and a repricing of the swap. SimpleQuote fiveYearsRate = s5yRate as SimpleQuote; fiveYearsRate.setValue(0.0460); Console.WriteLine(dblrule); Console.WriteLine("5-year market swap-rate = {0:0.00%}", s5yRate.value()); Console.WriteLine(dblrule); Console.WriteLine(tab + "5-years swap paying {0:0.00%}", fixedRate); Console.WriteLine(headers[0] + separator + headers[1] + separator + headers[2] + separator + headers[3] + separator); Console.WriteLine(rule); // now get the updated results forecastingTermStructure.linkTo(depoSwapTermStructure); discountingTermStructure.linkTo(depoSwapTermStructure); NPV = spot5YearSwap.NPV(); fairSpread = spot5YearSwap.fairSpread(); fairRate = spot5YearSwap.fairRate(); Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap"); Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); if (!(Math.Abs(fairRate-s5yRate.value())<1e-8)) throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate-s5yRate.value())); forecastingTermStructure.linkTo(depoFutSwapTermStructure); discountingTermStructure.linkTo(depoFutSwapTermStructure); NPV = spot5YearSwap.NPV(); fairSpread = spot5YearSwap.fairSpread(); fairRate = spot5YearSwap.fairRate(); Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap"); Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); if (!(Math.Abs(fairRate-s5yRate.value())<1e-8)) throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate-s5yRate.value())); forecastingTermStructure.linkTo(depoFRASwapTermStructure); discountingTermStructure.linkTo(depoFRASwapTermStructure); NPV = spot5YearSwap.NPV(); fairSpread = spot5YearSwap.fairSpread(); fairRate = spot5YearSwap.fairRate(); Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap"); Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); if (!(Math.Abs(fairRate-s5yRate.value())<1e-8)) throw new ApplicationException("5-years swap mispriced by " + Math.Abs(fairRate-s5yRate.value())); Console.WriteLine(rule); // the 1Y forward 5Y swap changes as well Console.WriteLine(tab + "5-years, 1-year forward swap paying {0:0.00%}", fixedRate); Console.WriteLine(headers[0] + separator + headers[1] + separator + headers[2] + separator + headers[3] + separator); Console.WriteLine(rule); forecastingTermStructure.linkTo(depoSwapTermStructure); discountingTermStructure.linkTo(depoSwapTermStructure); NPV = oneYearForward5YearSwap.NPV(); fairSpread = oneYearForward5YearSwap.fairSpread(); fairRate = oneYearForward5YearSwap.fairRate(); Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-swap"); Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); forecastingTermStructure.linkTo(depoFutSwapTermStructure); discountingTermStructure.linkTo(depoFutSwapTermStructure); NPV = oneYearForward5YearSwap.NPV(); fairSpread = oneYearForward5YearSwap.fairSpread(); fairRate = oneYearForward5YearSwap.fairRate(); Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-fut-swap"); Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); forecastingTermStructure.linkTo(depoFRASwapTermStructure); discountingTermStructure.linkTo(depoFRASwapTermStructure); NPV = oneYearForward5YearSwap.NPV(); fairSpread = oneYearForward5YearSwap.fairSpread(); fairRate = oneYearForward5YearSwap.fairRate(); Console.Write("{0," + headers[0].Length + ":0.00}" + separator, "depo-FRA-swap"); Console.Write("{0," + headers[1].Length + ":0.00}" + separator, NPV); Console.Write("{0," + headers[2].Length + ":0.00%}" + separator, fairSpread); Console.WriteLine("{0," + headers[3].Length + ":0.00%}" + separator, fairRate); Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer); Console.Write("Press any key to continue ..."); Console.ReadKey(); }
public void testModifiedCalendars() { Calendar c1 = new TARGET(); Calendar c2 = new UnitedStates(UnitedStates.Market.NYSE); Date d1 = new Date(1, Month.May, 2004); // holiday for both calendars Date d2 = new Date(26, Month.April, 2004); // business day Assert.IsTrue(c1.isHoliday(d1), "wrong assumption---correct the test"); Assert.IsTrue(c1.isBusinessDay(d2), "wrong assumption---correct the test"); Assert.IsTrue(c2.isHoliday(d1), "wrong assumption---correct the test"); Assert.IsTrue(c2.isBusinessDay(d2), "wrong assumption---correct the test"); // modify the TARGET calendar c1.removeHoliday(d1); c1.addHoliday(d2); // test Assert.IsFalse(c1.isHoliday(d1), d1 + " still a holiday for original TARGET instance"); Assert.IsFalse(c1.isBusinessDay(d2), d2 + " still a business day for original TARGET instance"); // any instance of TARGET should be modified... Calendar c3 = new TARGET(); Assert.IsFalse(c3.isHoliday(d1), d1 + " still a holiday for generic TARGET instance"); Assert.IsFalse(c3.isBusinessDay(d2), d2 + " still a business day for generic TARGET instance"); // ...but not other calendars Assert.IsFalse(c2.isBusinessDay(d1), d1 + " business day for New York"); Assert.IsFalse(c2.isHoliday(d2), d2 + " holiday for New York"); // restore original holiday set---test the other way around c3.addHoliday(d1); c3.removeHoliday(d2); Assert.IsFalse(c1.isBusinessDay(d1), d1 + " still a business day"); Assert.IsFalse(c1.isHoliday(d2), d2 + " still a holiday"); }
public void testEndOfMonth() { //BOOST_MESSAGE("Testing end-of-month calculation..."); Calendar c = new TARGET(); // any calendar would be OK Date eom, counter = Date.minDate(); Date last = Date.maxDate() - new Period(2, TimeUnit.Months); while (counter<=last) { eom = c.endOfMonth(counter); // check that eom is eom if (!c.isEndOfMonth(eom)) Assert.Fail("\n " + eom.weekday() + " " + eom + " is not the last business day in " + eom.month() + " " + eom.year() + " according to " + c.name()); // check that eom is in the same month as counter if (eom.month()!=counter.month()) Assert.Fail("\n " + eom + " is not in the same month as " + counter); counter = counter + 1; } }
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 void testCachedValue() { // Testing credit-default swap against cached values... SavedSettings backup = new SavedSettings(); // Initialize curves Settings.setEvaluationDate(new Date(9,Month.June,2006)); Date today = Settings.evaluationDate(); Calendar calendar = new TARGET(); Handle<Quote> hazardRate = new Handle<Quote>(new SimpleQuote(0.01234)); RelinkableHandle<DefaultProbabilityTermStructure> probabilityCurve = new RelinkableHandle<DefaultProbabilityTermStructure>(); probabilityCurve.linkTo(new FlatHazardRate(0, calendar, hazardRate, new Actual360())); RelinkableHandle<YieldTermStructure> discountCurve = new RelinkableHandle<YieldTermStructure>(); discountCurve.linkTo(new FlatForward(today,0.06,new Actual360())); // Build the schedule Date issueDate = calendar.advance(today, -1, TimeUnit.Years); Date maturity = calendar.advance(issueDate, 10, TimeUnit.Years); Frequency frequency = Frequency.Semiannual; BusinessDayConvention convention = BusinessDayConvention.ModifiedFollowing; Schedule schedule = new Schedule(issueDate, maturity, new Period(frequency), calendar, convention, convention, DateGeneration.Rule.Forward, false); // Build the CDS double fixedRate = 0.0120; DayCounter dayCount = new Actual360(); double notional = 10000.0; double recoveryRate = 0.4; CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, notional, fixedRate, schedule, convention, dayCount, true, true); cds.setPricingEngine(new MidPointCdsEngine(probabilityCurve,recoveryRate,discountCurve)); double npv = 295.0153398; double fairRate = 0.007517539081; double calculatedNpv = cds.NPV(); double calculatedFairRate = cds.fairSpread(); double tolerance = 1.0e-7; if (Math.Abs(calculatedNpv - npv) > tolerance) Assert.Fail( "Failed to reproduce NPV with mid-point engine\n" + " calculated NPV: " + calculatedNpv + "\n" + " expected NPV: " + npv); if (Math.Abs(calculatedFairRate - fairRate) > tolerance) Assert.Fail( "Failed to reproduce fair rate with mid-point engine\n" + " calculated fair rate: " + calculatedFairRate + "\n" + " expected fair rate: " + fairRate); cds.setPricingEngine(new IntegralCdsEngine(new Period(1,TimeUnit.Days),probabilityCurve, recoveryRate,discountCurve)); calculatedNpv = cds.NPV(); calculatedFairRate = cds.fairSpread(); tolerance = 1.0e-5; if (Math.Abs(calculatedNpv - npv) > notional*tolerance*10) Assert.Fail( "Failed to reproduce NPV with integral engine " + "(step = 1 day)\n" + " calculated NPV: " + calculatedNpv + "\n" + " expected NPV: " + npv); if (Math.Abs(calculatedFairRate - fairRate) > tolerance) Assert.Fail( "Failed to reproduce fair rate with integral engine " + "(step = 1 day)\n" + " calculated fair rate: " + calculatedFairRate + "\n" + " expected fair rate: " + fairRate); cds.setPricingEngine(new IntegralCdsEngine(new Period(1,TimeUnit.Weeks),probabilityCurve,recoveryRate,discountCurve)); calculatedNpv = cds.NPV(); calculatedFairRate = cds.fairSpread(); tolerance = 1.0e-5; if (Math.Abs(calculatedNpv - npv) > notional*tolerance*10) Assert.Fail( "Failed to reproduce NPV with integral engine " +"(step = 1 week)\n" + " calculated NPV: " + calculatedNpv + "\n" + " expected NPV: " + npv); if (Math.Abs(calculatedFairRate - fairRate) > tolerance) Assert.Fail( "Failed to reproduce fair rate with integral engine " +"(step = 1 week)\n" + " calculated fair rate: " + calculatedFairRate + "\n" + " expected fair rate: " + fairRate); }
//static void Main(string[] args) //{ // List<double> xGrid = Enumerable.Range(0, 100).Select(x => x / 10.0).ToList(); // List<double> yGrid = Enumerable.Range(0, 100).Select(x => x / 10.0).ToList(); // //List<double> xGrid = Enumerable.Range(0, 100); // CubicInterpolation cubic = new CubicInterpolation(xGrid, xGrid.Count, yGrid, // CubicInterpolation.DerivativeApprox.Kruger, true, // CubicInterpolation.BoundaryCondition.SecondDerivative , 0.0, // CubicInterpolation.BoundaryCondition.SecondDerivative , 0.0); //} static void Main(string[] args) { DateTime timer = DateTime.Now; // set up dates Calendar calendar = new TARGET(); Date todaysDate = new Date(15, Month.May, 1998); Date settlementDate = new Date(17, Month.May, 1998); Settings.setEvaluationDate(todaysDate); // our options Option.Type type = Option.Type.Put; double underlying = 36; double strike = 40; double dividendYield = 0.00; double riskFreeRate = 0.06; double volatility = 0.20; Date maturity = new Date(17, Month.May, 1999); DayCounter dayCounter = new Actual365Fixed(); Console.WriteLine("Option type = " + type); Console.WriteLine("Maturity = " + maturity); Console.WriteLine("Underlying price = " + underlying); Console.WriteLine("Strike = " + strike); Console.WriteLine("Risk-free interest rate = {0:0.000000%}", riskFreeRate); Console.WriteLine("Dividend yield = {0:0.000000%}", dividendYield); Console.WriteLine("Volatility = {0:0.000000%}", volatility); Console.Write("\n"); string method; Console.Write("\n"); // write column headings int[] widths = new int[] { 35, 14, 14, 14 }; Console.Write("{0,-" + widths[0] + "}", "Method"); Console.Write("{0,-" + widths[1] + "}", "European"); Console.Write("{0,-" + widths[2] + "}", "Bermudan"); Console.WriteLine("{0,-" + widths[3] + "}", "American"); List<Date> exerciseDates = new List<Date>(); ; for (int i = 1; i <= 4; i++) exerciseDates.Add(settlementDate + new Period(3 * i, TimeUnit.Months)); Exercise europeanExercise = new EuropeanExercise(maturity); Exercise bermudanExercise = new BermudanExercise(exerciseDates); Exercise americanExercise = new AmericanExercise(settlementDate, maturity); Handle<Quote> underlyingH = new Handle<Quote>(new SimpleQuote(underlying)); // bootstrap the yield/dividend/vol curves var flatTermStructure = new Handle<YieldTermStructure>(new FlatForward(settlementDate, riskFreeRate, dayCounter)); var flatDividendTS = new Handle<YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter)); var flatVolTS = new Handle<BlackVolTermStructure>(new BlackConstantVol(settlementDate, calendar, volatility, dayCounter)); StrikedTypePayoff payoff = new PlainVanillaPayoff(type, strike); var bsmProcess = new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS); // options VanillaOption europeanOption = new VanillaOption(payoff, europeanExercise); VanillaOption bermudanOption = new VanillaOption(payoff, bermudanExercise); VanillaOption americanOption = new VanillaOption(payoff, americanExercise); // Analytic formulas: // Black-Scholes for European method = "Black-Scholes"; europeanOption.setPricingEngine(new AnalyticEuropeanEngine(bsmProcess)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + "}", "N/A"); Console.WriteLine("{0,-" + widths[3] + "}", "N/A"); europeanOption.theta(); // Barone-Adesi and Whaley approximation for American method = "Barone-Adesi/Whaley"; americanOption.setPricingEngine(new BaroneAdesiWhaleyApproximationEngine(bsmProcess)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + "}", "N/A"); Console.Write("{0,-" + widths[2] + "}", "N/A"); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); // Bjerksund and Stensland approximation for American method = "Bjerksund/Stensland"; americanOption.setPricingEngine(new BjerksundStenslandApproximationEngine(bsmProcess)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + "}", "N/A"); Console.Write("{0,-" + widths[2] + "}", "N/A"); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); // Integral method = "Integral"; europeanOption.setPricingEngine(new IntegralEngine(bsmProcess)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + "}", "N/A"); Console.WriteLine("{0,-" + widths[3] + "}", "N/A"); // Finite differences int timeSteps = 801; method = "Finite differences"; europeanOption.setPricingEngine(new FDEuropeanEngine(bsmProcess, timeSteps, timeSteps - 1)); bermudanOption.setPricingEngine(new FDBermudanEngine(bsmProcess, timeSteps, timeSteps - 1)); americanOption.setPricingEngine(new FDAmericanEngine(bsmProcess, timeSteps, timeSteps - 1)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); // Binomial method: Jarrow-Rudd method = "Binomial Jarrow-Rudd"; europeanOption.setPricingEngine(new BinomialVanillaEngine<JarrowRudd>(bsmProcess, timeSteps)); bermudanOption.setPricingEngine(new BinomialVanillaEngine<JarrowRudd>(bsmProcess, timeSteps)); americanOption.setPricingEngine(new BinomialVanillaEngine<JarrowRudd>(bsmProcess, timeSteps)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); method = "Binomial Cox-Ross-Rubinstein"; europeanOption.setPricingEngine(new BinomialVanillaEngine<CoxRossRubinstein>(bsmProcess, timeSteps)); bermudanOption.setPricingEngine(new BinomialVanillaEngine<CoxRossRubinstein>(bsmProcess, timeSteps)); americanOption.setPricingEngine(new BinomialVanillaEngine<CoxRossRubinstein>(bsmProcess, timeSteps)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); // Binomial method: Additive equiprobabilities method = "Additive equiprobabilities"; europeanOption.setPricingEngine(new BinomialVanillaEngine<AdditiveEQPBinomialTree>(bsmProcess, timeSteps)); bermudanOption.setPricingEngine(new BinomialVanillaEngine<AdditiveEQPBinomialTree>(bsmProcess, timeSteps)); americanOption.setPricingEngine(new BinomialVanillaEngine<AdditiveEQPBinomialTree>(bsmProcess, timeSteps)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); // Binomial method: Binomial Trigeorgis method = "Binomial Trigeorgis"; europeanOption.setPricingEngine(new BinomialVanillaEngine<Trigeorgis>(bsmProcess, timeSteps)); bermudanOption.setPricingEngine(new BinomialVanillaEngine<Trigeorgis>(bsmProcess, timeSteps)); americanOption.setPricingEngine(new BinomialVanillaEngine<Trigeorgis>(bsmProcess, timeSteps)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); // Binomial method: Binomial Tian method = "Binomial Tian"; europeanOption.setPricingEngine(new BinomialVanillaEngine<Tian>(bsmProcess, timeSteps)); bermudanOption.setPricingEngine(new BinomialVanillaEngine<Tian>(bsmProcess, timeSteps)); americanOption.setPricingEngine(new BinomialVanillaEngine<Tian>(bsmProcess, timeSteps)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); // Binomial method: Binomial Leisen-Reimer method = "Binomial Leisen-Reimer"; europeanOption.setPricingEngine(new BinomialVanillaEngine<LeisenReimer>(bsmProcess, timeSteps)); bermudanOption.setPricingEngine(new BinomialVanillaEngine<LeisenReimer>(bsmProcess, timeSteps)); americanOption.setPricingEngine(new BinomialVanillaEngine<LeisenReimer>(bsmProcess, timeSteps)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); // Binomial method: Binomial Joshi method = "Binomial Joshi"; europeanOption.setPricingEngine(new BinomialVanillaEngine<Joshi4>(bsmProcess, timeSteps)); bermudanOption.setPricingEngine(new BinomialVanillaEngine<Joshi4>(bsmProcess, timeSteps)); americanOption.setPricingEngine(new BinomialVanillaEngine<Joshi4>(bsmProcess, timeSteps)); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + ":0.000000}", bermudanOption.NPV()); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); // Monte Carlo Method: MC (crude) timeSteps = 1; method = "MC (crude)"; ulong mcSeed = 42; IPricingEngine mcengine1 = new MakeMCEuropeanEngine<PseudoRandom>(bsmProcess) .withSteps(timeSteps) .withAbsoluteTolerance(0.02) .withSeed(mcSeed) .value(); europeanOption.setPricingEngine(mcengine1); // Real errorEstimate = europeanOption.errorEstimate(); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + ":0.000000}", "N/A"); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", "N/A"); // Monte Carlo Method: QMC (Sobol) method = "QMC (Sobol)"; int nSamples = 32768; // 2^15 IPricingEngine mcengine2 = new MakeMCEuropeanEngine<LowDiscrepancy>(bsmProcess) .withSteps(timeSteps) .withSamples(nSamples) .value(); europeanOption.setPricingEngine(mcengine2); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", europeanOption.NPV()); Console.Write("{0,-" + widths[2] + ":0.000000}", "N/A"); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", "N/A"); // Monte Carlo Method: MC (Longstaff Schwartz) method = "MC (Longstaff Schwartz)"; IPricingEngine mcengine3 = new MakeMCAmericanEngine<PseudoRandom>(bsmProcess) .withSteps(100) .withAntitheticVariate() .withCalibrationSamples(4096) .withAbsoluteTolerance(0.02) .withSeed(mcSeed) .value(); americanOption.setPricingEngine(mcengine3); Console.Write("{0,-" + widths[0] + "}", method); Console.Write("{0,-" + widths[1] + ":0.000000}", "N/A"); Console.Write("{0,-" + widths[2] + ":0.000000}", "N/A"); Console.WriteLine("{0,-" + widths[3] + ":0.000000}", americanOption.NPV()); // End test Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer); Console.WriteLine(); Console.Write("Press any key to continue ..."); Console.ReadKey(); }
public void testZSpreadWithGenericBond() { // Testing clean and dirty price with null Z-spread against theoretical prices... CommonVars vars = new CommonVars(); Calendar bondCalendar = new TARGET(); int settlementDays = 3; int fixingDays = 2; bool inArrears = false; // Fixed Underlying bond (Isin: DE0001135275 DBR 4 01/04/37) // maturity doesn't occur on a business day Date fixedBondStartDate1 = new Date(4,Month.January,2005); Date fixedBondMaturityDate1 = new Date(4,Month.January,2037); Schedule fixedBondSchedule1= new Schedule(fixedBondStartDate1, fixedBondMaturityDate1, new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> fixedBondLeg1 = new FixedRateLeg(fixedBondSchedule1) .withCouponRates(0.04, new ActualActual(ActualActual.Convention.ISDA)) .withNotionals(vars.faceAmount); Date fixedbondRedemption1 = bondCalendar.adjust(fixedBondMaturityDate1, BusinessDayConvention.Following); fixedBondLeg1.Add(new SimpleCashFlow(100.0, fixedbondRedemption1)); Bond fixedBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, fixedBondMaturityDate1, fixedBondStartDate1, fixedBondLeg1); IPricingEngine bondEngine = new DiscountingBondEngine(vars.termStructure); fixedBond1.setPricingEngine(bondEngine); double fixedBondImpliedValue1 = fixedBond1.cleanPrice(); Date fixedBondSettlementDate1= fixedBond1.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double fixedBondCleanPrice1 = BondFunctions.cleanPrice(fixedBond1, vars.termStructure, vars.spread, new Actual365Fixed(), vars.compounding, Frequency.Annual, fixedBondSettlementDate1); double tolerance = 1.0e-13; double error1 = Math.Abs(fixedBondImpliedValue1-fixedBondCleanPrice1); if (error1>tolerance) { Assert.Fail("wrong clean price for fixed bond:" + "\n market asset swap spread: " + fixedBondImpliedValue1 + "\n par asset swap spread: " + fixedBondCleanPrice1 + "\n error: " + error1 + "\n tolerance: " + tolerance); } // Fixed Underlying bond (Isin: IT0006527060 IBRD 5 02/05/19) // maturity occurs on a business day Date fixedBondStartDate2 = new Date(5,Month.February,2005); Date fixedBondMaturityDate2 = new Date(5,Month.February,2019); Schedule fixedBondSchedule2= new Schedule(fixedBondStartDate2, fixedBondMaturityDate2, new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> fixedBondLeg2 = new FixedRateLeg(fixedBondSchedule2) .withCouponRates(0.05, new Thirty360(Thirty360.Thirty360Convention.BondBasis)) .withNotionals(vars.faceAmount); Date fixedbondRedemption2 = bondCalendar.adjust(fixedBondMaturityDate2, BusinessDayConvention.Following); fixedBondLeg2.Add(new SimpleCashFlow(100.0, fixedbondRedemption2)); Bond fixedBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, fixedBondMaturityDate2, fixedBondStartDate2, fixedBondLeg2); fixedBond2.setPricingEngine(bondEngine); double fixedBondImpliedValue2 = fixedBond2.cleanPrice(); Date fixedBondSettlementDate2= fixedBond2.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double fixedBondCleanPrice2 = BondFunctions.cleanPrice(fixedBond2, vars.termStructure, vars.spread, new Actual365Fixed(), vars.compounding, Frequency.Annual, fixedBondSettlementDate2); double error3 = Math.Abs(fixedBondImpliedValue2-fixedBondCleanPrice2); if (error3>tolerance) { Assert.Fail("wrong clean price for fixed bond:" + "\n market asset swap spread: " + fixedBondImpliedValue2 + "\n par asset swap spread: " + fixedBondCleanPrice2 + "\n error: " + error3 + "\n tolerance: " + tolerance); } // FRN Underlying bond (Isin: IT0003543847 ISPIM 0 09/29/13) // maturity doesn't occur on a business day Date floatingBondStartDate1 = new Date(29,Month.September,2003); Date floatingBondMaturityDate1 = new Date(29,Month.September,2013); Schedule floatingBondSchedule1= new Schedule(floatingBondStartDate1, floatingBondMaturityDate1, new Period(Frequency.Semiannual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> floatingBondLeg1 = new IborLeg(floatingBondSchedule1, vars.iborIndex) .withPaymentDayCounter(new Actual360()) .withFixingDays(fixingDays) .withSpreads(0.0056) .inArrears(inArrears) .withNotionals(vars.faceAmount); Date floatingbondRedemption1 = bondCalendar.adjust(floatingBondMaturityDate1, BusinessDayConvention.Following); floatingBondLeg1.Add(new SimpleCashFlow(100.0, floatingbondRedemption1)); Bond floatingBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, floatingBondMaturityDate1, floatingBondStartDate1, floatingBondLeg1); floatingBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond1.cashflows(), vars.pricer); vars.iborIndex.addFixing(new Date(27,Month.March,2007), 0.0402); double floatingBondImpliedValue1 = floatingBond1.cleanPrice(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double floatingBondCleanPrice1 = BondFunctions.cleanPrice(floatingBond1, vars.termStructure, vars.spread, new Actual365Fixed(), vars.compounding, Frequency.Semiannual, fixedBondSettlementDate1); double error5 = Math.Abs(floatingBondImpliedValue1-floatingBondCleanPrice1); if (error5>tolerance) { Assert.Fail("wrong clean price for fixed bond:" + "\n market asset swap spread: " + floatingBondImpliedValue1 + "\n par asset swap spread: " + floatingBondCleanPrice1 + "\n error: " + error5 + "\n tolerance: " + tolerance); } // FRN Underlying bond (Isin: XS0090566539 COE 0 09/24/18) // maturity occurs on a business day Date floatingBondStartDate2 = new Date(24,Month.September,2004); Date floatingBondMaturityDate2 = new Date(24,Month.September,2018); Schedule floatingBondSchedule2 = new Schedule(floatingBondStartDate2, floatingBondMaturityDate2, new Period(Frequency.Semiannual), bondCalendar, BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, DateGeneration.Rule.Backward, false); List<CashFlow> floatingBondLeg2 = new IborLeg(floatingBondSchedule2, vars.iborIndex) .withFixingDays(fixingDays) .withSpreads(0.0025) .withPaymentDayCounter(new Actual360()) .inArrears(inArrears) .withPaymentAdjustment(BusinessDayConvention.ModifiedFollowing) .withNotionals(vars.faceAmount); Date floatingbondRedemption2 = bondCalendar.adjust(floatingBondMaturityDate2, BusinessDayConvention.ModifiedFollowing); floatingBondLeg2.Add(new SimpleCashFlow(100.0, floatingbondRedemption2)); Bond floatingBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, floatingBondMaturityDate2, floatingBondStartDate2, floatingBondLeg2); floatingBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond2.cashflows(), vars.pricer); vars.iborIndex.addFixing(new Date(22,Month.March,2007), 0.04013); double floatingBondImpliedValue2 = floatingBond2.cleanPrice(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double floatingBondCleanPrice2 = BondFunctions.cleanPrice(floatingBond2, vars.termStructure, vars.spread, new Actual365Fixed(), vars.compounding, Frequency.Semiannual, fixedBondSettlementDate1); double error7 = Math.Abs(floatingBondImpliedValue2-floatingBondCleanPrice2); if (error7>tolerance) { Assert.Fail("wrong clean price for fixed bond:" + "\n market asset swap spread: " + floatingBondImpliedValue2 + "\n par asset swap spread: " + floatingBondCleanPrice2 + "\n error: " + error7 + "\n tolerance: " + tolerance); } // CMS Underlying bond (Isin: XS0228052402 CRDIT 0 8/22/20) // maturity doesn't occur on a business day Date cmsBondStartDate1 = new Date(22,Month.August,2005); Date cmsBondMaturityDate1 = new Date(22,Month.August,2020); Schedule cmsBondSchedule1= new Schedule(cmsBondStartDate1, cmsBondMaturityDate1, new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> cmsBondLeg1 = new CmsLeg(cmsBondSchedule1, vars.swapIndex) .withPaymentDayCounter(new Thirty360()) .withFixingDays(fixingDays) .withCaps(0.055) .withFloors(0.025) .inArrears(inArrears) .withNotionals(vars.faceAmount); Date cmsbondRedemption1 = bondCalendar.adjust(cmsBondMaturityDate1, BusinessDayConvention.Following); cmsBondLeg1.Add(new SimpleCashFlow(100.0, cmsbondRedemption1)); Bond cmsBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, cmsBondMaturityDate1, cmsBondStartDate1, cmsBondLeg1); cmsBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond1.cashflows(), vars.cmspricer); vars.swapIndex.addFixing(new Date(18,Month.August,2006), 0.04158); double cmsBondImpliedValue1 = cmsBond1.cleanPrice(); Date cmsBondSettlementDate1= cmsBond1.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double cmsBondCleanPrice1 = BondFunctions.cleanPrice(cmsBond1, vars.termStructure, vars.spread, new Actual365Fixed(), vars.compounding, Frequency.Annual, cmsBondSettlementDate1); double error9 = Math.Abs(cmsBondImpliedValue1-cmsBondCleanPrice1); if (error9>tolerance) { Assert.Fail("wrong clean price for fixed bond:" + "\n market asset swap spread: " + cmsBondImpliedValue1 + "\n par asset swap spread: " + cmsBondCleanPrice1 + "\n error: " + error9 + "\n tolerance: " + tolerance); } // CMS Underlying bond (Isin: XS0218766664 ISPIM 0 5/6/15) // maturity occurs on a business day Date cmsBondStartDate2 = new Date(06,Month.May,2005); Date cmsBondMaturityDate2 = new Date(06,Month.May,2015); Schedule cmsBondSchedule2= new Schedule(cmsBondStartDate2, cmsBondMaturityDate2, new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> cmsBondLeg2 = new CmsLeg(cmsBondSchedule2, vars.swapIndex) .withPaymentDayCounter(new Thirty360()) .withFixingDays(fixingDays) .withGearings(0.84) .inArrears(inArrears) .withNotionals(vars.faceAmount); Date cmsbondRedemption2 = bondCalendar.adjust(cmsBondMaturityDate2, BusinessDayConvention.Following); cmsBondLeg2.Add(new SimpleCashFlow(100.0, cmsbondRedemption2)); Bond cmsBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, cmsBondMaturityDate2, cmsBondStartDate2, cmsBondLeg2); cmsBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond2.cashflows(), vars.cmspricer); vars.swapIndex.addFixing(new Date(04,Month.May,2006), 0.04217); double cmsBondImpliedValue2 = cmsBond2.cleanPrice(); Date cmsBondSettlementDate2= cmsBond2.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double cmsBondCleanPrice2 = BondFunctions.cleanPrice(cmsBond2, vars.termStructure, vars.spread, new Actual365Fixed(), vars.compounding, Frequency.Annual, cmsBondSettlementDate2); double error11 = Math.Abs(cmsBondImpliedValue2-cmsBondCleanPrice2); if (error11>tolerance) { Assert.Fail("wrong clean price for fixed bond:" + "\n market asset swap spread: " + cmsBondImpliedValue2 + "\n par asset swap spread: " + cmsBondCleanPrice2 + "\n error: " + error11 + "\n tolerance: " + tolerance); } // Zero Coupon bond (Isin: DE0004771662 IBRD 0 12/20/15) // maturity doesn't occur on a business day Date zeroCpnBondStartDate1 = new Date(19,Month.December,1985); Date zeroCpnBondMaturityDate1 = new Date(20,Month.December,2015); Date zeroCpnBondRedemption1 = bondCalendar.adjust(zeroCpnBondMaturityDate1, BusinessDayConvention.Following); List<CashFlow> zeroCpnBondLeg1 = new List<CashFlow>{new SimpleCashFlow(100.0, zeroCpnBondRedemption1)}; Bond zeroCpnBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, zeroCpnBondMaturityDate1, zeroCpnBondStartDate1, zeroCpnBondLeg1); zeroCpnBond1.setPricingEngine(bondEngine); double zeroCpnBondImpliedValue1 = zeroCpnBond1.cleanPrice(); Date zeroCpnBondSettlementDate1= zeroCpnBond1.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double zeroCpnBondCleanPrice1 = BondFunctions.cleanPrice(zeroCpnBond1, vars.termStructure, vars.spread, new Actual365Fixed(), vars.compounding, Frequency.Annual, zeroCpnBondSettlementDate1); double error13 = Math.Abs(zeroCpnBondImpliedValue1-zeroCpnBondCleanPrice1); if (error13>tolerance) { Assert.Fail("wrong clean price for zero coupon bond:" + "\n zero cpn implied value: " + zeroCpnBondImpliedValue1 + "\n zero cpn price: " + zeroCpnBondCleanPrice1 + "\n error: " + error13 + "\n tolerance: " + tolerance); } // Zero Coupon bond (Isin: IT0001200390 ISPIM 0 02/17/28) // maturity occurs on a business day Date zeroCpnBondStartDate2 = new Date(17,Month.February,1998); Date zeroCpnBondMaturityDate2 = new Date(17,Month.February,2028); Date zerocpbondRedemption2 = bondCalendar.adjust(zeroCpnBondMaturityDate2, BusinessDayConvention.Following); List<CashFlow> zeroCpnBondLeg2 = new List<CashFlow>{new SimpleCashFlow(100.0, zerocpbondRedemption2)}; Bond zeroCpnBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, zeroCpnBondMaturityDate2, zeroCpnBondStartDate2, zeroCpnBondLeg2); zeroCpnBond2.setPricingEngine(bondEngine); double zeroCpnBondImpliedValue2 = zeroCpnBond2.cleanPrice(); Date zeroCpnBondSettlementDate2= zeroCpnBond2.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double zeroCpnBondCleanPrice2 = BondFunctions.cleanPrice(zeroCpnBond2, vars.termStructure, vars.spread, new Actual365Fixed(), vars.compounding, Frequency.Annual, zeroCpnBondSettlementDate2); double error15 = Math.Abs(zeroCpnBondImpliedValue2-zeroCpnBondCleanPrice2); if (error15>tolerance) { Assert.Fail("wrong clean price for zero coupon bond:" + "\n zero cpn implied value: " + zeroCpnBondImpliedValue2 + "\n zero cpn price: " + zeroCpnBondCleanPrice2 + "\n error: " + error15 + "\n tolerance: " + tolerance); } }
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 testFairUpfront() { // Testing fair-upfront calculation for credit-default swaps... SavedSettings backup = new SavedSettings(); // Initialize curves Calendar calendar = new TARGET(); Date today = calendar.adjust(Date.Today); Settings.setEvaluationDate(today); Handle<Quote> hazardRate = new Handle<Quote>(new SimpleQuote(0.01234)); RelinkableHandle<DefaultProbabilityTermStructure> probabilityCurve = new RelinkableHandle<DefaultProbabilityTermStructure>(); probabilityCurve.linkTo(new FlatHazardRate(0, calendar, hazardRate, new Actual360())); RelinkableHandle<YieldTermStructure> discountCurve = new RelinkableHandle<YieldTermStructure>(); discountCurve.linkTo(new FlatForward(today,0.06,new Actual360())); // Build the schedule Date issueDate = today; Date maturity = calendar.advance(issueDate, 10, TimeUnit.Years); BusinessDayConvention convention = BusinessDayConvention.Following; Schedule schedule = new MakeSchedule().from(issueDate) .to(maturity) .withFrequency(Frequency.Quarterly) .withCalendar(calendar) .withTerminationDateConvention(convention) .withRule(DateGeneration.Rule.TwentiethIMM).value(); // Build the CDS double fixedRate = 0.05; double upfront = 0.001; DayCounter dayCount = new Actual360(); double notional = 10000.0; double recoveryRate = 0.4; IPricingEngine engine = new MidPointCdsEngine(probabilityCurve, recoveryRate, discountCurve, true); CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, notional, upfront, fixedRate, schedule, convention, dayCount, true, true); cds.setPricingEngine(engine); double fairUpfront = cds.fairUpfront(); CreditDefaultSwap fairCds = new CreditDefaultSwap(Protection.Side.Seller, notional, fairUpfront, fixedRate, schedule, convention, dayCount, true, true); fairCds.setPricingEngine(engine); double fairNPV = fairCds.NPV(); double tolerance = 1e-10; if (Math.Abs(fairNPV) > tolerance) Assert.Fail( "Failed to reproduce null NPV with calculated fair upfront\n" + " calculated upfront: " + fairUpfront + "\n" + " calculated NPV: " + fairNPV); // same with null upfront to begin with upfront = 0.0; CreditDefaultSwap cds2 = new CreditDefaultSwap(Protection.Side.Seller, notional, upfront, fixedRate, schedule, convention, dayCount, true, true); cds2.setPricingEngine(engine); fairUpfront = cds2.fairUpfront(); CreditDefaultSwap fairCds2 = new CreditDefaultSwap(Protection.Side.Seller, notional, fairUpfront, fixedRate, schedule, convention, dayCount, true, true); fairCds2.setPricingEngine(engine); fairNPV = fairCds2.NPV(); if (Math.Abs(fairNPV) > tolerance) Assert.Fail( "Failed to reproduce null NPV with calculated fair upfront\n" + " calculated upfront: " + fairUpfront + "\n" + " calculated NPV: " + fairNPV); }
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 testImpliedHazardRate() { // Testing implied hazard-rate for credit-default swaps... SavedSettings backup = new SavedSettings(); // Initialize curves Calendar calendar = new TARGET(); Date today = calendar.adjust(Date.Today); Settings.setEvaluationDate(today); double h1 = 0.30, h2 = 0.40; DayCounter dayCounter = new Actual365Fixed(); List<Date> dates = new List<Date>(3); List<double> hazardRates = new List<double>(3); dates.Add(today); hazardRates.Add(h1); dates.Add(today + new Period(5,TimeUnit.Years)); hazardRates.Add(h1); dates.Add(today + new Period(10,TimeUnit.Years)); hazardRates.Add(h2); RelinkableHandle<DefaultProbabilityTermStructure> probabilityCurve = new RelinkableHandle<DefaultProbabilityTermStructure>(); probabilityCurve.linkTo(new InterpolatedHazardRateCurve<BackwardFlat>(dates, hazardRates, dayCounter)); RelinkableHandle<YieldTermStructure> discountCurve = new RelinkableHandle<YieldTermStructure>(); discountCurve.linkTo(new FlatForward(today,0.03,new Actual360())); Frequency frequency = Frequency.Semiannual; BusinessDayConvention convention = BusinessDayConvention.ModifiedFollowing; Date issueDate = calendar.advance(today, -6, TimeUnit.Months); double fixedRate = 0.0120; DayCounter cdsDayCount = new Actual360(); double notional = 10000.0; double recoveryRate = 0.4; double? latestRate = null; for (int n=6; n<=10; ++n) { Date maturity = calendar.advance(issueDate, n, TimeUnit.Years); Schedule schedule = new Schedule(issueDate, maturity, new Period(frequency), calendar, convention, convention, DateGeneration.Rule.Forward, false); CreditDefaultSwap cds = new CreditDefaultSwap(Protection.Side.Seller, notional, fixedRate, schedule, convention, cdsDayCount,true, true); cds.setPricingEngine(new MidPointCdsEngine(probabilityCurve, recoveryRate, discountCurve)); double NPV = cds.NPV(); double flatRate = cds.impliedHazardRate(NPV, discountCurve, dayCounter, recoveryRate); if (flatRate < h1 || flatRate > h2) { Assert.Fail("implied hazard rate outside expected range\n" + " maturity: " + n + " years\n" + " expected minimum: " + h1 + "\n" + " expected maximum: " + h2 + "\n" + " implied rate: " + flatRate); } if (n > 6 && flatRate < latestRate) { Assert.Fail("implied hazard rate decreasing with swap maturity\n" + " maturity: " + n + " years\n" + " previous rate: " + latestRate + "\n" + " implied rate: " + flatRate); } latestRate = flatRate; RelinkableHandle<DefaultProbabilityTermStructure> probability = new RelinkableHandle<DefaultProbabilityTermStructure>(); probability.linkTo(new FlatHazardRate( today,new Handle<Quote>(new SimpleQuote(flatRate)),dayCounter)); CreditDefaultSwap cds2 = new CreditDefaultSwap(Protection.Side.Seller, notional, fixedRate, schedule, convention, cdsDayCount,true, true); cds2.setPricingEngine(new MidPointCdsEngine(probability,recoveryRate,discountCurve)); double NPV2 = cds2.NPV(); double tolerance = 1.0; if (Math.Abs(NPV-NPV2) > tolerance) { Assert.Fail("failed to reproduce NPV with implied rate\n" + " expected: " + NPV + "\n" + " calculated: " + NPV2); } } }
public void testJointCalendars() { Calendar c1 = new TARGET(), c2 = new UnitedKingdom(), c3 = new UnitedStates(UnitedStates.Market.NYSE), c4 = new Japan(); Calendar c12h = new JointCalendar(c1, c2, JointCalendar.JointCalendarRule.JoinHolidays), c12b = new JointCalendar(c1,c2,JointCalendar.JointCalendarRule.JoinBusinessDays), c123h = new JointCalendar(c1,c2,c3,JointCalendar.JointCalendarRule.JoinHolidays), c123b = new JointCalendar(c1,c2,c3,JointCalendar.JointCalendarRule.JoinBusinessDays), c1234h = new JointCalendar(c1,c2,c3,c4,JointCalendar.JointCalendarRule.JoinHolidays), c1234b = new JointCalendar(c1,c2,c3,c4,JointCalendar.JointCalendarRule.JoinBusinessDays); // test one year, starting today Date firstDate = Date.Today, endDate = firstDate + new Period(1, TimeUnit.Years); for (Date d = firstDate; d < endDate; d++) { bool b1 = c1.isBusinessDay(d), b2 = c2.isBusinessDay(d), b3 = c3.isBusinessDay(d), b4 = c4.isBusinessDay(d); if ((b1 && b2) != c12h.isBusinessDay(d)) Assert.Fail("At date " + d + ":\n" + " inconsistency between joint calendar " + c12h.name() + " (joining holidays)\n" + " and its components"); if ((b1 || b2) != c12b.isBusinessDay(d)) Assert.Fail("At date " + d + ":\n" + " inconsistency between joint calendar " + c12b.name() + " (joining business days)\n" + " and its components"); if ((b1 && b2 && b3) != c123h.isBusinessDay(d)) Assert.Fail("At date " + d + ":\n" + " inconsistency between joint calendar " + c123h.name() + " (joining holidays)\n" + " and its components"); if ((b1 || b2 || b3) != c123b.isBusinessDay(d)) Assert.Fail("At date " + d + ":\n" + " inconsistency between joint calendar " + c123b.name() + " (joining business days)\n" + " and its components"); if ((b1 && b2 && b3 && b4) != c1234h.isBusinessDay(d)) Assert.Fail("At date " + d + ":\n" + " inconsistency between joint calendar " + c1234h.name() + " (joining holidays)\n" + " and its components"); if ((b1 || b2 || b3 || b4) != c1234b.isBusinessDay(d)) Assert.Fail("At date " + d + ":\n" + " inconsistency between joint calendar " + c1234b.name() + " (joining business days)\n" + " and its components"); } }
public void testSwaps() { //BOOST_MESSAGE("Testing Hull-White swap pricing against known values..."); Date today; //=Settings::instance().evaluationDate();; Calendar calendar = new TARGET(); today = calendar.adjust(Date.Today); Settings.setEvaluationDate(today); Date settlement = calendar.advance(today, 2, TimeUnit.Days); Date[] dates = { settlement, calendar.advance(settlement,1,TimeUnit.Weeks), calendar.advance(settlement,1,TimeUnit.Months), calendar.advance(settlement,3,TimeUnit.Months), calendar.advance(settlement,6,TimeUnit.Months), calendar.advance(settlement,9,TimeUnit.Months), calendar.advance(settlement,1,TimeUnit.Years), calendar.advance(settlement,2,TimeUnit.Years), calendar.advance(settlement,3,TimeUnit.Years), calendar.advance(settlement,5,TimeUnit.Years), calendar.advance(settlement,10,TimeUnit.Years), calendar.advance(settlement,15,TimeUnit.Years) }; double[] discounts = { 1.0, 0.999258, 0.996704, 0.990809, 0.981798, 0.972570, 0.963430, 0.929532, 0.889267, 0.803693, 0.596903, 0.433022 }; //for (int i = 0; i < dates.Length; i++) // dates[i] + dates.Length; LogLinear Interpolator = new LogLinear(); Handle<YieldTermStructure> termStructure = new Handle<YieldTermStructure>( new InterpolatedDiscountCurve<LogLinear>( dates.ToList<Date>(), discounts.ToList<double>(), new Actual365Fixed(),new Calendar(), null, null , Interpolator) ); HullWhite model = new HullWhite(termStructure); int[] start = { -3, 0, 3 }; int[] length = { 2, 5, 10 }; double[] rates = { 0.02, 0.04, 0.06 }; IborIndex euribor = new Euribor6M(termStructure); IPricingEngine engine = new TreeVanillaSwapEngine(model, 120, termStructure); #if QL_USE_INDEXED_COUPON double tolerance = 4.0e-3; #else double tolerance = 1.0e-8; #endif for (int i=0; i<start.Length; i++) { Date startDate = calendar.advance(settlement,start[i],TimeUnit.Months); if (startDate < today) { Date fixingDate = calendar.advance(startDate,-2,TimeUnit.Days); //TimeSeries<double> pastFixings; ObservableValue<TimeSeries<double>> pastFixings = new ObservableValue<TimeSeries<double>>(); pastFixings.value()[fixingDate] = 0.03; IndexManager.instance().setHistory(euribor.name(), pastFixings); } for (int j=0; j<length.Length; j++) { Date maturity = calendar.advance(startDate, length[i], TimeUnit.Years); Schedule fixedSchedule = new Schedule(startDate, maturity, new Period(Frequency.Annual), calendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Forward, false); Schedule floatSchedule = new Schedule(startDate, maturity, new Period(Frequency.Semiannual), calendar, BusinessDayConvention.Following, BusinessDayConvention.Following, DateGeneration.Rule.Forward, false); for (int k=0; k<rates.Length; k++) { VanillaSwap swap = new VanillaSwap(VanillaSwap.Type.Payer, 1000000.0, fixedSchedule, rates[k], new Thirty360(), floatSchedule, euribor, 0.0, new Actual360()); swap.setPricingEngine(new DiscountingSwapEngine(termStructure)); double expected = swap.NPV(); swap.setPricingEngine(engine); double calculated = swap.NPV(); double error = Math.Abs((expected-calculated)/expected); if (error > tolerance) { Assert.Fail("Failed to reproduce swap NPV:" //+ QL_FIXED << std::setprecision(9) + "\n calculated: " + calculated + "\n expected: " + expected //+ QL_SCIENTIFIC + "\n rel. error: " + error); } } } } }
public void testTARGET() { List<Date> expectedHol = new List<Date>(); expectedHol.Add(new Date(1,Month.January,1999)); expectedHol.Add(new Date(31, Month.December, 1999)); expectedHol.Add(new Date(21, Month.April, 2000)); expectedHol.Add(new Date(24, Month.April, 2000)); expectedHol.Add(new Date(1, Month.May, 2000)); expectedHol.Add(new Date(25, Month.December, 2000)); expectedHol.Add(new Date(26, Month.December, 2000)); expectedHol.Add(new Date(1, Month.January, 2001)); expectedHol.Add(new Date(13, Month.April, 2001)); expectedHol.Add(new Date(16, Month.April, 2001)); expectedHol.Add(new Date(1, Month.May, 2001)); expectedHol.Add(new Date(25, Month.December, 2001)); expectedHol.Add(new Date(26, Month.December, 2001)); expectedHol.Add(new Date(31, Month.December, 2001)); expectedHol.Add(new Date(1, Month.January, 2002)); expectedHol.Add(new Date(29, Month.March, 2002)); expectedHol.Add(new Date(1, Month.April, 2002)); expectedHol.Add(new Date(1, Month.May, 2002)); expectedHol.Add(new Date(25, Month.December, 2002)); expectedHol.Add(new Date(26, Month.December, 2002)); expectedHol.Add(new Date(1, Month.January, 2003)); expectedHol.Add(new Date(18, Month.April, 2003)); expectedHol.Add(new Date(21, Month.April, 2003)); expectedHol.Add(new Date(1, Month.May, 2003)); expectedHol.Add(new Date(25, Month.December, 2003)); expectedHol.Add(new Date(26, Month.December, 2003)); expectedHol.Add(new Date(1, Month.January, 2004)); expectedHol.Add(new Date(9, Month.April, 2004)); expectedHol.Add(new Date(12, Month.April, 2004)); expectedHol.Add(new Date(25, Month.March, 2005)); expectedHol.Add(new Date(28, Month.March, 2005)); expectedHol.Add(new Date(26, Month.December, 2005)); expectedHol.Add(new Date(14, Month.April, 2006)); expectedHol.Add(new Date(17, Month.April, 2006)); expectedHol.Add(new Date(1, Month.May, 2006)); expectedHol.Add(new Date(25, Month.December, 2006)); expectedHol.Add(new Date(26, Month.December, 2006)); Calendar c = new TARGET(); List<Date> hol = Calendar.holidayList(c, new Date(1, Month.January, 1999), new Date(31, Month.December, 2006)); for (int i=0; i<Math.Min(hol.Count, expectedHol.Count); i++) { if (hol[i]!=expectedHol[i]) Assert.Fail("expected holiday was " + expectedHol[i] + " while calculated holiday is " + hol[i]); } if (hol.Count!=expectedHol.Count) Assert.Fail("there were " + expectedHol.Count + " expected holidays, while there are " + hol.Count + " calculated holidays"); }
static void Main(string[] args) { DateTime timer = DateTime.Now; Date todaysDate = new Date(15, 2, 2002); Calendar calendar = new TARGET(); Date settlementDate = new Date(19, 2, 2002); Settings.setEvaluationDate(todaysDate); // flat yield term structure impling 1x5 swap at 5% Quote flatRate = new SimpleQuote(0.04875825); Handle<YieldTermStructure> rhTermStructure = new Handle<YieldTermStructure>( new FlatForward(settlementDate, new Handle<Quote>(flatRate), new Actual365Fixed())); // Define the ATM/OTM/ITM swaps Frequency fixedLegFrequency = Frequency.Annual; BusinessDayConvention fixedLegConvention = BusinessDayConvention.Unadjusted; BusinessDayConvention floatingLegConvention = BusinessDayConvention.ModifiedFollowing; DayCounter fixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European); Frequency floatingLegFrequency = Frequency.Semiannual; VanillaSwap.Type type = VanillaSwap.Type.Payer; double dummyFixedRate = 0.03; IborIndex indexSixMonths = new Euribor6M(rhTermStructure); Date startDate = calendar.advance(settlementDate, 1, TimeUnit.Years, floatingLegConvention); Date maturity = calendar.advance(startDate, 5, TimeUnit.Years, floatingLegConvention); Schedule fixedSchedule = new Schedule(startDate, maturity, new Period(fixedLegFrequency), calendar, fixedLegConvention, fixedLegConvention, DateGeneration.Rule.Forward, false); Schedule floatSchedule = new Schedule(startDate, maturity, new Period(floatingLegFrequency), calendar, floatingLegConvention, floatingLegConvention, DateGeneration.Rule.Forward, false); VanillaSwap swap = new VanillaSwap( type, 1000.0, fixedSchedule, dummyFixedRate, fixedLegDayCounter, floatSchedule, indexSixMonths, 0.0, indexSixMonths.dayCounter()); swap.setPricingEngine(new DiscountingSwapEngine(rhTermStructure)); double fixedAtmRate = swap.fairRate(); double fixedOtmRate = fixedAtmRate * 1.2; double fixedItmRate = fixedAtmRate * 0.8; VanillaSwap atmSwap = new VanillaSwap( type, 1000.0, fixedSchedule, fixedAtmRate, fixedLegDayCounter, floatSchedule, indexSixMonths, 0.0, indexSixMonths.dayCounter()); VanillaSwap otmSwap = new VanillaSwap( type, 1000.0, fixedSchedule, fixedOtmRate, fixedLegDayCounter, floatSchedule, indexSixMonths, 0.0, indexSixMonths.dayCounter()); VanillaSwap itmSwap = new VanillaSwap( type, 1000.0, fixedSchedule, fixedItmRate, fixedLegDayCounter, floatSchedule, indexSixMonths, 0.0, indexSixMonths.dayCounter()); // defining the swaptions to be used in model calibration List<Period> swaptionMaturities = new List<Period>(5); swaptionMaturities.Add(new Period(1, TimeUnit.Years)); swaptionMaturities.Add(new Period(2, TimeUnit.Years)); swaptionMaturities.Add(new Period(3, TimeUnit.Years)); swaptionMaturities.Add(new Period(4, TimeUnit.Years)); swaptionMaturities.Add(new Period(5, TimeUnit.Years)); List<CalibrationHelper> swaptions = new List<CalibrationHelper>(); // List of times that have to be included in the timegrid List<double> times = new List<double>(); for (int i = 0; i < NumRows; i++) { int j = NumCols - i - 1; // 1x5, 2x4, 3x3, 4x2, 5x1 int k = i * NumCols + j; Quote vol = new SimpleQuote(SwaptionVols[k]); swaptions.Add(new SwaptionHelper(swaptionMaturities[i], new Period(SwapLenghts[j], TimeUnit.Years), new Handle<Quote>(vol), indexSixMonths, indexSixMonths.tenor(), indexSixMonths.dayCounter(), indexSixMonths.dayCounter(), rhTermStructure, false)); swaptions.Last().addTimesTo(times); } // Building time-grid TimeGrid grid = new TimeGrid(times, 30); // defining the models G2 modelG2 = new G2(rhTermStructure); HullWhite modelHw = new HullWhite(rhTermStructure); HullWhite modelHw2 = new HullWhite(rhTermStructure); BlackKarasinski modelBk = new BlackKarasinski(rhTermStructure); // model calibrations Console.WriteLine("G2 (analytic formulae) calibration"); for (int i = 0; i < swaptions.Count; i++) swaptions[i].setPricingEngine(new G2SwaptionEngine(modelG2, 6.0, 16)); CalibrateModel(modelG2, swaptions); Console.WriteLine("calibrated to:\n" + "a = {0:0.000000}, " + "sigma = {1:0.0000000}\n" + "b = {2:0.000000}, " + "eta = {3:0.0000000}\n" + "rho = {4:0.00000}\n", modelG2.parameters()[0], modelG2.parameters()[1], modelG2.parameters()[2], modelG2.parameters()[3], modelG2.parameters()[4]); Console.WriteLine("Hull-White (analytic formulae) calibration"); for (int i = 0; i < swaptions.Count; i++) swaptions[i].setPricingEngine(new JamshidianSwaptionEngine(modelHw)); CalibrateModel(modelHw, swaptions); Console.WriteLine("calibrated to:\n" + "a = {0:0.000000}, " + "sigma = {1:0.0000000}\n", modelHw.parameters()[0], modelHw.parameters()[1]); Console.WriteLine("Hull-White (numerical) calibration"); for (int i = 0; i < swaptions.Count(); i++) swaptions[i].setPricingEngine(new TreeSwaptionEngine(modelHw2, grid)); CalibrateModel(modelHw2, swaptions); Console.WriteLine("calibrated to:\n" + "a = {0:0.000000}, " + "sigma = {1:0.0000000}\n", modelHw2.parameters()[0], modelHw2.parameters()[1]); Console.WriteLine("Black-Karasinski (numerical) calibration"); for (int i = 0; i < swaptions.Count; i++) swaptions[i].setPricingEngine(new TreeSwaptionEngine(modelBk, grid)); CalibrateModel(modelBk, swaptions); Console.WriteLine("calibrated to:\n" + "a = {0:0.000000}, " + "sigma = {1:0.00000}\n", modelBk.parameters()[0], modelBk.parameters()[1]); // ATM Bermudan swaption pricing Console.WriteLine("Payer bermudan swaption " + "struck at {0:0.00000 %} (ATM)", fixedAtmRate); List<Date> bermudanDates = new List<Date>(); List<CashFlow> leg = swap.fixedLeg(); for (int i = 0; i < leg.Count; i++) { Coupon coupon = (Coupon)leg[i]; bermudanDates.Add(coupon.accrualStartDate()); } Exercise bermudanExercise = new BermudanExercise(bermudanDates); Swaption bermudanSwaption = new Swaption(atmSwap, bermudanExercise); // Do the pricing for each model // G2 price the European swaption here, it should switch to bermudan bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelG2, 50)); Console.WriteLine("G2: {0:0.00}", bermudanSwaption.NPV()); bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw, 50)); Console.WriteLine("HW: {0:0.000}", bermudanSwaption.NPV()); bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw2, 50)); Console.WriteLine("HW (num): {0:0.000}", bermudanSwaption.NPV()); bermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelBk, 50)); Console.WriteLine("BK: {0:0.000}", bermudanSwaption.NPV()); // OTM Bermudan swaption pricing Console.WriteLine("Payer bermudan swaption " + "struck at {0:0.00000 %} (OTM)", fixedOtmRate); Swaption otmBermudanSwaption = new Swaption(otmSwap, bermudanExercise); // Do the pricing for each model otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelG2, 50)); Console.WriteLine("G2: {0:0.0000}", otmBermudanSwaption.NPV()); otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw, 50)); Console.WriteLine("HW: {0:0.0000}", otmBermudanSwaption.NPV()); otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw2, 50)); Console.WriteLine("HW (num): {0:0.000}", otmBermudanSwaption.NPV()); otmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelBk, 50)); Console.WriteLine("BK: {0:0.0000}", otmBermudanSwaption.NPV()); // ITM Bermudan swaption pricing Console.WriteLine("Payer bermudan swaption " + "struck at {0:0.00000 %} (ITM)", fixedItmRate); Swaption itmBermudanSwaption = new Swaption(itmSwap, bermudanExercise); // Do the pricing for each model itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelG2, 50)); Console.WriteLine("G2: {0:0.000}", itmBermudanSwaption.NPV()); itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw, 50)); Console.WriteLine("HW: {0:0.000}", itmBermudanSwaption.NPV()); itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelHw2, 50)); Console.WriteLine("HW (num): {0:0.000}", itmBermudanSwaption.NPV()); itmBermudanSwaption.setPricingEngine(new TreeSwaptionEngine(modelBk, 50)); Console.WriteLine("BK: {0:0.000}", itmBermudanSwaption.NPV()); Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer); Console.WriteLine(); Console.Write("Press any key to continue ..."); Console.ReadKey(); }
public void testFlatHazardRate() { // Testing flat hazard rate... double hazardRate = 0.0100; Handle<Quote> hazardRateQuote = new Handle<Quote>(new SimpleQuote(hazardRate)); DayCounter dayCounter = new Actual360(); Calendar calendar = new TARGET(); int n = 20; double tolerance = 1.0e-10; Date today = Settings.evaluationDate(); Date startDate = today; Date endDate = startDate; FlatHazardRate flatHazardRate = new FlatHazardRate(today, hazardRateQuote, dayCounter); for(int i=0; i<n; i++) { endDate = calendar.advance(endDate, 1, TimeUnit.Years); double t = dayCounter.yearFraction(startDate, endDate); double probability = 1.0 - Math.Exp(-hazardRate * t); double computedProbability = flatHazardRate.defaultProbability(t); if (Math.Abs(probability - computedProbability) > tolerance) Assert.Fail( "Failed to reproduce probability for flat hazard rate\n" + " calculated probability: " + computedProbability + "\n" + " expected probability: " + probability); } }
public void testMASWWithGenericBond() { // Testing market asset swap against par asset swap with generic bond... CommonVars vars = new CommonVars(); Calendar bondCalendar = new TARGET(); int settlementDays = 3; int fixingDays = 2; bool payFixedRate = true; bool parAssetSwap = true; bool mktAssetSwap = false; bool inArrears = false; // Fixed Underlying bond (Isin: DE0001135275 DBR 4 01/04/37) // maturity doesn't occur on a business day Date fixedBondStartDate1 = new Date(4,Month.January,2005); Date fixedBondMaturityDate1 = new Date(4,Month.January,2037); Schedule fixedBondSchedule1 = new Schedule(fixedBondStartDate1, fixedBondMaturityDate1, new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> fixedBondLeg1 = new FixedRateLeg(fixedBondSchedule1) .withCouponRates(0.04, new ActualActual(ActualActual.Convention.ISDA)) .withNotionals(vars.faceAmount); Date fixedbondRedemption1 = bondCalendar.adjust(fixedBondMaturityDate1, BusinessDayConvention.Following); fixedBondLeg1.Add(new SimpleCashFlow(100.0, fixedbondRedemption1)); Bond fixedBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, fixedBondMaturityDate1, fixedBondStartDate1, fixedBondLeg1); IPricingEngine bondEngine = new DiscountingBondEngine(vars.termStructure); IPricingEngine swapEngine = new DiscountingSwapEngine(vars.termStructure); fixedBond1.setPricingEngine(bondEngine); double fixedBondMktPrice1 = 89.22 ; // market price observed on 7th June 2007 double fixedBondMktFullPrice1=fixedBondMktPrice1+fixedBond1.accruedAmount(); AssetSwap fixedBondParAssetSwap1= new AssetSwap(payFixedRate, fixedBond1, fixedBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); fixedBondParAssetSwap1.setPricingEngine(swapEngine); double fixedBondParAssetSwapSpread1 = fixedBondParAssetSwap1.fairSpread(); AssetSwap fixedBondMktAssetSwap1 = new AssetSwap(payFixedRate, fixedBond1, fixedBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); fixedBondMktAssetSwap1.setPricingEngine(swapEngine); double fixedBondMktAssetSwapSpread1 = fixedBondMktAssetSwap1.fairSpread(); double tolerance = 1.0e-13; double error1 = Math.Abs(fixedBondMktAssetSwapSpread1- 100*fixedBondParAssetSwapSpread1/fixedBondMktFullPrice1); if (error1>tolerance) Assert.Fail("wrong asset swap spreads for fixed bond:" + "\n market asset swap spread: " + fixedBondMktAssetSwapSpread1 + "\n par asset swap spread: " + fixedBondParAssetSwapSpread1 + "\n error: " + error1 + "\n tolerance: " + tolerance); // Fixed Underlying bond (Isin: IT0006527060 IBRD 5 02/05/19) // maturity occurs on a business day Date fixedBondStartDate2 = new Date(5,Month.February,2005); Date fixedBondMaturityDate2 = new Date(5,Month.February,2019); Schedule fixedBondSchedule2 = new Schedule(fixedBondStartDate2, fixedBondMaturityDate2, new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> fixedBondLeg2 = new FixedRateLeg(fixedBondSchedule2) .withCouponRates(0.05, new Thirty360(Thirty360.Thirty360Convention.BondBasis)) .withNotionals(vars.faceAmount); Date fixedbondRedemption2 = bondCalendar.adjust(fixedBondMaturityDate2, BusinessDayConvention.Following); fixedBondLeg2.Add(new SimpleCashFlow(100.0, fixedbondRedemption2)); Bond fixedBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, fixedBondMaturityDate2, fixedBondStartDate2, fixedBondLeg2); fixedBond2.setPricingEngine(bondEngine); double fixedBondMktPrice2 = 99.98 ; // market price observed on 7th June 2007 double fixedBondMktFullPrice2=fixedBondMktPrice2+fixedBond2.accruedAmount(); AssetSwap fixedBondParAssetSwap2= new AssetSwap(payFixedRate, fixedBond2, fixedBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); fixedBondParAssetSwap2.setPricingEngine(swapEngine); double fixedBondParAssetSwapSpread2 = fixedBondParAssetSwap2.fairSpread(); AssetSwap fixedBondMktAssetSwap2= new AssetSwap(payFixedRate, fixedBond2, fixedBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); fixedBondMktAssetSwap2.setPricingEngine(swapEngine); double fixedBondMktAssetSwapSpread2 = fixedBondMktAssetSwap2.fairSpread(); double error2 = Math.Abs(fixedBondMktAssetSwapSpread2- 100*fixedBondParAssetSwapSpread2/fixedBondMktFullPrice2); if (error2>tolerance) Assert.Fail("wrong asset swap spreads for fixed bond:" + "\n market asset swap spread: " + fixedBondMktAssetSwapSpread2 + "\n par asset swap spread: " + fixedBondParAssetSwapSpread2 + "\n error: " + error2 + "\n tolerance: " + tolerance); // FRN Underlying bond (Isin: IT0003543847 ISPIM 0 09/29/13) // maturity doesn't occur on a business day Date floatingBondStartDate1 = new Date(29,Month.September,2003); Date floatingBondMaturityDate1 = new Date(29,Month.September,2013); Schedule floatingBondSchedule1= new Schedule(floatingBondStartDate1, floatingBondMaturityDate1, new Period(Frequency.Semiannual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> floatingBondLeg1 = new IborLeg(floatingBondSchedule1, vars.iborIndex) .withPaymentDayCounter(new Actual360()) .withFixingDays(fixingDays) .withSpreads(0.0056) .inArrears(inArrears) .withNotionals(vars.faceAmount); Date floatingbondRedemption1 = bondCalendar.adjust(floatingBondMaturityDate1, BusinessDayConvention.Following); floatingBondLeg1.Add(new SimpleCashFlow(100.0, floatingbondRedemption1)); Bond floatingBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, floatingBondMaturityDate1, floatingBondStartDate1, floatingBondLeg1); floatingBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond1.cashflows(), vars.pricer); vars.iborIndex.addFixing(new Date(27,Month.March,2007), 0.0402); // market price observed on 7th June 2007 double floatingBondMktPrice1 = 101.64 ; double floatingBondMktFullPrice1 = floatingBondMktPrice1+floatingBond1.accruedAmount(); AssetSwap floatingBondParAssetSwap1 = new AssetSwap(payFixedRate, floatingBond1, floatingBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); floatingBondParAssetSwap1.setPricingEngine(swapEngine); double floatingBondParAssetSwapSpread1 = floatingBondParAssetSwap1.fairSpread(); AssetSwap floatingBondMktAssetSwap1 = new AssetSwap(payFixedRate, floatingBond1, floatingBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); floatingBondMktAssetSwap1.setPricingEngine(swapEngine); double floatingBondMktAssetSwapSpread1 = floatingBondMktAssetSwap1.fairSpread(); double error3 = Math.Abs(floatingBondMktAssetSwapSpread1- 100*floatingBondParAssetSwapSpread1/floatingBondMktFullPrice1); if (error3>tolerance) Assert.Fail("wrong asset swap spreads for floating bond:" + "\n market asset swap spread: " + floatingBondMktAssetSwapSpread1 + "\n par asset swap spread: " + floatingBondParAssetSwapSpread1 + "\n error: " + error3 + "\n tolerance: " + tolerance); // FRN Underlying bond (Isin: XS0090566539 COE 0 09/24/18) // maturity occurs on a business day Date floatingBondStartDate2 = new Date(24,Month.September,2004); Date floatingBondMaturityDate2 = new Date(24,Month.September,2018); Schedule floatingBondSchedule2 = new Schedule(floatingBondStartDate2, floatingBondMaturityDate2, new Period(Frequency.Semiannual), bondCalendar, BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, DateGeneration.Rule.Backward, false); List<CashFlow> floatingBondLeg2 = new IborLeg(floatingBondSchedule2, vars.iborIndex) .withFixingDays(fixingDays) .withSpreads(0.0025) .inArrears(inArrears) .withPaymentDayCounter(new Actual360()) .withPaymentAdjustment(BusinessDayConvention.ModifiedFollowing) .withNotionals(vars.faceAmount); Date floatingbondRedemption2 = bondCalendar.adjust(floatingBondMaturityDate2, BusinessDayConvention.ModifiedFollowing); floatingBondLeg2.Add(new SimpleCashFlow(100.0, floatingbondRedemption2)); Bond floatingBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, floatingBondMaturityDate2, floatingBondStartDate2, floatingBondLeg2); floatingBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond2.cashflows(), vars.pricer); vars.iborIndex.addFixing(new Date(22,Month.March,2007), 0.04013); // market price observed on 7th June 2007 double floatingBondMktPrice2 = 101.248 ; double floatingBondMktFullPrice2 = floatingBondMktPrice2+floatingBond2.accruedAmount(); AssetSwap floatingBondParAssetSwap2 = new AssetSwap(payFixedRate, floatingBond2, floatingBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); floatingBondParAssetSwap2.setPricingEngine(swapEngine); double floatingBondParAssetSwapSpread2 = floatingBondParAssetSwap2.fairSpread(); AssetSwap floatingBondMktAssetSwap2 = new AssetSwap(payFixedRate, floatingBond2, floatingBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); floatingBondMktAssetSwap2.setPricingEngine(swapEngine); double floatingBondMktAssetSwapSpread2 = floatingBondMktAssetSwap2.fairSpread(); double error4 = Math.Abs(floatingBondMktAssetSwapSpread2- 100*floatingBondParAssetSwapSpread2/floatingBondMktFullPrice2); if (error4>tolerance) Assert.Fail("wrong asset swap spreads for floating bond:" + "\n market asset swap spread: " + floatingBondMktAssetSwapSpread2 + "\n par asset swap spread: " + floatingBondParAssetSwapSpread2 + "\n error: " + error4 + "\n tolerance: " + tolerance); // CMS Underlying bond (Isin: XS0228052402 CRDIT 0 8/22/20) // maturity doesn't occur on a business day Date cmsBondStartDate1 = new Date(22,Month.August,2005); Date cmsBondMaturityDate1 = new Date(22,Month.August,2020); Schedule cmsBondSchedule1= new Schedule(cmsBondStartDate1, cmsBondMaturityDate1, new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> cmsBondLeg1 = new CmsLeg(cmsBondSchedule1, vars.swapIndex) .withPaymentDayCounter(new Thirty360()) .withFixingDays(fixingDays) .withCaps(0.055) .withFloors(0.025) .inArrears(inArrears) .withNotionals(vars.faceAmount); Date cmsbondRedemption1 = bondCalendar.adjust(cmsBondMaturityDate1, BusinessDayConvention.Following); cmsBondLeg1.Add(new SimpleCashFlow(100.0, cmsbondRedemption1)); Bond cmsBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, cmsBondMaturityDate1, cmsBondStartDate1, cmsBondLeg1); cmsBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond1.cashflows(), vars.cmspricer); vars.swapIndex.addFixing(new Date(18,Month.August,2006), 0.04158); double cmsBondMktPrice1 = 88.45 ; // market price observed on 7th June 2007 double cmsBondMktFullPrice1 = cmsBondMktPrice1+cmsBond1.accruedAmount(); AssetSwap cmsBondParAssetSwap1 = new AssetSwap(payFixedRate, cmsBond1, cmsBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); cmsBondParAssetSwap1.setPricingEngine(swapEngine); double cmsBondParAssetSwapSpread1 = cmsBondParAssetSwap1.fairSpread(); AssetSwap cmsBondMktAssetSwap1 = new AssetSwap(payFixedRate, cmsBond1, cmsBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); cmsBondMktAssetSwap1.setPricingEngine(swapEngine); double cmsBondMktAssetSwapSpread1 = cmsBondMktAssetSwap1.fairSpread(); double error5 = Math.Abs(cmsBondMktAssetSwapSpread1- 100*cmsBondParAssetSwapSpread1/cmsBondMktFullPrice1); if (error5>tolerance) Assert.Fail("wrong asset swap spreads for cms bond:" + "\n market asset swap spread: " + cmsBondMktAssetSwapSpread1 + "\n par asset swap spread: " + cmsBondParAssetSwapSpread1 + "\n error: " + error5 + "\n tolerance: " + tolerance); // CMS Underlying bond (Isin: XS0218766664 ISPIM 0 5/6/15) // maturity occurs on a business day Date cmsBondStartDate2 = new Date(06,Month.May,2005); Date cmsBondMaturityDate2 = new Date(06,Month.May,2015); Schedule cmsBondSchedule2= new Schedule(cmsBondStartDate2, cmsBondMaturityDate2, new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> cmsBondLeg2 = new CmsLeg(cmsBondSchedule2, vars.swapIndex) .withPaymentDayCounter(new Thirty360()) .withFixingDays(fixingDays) .withGearings(0.84) .inArrears(inArrears) .withNotionals(vars.faceAmount); Date cmsbondRedemption2 = bondCalendar.adjust(cmsBondMaturityDate2, BusinessDayConvention.Following); cmsBondLeg2.Add(new SimpleCashFlow(100.0, cmsbondRedemption2)); Bond cmsBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, cmsBondMaturityDate2, cmsBondStartDate2, cmsBondLeg2); cmsBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond2.cashflows(), vars.cmspricer); vars.swapIndex.addFixing(new Date(04,Month.May,2006), 0.04217); double cmsBondMktPrice2 = 94.08 ; // market price observed on 7th June 2007 double cmsBondMktFullPrice2 = cmsBondMktPrice2+cmsBond2.accruedAmount(); AssetSwap cmsBondParAssetSwap2 = new AssetSwap(payFixedRate, cmsBond2, cmsBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); cmsBondParAssetSwap2.setPricingEngine(swapEngine); double cmsBondParAssetSwapSpread2 = cmsBondParAssetSwap2.fairSpread(); AssetSwap cmsBondMktAssetSwap2 = new AssetSwap(payFixedRate, cmsBond2, cmsBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); cmsBondMktAssetSwap2.setPricingEngine(swapEngine); double cmsBondMktAssetSwapSpread2 = cmsBondMktAssetSwap2.fairSpread(); double error6 = Math.Abs(cmsBondMktAssetSwapSpread2- 100*cmsBondParAssetSwapSpread2/cmsBondMktFullPrice2); if (error6>tolerance) Assert.Fail("wrong asset swap spreads for cms bond:" + "\n market asset swap spread: " + cmsBondMktAssetSwapSpread2 + "\n par asset swap spread: " + cmsBondParAssetSwapSpread2 + "\n error: " + error6 + "\n tolerance: " + tolerance); // Zero Coupon bond (Isin: DE0004771662 IBRD 0 12/20/15) // maturity doesn't occur on a business day Date zeroCpnBondStartDate1 = new Date(19,Month.December,1985); Date zeroCpnBondMaturityDate1 = new Date(20,Month.December,2015); Date zeroCpnBondRedemption1 = bondCalendar.adjust(zeroCpnBondMaturityDate1, BusinessDayConvention.Following); List<CashFlow> zeroCpnBondLeg1 = new List<CashFlow>{new SimpleCashFlow(100.0, zeroCpnBondRedemption1)}; Bond zeroCpnBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, zeroCpnBondMaturityDate1, zeroCpnBondStartDate1, zeroCpnBondLeg1); zeroCpnBond1.setPricingEngine(bondEngine); // market price observed on 12th June 2007 double zeroCpnBondMktPrice1 = 70.436 ; double zeroCpnBondMktFullPrice1 = zeroCpnBondMktPrice1+zeroCpnBond1.accruedAmount(); AssetSwap zeroCpnBondParAssetSwap1 = new AssetSwap(payFixedRate,zeroCpnBond1, zeroCpnBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); zeroCpnBondParAssetSwap1.setPricingEngine(swapEngine); double zeroCpnBondParAssetSwapSpread1 = zeroCpnBondParAssetSwap1.fairSpread(); AssetSwap zeroCpnBondMktAssetSwap1 = new AssetSwap(payFixedRate,zeroCpnBond1, zeroCpnBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); zeroCpnBondMktAssetSwap1.setPricingEngine(swapEngine); double zeroCpnBondMktAssetSwapSpread1 = zeroCpnBondMktAssetSwap1.fairSpread(); double error7 = Math.Abs(zeroCpnBondMktAssetSwapSpread1- 100*zeroCpnBondParAssetSwapSpread1/zeroCpnBondMktFullPrice1); if (error7>tolerance) Assert.Fail("wrong asset swap spreads for zero cpn bond:" + "\n market asset swap spread: " + zeroCpnBondMktAssetSwapSpread1 + "\n par asset swap spread: " + zeroCpnBondParAssetSwapSpread1 + "\n error: " + error7 + "\n tolerance: " + tolerance); // Zero Coupon bond (Isin: IT0001200390 ISPIM 0 02/17/28) // maturity occurs on a business day Date zeroCpnBondStartDate2 = new Date(17,Month.February,1998); Date zeroCpnBondMaturityDate2 = new Date(17,Month.February,2028); Date zerocpbondRedemption2 = bondCalendar.adjust(zeroCpnBondMaturityDate2, BusinessDayConvention.Following); List<CashFlow> zeroCpnBondLeg2 = new List<CashFlow>{new SimpleCashFlow(100.0, zerocpbondRedemption2)}; Bond zeroCpnBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, zeroCpnBondMaturityDate2, zeroCpnBondStartDate2, zeroCpnBondLeg2); zeroCpnBond2.setPricingEngine(bondEngine); // double zeroCpnBondPrice2 = zeroCpnBond2.cleanPrice(); // market price observed on 12th June 2007 double zeroCpnBondMktPrice2 = 35.160 ; double zeroCpnBondMktFullPrice2 = zeroCpnBondMktPrice2+zeroCpnBond2.accruedAmount(); AssetSwap zeroCpnBondParAssetSwap2 = new AssetSwap(payFixedRate,zeroCpnBond2, zeroCpnBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); zeroCpnBondParAssetSwap2.setPricingEngine(swapEngine); double zeroCpnBondParAssetSwapSpread2 = zeroCpnBondParAssetSwap2.fairSpread(); AssetSwap zeroCpnBondMktAssetSwap2 = new AssetSwap(payFixedRate,zeroCpnBond2, zeroCpnBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); zeroCpnBondMktAssetSwap2.setPricingEngine(swapEngine); double zeroCpnBondMktAssetSwapSpread2 = zeroCpnBondMktAssetSwap2.fairSpread(); double error8 = Math.Abs(zeroCpnBondMktAssetSwapSpread2- 100*zeroCpnBondParAssetSwapSpread2/zeroCpnBondMktFullPrice2); if (error8>tolerance) Assert.Fail("wrong asset swap spreads for zero cpn bond:" + "\n market asset swap spread: " + zeroCpnBondMktAssetSwapSpread2 + "\n par asset swap spread: " + zeroCpnBondParAssetSwapSpread2 + "\n error: " + error8 + "\n tolerance: " + tolerance); }
static void Main(string[] args) { DateTime timer = DateTime.Now; /********************* *** MARKET DATA *** *********************/ Calendar calendar = new TARGET(); Date settlementDate = new Date(18, Month.September, 2008); // must be a business day settlementDate = calendar.adjust(settlementDate); int fixingDays = 3; int settlementDays = 3; Date todaysDate = calendar.advance(settlementDate, -fixingDays, TimeUnit.Days); // nothing to do with Date::todaysDate Settings.setEvaluationDate(todaysDate); Console.WriteLine("Today: {0}, {1}", todaysDate.DayOfWeek, todaysDate); Console.WriteLine("Settlement date: {0}, {1}", settlementDate.DayOfWeek, settlementDate); // Building of the bonds discounting yield curve /********************* *** RATE HELPERS *** *********************/ // RateHelpers are built from the above quotes together with // other instrument dependant infos. Quotes are passed in // relinkable handles which could be relinked to some other // data source later. // Common data // ZC rates for the short end double zc3mQuote=0.0096; double zc6mQuote=0.0145; double zc1yQuote=0.0194; Quote zc3mRate = new SimpleQuote(zc3mQuote); Quote zc6mRate = new SimpleQuote(zc6mQuote); Quote zc1yRate = new SimpleQuote(zc1yQuote); DayCounter zcBondsDayCounter = new Actual365Fixed(); RateHelper zc3m = new DepositRateHelper(new Handle<Quote>(zc3mRate), new Period(3, TimeUnit.Months), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, zcBondsDayCounter); RateHelper zc6m = new DepositRateHelper(new Handle<Quote>(zc6mRate), new Period(6, TimeUnit.Months), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, zcBondsDayCounter); RateHelper zc1y = new DepositRateHelper(new Handle<Quote>(zc1yRate), new Period(1, TimeUnit.Years), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, zcBondsDayCounter); // setup bonds double redemption = 100.0; const int numberOfBonds = 5; Date[] issueDates = { new Date (15, Month.March, 2005), new Date (15, Month.June, 2005), new Date (30, Month.June, 2006), new Date (15, Month.November, 2002), new Date (15, Month.May, 1987) }; Date[] maturities = { new Date (31, Month.August, 2010), new Date (31, Month.August, 2011), new Date (31, Month.August, 2013), new Date (15, Month.August, 2018), new Date (15, Month.May, 2038) }; double[] couponRates = { 0.02375, 0.04625, 0.03125, 0.04000, 0.04500 }; double[] marketQuotes = { 100.390625, 106.21875, 100.59375, 101.6875, 102.140625 }; List<SimpleQuote> quote = new List<SimpleQuote>(); for (int i=0; i<numberOfBonds; i++) { SimpleQuote cp = new SimpleQuote(marketQuotes[i]); quote.Add(cp); } List<RelinkableHandle<Quote>> quoteHandle = new InitializedList<RelinkableHandle<Quote>>(numberOfBonds); for (int i=0; i<numberOfBonds; i++) { quoteHandle[i].linkTo(quote[i]); } // Definition of the rate helpers List<FixedRateBondHelper> bondsHelpers = new List<FixedRateBondHelper>(); for (int i=0; i<numberOfBonds; i++) { Schedule schedule = new Schedule(issueDates[i], maturities[i], new Period(Frequency.Semiannual), new UnitedStates(UnitedStates.Market.GovernmentBond), BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); FixedRateBondHelper bondHelper = new FixedRateBondHelper(quoteHandle[i], settlementDays, 100.0, schedule, new List<double>() { couponRates[i] }, new ActualActual(ActualActual.Convention.Bond), BusinessDayConvention.Unadjusted, redemption, issueDates[i]); bondsHelpers.Add(bondHelper); } /********************* ** CURVE BUILDING ** *********************/ // Any DayCounter would be fine. // ActualActual::ISDA ensures that 30 years is 30.0 DayCounter termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA); double tolerance = 1.0e-15; // A depo-bond curve List<RateHelper> bondInstruments = new List<RateHelper>(); // Adding the ZC bonds to the curve for the short end bondInstruments.Add(zc3m); bondInstruments.Add(zc6m); bondInstruments.Add(zc1y); // Adding the Fixed rate bonds to the curve for the long end for (int i=0; i<numberOfBonds; i++) { bondInstruments.Add(bondsHelpers[i]); } YieldTermStructure bondDiscountingTermStructure = new PiecewiseYieldCurve<Discount,LogLinear>( settlementDate, bondInstruments, termStructureDayCounter, new List<Handle<Quote>>(), new List<Date>(), tolerance); // Building of the Libor forecasting curve // deposits double d1wQuote=0.043375; double d1mQuote=0.031875; double d3mQuote=0.0320375; double d6mQuote=0.03385; double d9mQuote=0.0338125; double d1yQuote=0.0335125; // swaps double s2yQuote=0.0295; double s3yQuote=0.0323; double s5yQuote=0.0359; double s10yQuote=0.0412; double s15yQuote=0.0433; /******************** *** QUOTES *** ********************/ // SimpleQuote stores a value which can be manually changed; // other Quote subclasses could read the value from a database // or some kind of data feed. // deposits Quote d1wRate = new SimpleQuote(d1wQuote); Quote d1mRate = new SimpleQuote(d1mQuote); Quote d3mRate = new SimpleQuote(d3mQuote); Quote d6mRate = new SimpleQuote(d6mQuote); Quote d9mRate = new SimpleQuote(d9mQuote); Quote d1yRate = new SimpleQuote(d1yQuote); // swaps Quote s2yRate = new SimpleQuote(s2yQuote); Quote s3yRate = new SimpleQuote(s3yQuote); Quote s5yRate = new SimpleQuote(s5yQuote); Quote s10yRate = new SimpleQuote(s10yQuote); Quote s15yRate = new SimpleQuote(s15yQuote); /********************* *** RATE HELPERS *** *********************/ // RateHelpers are built from the above quotes together with // other instrument dependant infos. Quotes are passed in // relinkable handles which could be relinked to some other // data source later. // deposits DayCounter depositDayCounter = new Actual360(); RateHelper d1w = new DepositRateHelper( new Handle<Quote>(d1wRate), new Period(1, TimeUnit.Weeks), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); RateHelper d1m = new DepositRateHelper( new Handle<Quote>(d1mRate), new Period(1, TimeUnit.Months), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); RateHelper d3m = new DepositRateHelper( new Handle<Quote>(d3mRate), new Period(3, TimeUnit.Months), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); RateHelper d6m = new DepositRateHelper( new Handle<Quote>(d6mRate), new Period(6, TimeUnit.Months), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); RateHelper d9m = new DepositRateHelper( new Handle<Quote>(d9mRate), new Period(9, TimeUnit.Months), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); RateHelper d1y = new DepositRateHelper( new Handle<Quote>(d1yRate), new Period(1, TimeUnit.Years), fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); // setup swaps Frequency swFixedLegFrequency =Frequency.Annual; BusinessDayConvention swFixedLegConvention = BusinessDayConvention.Unadjusted; DayCounter swFixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European); IborIndex swFloatingLegIndex = new Euribor6M(); Period forwardStart = new Period(1, TimeUnit.Days); RateHelper s2y = new SwapRateHelper( new Handle<Quote>(s2yRate), new Period(2, TimeUnit.Years), calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex, new Handle<Quote>(),forwardStart); RateHelper s3y = new SwapRateHelper( new Handle<Quote>(s3yRate), new Period(3, TimeUnit.Years), calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex, new Handle<Quote>(),forwardStart); RateHelper s5y = new SwapRateHelper( new Handle<Quote>(s5yRate), new Period(5, TimeUnit.Years), calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex, new Handle<Quote>(),forwardStart); RateHelper s10y = new SwapRateHelper( new Handle<Quote>(s10yRate), new Period(10, TimeUnit.Years), calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex, new Handle<Quote>(),forwardStart); RateHelper s15y = new SwapRateHelper( new Handle<Quote>(s15yRate), new Period(15, TimeUnit.Years), calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex, new Handle<Quote>(),forwardStart); /********************* ** CURVE BUILDING ** *********************/ // Any DayCounter would be fine. // ActualActual::ISDA ensures that 30 years is 30.0 // A depo-swap curve List<RateHelper> depoSwapInstruments = new List<RateHelper>(); depoSwapInstruments.Add(d1w); depoSwapInstruments.Add(d1m); depoSwapInstruments.Add(d3m); depoSwapInstruments.Add(d6m); depoSwapInstruments.Add(d9m); depoSwapInstruments.Add(d1y); depoSwapInstruments.Add(s2y); depoSwapInstruments.Add(s3y); depoSwapInstruments.Add(s5y); depoSwapInstruments.Add(s10y); depoSwapInstruments.Add(s15y); YieldTermStructure depoSwapTermStructure = new PiecewiseYieldCurve<Discount,LogLinear>( settlementDate, depoSwapInstruments, termStructureDayCounter, new List<Handle<Quote> >(), new List<Date>(), tolerance); // Term structures that will be used for pricing: // the one used for discounting cash flows RelinkableHandle<YieldTermStructure> discountingTermStructure = new RelinkableHandle<YieldTermStructure>(); // the one used for forward rate forecasting RelinkableHandle<YieldTermStructure> forecastingTermStructure = new RelinkableHandle<YieldTermStructure>(); /********************* * BONDS TO BE PRICED * **********************/ // Common data double faceAmount = 100; // Pricing engine IPricingEngine bondEngine = new DiscountingBondEngine(discountingTermStructure); // Zero coupon bond ZeroCouponBond zeroCouponBond = new ZeroCouponBond( settlementDays, new UnitedStates(UnitedStates.Market.GovernmentBond), faceAmount, new Date(15, Month.August,2013), BusinessDayConvention.Following, 116.92, new Date(15, Month.August,2003)); zeroCouponBond.setPricingEngine(bondEngine); // Fixed 4.5% US Treasury Note Schedule fixedBondSchedule = new Schedule(new Date(15, Month.May, 2007), new Date(15,Month.May,2017), new Period(Frequency.Semiannual), new UnitedStates(UnitedStates.Market.GovernmentBond), BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); FixedRateBond fixedRateBond = new FixedRateBond( settlementDays, faceAmount, fixedBondSchedule, new List<double>() { 0.045 }, new ActualActual(ActualActual.Convention.Bond), BusinessDayConvention.ModifiedFollowing, 100.0, new Date(15, Month.May, 2007)); fixedRateBond.setPricingEngine(bondEngine); // Floating rate bond (3M USD Libor + 0.1%) // Should and will be priced on another curve later... RelinkableHandle<YieldTermStructure> liborTermStructure = new RelinkableHandle<YieldTermStructure>(); IborIndex libor3m = new USDLibor(new Period(3, TimeUnit.Months), liborTermStructure); libor3m.addFixing(new Date(17, Month.July, 2008),0.0278625); Schedule floatingBondSchedule = new Schedule(new Date(21, Month.October, 2005), new Date(21, Month.October, 2010), new Period(Frequency.Quarterly), new UnitedStates(UnitedStates.Market.NYSE), BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, true); FloatingRateBond floatingRateBond = new FloatingRateBond( settlementDays, faceAmount, floatingBondSchedule, libor3m, new Actual360(), BusinessDayConvention.ModifiedFollowing, 2, // Gearings new List<double>() { 1.0 }, // Spreads new List<double>() { 0.001 }, // Caps new List<double>(), // Floors new List<double>(), // Fixing in arrears true, 100.0, new Date(21, Month.October, 2005)); floatingRateBond.setPricingEngine(bondEngine); // Coupon pricers IborCouponPricer pricer = new BlackIborCouponPricer(); // optionLet volatilities double volatility = 0.0; Handle<OptionletVolatilityStructure> vol; vol = new Handle<OptionletVolatilityStructure>( new ConstantOptionletVolatility( settlementDays, calendar, BusinessDayConvention.ModifiedFollowing, volatility, new Actual365Fixed())); pricer.setCapletVolatility(vol); Utils.setCouponPricer(floatingRateBond.cashflows(),pricer); // Yield curve bootstrapping forecastingTermStructure.linkTo(depoSwapTermStructure); discountingTermStructure.linkTo(bondDiscountingTermStructure); // We are using the depo & swap curve to estimate the future Libor rates liborTermStructure.linkTo(depoSwapTermStructure); /*************** * BOND PRICING * ****************/ // write column headings int[] widths = { 18, 10, 10, 10 }; Console.WriteLine("{0,18}{1,10}{2,10}{3,10}", "", "ZC", "Fixed", "Floating"); string separator = " | "; int width = widths[0] + widths[1] + widths[2] + widths[3]; string rule = "".PadLeft(width, '-'), dblrule = "".PadLeft(width, '='); string tab = "".PadLeft(8, ' '); Console.WriteLine(rule); Console.WriteLine("Net present value".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}", zeroCouponBond.NPV(), fixedRateBond.NPV(), floatingRateBond.NPV()); Console.WriteLine("Clean price".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}", zeroCouponBond.cleanPrice(), fixedRateBond.cleanPrice(), floatingRateBond.cleanPrice()); Console.WriteLine("Dirty price".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}", zeroCouponBond.dirtyPrice(), fixedRateBond.dirtyPrice(), floatingRateBond.dirtyPrice()); Console.WriteLine("Accrued coupon".PadLeft(widths[0]) + "{0,10:n2}{1,10:n2}{2,10:n2}", zeroCouponBond.accruedAmount(), fixedRateBond.accruedAmount(), floatingRateBond.accruedAmount()); Console.WriteLine("Previous coupon".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}", "N/A", fixedRateBond.previousCoupon(), floatingRateBond.previousCoupon()); Console.WriteLine("Next coupon".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}", "N/A", fixedRateBond.nextCoupon(), floatingRateBond.nextCoupon()); Console.WriteLine("Yield".PadLeft(widths[0]) + "{0,10:0.00%}{1,10:0.00%}{2,10:0.00%}", zeroCouponBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual), fixedRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual), floatingRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual)); Console.WriteLine(); // Other computations Console.WriteLine("Sample indirect computations (for the floating rate bond): "); Console.WriteLine(rule); Console.WriteLine("Yield to Clean Price: {0:n2}", floatingRateBond.cleanPrice(floatingRateBond.yield(new Actual360(), Compounding.Compounded, Frequency.Annual), new Actual360(), Compounding.Compounded, Frequency.Annual, settlementDate)); Console.WriteLine("Clean Price to Yield: {0:0.00%}", floatingRateBond.yield(floatingRateBond.cleanPrice(),new Actual360(), Compounding.Compounded, Frequency.Annual, settlementDate)); /* "Yield to Price" "Price to Yield" */ Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer); Console.WriteLine(); Console.Write("Press any key to continue ..."); Console.ReadKey(); }
public void calculate(double[] p, GBMParaViewModel para) { this.xData_ = p; this.yData_ = new double[p.Length]; double sellBuySign = 1.0; if (this.sellBuy_ == "매도") { sellBuySign = -1.0; } else { } // set up dates Calendar calendar = new TARGET(); //Date todaysDate = new Date(DateTime.Now); Date settlementDate = new Date(para.ReferenceDate_); Settings.setEvaluationDate(settlementDate); // our options Option.Type type = this.callPutEnum_; double underlying = para.CurrentPrice_; double strike = this.strike_; double dividendYield = para.Dividend_ / 100; double riskFreeRate = para.Drift_ / 100; if (this.callPutEnum_ == Option.Type.Call) { this.imVol_ = para.Call_Interpolation_.value(this.strike_); } else if (this.callPutEnum_ == Option.Type.Put) { this.imVol_ = para.Put_Interpolation_.value(this.strike_); } double volatility = (this.imVol_ ) / 100; Date maturity = new Date(this.maturiry_.AddDays(1)); if (this.callPutEnum_ == 0) { this.deltaCal_ = 1.0; this.gammaCal_ = 0.0; this.vegaCal_ = 0.0; this.thetaCal_ = 0.0; this.rhoCal_ = 0.0; this.deltaPosition_ = sellBuySign * this.unit_ * 500000 * underlying; this.deltaRisk_ = this.deltaPosition_ * 0.09; this.gammaRisk_ = 0.0; this.vegaRisk_ = 0.0; this.totalRisk_ = this.deltaRisk_ + this.gammaRisk_ + this.vegaRisk_; this.deepOTM_ = 0.0; //this.remainDays_ = maturity - settlementDate; this.remainDays_ = (this.maturiry_ - para.ReferenceDate_).Days + 1; return; } DayCounter dayCounter = new Actual365Fixed(); Exercise europeanExercise = new EuropeanExercise(maturity); SimpleQuote quote = new SimpleQuote(underlying); Handle<Quote> underlyingH = new Handle<Quote>(quote); // bootstrap the yield/dividend/vol curves var flatTermStructure = new Handle<YieldTermStructure>(new FlatForward(settlementDate, riskFreeRate, dayCounter)); var flatDividendTS = new Handle<YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter)); var flatVolTS = new Handle<BlackVolTermStructure>(new BlackConstantVol(settlementDate, calendar, volatility, dayCounter)); StrikedTypePayoff payoff = new PlainVanillaPayoff(type, strike); var bsmProcess = new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS); // options VanillaOption europeanOption = new VanillaOption(payoff, europeanExercise); // Analytic formulas: // Black-Scholes for European europeanOption.setPricingEngine(new AnalyticEuropeanEngine(bsmProcess)); this.npv_ = Math.Round(europeanOption.NPV(), 6); this.deltaCal_ = sellBuySign * Math.Round(europeanOption.delta(), 6); this.gammaCal_ = sellBuySign * Math.Round(europeanOption.gamma(), 6); this.vegaCal_ = sellBuySign * Math.Round(europeanOption.vega() / 100, 6); this.thetaCal_ = sellBuySign * Math.Round(europeanOption.theta() / 365, 6); this.rhoCal_ = sellBuySign * Math.Round(europeanOption.rho() / 100, 6); this.deltaPosition_ = Math.Round(this.deltaCal_ * this.unit_ * 500000 * underlying,0); this.deltaRisk_ = Math.Round(this.deltaPosition_ * 0.09,0); this.gammaRisk_ = Math.Round(0.5 * this.gammaCal_ * (underlying * underlying * 0.08 * 0.08) * this.unit_ * 500000, 0); this.vegaRisk_ = Math.Round(this.vegaCal_ * this.imVol_ * 0.25 * this.unit_ * 500000, 0); this.totalRisk_ = this.deltaRisk_ + this.gammaRisk_ + this.vegaRisk_; this.deepOTM_ = 0.0; //this.remainDays_ = maturity - settlementDate; this.remainDays_ = (this.maturiry_ - para.ReferenceDate_).Days + 1; for (int i = 0; i < this.xData_.Length; i++) { quote.setValue(this.xData_[i]); this.yData_[i] = 500000.0 * (double)this.unit_ * europeanOption.NPV(); } }