diff --git a/ql/cashflows/capflooredinflationcoupon.cpp b/ql/cashflows/capflooredinflationcoupon.cpp index 5bdec54ecb6..cb2a5fbe6a6 100644 --- a/ql/cashflows/capflooredinflationcoupon.cpp +++ b/ql/cashflows/capflooredinflationcoupon.cpp @@ -64,6 +64,7 @@ namespace QuantLib { underlying->fixingDays(), underlying->yoyIndex(), underlying->observationLag(), + underlying->interpolation(), underlying->dayCounter(), underlying->gearing(), underlying->spread(), diff --git a/ql/cashflows/capflooredinflationcoupon.hpp b/ql/cashflows/capflooredinflationcoupon.hpp index 2a2491507fc..3b48d600c38 100644 --- a/ql/cashflows/capflooredinflationcoupon.hpp +++ b/ql/cashflows/capflooredinflationcoupon.hpp @@ -79,6 +79,7 @@ namespace QuantLib { Natural fixingDays, const ext::shared_ptr& index, const Period& observationLag, + const CPI::InterpolationType interpolation, const DayCounter& dayCounter, Real gearing = 1.0, Spread spread = 0.0, @@ -87,12 +88,36 @@ namespace QuantLib { const Date& refPeriodStart = Date(), const Date& refPeriodEnd = Date()) : YoYInflationCoupon(paymentDate, nominal, startDate, endDate, - fixingDays, index, observationLag, dayCounter, - gearing, spread, refPeriodStart, refPeriodEnd), + fixingDays, index, observationLag, interpolation, + dayCounter, gearing, spread, + refPeriodStart, refPeriodEnd), isFloored_(false), isCapped_(false) { setCommon(cap, floor); } + /*! \deprecated Use the overload that passes an interpolation type instead. + Deprecated in version 1.36. + */ + [[deprecated("Use the overload that passes an interpolation type instead")]] + CappedFlooredYoYInflationCoupon(const Date& paymentDate, + Real nominal, + const Date& startDate, + const Date& endDate, + Natural fixingDays, + const ext::shared_ptr& index, + const Period& observationLag, + const DayCounter& dayCounter, + Real gearing = 1.0, + Spread spread = 0.0, + const Rate cap = Null(), + const Rate floor = Null(), + const Date& refPeriodStart = Date(), + const Date& refPeriodEnd = Date()) + : CappedFlooredYoYInflationCoupon(paymentDate, nominal, startDate, endDate, + fixingDays, index, observationLag, CPI::AsIndex, + dayCounter, gearing, spread, cap, floor, + refPeriodStart, refPeriodEnd) {} + //! \name augmented Coupon interface //@{ //! swap(let) rate diff --git a/ql/cashflows/yoyinflationcoupon.cpp b/ql/cashflows/yoyinflationcoupon.cpp index db8e5a0b4ed..3fe3ec2665c 100644 --- a/ql/cashflows/yoyinflationcoupon.cpp +++ b/ql/cashflows/yoyinflationcoupon.cpp @@ -28,21 +28,39 @@ namespace QuantLib { YoYInflationCoupon:: YoYInflationCoupon(const Date& paymentDate, - Real nominal, - const Date& startDate, - const Date& endDate, - Natural fixingDays, - const ext::shared_ptr& yoyIndex, - const Period& observationLag, - const DayCounter& dayCounter, - Real gearing, - Spread spread, - const Date& refPeriodStart, - const Date& refPeriodEnd) + Real nominal, + const Date& startDate, + const Date& endDate, + Natural fixingDays, + const ext::shared_ptr& yoyIndex, + const Period& observationLag, + CPI::InterpolationType interpolation, + const DayCounter& dayCounter, + Real gearing, + Spread spread, + const Date& refPeriodStart, + const Date& refPeriodEnd) : InflationCoupon(paymentDate, nominal, startDate, endDate, - fixingDays, yoyIndex, observationLag, - dayCounter, refPeriodStart, refPeriodEnd), - yoyIndex_(yoyIndex), gearing_(gearing), spread_(spread) {} + fixingDays, yoyIndex, observationLag, + dayCounter, refPeriodStart, refPeriodEnd), + yoyIndex_(yoyIndex), interpolation_(interpolation), gearing_(gearing), spread_(spread) {} + + YoYInflationCoupon:: + YoYInflationCoupon(const Date& paymentDate, + Real nominal, + const Date& startDate, + const Date& endDate, + Natural fixingDays, + const ext::shared_ptr& yoyIndex, + const Period& observationLag, + const DayCounter& dayCounter, + Real gearing, + Spread spread, + const Date& refPeriodStart, + const Date& refPeriodEnd) + : YoYInflationCoupon(paymentDate, nominal, startDate, endDate, + fixingDays, yoyIndex, observationLag, CPI::AsIndex, + dayCounter, gearing, spread, refPeriodStart, refPeriodEnd) {} void YoYInflationCoupon::accept(AcyclicVisitor& v) { @@ -60,16 +78,23 @@ namespace QuantLib { } Rate YoYInflationCoupon::indexFixing() const { - return CPI::laggedYoYRate(yoyIndex(), accrualEndDate(), observationLag(), CPI::AsIndex); + return CPI::laggedYoYRate(yoyIndex(), accrualEndDate(), observationLag(), interpolation_); } yoyInflationLeg::yoyInflationLeg(Schedule schedule, Calendar paymentCalendar, ext::shared_ptr index, - const Period& observationLag) + const Period& observationLag, + CPI::InterpolationType interpolation) : schedule_(std::move(schedule)), index_(std::move(index)), observationLag_(observationLag), - paymentCalendar_(std::move(paymentCalendar)) {} + interpolation_(interpolation), paymentCalendar_(std::move(paymentCalendar)) {} + + yoyInflationLeg::yoyInflationLeg(Schedule schedule, + Calendar paymentCalendar, + ext::shared_ptr index, + const Period& observationLag) + : yoyInflationLeg(schedule, paymentCalendar, index, observationLag, CPI::AsIndex) {} yoyInflationLeg& yoyInflationLeg::withNotionals(Real notional) { @@ -199,6 +224,7 @@ namespace QuantLib { detail::get(fixingDays_, i, 0), index_, observationLag_, + interpolation_, paymentDayCounter_, detail::get(gearings_, i, 1.0), detail::get(spreads_, i, 0.0), @@ -211,6 +237,7 @@ namespace QuantLib { detail::get(fixingDays_, i, 0), index_, observationLag_, + interpolation_, paymentDayCounter_, detail::get(gearings_, i, 1.0), detail::get(spreads_, i, 0.0), diff --git a/ql/cashflows/yoyinflationcoupon.hpp b/ql/cashflows/yoyinflationcoupon.hpp index 8cccf5cdd10..c5f6fbee8b7 100644 --- a/ql/cashflows/yoyinflationcoupon.hpp +++ b/ql/cashflows/yoyinflationcoupon.hpp @@ -33,20 +33,37 @@ namespace QuantLib { //! %Coupon paying a YoY-inflation type index class YoYInflationCoupon : public InflationCoupon { - public: + public: + YoYInflationCoupon(const Date& paymentDate, + Real nominal, + const Date& startDate, + const Date& endDate, + Natural fixingDays, + const ext::shared_ptr& index, + const Period& observationLag, + CPI::InterpolationType interpolation, + const DayCounter& dayCounter, + Real gearing = 1.0, + Spread spread = 0.0, + const Date& refPeriodStart = Date(), + const Date& refPeriodEnd = Date()); + + /*! \deprecated Use the overload that passes an interpolation type instead. + Deprecated in version 1.36. + */ + [[deprecated("Use the overload that passes an interpolation type instead")]] YoYInflationCoupon(const Date& paymentDate, - Real nominal, - const Date& startDate, - const Date& endDate, - Natural fixingDays, - const ext::shared_ptr& index, - const Period& observationLag, - const DayCounter& dayCounter, - Real gearing = 1.0, - Spread spread = 0.0, - const Date& refPeriodStart = Date(), - const Date& refPeriodEnd = Date() - ); + Real nominal, + const Date& startDate, + const Date& endDate, + Natural fixingDays, + const ext::shared_ptr& index, + const Period& observationLag, + const DayCounter& dayCounter, + Real gearing = 1.0, + Spread spread = 0.0, + const Date& refPeriodStart = Date(), + const Date& refPeriodEnd = Date()); //! \name Inspectors //@{ @@ -60,6 +77,7 @@ namespace QuantLib { Rate adjustedFixing() const; const ext::shared_ptr& yoyIndex() const; + CPI::InterpolationType interpolation() const; //@} //! \name Visitability @@ -67,10 +85,10 @@ namespace QuantLib { void accept(AcyclicVisitor&) override; //@} - private: + private: ext::shared_ptr yoyIndex_; - protected: - + CPI::InterpolationType interpolation_; + protected: Real gearing_; Spread spread_; bool checkPricerImpl(const ext::shared_ptr&) const override; @@ -81,6 +99,10 @@ namespace QuantLib { return yoyIndex_; } + inline CPI::InterpolationType YoYInflationCoupon::interpolation() const { + return interpolation_; + } + inline Rate YoYInflationCoupon::adjustedFixing() const { return (rate()-spread())/gearing(); } @@ -89,9 +111,17 @@ namespace QuantLib { //! Helper class building a sequence of capped/floored yoy inflation coupons - //! payoff is: spread + gearing x index class yoyInflationLeg { public: + yoyInflationLeg(Schedule schedule, + Calendar cal, + ext::shared_ptr index, + const Period& observationLag, + CPI::InterpolationType interpolation); + /*! \deprecated Use the overload that passes an interpolation type instead. + Deprecated in version 1.36. + */ + [[deprecated("Use the overload that passes an interpolation type instead")]] yoyInflationLeg(Schedule schedule, Calendar cal, ext::shared_ptr index, @@ -115,6 +145,7 @@ namespace QuantLib { Schedule schedule_; ext::shared_ptr index_; Period observationLag_; + CPI::InterpolationType interpolation_; std::vector notionals_; DayCounter paymentDayCounter_; BusinessDayConvention paymentAdjustment_ = ModifiedFollowing; diff --git a/ql/experimental/inflation/interpolatedyoyoptionletstripper.hpp b/ql/experimental/inflation/interpolatedyoyoptionletstripper.hpp index 7fdabc40eef..3c6047432fb 100644 --- a/ql/experimental/inflation/interpolatedyoyoptionletstripper.hpp +++ b/ql/experimental/inflation/interpolatedyoyoptionletstripper.hpp @@ -58,8 +58,7 @@ namespace QuantLib { //@} protected: - mutable std::vector > - volCurves_; + mutable std::vector > volCurves_; // used to set up the first point on each vol curve // using assumptions on unobserved vols at start @@ -114,7 +113,7 @@ namespace QuantLib { capfloor_ = MakeYoYInflationCapFloor(type, anIndex, (Size)std::floor(0.5+surf->timeFromReference(surf->minMaturity())), - surf->calendar(), lag) + surf->calendar(), lag, CPI::AsIndex) .withNominal(10000.0) .withStrike(K); @@ -238,7 +237,8 @@ namespace QuantLib { lag_, dc, cal, fixingDays_, - anIndex, K, nT, p_))); + anIndex, CPI::Flat, + K, nT, p_))); ext::shared_ptr yoyVolBLACK( new ConstantYoYOptionletVolatility(found, settlementDays, diff --git a/ql/experimental/inflation/yoyoptionlethelpers.cpp b/ql/experimental/inflation/yoyoptionlethelpers.cpp index a7a74f891a3..b30ee2283ad 100644 --- a/ql/experimental/inflation/yoyoptionlethelpers.cpp +++ b/ql/experimental/inflation/yoyoptionlethelpers.cpp @@ -32,6 +32,7 @@ namespace QuantLib { Calendar paymentCalendar, Natural fixingDays, ext::shared_ptr index, + CPI::InterpolationType interpolation, Rate strike, Size n, ext::shared_ptr pricer) @@ -43,7 +44,7 @@ namespace QuantLib { // build the instrument to reprice (only need do this once) yoyCapFloor_ = MakeYoYInflationCapFloor(capFloorType_, index_, - n_, calendar_, lag_) + n_, calendar_, lag_, interpolation) .withNominal(notional) .withFixingDays(fixingDays_) .withPaymentDayCounter(yoyDayCounter_) @@ -63,6 +64,20 @@ namespace QuantLib { // haven't yet set the vol (term structure = surface) } + YoYOptionletHelper::YoYOptionletHelper(const Handle& price, + Real notional, + YoYInflationCapFloor::Type capFloorType, + Period& lag, + DayCounter yoyDayCounter, + Calendar paymentCalendar, + Natural fixingDays, + ext::shared_ptr index, + Rate strike, + Size n, + ext::shared_ptr pricer) + : YoYOptionletHelper(price, notional, capFloorType, lag, yoyDayCounter, paymentCalendar, + fixingDays, index, CPI::AsIndex, strike, n, pricer) {} + Real YoYOptionletHelper::impliedQuote() const { yoyCapFloor_->deepUpdate(); diff --git a/ql/experimental/inflation/yoyoptionlethelpers.hpp b/ql/experimental/inflation/yoyoptionlethelpers.hpp index bb5e9452d9f..b098726887e 100644 --- a/ql/experimental/inflation/yoyoptionlethelpers.hpp +++ b/ql/experimental/inflation/yoyoptionlethelpers.hpp @@ -36,8 +36,23 @@ namespace QuantLib { : public BootstrapHelper { public: YoYOptionletHelper(const Handle& price, - Real notional, // get the price level right - // (e.g. bps = 10,000) + Real notional, // get the price level right, e.g., bps = 10,000 + YoYInflationCapFloor::Type capFloorType, + Period& lag, + DayCounter yoyDayCounter, + Calendar paymentCalendar, + Natural fixingDays, + ext::shared_ptr index, + CPI::InterpolationType interpolation, + Rate strike, + Size n, + ext::shared_ptr pricer); + /*! \deprecated Use the overload that passes an interpolation type instead. + Deprecated in version 1.36. + */ + [[deprecated("Use the overload that passes an interpolation type instead")]] + YoYOptionletHelper(const Handle& price, + Real notional, YoYInflationCapFloor::Type capFloorType, Period& lag, DayCounter yoyDayCounter, @@ -55,8 +70,7 @@ namespace QuantLib { YoYInflationCapFloor::Type capFloorType_; Period lag_; Natural fixingDays_; - ext::shared_ptr index_; // VERY important - has - // nominal & yoy curves + ext::shared_ptr index_; Rate strike_; Size n_; // how many payments DayCounter yoyDayCounter_; diff --git a/ql/instruments/makeyoyinflationcapfloor.cpp b/ql/instruments/makeyoyinflationcapfloor.cpp index c886547d435..21616c87bfc 100644 --- a/ql/instruments/makeyoyinflationcapfloor.cpp +++ b/ql/instruments/makeyoyinflationcapfloor.cpp @@ -30,12 +30,21 @@ namespace QuantLib { ext::shared_ptr index, const Size& length, Calendar cal, - const Period& observationLag) + const Period& observationLag, + CPI::InterpolationType interpolation) : capFloorType_(capFloorType), length_(length), calendar_(std::move(cal)), - index_(std::move(index)), observationLag_(observationLag), strike_(Null()), + index_(std::move(index)), observationLag_(observationLag), + interpolation_(interpolation), strike_(Null()), dayCounter_(Thirty360(Thirty360::BondBasis)) {} + MakeYoYInflationCapFloor::MakeYoYInflationCapFloor(YoYInflationCapFloor::Type capFloorType, + ext::shared_ptr index, + const Size& length, + Calendar cal, + const Period& observationLag) + : MakeYoYInflationCapFloor(capFloorType, index, length, cal, observationLag, CPI::AsIndex) {} + MakeYoYInflationCapFloor::operator YoYInflationCapFloor() const { ext::shared_ptr capfloor = *this; return *capfloor; @@ -58,7 +67,7 @@ namespace QuantLib { Unadjusted, Unadjusted, // ref periods & acc periods DateGeneration::Forward, false); Leg leg = yoyInflationLeg(schedule, calendar_, index_, - observationLag_) + observationLag_, interpolation_) .withPaymentAdjustment(roll_) .withPaymentDayCounter(dayCounter_) .withNotionals(nominal_) diff --git a/ql/instruments/makeyoyinflationcapfloor.hpp b/ql/instruments/makeyoyinflationcapfloor.hpp index 8fb8aef7e00..23bb3a6f631 100644 --- a/ql/instruments/makeyoyinflationcapfloor.hpp +++ b/ql/instruments/makeyoyinflationcapfloor.hpp @@ -37,6 +37,16 @@ namespace QuantLib { */ class MakeYoYInflationCapFloor { public: + MakeYoYInflationCapFloor(YoYInflationCapFloor::Type capFloorType, + ext::shared_ptr index, + const Size& length, + Calendar cal, + const Period& observationLag, + CPI::InterpolationType interpolation); + /*! \deprecated Use the overload that passes an interpolation type instead. + Deprecated in version 1.36. + */ + [[deprecated("Use the overload that passes an interpolation type instead")]] MakeYoYInflationCapFloor(YoYInflationCapFloor::Type capFloorType, ext::shared_ptr index, const Size& length, @@ -66,6 +76,7 @@ namespace QuantLib { Calendar calendar_; ext::shared_ptr index_; Period observationLag_; + CPI::InterpolationType interpolation_; Rate strike_; bool firstCapletExcluded_ = false, asOptionlet_ = false; Date effectiveDate_; diff --git a/ql/instruments/yearonyearinflationswap.cpp b/ql/instruments/yearonyearinflationswap.cpp index b4c8d71adc8..6760edc6003 100644 --- a/ql/instruments/yearonyearinflationswap.cpp +++ b/ql/instruments/yearonyearinflationswap.cpp @@ -39,6 +39,7 @@ namespace QuantLib { Schedule yoySchedule, ext::shared_ptr yoyIndex, const Period& observationLag, + CPI::InterpolationType interpolation, Spread spread, DayCounter yoyDayCount, Calendar paymentCalendar, @@ -54,7 +55,8 @@ namespace QuantLib { .withCouponRates(fixedRate_, fixedDayCount_) // Simple compounding by default .withPaymentAdjustment(paymentConvention_); - Leg yoyLeg = yoyInflationLeg(yoySchedule_, paymentCalendar_, yoyIndex_, observationLag_) + Leg yoyLeg = yoyInflationLeg(yoySchedule_, paymentCalendar_, yoyIndex_, + observationLag_, interpolation) .withNotionals(nominal_) .withPaymentDayCounter(yoyDayCount_) .withPaymentAdjustment(paymentConvention_) @@ -75,6 +77,21 @@ namespace QuantLib { } } + YearOnYearInflationSwap::YearOnYearInflationSwap(Type type, + Real nominal, + Schedule fixedSchedule, + Rate fixedRate, + DayCounter fixedDayCount, + Schedule yoySchedule, + ext::shared_ptr yoyIndex, + const Period& observationLag, + Spread spread, + DayCounter yoyDayCount, + Calendar paymentCalendar, + BusinessDayConvention paymentConvention) + : YearOnYearInflationSwap(type, nominal, fixedSchedule, fixedRate, fixedDayCount, + yoySchedule, yoyIndex, observationLag, CPI::AsIndex, + spread, yoyDayCount, paymentCalendar, paymentConvention) {} void YearOnYearInflationSwap::setupArguments(PricingEngine::arguments* args) const { diff --git a/ql/instruments/yearonyearinflationswap.hpp b/ql/instruments/yearonyearinflationswap.hpp index 2143e167c80..50657d14edf 100644 --- a/ql/instruments/yearonyearinflationswap.hpp +++ b/ql/instruments/yearonyearinflationswap.hpp @@ -26,12 +26,12 @@ #define quantlib_yyiis_hpp #include +#include #include #include #include namespace QuantLib { - class YoYInflationIndex; //! Year-on-year inflation-indexed swap /*! Quoted as a fixed rate \f$ K \f$. At start: @@ -49,6 +49,24 @@ namespace QuantLib { class arguments; class results; class engine; + YearOnYearInflationSwap( + Type type, + Real nominal, + Schedule fixedSchedule, + Rate fixedRate, + DayCounter fixedDayCount, + Schedule yoySchedule, + ext::shared_ptr yoyIndex, + const Period& observationLag, + CPI::InterpolationType interpolation, + Spread spread, + DayCounter yoyDayCount, + Calendar paymentCalendar, // inflation index does not have a calendar + BusinessDayConvention paymentConvention = ModifiedFollowing); + /*! \deprecated Use the overload that passes an interpolation type instead. + Deprecated in version 1.36. + */ + [[deprecated("Use the overload that passes an interpolation type instead")]] YearOnYearInflationSwap( Type type, Real nominal, @@ -142,7 +160,7 @@ namespace QuantLib { }; class YearOnYearInflationSwap::engine : public GenericEngine {}; + YearOnYearInflationSwap::results> {}; // inline definitions diff --git a/test-suite/inflation.cpp b/test-suite/inflation.cpp index 28d16e64658..42e760adb8d 100644 --- a/test-suite/inflation.cpp +++ b/test-suite/inflation.cpp @@ -1164,6 +1164,7 @@ BOOST_AUTO_TEST_CASE(testYYTermStructure) { yoySchedule, iir, observationLag, + CPI::Flat, 0.0, //spread on index dc, UnitedKingdom()); @@ -1200,6 +1201,7 @@ BOOST_AUTO_TEST_CASE(testYYTermStructure) { yoySchedule, iir, observationLag, + CPI::Flat, 0.0, //spread on index dc, UnitedKingdom()); @@ -1320,6 +1322,7 @@ BOOST_AUTO_TEST_CASE(testYYTermStructureWithLag) { yoySchedule, iir, observationLag, + CPI::Flat, 0.0, //spread on index dc, UnitedKingdom()); @@ -1356,6 +1359,7 @@ BOOST_AUTO_TEST_CASE(testYYTermStructureWithLag) { yoySchedule, iir, observationLag, + CPI::Flat, 0.0, //spread on index dc, UnitedKingdom()); diff --git a/test-suite/inflationcapfloor.cpp b/test-suite/inflationcapfloor.cpp index 98d5a95a472..26f877392a1 100644 --- a/test-suite/inflationcapfloor.cpp +++ b/test-suite/inflationcapfloor.cpp @@ -195,7 +195,7 @@ struct CommonVars { Schedule schedule(startDate, endDate, Period(frequency), calendar, Unadjusted,Unadjusted,// ref periods & acc periods DateGeneration::Forward, false); - return yoyInflationLeg(schedule, calendar, ii, observationLag) + return yoyInflationLeg(schedule, calendar, ii, observationLag, CPI::Flat) .withNotionals(nominals) .withPaymentDayCounter(dc) .withPaymentAdjustment(convention); @@ -424,7 +424,7 @@ BOOST_AUTO_TEST_CASE(testParity) { YearOnYearInflationSwap swap(Swap::Payer, 1000000.0, yoySchedule, // fixed schedule, but same as yoy strike, vars.dc, yoySchedule, vars.iir, - vars.observationLag, + vars.observationLag, CPI::Flat, 0.0, // spread on index vars.dc, UnitedKingdom()); diff --git a/test-suite/inflationcapflooredcoupon.cpp b/test-suite/inflationcapflooredcoupon.cpp index 568d9e77544..14d185a8524 100644 --- a/test-suite/inflationcapflooredcoupon.cpp +++ b/test-suite/inflationcapflooredcoupon.cpp @@ -210,7 +210,7 @@ struct CommonVars { std::vector gearingVector(length, gearing); std::vector spreadVector(length, spread); - Leg yoyLeg = yoyInflationLeg(schedule, calendar, ii, observationLag) + Leg yoyLeg = yoyInflationLeg(schedule, calendar, ii, observationLag, CPI::Flat) .withNotionals(nominals) .withPaymentDayCounter(dc) .withGearings(gearingVector) @@ -285,7 +285,7 @@ struct CommonVars { Unadjusted,Unadjusted,// ref periods & acc periods DateGeneration::Forward, false); - Leg yoyLeg = yoyInflationLeg(schedule, calendar, ii, observationLag) + Leg yoyLeg = yoyInflationLeg(schedule, calendar, ii, observationLag, CPI::Flat) .withNotionals(nominals) .withPaymentDayCounter(dc) .withPaymentAdjustment(convention) @@ -725,6 +725,7 @@ BOOST_AUTO_TEST_CASE(testInstrumentEquality) { yoySchedule, vars.iir, vars.observationLag, + CPI::Flat, 0.0, //spread on index vars.dc, UnitedKingdom());