26
26
#include < ql/cashflows/iborcoupon.hpp>
27
27
#include < ql/cashflows/lineartsrpricer.hpp>
28
28
#include < ql/indexes/iborindex.hpp>
29
- #include < ql/instruments/vanillaswap.hpp>
30
29
#include < ql/instruments/overnightindexedswap.hpp>
30
+ #include < ql/instruments/vanillaswap.hpp>
31
31
#include < ql/math/integrals/kronrodintegral.hpp>
32
32
#include < ql/math/solvers1d/brent.hpp>
33
33
#include < ql/pricingengines/blackformula.hpp>
@@ -123,23 +123,31 @@ namespace QuantLib {
123
123
124
124
today_ = QuantLib::Settings::instance ().evaluationDate ();
125
125
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
+
132
139
133
- spreadLegValue_ = spread_ * coupon_->accrualPeriod () *
134
- discountCurve_->discount (paymentDate_) *
140
+ couponDiscountRatio_ = couponCurvePaymentDiscount / discountCurvePaymentDiscount_;
141
+
142
+ spreadLegValue_ = spread_ * coupon_->accrualPeriod () * discountCurvePaymentDiscount_ *
135
143
couponDiscountRatio_;
136
144
137
145
if (fixingDate_ > today_) {
138
146
139
147
swapTenor_ = swapIndex_->tenor ();
140
148
141
149
Leg swapFixedLeg;
142
- if (auto on = boost ::dynamic_pointer_cast<OvernightIndexedSwapIndex>(swapIndex_)) {
150
+ if (auto on = ext ::dynamic_pointer_cast<OvernightIndexedSwapIndex>(swapIndex_)) {
143
151
onSwap_ = on->underlyingSwap (fixingDate_);
144
152
swapRateValue_ = onSwap_->fairRate ();
145
153
annuity_ = 1.0E4 * std::fabs (onSwap_->fixedLegBPS ());
@@ -371,8 +379,7 @@ namespace QuantLib {
371
379
372
380
Rate LinearTsrPricer::swapletRate () const {
373
381
return swapletPrice () /
374
- (coupon_->accrualPeriod () *
375
- discountCurve_->discount (paymentDate_) * couponDiscountRatio_);
382
+ (coupon_->accrualPeriod () * discountCurvePaymentDiscount_ * couponDiscountRatio_);
376
383
}
377
384
378
385
Real LinearTsrPricer::capletPrice (Rate effectiveCap) const {
@@ -381,10 +388,8 @@ namespace QuantLib {
381
388
// the fixing is determined
382
389
const Rate Rs = std::max (
383
390
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_);
388
393
return price;
389
394
} else {
390
395
Real capletPrice = optionletPrice (Option::Call, effectiveCap);
@@ -394,8 +399,7 @@ namespace QuantLib {
394
399
395
400
Rate LinearTsrPricer::capletRate (Rate effectiveCap) const {
396
401
return capletPrice (effectiveCap) /
397
- (coupon_->accrualPeriod () *
398
- discountCurve_->discount (paymentDate_) * couponDiscountRatio_);
402
+ (coupon_->accrualPeriod () * discountCurvePaymentDiscount_ * couponDiscountRatio_);
399
403
}
400
404
401
405
Real LinearTsrPricer::floorletPrice (Rate effectiveFloor) const {
@@ -404,10 +408,8 @@ namespace QuantLib {
404
408
// the fixing is determined
405
409
const Rate Rs = std::max (
406
410
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_);
411
413
return price;
412
414
} else {
413
415
Real floorletPrice = optionletPrice (Option::Put, effectiveFloor);
@@ -417,8 +419,7 @@ namespace QuantLib {
417
419
418
420
Rate LinearTsrPricer::floorletRate (Rate effectiveFloor) const {
419
421
return floorletPrice (effectiveFloor) /
420
- (coupon_->accrualPeriod () *
421
- discountCurve_->discount (paymentDate_) * couponDiscountRatio_);
422
+ (coupon_->accrualPeriod () * discountCurvePaymentDiscount_ * couponDiscountRatio_);
422
423
}
423
424
424
425
Real LinearTsrPricer::swapletPrice () const {
@@ -427,14 +428,12 @@ namespace QuantLib {
427
428
const Rate Rs = coupon_->swapIndex ()->fixing (fixingDate_);
428
429
Rate price =
429
430
(gearing_ * Rs + spread_) *
430
- (coupon_->accrualPeriod () *
431
- discountCurve_->discount (paymentDate_) * couponDiscountRatio_);
431
+ (coupon_->accrualPeriod () * discountCurvePaymentDiscount_ * couponDiscountRatio_);
432
432
return price;
433
433
} else {
434
434
Real atmCapletPrice = optionletPrice (Option::Call, swapRateValue_);
435
435
Real atmFloorletPrice = optionletPrice (Option::Put, swapRateValue_);
436
- return gearing_ * (coupon_->accrualPeriod () *
437
- discountCurve_->discount (paymentDate_) *
436
+ return gearing_ * (coupon_->accrualPeriod () * discountCurvePaymentDiscount_ *
438
437
swapRateValue_ * couponDiscountRatio_ +
439
438
atmCapletPrice - atmFloorletPrice) +
440
439
spreadLegValue_;
0 commit comments