557 {
558
559 DLOG(
"build swaption basket");
560
561 QL_REQUIRE(
data_->optionExpiries().size() ==
data_->optionTerms().size(),
"swaption vector size mismatch");
562 QL_REQUIRE(
data_->optionExpiries().size() ==
data_->optionStrikes().size(),
"swaption vector size mismatch");
563
564 std::ostringstream
log;
565
566 std::vector<Time> expiryTimes;
567 std::vector<Time> maturityTimes;
572
574 Date lastRefCalDate = Date::minDate();
575 std::vector<Date> referenceCalibrationDates;
578
579 for (Size j = 0; j <
data_->optionExpiries().
size(); j++) {
580 bool expiryDateBased, termDateBased;
581 Period expiryPb, termPb;
582 Date expiryDb, termDb;
583 Real termT = Null<Real>();
584
585 getExpiryAndTerm(j, expiryPb, termPb, expiryDb, termDb, termT, expiryDateBased, termDateBased);
587
588
589
590 Period termTmp = static_cast<Size>(termT + 0.5) * Years;
592 auto fixedLegTenor =
594 auto fixedDayCounter =
598 Size settlementDays = Null<Size>();
599 RateAveraging::Type averagingMethod = RateAveraging::Compound;
600 if (
auto on = dynamic_pointer_cast<OvernightIndexedSwapIndex>(*
swapIndex_)) {
601 settlementDays = on->fixingDays();
602 averagingMethod = on->averagingMethod();
603 }
604
605 Real dummyQuote =
svts_->volatilityType() == Normal ? 0.0020 : 0.10;
606 auto volQuote = QuantLib::ext::make_shared<SimpleQuote>(dummyQuote);
607 Handle<Quote> vol = Handle<Quote>(volQuote);
608 QuantLib::ext::shared_ptr<SwaptionHelper>
helper;
609 Real updatedStrike;
610
611 if (expiryDateBased && termDateBased) {
612 Real shift =
svts_->volatilityType() == ShiftedLognormal ?
svts_->shift(expiryDb, termT) : 0.0;
613 std::tie(
helper, updatedStrike) = createSwaptionHelper(
614 expiryDb, termDb,
svts_, vol, iborIndex, fixedLegTenor, fixedDayCounter, floatDayCounter,
616 }
617 if (expiryDateBased && !termDateBased) {
618 Real shift =
svts_->volatilityType() == ShiftedLognormal ?
svts_->shift(expiryDb, termPb) : 0.0;
619 std::tie(
helper, updatedStrike) = createSwaptionHelper(
620 expiryDb, termPb,
svts_, vol, iborIndex, fixedLegTenor, fixedDayCounter, floatDayCounter,
622 }
623 if (!expiryDateBased && termDateBased) {
624 Date expiry =
svts_->optionDateFromTenor(expiryPb);
625 Real shift =
svts_->volatilityType() == ShiftedLognormal ?
svts_->shift(expiryPb, termT) : 0.0;
626 std::tie(
helper, updatedStrike) = createSwaptionHelper(
627 expiry, termDb,
svts_, vol, iborIndex, fixedLegTenor, fixedDayCounter, floatDayCounter,
629 }
630 if (!expiryDateBased && !termDateBased) {
631 Real shift =
svts_->volatilityType() == ShiftedLognormal ?
svts_->shift(expiryPb, termPb) : 0.0;
632 std::tie(
helper, updatedStrike) = createSwaptionHelper(
633 expiryPb, termPb,
svts_, vol, iborIndex, fixedLegTenor, fixedDayCounter, floatDayCounter,
635 }
636
637
638 Date expiryDate =
helper->swaption()->exercise()->date(0);
639 auto refCalDate =
640 std::lower_bound(referenceCalibrationDates.begin(), referenceCalibrationDates.end(), expiryDate);
641 if (refCalDate == referenceCalibrationDates.end() || *refCalDate > lastRefCalDate) {
647 Date matDate =
helper->underlyingSwap() ?
helper->underlyingSwap()->maturityDate()
648 :
helper->underlyingOvernightIndexedSwap()->maturityDate();
650 if (refCalDate != referenceCalibrationDates.end())
651 lastRefCalDate = *refCalDate;
652 }
653 }
654
655 std::sort(expiryTimes.begin(), expiryTimes.end());
656 auto itExpiryTime = unique(expiryTimes.begin(), expiryTimes.end());
657 expiryTimes.resize(distance(expiryTimes.begin(), itExpiryTime));
658
660 for (Size j = 0; j < expiryTimes.size(); j++)
662
663 std::sort(maturityTimes.begin(), maturityTimes.end());
664 auto itMaturityTime = unique(maturityTimes.begin(), maturityTimes.end());
665 maturityTimes.resize(distance(maturityTimes.begin(), itMaturityTime));
666
668 for (Size j = 0; j < maturityTimes.size(); j++)
670
672}
std::vector< QuantLib::ext::shared_ptr< SimpleQuote > > swaptionBasketVols_
std::vector< QuantLib::Real > swaptionVolCache_
std::vector< Real > swaptionStrike_
Real getStrike(const Size j) const
void getExpiryAndTerm(const Size j, Period &expiryPb, Period &termPb, Date &expiryDb, Date &termDb, Real &termT, bool &expiryDateBased, bool &termDateBased) const
RandomVariable log(RandomVariable x)
Size size(const ValueType &v)
QuantLib::BootstrapHelper< QuantLib::OptionletVolatilityStructure > helper