Skip to content

Commit 9b0ccc4

Browse files
author
jenkins
committed
git subrepo pull (merge) ore
subrepo: subdir: "ore" merged: "ee36042a7e" upstream: origin: "git@gitlab.acadiasoft.net:qs/ore.git" branch: "master" commit: "375786e251" git-subrepo: version: "0.4.6" origin: "https://github.com/ingydotnet/git-subrepo" commit: "73a0129"
2 parents 37bc54e + 375786e commit 9b0ccc4

3 files changed

Lines changed: 42 additions & 36 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);

QuantExt/qle/termstructures/tenorbasisswaphelper.cpp

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ TenorBasisSwapHelper::TenorBasisSwapHelper(Handle<Quote> spread, const Period& s
6262
6363
*/
6464

65-
setDiscountRelinkableHandle_ = false;
65+
automaticDiscountRelinkableHandle_ = false;
6666

6767
bool payGiven = !payIndex_->forwardingTermStructure().empty();
6868
bool recGiven = !receiveIndex_->forwardingTermStructure().empty();
@@ -71,6 +71,9 @@ TenorBasisSwapHelper::TenorBasisSwapHelper(Handle<Quote> spread, const Period& s
7171
QuantLib::ext::shared_ptr<OvernightIndex> payIndexON = QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(payIndex_);
7272
QuantLib::ext::shared_ptr<OvernightIndex> recIndexON = QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(receiveIndex_);
7373

74+
if(discountGiven)
75+
discountRelinkableHandle_.linkTo(*discountHandle_);
76+
7477
if (!payGiven && !recGiven && !discountGiven) {
7578
// case 0
7679
QL_FAIL("no curve given");
@@ -81,10 +84,11 @@ TenorBasisSwapHelper::TenorBasisSwapHelper(Handle<Quote> spread, const Period& s
8184
// case 2
8285
payIndex_ = QuantLib::ext::static_pointer_cast<IborIndex>(payIndex_->clone(termStructureHandle_));
8386
payIndex_->unregisterWith(termStructureHandle_);
84-
if (!payIndexON && recIndexON)
87+
if (!payIndexON && recIndexON) {
8588
discountRelinkableHandle_.linkTo(*receiveIndex_->forwardingTermStructure());
86-
else
87-
setDiscountRelinkableHandle_ = true;
89+
} else {
90+
automaticDiscountRelinkableHandle_ = true;
91+
}
8892
} else if (!payGiven && recGiven && discountGiven) {
8993
// case 3
9094
payIndex_ = QuantLib::ext::static_pointer_cast<IborIndex>(payIndex_->clone(termStructureHandle_));
@@ -93,17 +97,18 @@ TenorBasisSwapHelper::TenorBasisSwapHelper(Handle<Quote> spread, const Period& s
9397
// case 4
9498
receiveIndex_ = QuantLib::ext::static_pointer_cast<IborIndex>(receiveIndex_->clone(termStructureHandle_));
9599
receiveIndex_->unregisterWith(termStructureHandle_);
96-
if (payIndexON && !recIndexON)
100+
if (payIndexON && !recIndexON) {
97101
discountRelinkableHandle_.linkTo(*payIndex_->forwardingTermStructure());
98-
else
99-
setDiscountRelinkableHandle_ = true;
102+
} else {
103+
automaticDiscountRelinkableHandle_ = true;
104+
}
100105
} else if (payGiven && !recGiven && discountGiven) {
101106
// case 5
102107
receiveIndex_ = QuantLib::ext::static_pointer_cast<IborIndex>(receiveIndex_->clone(termStructureHandle_));
103108
receiveIndex_->unregisterWith(termStructureHandle_);
104109
} else if (payGiven && recGiven && !discountGiven) {
105110
// case 6
106-
setDiscountRelinkableHandle_ = true;
111+
automaticDiscountRelinkableHandle_ = true;
107112
} else if (payGiven && recGiven && discountGiven) {
108113
// case 7
109114
QL_FAIL("Both Index and the Discount curves are all given");
@@ -120,7 +125,6 @@ TenorBasisSwapHelper::TenorBasisSwapHelper(Handle<Quote> spread, const Period& s
120125

121126
void TenorBasisSwapHelper::initializeDates() {
122127

123-
//CHECK : should the spot shift be based on pay ore receive, here we have the pay leg...
124128
QuantLib::ext::shared_ptr<Libor> payIndexAsLibor = QuantLib::ext::dynamic_pointer_cast<Libor>(payIndex_);
125129
Calendar spotCalendar = payIndexAsLibor != NULL ? payIndexAsLibor->jointCalendar() : payIndex_->fixingCalendar();
126130
Natural spotDays = payIndex_->fixingDays();
@@ -132,11 +136,11 @@ void TenorBasisSwapHelper::initializeDates() {
132136

133137
Date effectiveDate = spotCalendar.advance(valuationDate, spotDays * Days);
134138

135-
swap_ = QuantLib::ext::shared_ptr<TenorBasisSwap>(new TenorBasisSwap(
136-
effectiveDate, 1.0, swapTenor_, payIndex_, 0.0, payFrequency_, receiveIndex_, 0.0, recFrequency_,
137-
DateGeneration::Backward, includeSpread_, spreadOnRec_, type_, telescopicValueDates_));
139+
swap_ = QuantLib::ext::make_shared<TenorBasisSwap>(effectiveDate, 1.0, swapTenor_, payIndex_, 0.0, payFrequency_,
140+
receiveIndex_, 0.0, recFrequency_, DateGeneration::Backward,
141+
includeSpread_, spreadOnRec_, type_, telescopicValueDates_);
138142

139-
QuantLib::ext::shared_ptr<PricingEngine> engine(new DiscountingSwapEngine(discountRelinkableHandle_));
143+
auto engine = QuantLib::ext::make_shared<DiscountingSwapEngine>(discountRelinkableHandle_);
140144
swap_->setPricingEngine(engine);
141145

142146
earliestDate_ = swap_->startDate();
@@ -168,10 +172,8 @@ void TenorBasisSwapHelper::setTermStructure(YieldTermStructure* t) {
168172
QuantLib::ext::shared_ptr<YieldTermStructure> temp(t, null_deleter());
169173
termStructureHandle_.linkTo(temp, observer);
170174

171-
if (setDiscountRelinkableHandle_)
175+
if (automaticDiscountRelinkableHandle_)
172176
discountRelinkableHandle_.linkTo(temp, observer);
173-
else
174-
discountRelinkableHandle_.linkTo(*discountHandle_, observer);
175177

176178
RelativeDateRateHelper::setTermStructure(t);
177179
}

QuantExt/qle/termstructures/tenorbasisswaphelper.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class TenorBasisSwapHelper : public RelativeDateRateHelper {
6969
Period recFrequency_;
7070
bool telescopicValueDates_;
7171
QuantExt::SubPeriodsCoupon1::Type type_;
72-
bool setDiscountRelinkableHandle_;
72+
bool automaticDiscountRelinkableHandle_;
7373

7474
QuantLib::ext::shared_ptr<TenorBasisSwap> swap_;
7575
RelinkableHandle<YieldTermStructure> termStructureHandle_;

0 commit comments

Comments
 (0)