private List <BootstrapHelper <ZeroInflationTermStructure> > makeHelpers(Datum[] iiData, int N, ZeroInflationIndex ii, Period observationLag, Calendar calendar, BusinessDayConvention bdc, DayCounter dc) { List <BootstrapHelper <ZeroInflationTermStructure> > instruments = new List <BootstrapHelper <ZeroInflationTermStructure> >(); for (int i = 0; i < N; i++) { Date maturity = iiData[i].date; Handle <Quote> quote = new Handle <Quote>(new SimpleQuote(iiData[i].rate / 100.0)); BootstrapHelper <ZeroInflationTermStructure> anInstrument = new ZeroCouponInflationSwapHelper(quote, observationLag, maturity, calendar, bdc, dc, ii); instruments.Add(anInstrument); } return(instruments); }
public CPIBond(uint settlementDays, double faceAmount, bool growthOnly, double baseCPI, Period observationLag, ZeroInflationIndex cpiIndex, CPI.InterpolationType observationInterpolation, Schedule schedule, DoubleVector coupons, DayCounter accrualDayCounter, BusinessDayConvention paymentConvention) : this(NQuantLibcPINVOKE.new_CPIBond__SWIG_6(settlementDays, faceAmount, growthOnly, baseCPI, Period.getCPtr(observationLag), ZeroInflationIndex.getCPtr(cpiIndex), (int)observationInterpolation, Schedule.getCPtr(schedule), DoubleVector.getCPtr(coupons), DayCounter.getCPtr(accrualDayCounter), (int)paymentConvention), true) { if (NQuantLibcPINVOKE.SWIGPendingException.Pending) { throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve(); } }
public ZeroCouponInflationSwap(_ZeroCouponInflationSwap.Type type, double nominal, Date start, Date maturity, Calendar calendar, BusinessDayConvention convention, DayCounter dayCounter, double fixedRate, ZeroInflationIndex index, Period lag) : this(NQuantLibcPINVOKE.new_ZeroCouponInflationSwap__SWIG_3((int)type, nominal, Date.getCPtr(start), Date.getCPtr(maturity), Calendar.getCPtr(calendar), (int)convention, DayCounter.getCPtr(dayCounter), fixedRate, ZeroInflationIndex.getCPtr(index), Period.getCPtr(lag)), true) { if (NQuantLibcPINVOKE.SWIGPendingException.Pending) { throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve(); } }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(ZeroInflationIndex obj) { return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr); }
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); }
public void cpibondconsistency() { 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); 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); // now do the bond equivalent List <double> fixedRates = new InitializedList <double>(1, fixedRate); int settlementDays = 1;// cannot be zero! bool growthOnly = true; CPIBond cpiB = new CPIBond(settlementDays, nominal, growthOnly, baseCPI, contractObservationLag, fixedIndex, observationInterpolation, fixedSchedule, fixedRates, fixedDayCount, fixedPaymentConvention); DiscountingBondEngine dbe = new DiscountingBondEngine(common.nominalUK); cpiB.setPricingEngine(dbe); QAssert.IsTrue(Math.Abs(cpiB.NPV() - zisV.legNPV(0).GetValueOrDefault()) < 1e-5, "cpi bond does not equal equivalent cpi swap leg"); // remove circular refernce common.hcpi.linkTo(null); }
public ZeroCouponInflationSwapHelper(double rate, Period lag, Date maturity, Calendar calendar, BusinessDayConvention bdc, DayCounter dayCounter, ZeroInflationIndex index) : this(NQuantLibcPINVOKE.new_ZeroCouponInflationSwapHelper(rate, Period.getCPtr(lag), Date.getCPtr(maturity), Calendar.getCPtr(calendar), (int)bdc, DayCounter.getCPtr(dayCounter), ZeroInflationIndex.getCPtr(index)), true) { if (NQuantLibcPINVOKE.SWIGPendingException.Pending) { throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve(); } }
public CPISwap(_CPISwap.Type type, double nominal, bool subtractInflationNominal, double spread, DayCounter floatDayCount, Schedule floatSchedule, BusinessDayConvention floatRoll, uint fixingDays, IborIndex floatIndexPtr, double fixedRate, double baseCPI, DayCounter fixedDayCount, Schedule fixedSchedule, BusinessDayConvention fixedRoll, Period observationLag, ZeroInflationIndex fixedIndexPtr) : this(NQuantLibcPINVOKE.new_CPISwap__SWIG_2((int)type, nominal, subtractInflationNominal, spread, DayCounter.getCPtr(floatDayCount), Schedule.getCPtr(floatSchedule), (int)floatRoll, fixingDays, IborIndex.getCPtr(floatIndexPtr), fixedRate, baseCPI, DayCounter.getCPtr(fixedDayCount), Schedule.getCPtr(fixedSchedule), (int)fixedRoll, Period.getCPtr(observationLag), ZeroInflationIndex.getCPtr(fixedIndexPtr)), true) { if (NQuantLibcPINVOKE.SWIGPendingException.Pending) { throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve(); } }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(ZeroInflationIndex obj) { return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr; }
public ZeroCouponInflationSwapHelper(double rate, Period lag, Date maturity, Calendar calendar, BusinessDayConvention bdc, DayCounter dayCounter, ZeroInflationIndex index) : this(NQuantLibcPINVOKE.new_ZeroCouponInflationSwapHelper(rate, Period.getCPtr(lag), Date.getCPtr(maturity), Calendar.getCPtr(calendar), (int)bdc, DayCounter.getCPtr(dayCounter), ZeroInflationIndex.getCPtr(index)), true) { if (NQuantLibcPINVOKE.SWIGPendingException.Pending) throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve(); }
public ZeroCouponInflationSwapHelper(QuoteHandle quote, Period lag, Date maturity, Calendar calendar, BusinessDayConvention bcd, DayCounter dayCounter, ZeroInflationIndex index, YieldTermStructureHandle nominalTS) : this(NQuantLibcPINVOKE.new_ZeroCouponInflationSwapHelper__SWIG_0(QuoteHandle.getCPtr(quote), Period.getCPtr(lag), Date.getCPtr(maturity), Calendar.getCPtr(calendar), (int)bcd, DayCounter.getCPtr(dayCounter), ZeroInflationIndex.getCPtr(index), YieldTermStructureHandle.getCPtr(nominalTS)), true) { if (NQuantLibcPINVOKE.SWIGPendingException.Pending) { throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve(); } }
public ZeroCouponInflationSwap(_ZeroCouponInflationSwap.Type type, double nominal, Date start, Date maturity, Calendar calendar, BusinessDayConvention convention, DayCounter dayCounter, double fixedRate, ZeroInflationIndex index, Period lag) : this(NQuantLibcPINVOKE.new_ZeroCouponInflationSwap__SWIG_3((int)type, nominal, Date.getCPtr(start), Date.getCPtr(maturity), Calendar.getCPtr(calendar), (int)convention, DayCounter.getCPtr(dayCounter), fixedRate, ZeroInflationIndex.getCPtr(index), Period.getCPtr(lag)), true) { if (NQuantLibcPINVOKE.SWIGPendingException.Pending) throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve(); }
public void testZeroTermStructure() { // Testing zero inflation term structure... SavedSettings backup = new SavedSettings(); // try the Zero UK Calendar calendar = new UnitedKingdom(); BusinessDayConvention bdc = BusinessDayConvention.ModifiedFollowing; Date evaluationDate = new Date(13, Month.August, 2007); evaluationDate = calendar.adjust(evaluationDate); Settings.setEvaluationDate(evaluationDate); // fixing data Date from = new Date(1, Month.January, 2005); Date to = new Date(13, Month.August, 2007); Schedule rpiSchedule = new MakeSchedule().from(from).to(to) .withTenor(new Period(1, TimeUnit.Months)) .withCalendar(new UnitedKingdom()) .withConvention(BusinessDayConvention.ModifiedFollowing) .value(); double[] fixData = { 189.9, 189.9, 189.6, 190.5, 191.6, 192.0, 192.2, 192.2, 192.6, 193.1, 193.3, 193.6, 194.1, 193.4, 194.2, 195.0, 196.5, 197.7, 198.5, 198.5, 199.2, 200.1, 200.4, 201.1, 202.7, 201.6, 203.1, 204.4, 205.4, 206.2, 207.3, 206.1, -999.0 }; RelinkableHandle <ZeroInflationTermStructure> hz = new RelinkableHandle <ZeroInflationTermStructure>(); bool interp = false; UKRPI iiUKRPI = new UKRPI(interp, hz); for (int i = 0; i < rpiSchedule.Count; i++) { iiUKRPI.addFixing(rpiSchedule[i], fixData[i]); } ZeroInflationIndex ii = iiUKRPI as ZeroInflationIndex; YieldTermStructure nominalTS = nominalTermStructure(); // now build the zero inflation curve Datum[] zcData = { new Datum(new Date(13, Month.August, 2008), 2.93), new Datum(new Date(13, Month.August, 2009), 2.95), new Datum(new Date(13, Month.August, 2010), 2.965), new Datum(new Date(15, Month.August, 2011), 2.98), new Datum(new Date(13, Month.August, 2012), 3.0), new Datum(new Date(13, Month.August, 2014), 3.06), new Datum(new Date(13, Month.August, 2017), 3.175), new Datum(new Date(13, Month.August, 2019), 3.243), new Datum(new Date(15, Month.August, 2022), 3.293), new Datum(new Date(14, Month.August, 2027), 3.338), new Datum(new Date(13, Month.August, 2032), 3.348), new Datum(new Date(15, Month.August, 2037), 3.348), new Datum(new Date(13, Month.August, 2047), 3.308), new Datum(new Date(13, Month.August, 2057), 3.228) }; Period observationLag = new Period(2, TimeUnit.Months); DayCounter dc = new Thirty360(); Frequency frequency = Frequency.Monthly; List <BootstrapHelper <ZeroInflationTermStructure> > helpers = makeHelpers(zcData, zcData.Length, ii, observationLag, calendar, bdc, dc); double baseZeroRate = zcData[0].rate / 100.0; PiecewiseZeroInflationCurve <Linear> pZITS = new PiecewiseZeroInflationCurve <Linear>( evaluationDate, calendar, dc, observationLag, frequency, ii.interpolated(), baseZeroRate, new Handle <YieldTermStructure>(nominalTS), helpers); pZITS.recalculate(); // first check that the zero rates on the curve match the data // and that the helpers give the correct impled rates const double eps = 0.00000001; bool forceLinearInterpolation = false; for (int i = 0; i < zcData.Length; i++) { Assert.IsTrue(Math.Abs(zcData[i].rate / 100.0 - pZITS.zeroRate(zcData[i].date, observationLag, forceLinearInterpolation)) < eps, "ZITS zeroRate != instrument " + pZITS.zeroRate(zcData[i].date, observationLag, forceLinearInterpolation) + " vs " + zcData[i].rate / 100.0 + " interpolation: " + ii.interpolated() + " forceLinearInterpolation " + forceLinearInterpolation); Assert.IsTrue(Math.Abs(helpers[i].impliedQuote() - zcData[i].rate / 100.0) < eps, "ZITS implied quote != instrument " + helpers[i].impliedQuote() + " vs " + zcData[i].rate / 100.0); } // now test the forecasting capability of the index. hz.linkTo(pZITS); from = hz.link.baseDate(); to = hz.link.maxDate() - new Period(1, TimeUnit.Months); // a bit of margin for adjustments Schedule testIndex = new MakeSchedule().from(from).to(to) .withTenor(new Period(1, TimeUnit.Months)) .withCalendar(new UnitedKingdom()) .withConvention(BusinessDayConvention.ModifiedFollowing).value(); // we are testing UKRPI which is not interpolated Date bd = hz.link.baseDate(); double bf = ii.fixing(bd); for (int i = 0; i < testIndex.Count; i++) { Date d = testIndex[i]; double z = hz.link.zeroRate(d, new Period(0, TimeUnit.Days)); double t = hz.link.dayCounter().yearFraction(bd, d); if (!ii.interpolated()) // because fixing constant over period { t = hz.link.dayCounter().yearFraction(bd, Utils.inflationPeriod(d, ii.frequency()).Key); } double calc = bf * Math.Pow(1 + z, t); if (t <= 0) { calc = ii.fixing(d, false); // still historical } if (Math.Abs(calc - ii.fixing(d, true)) / 10000.0 > eps) { Assert.Fail("ZC index does not forecast correctly for date " + d + " from base date " + bd + " with fixing " + bf + ", correct: " + calc + ", fix: " + ii.fixing(d, true) + ", t " + t); } } //=========================================================================================== // Test zero-inflation-indexed (i.e. cpi ratio) cashflow // just ordinary indexed cashflow with a zero inflation index Date baseDate = new Date(1, Month.January, 2006); Date fixDate = new Date(1, Month.August, 2014); Date payDate = new UnitedKingdom().adjust(fixDate + new Period(3, TimeUnit.Months), BusinessDayConvention.ModifiedFollowing); Index ind = ii as Index; Utils.QL_REQUIRE(ind != null, () => "dynamic_pointer_cast to Index from InflationIndex failed"); double notional = 1000000.0;//1m IndexedCashFlow iicf = new IndexedCashFlow(notional, ind, baseDate, fixDate, payDate); double correctIndexed = ii.fixing(iicf.fixingDate()) / ii.fixing(iicf.baseDate()); double calculatedIndexed = iicf.amount() / iicf.notional(); Assert.IsTrue(Math.Abs(correctIndexed - calculatedIndexed) < eps, "IndexedCashFlow indexing wrong: " + calculatedIndexed + " vs correct = " + correctIndexed); //=========================================================================================== // Test zero coupon swap // first make one ... ZeroInflationIndex zii = ii as ZeroInflationIndex; Utils.QL_REQUIRE(zii != null, () => "dynamic_pointer_cast to ZeroInflationIndex from UKRPI failed"); ZeroCouponInflationSwap nzcis = new ZeroCouponInflationSwap(ZeroCouponInflationSwap.Type.Payer, 1000000.0, evaluationDate, zcData[6].date, // end date = maturity calendar, bdc, dc, zcData[6].rate / 100.0, // fixed rate zii, observationLag); // N.B. no coupon pricer because it is not a coupon, effect of inflation curve via // inflation curve attached to the inflation index. Handle <YieldTermStructure> hTS = new Handle <YieldTermStructure>(nominalTS); IPricingEngine sppe = new DiscountingSwapEngine(hTS); nzcis.setPricingEngine(sppe); // ... and price it, should be zero Assert.IsTrue(Math.Abs(nzcis.NPV()) < 0.00001, "ZCIS does not reprice to zero " + nzcis.NPV() + evaluationDate + " to " + zcData[6].date + " becoming " + nzcis.maturityDate() + " rate " + zcData[6].rate + " fixed leg " + nzcis.legNPV(0) + " indexed-predicted inflated leg " + nzcis.legNPV(1) + " discount " + nominalTS.discount(nzcis.maturityDate())); //=========================================================================================== // Test multiplicative seasonality in price // //Seasonality factors NOT normalized //and UKRPI is not interpolated Date trueBaseDate = Utils.inflationPeriod(hz.link.baseDate(), ii.frequency()).Value; Date seasonallityBaseDate = new Date(31, Month.January, trueBaseDate.year()); List <double> seasonalityFactors = new List <double>(12); seasonalityFactors.Add(1.003245); seasonalityFactors.Add(1.000000); seasonalityFactors.Add(0.999715); seasonalityFactors.Add(1.000495); seasonalityFactors.Add(1.000929); seasonalityFactors.Add(0.998687); seasonalityFactors.Add(0.995949); seasonalityFactors.Add(0.994682); seasonalityFactors.Add(0.995949); seasonalityFactors.Add(1.000519); seasonalityFactors.Add(1.003705); seasonalityFactors.Add(1.004186); //Creating two different seasonality objects // MultiplicativePriceSeasonality seasonality_1 = new MultiplicativePriceSeasonality(); InitializedList <double> seasonalityFactors_1 = new InitializedList <double>(12, 1.0); seasonality_1.set(seasonallityBaseDate, Frequency.Monthly, seasonalityFactors_1); MultiplicativePriceSeasonality seasonality_real = new MultiplicativePriceSeasonality(seasonallityBaseDate, Frequency.Monthly, seasonalityFactors); //Testing seasonality correction when seasonality factors are = 1 // double[] fixing = { ii.fixing(new Date(14, Month.January, 2013), true), ii.fixing(new Date(14, Month.February, 2013), true), ii.fixing(new Date(14, Month.March, 2013), true), ii.fixing(new Date(14, Month.April, 2013), true), ii.fixing(new Date(14, Month.May, 2013), true), ii.fixing(new Date(14, Month.June, 2013), true), ii.fixing(new Date(14, Month.July, 2013), true), ii.fixing(new Date(14, Month.August, 2013), true), ii.fixing(new Date(14, Month.September, 2013), true), ii.fixing(new Date(14, Month.October, 2013), true), ii.fixing(new Date(14, Month.November, 2013), true), ii.fixing(new Date(14, Month.December, 2013), true) }; hz.link.setSeasonality(seasonality_1); Utils.QL_REQUIRE(hz.link.hasSeasonality(), () => "[44] incorrectly believes NO seasonality correction"); double[] seasonalityFixing_1 = { ii.fixing(new Date(14, Month.January, 2013), true), ii.fixing(new Date(14, Month.February, 2013), true), ii.fixing(new Date(14, Month.March, 2013), true), ii.fixing(new Date(14, Month.April, 2013), true), ii.fixing(new Date(14, Month.May, 2013), true), ii.fixing(new Date(14, Month.June, 2013), true), ii.fixing(new Date(14, Month.July, 2013), true), ii.fixing(new Date(14, Month.August, 2013), true), ii.fixing(new Date(14, Month.September, 2013), true), ii.fixing(new Date(14, Month.October, 2013), true), ii.fixing(new Date(14, Month.November, 2013), true), ii.fixing(new Date(14, Month.December, 2013), true) }; for (int i = 0; i < 12; i++) { if (Math.Abs(fixing[i] - seasonalityFixing_1[i]) > eps) { Assert.Fail("Seasonality doesn't work correctly when seasonality factors are set = 1"); } } //Testing seasonality correction when seasonality factors are different from 1 // //0.998687 is the seasonality factor corresponding to June (the base CPI curve month) // double[] expectedFixing = { ii.fixing(new Date(14, Month.January, 2013), true) * 1.003245 / 0.998687, ii.fixing(new Date(14, Month.February, 2013), true) * 1.000000 / 0.998687, ii.fixing(new Date(14, Month.March, 2013), true) * 0.999715 / 0.998687, ii.fixing(new Date(14, Month.April, 2013), true) * 1.000495 / 0.998687, ii.fixing(new Date(14, Month.May, 2013), true) * 1.000929 / 0.998687, ii.fixing(new Date(14, Month.June, 2013), true) * 0.998687 / 0.998687, ii.fixing(new Date(14, Month.July, 2013), true) * 0.995949 / 0.998687, ii.fixing(new Date(14, Month.August, 2013), true) * 0.994682 / 0.998687, ii.fixing(new Date(14, Month.September, 2013), true) * 0.995949 / 0.998687, ii.fixing(new Date(14, Month.October, 2013), true) * 1.000519 / 0.998687, ii.fixing(new Date(14, Month.November, 2013), true) * 1.003705 / 0.998687, ii.fixing(new Date(14, Month.December, 2013), true) * 1.004186 / 0.998687 }; hz.link.setSeasonality(seasonality_real); double[] seasonalityFixing_real = { ii.fixing(new Date(14, Month.January, 2013), true), ii.fixing(new Date(14, Month.February, 2013), true), ii.fixing(new Date(14, Month.March, 2013), true), ii.fixing(new Date(14, Month.April, 2013), true), ii.fixing(new Date(14, Month.May, 2013), true), ii.fixing(new Date(14, Month.June, 2013), true), ii.fixing(new Date(14, Month.July, 2013), true), ii.fixing(new Date(14, Month.August, 2013), true), ii.fixing(new Date(14, Month.September, 2013), true), ii.fixing(new Date(14, Month.October, 2013), true), ii.fixing(new Date(14, Month.November, 2013), true), ii.fixing(new Date(14, Month.December, 2013), true) }; for (int i = 0; i < 12; i++) { if (Math.Abs(expectedFixing[i] - seasonalityFixing_real[i]) > 0.01) { Assert.Fail("Seasonality doesn't work correctly when considering seasonality factors != 1 " + expectedFixing[i] + " vs " + seasonalityFixing_real[i]); } } //Testing Unset function // Utils.QL_REQUIRE(hz.link.hasSeasonality(), () => "[4] incorrectly believes NO seasonality correction"); hz.link.setSeasonality(); Utils.QL_REQUIRE(!hz.link.hasSeasonality(), () => "[5] incorrectly believes HAS seasonality correction"); double[] seasonalityFixing_unset = { ii.fixing(new Date(14, Month.January, 2013), true), ii.fixing(new Date(14, Month.February, 2013), true), ii.fixing(new Date(14, Month.March, 2013), true), ii.fixing(new Date(14, Month.April, 2013), true), ii.fixing(new Date(14, Month.May, 2013), true), ii.fixing(new Date(14, Month.June, 2013), true), ii.fixing(new Date(14, Month.July, 2013), true), ii.fixing(new Date(14, Month.August, 2013), true), ii.fixing(new Date(14, Month.September, 2013), true), ii.fixing(new Date(14, Month.October, 2013), true), ii.fixing(new Date(14, Month.November, 2013), true), ii.fixing(new Date(14, Month.December, 2013), true) }; for (int i = 0; i < 12; i++) { if (Math.Abs(seasonalityFixing_unset[i] - seasonalityFixing_1[i]) > eps) { Assert.Fail("UnsetSeasonality doesn't work correctly " + seasonalityFixing_unset[i] + " vs " + seasonalityFixing_1[i]); } } //============================================================================== // now do an INTERPOLATED index, i.e. repeat everything on a fake version of // UKRPI (to save making another term structure) bool interpYES = true; UKRPI iiUKRPIyes = new UKRPI(interpYES, hz); for (int i = 0; i < fixData.Length; i++) { iiUKRPIyes.addFixing(rpiSchedule[i], fixData[i]); } ZeroInflationIndex iiyes = iiUKRPIyes as ZeroInflationIndex; // now build the zero inflation curve // same data, bigger lag or it will be a self-contradiction Period observationLagyes = new Period(3, TimeUnit.Months); List <BootstrapHelper <ZeroInflationTermStructure> > helpersyes = makeHelpers(zcData, zcData.Length, iiyes, observationLagyes, calendar, bdc, dc); PiecewiseZeroInflationCurve <Linear> pZITSyes = new PiecewiseZeroInflationCurve <Linear>( evaluationDate, calendar, dc, observationLagyes, frequency, iiyes.interpolated(), baseZeroRate, new Handle <YieldTermStructure>(nominalTS), helpersyes); pZITSyes.recalculate(); // first check that the zero rates on the curve match the data // and that the helpers give the correct impled rates forceLinearInterpolation = false; // still for (int i = 0; i < zcData.Length; i++) { Assert.IsTrue(Math.Abs(zcData[i].rate / 100.0 - pZITSyes.zeroRate(zcData[i].date, observationLagyes, forceLinearInterpolation)) < eps, "ZITS INTERPOLATED zeroRate != instrument " + pZITSyes.zeroRate(zcData[i].date, observationLagyes, forceLinearInterpolation) + " date " + zcData[i].date + " observationLagyes " + observationLagyes + " vs " + zcData[i].rate / 100.0 + " interpolation: " + iiyes.interpolated() + " forceLinearInterpolation " + forceLinearInterpolation); Assert.IsTrue(Math.Abs(helpersyes[i].impliedQuote() - zcData[i].rate / 100.0) < eps, "ZITS INTERPOLATED implied quote != instrument " + helpersyes[i].impliedQuote() + " vs " + zcData[i].rate / 100.0); } //====================================================================================== // now test the forecasting capability of the index. hz.linkTo(pZITSyes); from = hz.link.baseDate() + new Period(1, TimeUnit.Months); // to avoid historical linear bit for rest of base month to = hz.link.maxDate() - new Period(1, TimeUnit.Months); // a bit of margin for adjustments testIndex = new MakeSchedule().from(from).to(to) .withTenor(new Period(1, TimeUnit.Months)) .withCalendar(new UnitedKingdom()) .withConvention(BusinessDayConvention.ModifiedFollowing).value(); // we are testing UKRPI which is FAKE interpolated for testing here bd = hz.link.baseDate(); bf = iiyes.fixing(bd); for (int i = 0; i < testIndex.Count; i++) { Date d = testIndex[i]; double z = hz.link.zeroRate(d, new Period(0, TimeUnit.Days)); double t = hz.link.dayCounter().yearFraction(bd, d); double calc = bf * Math.Pow(1 + z, t); if (t <= 0) { calc = iiyes.fixing(d); // still historical } if (Math.Abs(calc - iiyes.fixing(d)) > eps) { Assert.Fail("ZC INTERPOLATED index does not forecast correctly for date " + d + " from base date " + bd + " with fixing " + bf + ", correct: " + calc + ", fix: " + iiyes.fixing(d) + ", t " + t + ", zero " + z); } } //=========================================================================================== // Test zero coupon swap ZeroInflationIndex ziiyes = iiyes as ZeroInflationIndex; Utils.QL_REQUIRE(ziiyes != null, () => "dynamic_pointer_cast to ZeroInflationIndex from UKRPI-I failed"); ZeroCouponInflationSwap nzcisyes = new ZeroCouponInflationSwap(ZeroCouponInflationSwap.Type.Payer, 1000000.0, evaluationDate, zcData[6].date, // end date = maturity calendar, bdc, dc, zcData[6].rate / 100.0, // fixed rate ziiyes, observationLagyes); // N.B. no coupon pricer because it is not a coupon, effect of inflation curve via // inflation curve attached to the inflation index. nzcisyes.setPricingEngine(sppe); // ... and price it, should be zero Assert.IsTrue(Math.Abs(nzcisyes.NPV()) < 0.00001, "ZCIS-I does not reprice to zero " + nzcisyes.NPV() + evaluationDate + " to " + zcData[6].date + " becoming " + nzcisyes.maturityDate() + " rate " + zcData[6].rate + " fixed leg " + nzcisyes.legNPV(0) + " indexed-predicted inflated leg " + nzcisyes.legNPV(1) + " discount " + nominalTS.discount(nzcisyes.maturityDate()) ); // remove circular refernce hz.linkTo(new ZeroInflationTermStructure()); }
public CPIBond(uint settlementDays, double faceAmount, bool growthOnly, double baseCPI, Period observationLag, ZeroInflationIndex cpiIndex, CPI.InterpolationType observationInterpolation, Schedule schedule, DoubleVector coupons, DayCounter accrualDayCounter) : this(NQuantLibcPINVOKE.new_CPIBond__SWIG_7(settlementDays, faceAmount, growthOnly, baseCPI, Period.getCPtr(observationLag), ZeroInflationIndex.getCPtr(cpiIndex), (int)observationInterpolation, Schedule.getCPtr(schedule), DoubleVector.getCPtr(coupons), DayCounter.getCPtr(accrualDayCounter)), true) { if (NQuantLibcPINVOKE.SWIGPendingException.Pending) throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve(); }
public CPIBond(uint settlementDays, double faceAmount, bool growthOnly, double baseCPI, Period observationLag, ZeroInflationIndex cpiIndex, CPI.InterpolationType observationInterpolation, Schedule schedule, DoubleVector coupons, DayCounter accrualDayCounter, BusinessDayConvention paymentConvention, Date issueDate, Calendar paymentCalendar, Period exCouponPeriod, Calendar exCouponCalendar) : this(NQuantLibcPINVOKE.new_CPIBond__SWIG_2(settlementDays, faceAmount, growthOnly, baseCPI, Period.getCPtr(observationLag), ZeroInflationIndex.getCPtr(cpiIndex), (int)observationInterpolation, Schedule.getCPtr(schedule), DoubleVector.getCPtr(coupons), DayCounter.getCPtr(accrualDayCounter), (int)paymentConvention, Date.getCPtr(issueDate), Calendar.getCPtr(paymentCalendar), Period.getCPtr(exCouponPeriod), Calendar.getCPtr(exCouponCalendar)), true) { if (NQuantLibcPINVOKE.SWIGPendingException.Pending) throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve(); }