From 895c8672b4e19e582c6eb73ca4fb716d414377cf Mon Sep 17 00:00:00 2001 From: Nityahapani Date: Thu, 1 Oct 2026 04:45:15 +0000 Subject: [PATCH] Simplify SwaptionVolatilityCube::atmStrike() using SwapIndex::clone(tenor) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit atmStrike() built temporary SwapIndex objects by spelling out every constructor argument (familyName, fixingDays, currency, calendar, fixedLegTenor, convention, dayCounter, iborIndex) manually, with a separate branch for the exogenousDiscount case, totalling ~50 lines and a FIXME comment: // FIXME use a familyName-based index factory SwapIndex already provides exactly this: clone(const Period& tenor) returns a copy of the index with a different tenor while preserving all other attributes — including the discount curve when exogenousDiscount is true. The virtual dispatch also means subclasses of SwapIndex (e.g. EuriborSwapIsdaFixA, OvernightIndexedSwapIndex) correctly clone themselves rather than being silently downcast to a plain SwapIndex. Replace the four constructor branches with: const SwapIndex* base = (swapTenor > shortSwapIndexBase_->tenor()) ? swapIndexBase_.get() : shortSwapIndexBase_.get(); return base->clone(swapTenor)->fixing(optionD); No behaviour change for standard SwapIndex; correctness improvement for any SwapIndex subclass stored in swapIndexBase_ or shortSwapIndexBase_. --- .../volatility/swaption/swaptionvolcube.cpp | 57 ++----------------- 1 file changed, 4 insertions(+), 53 deletions(-) diff --git a/ql/termstructures/volatility/swaption/swaptionvolcube.cpp b/ql/termstructures/volatility/swaption/swaptionvolcube.cpp index 0701d1e4cfe..35571122eaf 100644 --- a/ql/termstructures/volatility/swaption/swaptionvolcube.cpp +++ b/ql/termstructures/volatility/swaption/swaptionvolcube.cpp @@ -88,59 +88,10 @@ namespace QuantLib { Rate SwaptionVolatilityCube::atmStrike(const Date& optionD, const Period& swapTenor) const { - - // FIXME use a familyName-based index factory - if (swapTenor > shortSwapIndexBase_->tenor()) { - if (swapIndexBase_->exogenousDiscount()) { - return SwapIndex(swapIndexBase_->familyName(), - swapTenor, - swapIndexBase_->fixingDays(), - swapIndexBase_->currency(), - swapIndexBase_->fixingCalendar(), - swapIndexBase_->fixedLegTenor(), - swapIndexBase_->fixedLegConvention(), - swapIndexBase_->dayCounter(), - swapIndexBase_->iborIndex(), - swapIndexBase_->discountingTermStructure()) - .fixing(optionD); - } else { - return SwapIndex(swapIndexBase_->familyName(), - swapTenor, - swapIndexBase_->fixingDays(), - swapIndexBase_->currency(), - swapIndexBase_->fixingCalendar(), - swapIndexBase_->fixedLegTenor(), - swapIndexBase_->fixedLegConvention(), - swapIndexBase_->dayCounter(), - swapIndexBase_->iborIndex()) - .fixing(optionD); - } - } else { - if (shortSwapIndexBase_->exogenousDiscount()) { - return SwapIndex(shortSwapIndexBase_->familyName(), - swapTenor, - shortSwapIndexBase_->fixingDays(), - shortSwapIndexBase_->currency(), - shortSwapIndexBase_->fixingCalendar(), - shortSwapIndexBase_->fixedLegTenor(), - shortSwapIndexBase_->fixedLegConvention(), - shortSwapIndexBase_->dayCounter(), - shortSwapIndexBase_->iborIndex(), - shortSwapIndexBase_->discountingTermStructure()) - .fixing(optionD); - } else { - return SwapIndex(shortSwapIndexBase_->familyName(), - swapTenor, - shortSwapIndexBase_->fixingDays(), - shortSwapIndexBase_->currency(), - shortSwapIndexBase_->fixingCalendar(), - shortSwapIndexBase_->fixedLegTenor(), - shortSwapIndexBase_->fixedLegConvention(), - shortSwapIndexBase_->dayCounter(), - shortSwapIndexBase_->iborIndex()) - .fixing(optionD); - } - } + const SwapIndex* base = (swapTenor > shortSwapIndexBase_->tenor()) + ? swapIndexBase_.get() + : shortSwapIndexBase_.get(); + return base->clone(swapTenor)->fixing(optionD); } }