Skip to content

Commit 2691acd

Browse files
pcaspersjenkins
authored andcommitted
QPR-12559 cover on coupons, thanks to github user noonediesalone
1 parent f8664de commit 2691acd

1 file changed

Lines changed: 23 additions & 19 deletions

File tree

OREAnalytics/orea/engine/parsensitivityinstrumentbuilder.cpp

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,29 +1063,33 @@ std::pair<QuantLib::ext::shared_ptr<QuantLib::Instrument>, Date> ParSensitivityI
10631063
Date settlementDate = payIndexCalendar.advance(payIndexCalendar.adjust(asof), payIndex->fixingDays() * Days);
10641064

10651065
bool telescopicValueDates = true;
1066-
QuantLib::ext::shared_ptr<Swap> helper = QuantLib::ext::make_shared<TenorBasisSwap>(
1066+
auto helper = QuantLib::ext::make_shared<TenorBasisSwap>(
10671067
settlementDate, 1.0, term, payIndex, 0.0, conv->payFrequency(), receiveIndex, 0.0, conv->receiveFrequency(),
10681068
DateGeneration::Backward, conv->includeSpread(), conv->spreadOnRec(), conv->subPeriodsCouponType(),
10691069
telescopicValueDates);
10701070

1071-
QuantLib::ext::shared_ptr<IborCoupon> lastCoupon1 =
1072-
QuantLib::ext::dynamic_pointer_cast<IborCoupon>(QuantLib::ext::static_pointer_cast<TenorBasisSwap>(helper)->payLeg().back());
1073-
Date maxDate2;
1074-
QuantLib::ext::shared_ptr<IborCoupon> lastCoupon2 =
1075-
QuantLib::ext::dynamic_pointer_cast<IborCoupon>(QuantLib::ext::static_pointer_cast<TenorBasisSwap>(helper)->recLeg().back());
1076-
if (lastCoupon2 != nullptr)
1077-
maxDate2 = lastCoupon2->fixingEndDate();
1078-
else {
1079-
QuantLib::ext::shared_ptr<QuantExt::SubPeriodsCoupon1> lastCoupon2;
1080-
if (conv->spreadOnRec())
1081-
lastCoupon2 = QuantLib::ext::dynamic_pointer_cast<QuantExt::SubPeriodsCoupon1>(
1082-
QuantLib::ext::static_pointer_cast<TenorBasisSwap>(helper)->payLeg().back());
1083-
else
1084-
lastCoupon2 = QuantLib::ext::dynamic_pointer_cast<QuantExt::SubPeriodsCoupon1>(
1085-
QuantLib::ext::static_pointer_cast<TenorBasisSwap>(helper)->recLeg().back());
1086-
maxDate2 = receiveIndexCalendar.advance(lastCoupon2->valueDates().back(), conv->receiveFrequency());
1087-
}
1088-
Date latestRelevantDate = std::max(helper->maturityDate(), std::max(lastCoupon1->fixingEndDate(), maxDate2));
1071+
auto lastPayCoupon = helper->payLeg().back();
1072+
auto lastReceiveCoupon = helper->recLeg().back();
1073+
1074+
auto lastCouponDate = [](QuantLib::ext::shared_ptr<CashFlow> flow, Period freq, Calendar cal) -> Date {
1075+
if (auto c = QuantLib::ext::dynamic_pointer_cast<IborCoupon>(flow))
1076+
return c->fixingEndDate();
1077+
Date d{};
1078+
if (auto c = QuantLib::ext::dynamic_pointer_cast<SubPeriodsCoupon1>(flow))
1079+
d = c->valueDates().back();
1080+
else if (auto c = QuantLib::ext::dynamic_pointer_cast<QuantLib::OvernightIndexedCoupon>(flow)) {
1081+
d = c->valueDates().back();
1082+
freq = 1 * Days;
1083+
} else {
1084+
QL_FAIL("makeTenorBasisSwap(): Either IborCoupon, SubPeriodsCoupon1 or OvernightIndexedCoupon cashflow "
1085+
"expected.");
1086+
}
1087+
return cal.advance(d, freq);
1088+
};
1089+
1090+
Date maxDate1 = lastCouponDate(lastPayCoupon, conv->payFrequency(), payIndexCalendar);
1091+
Date maxDate2 = lastCouponDate(lastReceiveCoupon, conv->receiveFrequency(), receiveIndexCalendar);
1092+
Date latestRelevantDate = std::max(helper->maturityDate(), std::max(maxDate1, maxDate2));
10891093

10901094
if (market != nullptr) {
10911095
QuantLib::ext::shared_ptr<PricingEngine> swapEngine = QuantLib::ext::make_shared<DiscountingSwapEngine>(discountCurve);

0 commit comments

Comments
 (0)