public void zciisconsistency() { CommonVars common = new CommonVars(); ZeroCouponInflationSwap.Type ztype = ZeroCouponInflationSwap.Type.Payer; double nominal = 1000000.0; Date startDate = new Date(common.evaluationDate); Date endDate = new Date(25, Month.November, 2059); Calendar cal = new UnitedKingdom(); BusinessDayConvention paymentConvention = BusinessDayConvention.ModifiedFollowing; DayCounter dummyDC = null, dc = new ActualActual(); Period observationLag = new Period(2, TimeUnit.Months); double quote = 0.03714; ZeroCouponInflationSwap zciis = new ZeroCouponInflationSwap(ztype, nominal, startDate, endDate, cal, paymentConvention, dc, quote, common.ii, observationLag); // simple structure so simple pricing engine - most work done by index DiscountingSwapEngine dse = new DiscountingSwapEngine(common.nominalUK); zciis.setPricingEngine(dse); QAssert.IsTrue(Math.Abs(zciis.NPV()) < 1e-3, "zciis does not reprice to zero"); List <Date> oneDate = new List <Date>(); oneDate.Add(endDate); Schedule schOneDate = new Schedule(oneDate, cal, paymentConvention); CPISwap.Type stype = CPISwap.Type.Payer; double inflationNominal = nominal; double floatNominal = inflationNominal * Math.Pow(1.0 + quote, 50); bool subtractInflationNominal = true; double dummySpread = 0.0, dummyFixedRate = 0.0; int fixingDays = 0; Date baseDate = startDate - observationLag; double baseCPI = common.ii.fixing(baseDate); IborIndex dummyFloatIndex = new IborIndex(); CPISwap cS = new CPISwap(stype, floatNominal, subtractInflationNominal, dummySpread, dummyDC, schOneDate, paymentConvention, fixingDays, dummyFloatIndex, dummyFixedRate, baseCPI, dummyDC, schOneDate, paymentConvention, observationLag, common.ii, InterpolationType.AsIndex, inflationNominal); cS.setPricingEngine(dse); QAssert.IsTrue(Math.Abs(cS.NPV()) < 1e-3, "CPISwap as ZCIIS does not reprice to zero"); for (int i = 0; i < 2; i++) { double cs = cS.legNPV(i).GetValueOrDefault(); double z = zciis.legNPV(i).GetValueOrDefault(); QAssert.IsTrue(Math.Abs(cs - z) < 1e-3, "zciis leg does not equal CPISwap leg"); } // remove circular refernce common.hcpi.linkTo(null); }
public void consistency() { // check inflation leg vs calculation directly from inflation TS CommonVars common = new CommonVars(); // ZeroInflationSwap aka CPISwap CPISwap.Type type = CPISwap.Type.Payer; double nominal = 1000000.0; bool subtractInflationNominal = true; // float+spread leg double spread = 0.0; DayCounter floatDayCount = new Actual365Fixed(); BusinessDayConvention floatPaymentConvention = BusinessDayConvention.ModifiedFollowing; int fixingDays = 0; IborIndex floatIndex = new GBPLibor(new Period(6, TimeUnit.Months), common.nominalUK); // fixed x inflation leg double fixedRate = 0.1; //1% would be 0.01 double baseCPI = 206.1; // would be 206.13871 if we were interpolating DayCounter fixedDayCount = new Actual365Fixed(); BusinessDayConvention fixedPaymentConvention = BusinessDayConvention.ModifiedFollowing; Calendar fixedPaymentCalendar = new UnitedKingdom(); ZeroInflationIndex fixedIndex = common.ii; Period contractObservationLag = common.contractObservationLag; InterpolationType observationInterpolation = common.contractObservationInterpolation; // set the schedules Date startDate = new Date(2, Month.October, 2007); Date endDate = new Date(2, Month.October, 2052); Schedule floatSchedule = new MakeSchedule().from(startDate).to(endDate) .withTenor(new Period(6, TimeUnit.Months)) .withCalendar(new UnitedKingdom()) .withConvention(floatPaymentConvention) .backwards().value(); Schedule fixedSchedule = new MakeSchedule().from(startDate).to(endDate) .withTenor(new Period(6, TimeUnit.Months)) .withCalendar(new UnitedKingdom()) .withConvention(BusinessDayConvention.Unadjusted) .backwards().value(); CPISwap zisV = new CPISwap(type, nominal, subtractInflationNominal, spread, floatDayCount, floatSchedule, floatPaymentConvention, fixingDays, floatIndex, fixedRate, baseCPI, fixedDayCount, fixedSchedule, fixedPaymentConvention, contractObservationLag, fixedIndex, observationInterpolation); Date asofDate = Settings.evaluationDate(); double[] floatFix = { 0.06255, 0.05975, 0.0637, 0.018425, 0.0073438, -1, -1 }; double[] cpiFix = { 211.4, 217.2, 211.4, 213.4, -2, -2 }; for (int i = 0; i < floatSchedule.Count; i++) { if (floatSchedule[i] < common.evaluationDate) { floatIndex.addFixing(floatSchedule[i], floatFix[i], true);//true=overwrite } CPICoupon zic = zisV.cpiLeg()[i] as CPICoupon; if (zic != null) { if (zic.fixingDate() < (common.evaluationDate - new Period(1, TimeUnit.Months))) { fixedIndex.addFixing(zic.fixingDate(), cpiFix[i], true); } } } // simple structure so simple pricing engine - most work done by index DiscountingSwapEngine dse = new DiscountingSwapEngine(common.nominalUK); zisV.setPricingEngine(dse); // get float+spread & fixed*inflation leg prices separately double testInfLegNPV = 0.0; double diff; for (int i = 0; i < zisV.leg(0).Count; i++) { Date zicPayDate = (zisV.leg(0))[i].date(); if (zicPayDate > asofDate) { testInfLegNPV += (zisV.leg(0))[i].amount() * common.nominalUK.link.discount(zicPayDate); } CPICoupon zicV = zisV.cpiLeg()[i] as CPICoupon; if (zicV != null) { diff = Math.Abs(zicV.rate() - (fixedRate * (zicV.indexFixing() / baseCPI))); QAssert.IsTrue(diff < 1e-8, "failed " + i + "th coupon reconstruction as " + (fixedRate * (zicV.indexFixing() / baseCPI)) + " vs rate = " + zicV.rate() + ", with difference: " + diff); } } double error = Math.Abs(testInfLegNPV - zisV.legNPV(0).Value); QAssert.IsTrue(error < 1e-5, "failed manual inf leg NPV calc vs pricing engine: " + testInfLegNPV + " vs " + zisV.legNPV(0)); diff = Math.Abs(1 - zisV.NPV() / 4191660.0); #if QL_USE_INDEXED_COUPON double max_diff = 1e-5; #else double max_diff = 3e-5; #endif QAssert.IsTrue(diff < max_diff, "failed stored consistency value test, ratio = " + diff); // remove circular refernce common.hcpi.linkTo(null); }