Skip to content

Commit 985be6e

Browse files
committed
Account for payment lag in CPI coupons
1 parent 5d3a2f2 commit 985be6e

3 files changed

Lines changed: 15 additions & 3 deletions

File tree

OREData/ored/portfolio/legdata.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,6 +1662,7 @@ Leg makeCPILeg(const LegData& data, const boost::shared_ptr<ZeroInflationIndex>&
16621662
bool finalFlowCapFloor = cpiLegData->finalFlowCap() != Null<Real>() || cpiLegData->finalFlowFloor() != Null<Real>();
16631663

16641664
applyAmortization(notionals, data, schedule, false);
1665+
PaymentLag paymentLag = parsePaymentLag(data.paymentLag());
16651666

16661667
QuantExt::CPILeg cpiLeg =
16671668
QuantExt::CPILeg(schedule, index,
@@ -1672,6 +1673,7 @@ Leg makeCPILeg(const LegData& data, const boost::shared_ptr<ZeroInflationIndex>&
16721673
.withPaymentDayCounter(dc)
16731674
.withPaymentAdjustment(bdc)
16741675
.withPaymentCalendar(paymentCalendar)
1676+
.withPaymentLag(boost::apply_visitor(PaymentLagInteger(), paymentLag))
16751677
.withFixedRates(rates)
16761678
.withObservationInterpolation(interpolationMethod)
16771679
.withSubtractInflationNominal(cpiLegData->subtractInflationNominal())

QuantExt/qle/cashflows/cpicoupon.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,11 @@ CPILeg& CPILeg::withPaymentCalendar(const Calendar& cal) {
277277
return *this;
278278
}
279279

280+
CPILeg& CPILeg::withPaymentLag(Natural lag) {
281+
paymentLag_ = lag;
282+
return *this;
283+
}
284+
280285
CPILeg& CPILeg::withFixingDays(Natural fixingDays) {
281286
fixingDays_ = std::vector<Natural>(1, fixingDays);
282287
return *this;
@@ -366,7 +371,7 @@ CPILeg::operator Leg() const {
366371
for (Size i = 0; i < n; ++i) {
367372
refStart = start = schedule_.date(i);
368373
refEnd = end = schedule_.date(i + 1);
369-
Date paymentDate = paymentCalendar_.adjust(end, paymentAdjustment_);
374+
Date paymentDate = paymentCalendar_.advance(end, paymentLag_, Days, paymentAdjustment_);
370375

371376
Date exCouponDate;
372377
if (exCouponPeriod_ != Period()) {
@@ -405,10 +410,13 @@ CPILeg::operator Leg() const {
405410
}
406411

407412
// in CPI legs you always have a notional flow of some sort
408-
Date paymentDate = paymentCalendar_.adjust(schedule_.date(n), paymentAdjustment_);
409413

414+
// Previous implementations didn't differentiate the observation and payment dates
415+
Date observationDate = paymentCalendar_.adjust(schedule_.date(n), paymentAdjustment_);
416+
Date paymentDate = paymentCalendar_.advance(schedule_.date(n), paymentLag_, Days, paymentAdjustment_);
417+
410418
ext::shared_ptr<CPICashFlow> xnl = ext::make_shared<CPICashFlow>(
411-
detail::get(notionals_, n, 0.0), index_, baseDate, baseCPI_, paymentDate, observationLag_,
419+
detail::get(notionals_, n, 0.0), index_, baseDate, baseCPI_, observationDate, observationLag_,
412420
observationInterpolation_, paymentDate, subtractInflationNominal_);
413421

414422
if (finalFlowCap_ == Null<Real>() && finalFlowFloor_ == Null<Real>()) {

QuantExt/qle/cashflows/cpicoupon.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ class CPILeg {
146146
CPILeg& withPaymentDayCounter(const DayCounter&);
147147
CPILeg& withPaymentAdjustment(BusinessDayConvention);
148148
CPILeg& withPaymentCalendar(const Calendar&);
149+
CPILeg& withPaymentLag(Natural lag);
149150
CPILeg& withFixingDays(Natural fixingDays);
150151
CPILeg& withFixingDays(const std::vector<Natural>& fixingDays);
151152
CPILeg& withObservationInterpolation(CPI::InterpolationType);
@@ -176,6 +177,7 @@ class CPILeg {
176177
DayCounter paymentDayCounter_;
177178
BusinessDayConvention paymentAdjustment_;
178179
Calendar paymentCalendar_;
180+
Natural paymentLag_;
179181
std::vector<Natural> fixingDays_;
180182
CPI::InterpolationType observationInterpolation_;
181183
bool subtractInflationNominal_;

0 commit comments

Comments
 (0)