Skip to content

Commit b22dcd3

Browse files
Merge branch 'QPR-11975' into 'master'
QPR-11975 fix past payment dates Closes QPR-11975 See merge request qs/quantlib!57
2 parents 88c3a2c + 00d2fce commit b22dcd3

File tree

2 files changed

+29
-29
lines changed

2 files changed

+29
-29
lines changed

ql/cashflows/lineartsrpricer.cpp

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
#include <ql/cashflows/iborcoupon.hpp>
2727
#include <ql/cashflows/lineartsrpricer.hpp>
2828
#include <ql/indexes/iborindex.hpp>
29-
#include <ql/instruments/vanillaswap.hpp>
3029
#include <ql/instruments/overnightindexedswap.hpp>
30+
#include <ql/instruments/vanillaswap.hpp>
3131
#include <ql/math/integrals/kronrodintegral.hpp>
3232
#include <ql/math/solvers1d/brent.hpp>
3333
#include <ql/pricingengines/blackformula.hpp>
@@ -123,23 +123,31 @@ namespace QuantLib {
123123

124124
today_ = QuantLib::Settings::instance().evaluationDate();
125125

126-
if (paymentDate_ > today_ && !couponDiscountCurve_.empty())
127-
couponDiscountRatio_ =
128-
couponDiscountCurve_->discount(paymentDate_) /
129-
discountCurve_->discount(paymentDate_);
130-
else
131-
couponDiscountRatio_ = 1.;
126+
Real couponCurvePaymentDiscount;
127+
if (!couponDiscountCurve_.empty() && paymentDate_ > couponDiscountCurve_->referenceDate()) {
128+
couponCurvePaymentDiscount = couponDiscountCurve_->discount(paymentDate_);
129+
} else {
130+
couponCurvePaymentDiscount = 1.0;
131+
}
132+
133+
if (paymentDate_ > discountCurve_->referenceDate()) {
134+
discountCurvePaymentDiscount_ = discountCurve_->discount(paymentDate_);
135+
} else {
136+
discountCurvePaymentDiscount_ = 1.0;
137+
}
138+
132139

133-
spreadLegValue_ = spread_ * coupon_->accrualPeriod() *
134-
discountCurve_->discount(paymentDate_) *
140+
couponDiscountRatio_ = couponCurvePaymentDiscount / discountCurvePaymentDiscount_;
141+
142+
spreadLegValue_ = spread_ * coupon_->accrualPeriod() * discountCurvePaymentDiscount_ *
135143
couponDiscountRatio_;
136144

137145
if (fixingDate_ > today_) {
138146

139147
swapTenor_ = swapIndex_->tenor();
140148

141149
Leg swapFixedLeg;
142-
if(auto on = boost::dynamic_pointer_cast<OvernightIndexedSwapIndex>(swapIndex_)) {
150+
if(auto on = ext::dynamic_pointer_cast<OvernightIndexedSwapIndex>(swapIndex_)) {
143151
onSwap_ = on->underlyingSwap(fixingDate_);
144152
swapRateValue_ = onSwap_->fairRate();
145153
annuity_ = 1.0E4 * std::fabs(onSwap_->fixedLegBPS());
@@ -371,8 +379,7 @@ namespace QuantLib {
371379

372380
Rate LinearTsrPricer::swapletRate() const {
373381
return swapletPrice() /
374-
(coupon_->accrualPeriod() *
375-
discountCurve_->discount(paymentDate_) * couponDiscountRatio_);
382+
(coupon_->accrualPeriod() * discountCurvePaymentDiscount_ * couponDiscountRatio_);
376383
}
377384

378385
Real LinearTsrPricer::capletPrice(Rate effectiveCap) const {
@@ -381,10 +388,8 @@ namespace QuantLib {
381388
// the fixing is determined
382389
const Rate Rs = std::max(
383390
coupon_->swapIndex()->fixing(fixingDate_) - effectiveCap, 0.);
384-
Rate price =
385-
(gearing_ * Rs) *
386-
(coupon_->accrualPeriod() *
387-
discountCurve_->discount(paymentDate_) * couponDiscountRatio_);
391+
Rate price = (gearing_ * Rs) * (coupon_->accrualPeriod() *
392+
discountCurvePaymentDiscount_ * couponDiscountRatio_);
388393
return price;
389394
} else {
390395
Real capletPrice = optionletPrice(Option::Call, effectiveCap);
@@ -394,8 +399,7 @@ namespace QuantLib {
394399

395400
Rate LinearTsrPricer::capletRate(Rate effectiveCap) const {
396401
return capletPrice(effectiveCap) /
397-
(coupon_->accrualPeriod() *
398-
discountCurve_->discount(paymentDate_) * couponDiscountRatio_);
402+
(coupon_->accrualPeriod() * discountCurvePaymentDiscount_ * couponDiscountRatio_);
399403
}
400404

401405
Real LinearTsrPricer::floorletPrice(Rate effectiveFloor) const {
@@ -404,10 +408,8 @@ namespace QuantLib {
404408
// the fixing is determined
405409
const Rate Rs = std::max(
406410
effectiveFloor - coupon_->swapIndex()->fixing(fixingDate_), 0.);
407-
Rate price =
408-
(gearing_ * Rs) *
409-
(coupon_->accrualPeriod() *
410-
discountCurve_->discount(paymentDate_) * couponDiscountRatio_);
411+
Rate price = (gearing_ * Rs) * (coupon_->accrualPeriod() *
412+
discountCurvePaymentDiscount_ * couponDiscountRatio_);
411413
return price;
412414
} else {
413415
Real floorletPrice = optionletPrice(Option::Put, effectiveFloor);
@@ -417,8 +419,7 @@ namespace QuantLib {
417419

418420
Rate LinearTsrPricer::floorletRate(Rate effectiveFloor) const {
419421
return floorletPrice(effectiveFloor) /
420-
(coupon_->accrualPeriod() *
421-
discountCurve_->discount(paymentDate_) * couponDiscountRatio_);
422+
(coupon_->accrualPeriod() * discountCurvePaymentDiscount_ * couponDiscountRatio_);
422423
}
423424

424425
Real LinearTsrPricer::swapletPrice() const {
@@ -427,14 +428,12 @@ namespace QuantLib {
427428
const Rate Rs = coupon_->swapIndex()->fixing(fixingDate_);
428429
Rate price =
429430
(gearing_ * Rs + spread_) *
430-
(coupon_->accrualPeriod() *
431-
discountCurve_->discount(paymentDate_) * couponDiscountRatio_);
431+
(coupon_->accrualPeriod() * discountCurvePaymentDiscount_ * couponDiscountRatio_);
432432
return price;
433433
} else {
434434
Real atmCapletPrice = optionletPrice(Option::Call, swapRateValue_);
435435
Real atmFloorletPrice = optionletPrice(Option::Put, swapRateValue_);
436-
return gearing_ * (coupon_->accrualPeriod() *
437-
discountCurve_->discount(paymentDate_) *
436+
return gearing_ * (coupon_->accrualPeriod() * discountCurvePaymentDiscount_ *
438437
swapRateValue_ * couponDiscountRatio_ +
439438
atmCapletPrice - atmFloorletPrice) +
440439
spreadLegValue_;

ql/cashflows/lineartsrpricer.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,8 @@ namespace QuantLib {
233233
Real gearing_, spread_;
234234

235235
Period swapTenor_;
236-
Real spreadLegValue_, swapRateValue_, couponDiscountRatio_, annuity_;
236+
Real spreadLegValue_, swapRateValue_, couponDiscountRatio_, discountCurvePaymentDiscount_,
237+
annuity_;
237238

238239
ext::shared_ptr<SwapIndex> swapIndex_;
239240
ext::shared_ptr<VanillaSwap> swap_;

0 commit comments

Comments
 (0)