From 0eff87734e487f4bb672a97bf634c7e4d0004caa Mon Sep 17 00:00:00 2001 From: Peter Caspers Date: Sat, 1 Nov 2025 14:02:31 +0100 Subject: [PATCH 1/4] QPR-13654 move built flag to trade level --- OREData/ored/portfolio/portfolio.cpp | 10 +++++++--- OREData/ored/portfolio/portfolio.hpp | 3 +-- OREData/ored/portfolio/trade.cpp | 2 ++ OREData/ored/portfolio/trade.hpp | 7 +++++++ 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/OREData/ored/portfolio/portfolio.cpp b/OREData/ored/portfolio/portfolio.cpp index 22317fbd2f..44529070c5 100644 --- a/OREData/ored/portfolio/portfolio.cpp +++ b/OREData/ored/portfolio/portfolio.cpp @@ -42,7 +42,6 @@ void Portfolio::clear() { } void Portfolio::reset() { - isBuilt_ = false; LOG("Reset portfolio of size " << trades_.size()); for (auto [id, t] : trades_) t->reset(); @@ -175,9 +174,13 @@ void Portfolio::build(const QuantLib::ext::shared_ptr& engineFact .log(); } QL_REQUIRE(trades_.size() > 0, "Portfolio does not contain any built trades, context is '" + context + "'"); - isBuilt_ = true; } +bool Portfolio::isBuilt() const { + return std::all_of(trades_.begin(), trades_.end(), [](const auto& s) { return s.second->isBuilt(); }); +} + + Date Portfolio::maturity() const { QL_REQUIRE(trades_.size() > 0, "Cannot get maturity of an empty portfolio"); Date mat = Date::minDate(); @@ -221,7 +224,6 @@ void Portfolio::add(const QuantLib::ext::shared_ptr& trade) { QL_REQUIRE(!has(trade->id()), "Attempted to add a trade to the portfolio with an id, which already exists."); underlyingIndicesCache_.clear(); trades_[trade->id()] = trade; - isBuilt_ = false; } bool Portfolio::has(const string& id) { return trades_.find(id) != trades_.end(); } @@ -308,6 +310,7 @@ std::pair, bool> buildTrade(QuantLib::ext::shar try { trade->reset(); trade->build(engineFactory); + trade->setBuilt(); TLOG("Required Fixings for trade " << trade->id() << ":"); TLOGGERSTREAM(trade->requiredFixings()); return std::make_pair(nullptr, true); @@ -326,6 +329,7 @@ std::pair, bool> buildTrade(QuantLib::ext::shar failed->setEnvelope(trade->envelope()); failed->build(engineFactory); failed->resetPricingStats(trade->getNumberOfPricings(), trade->getCumulativePricingTime()); + failed->setBuilt(); LOG("Built failed trade with id " << failed->id()); return std::make_pair(failed, false); } else { diff --git a/OREData/ored/portfolio/portfolio.hpp b/OREData/ored/portfolio/portfolio.hpp index e966b13a4d..8630634f5e 100644 --- a/OREData/ored/portfolio/portfolio.hpp +++ b/OREData/ored/portfolio/portfolio.hpp @@ -87,7 +87,7 @@ class Portfolio : public XMLSerializable { const bool emitStructuredError = true); //! if the portfolio has been built - bool isBuilt() const { return isBuilt_; } + bool isBuilt() const; //! Calculates the maturity of the portfolio QuantLib::Date maturity() const; @@ -138,7 +138,6 @@ class Portfolio : public XMLSerializable { bool buildFailedTrades_, ignoreTradeBuildFail_; std::map> trades_; std::map> underlyingIndicesCache_; - bool isBuilt_ = false; }; std::pair, bool> buildTrade( diff --git a/OREData/ored/portfolio/trade.cpp b/OREData/ored/portfolio/trade.cpp index bbb5bf74bf..12c98fb86d 100644 --- a/OREData/ored/portfolio/trade.cpp +++ b/OREData/ored/portfolio/trade.cpp @@ -300,6 +300,8 @@ void Trade::reset() { savedNumberOfPricings_ += instrument_->getNumberOfPricings(); savedCumulativePricingTime_ += instrument_->getCumulativePricingTime(); } + // reset build status + setBuilt(false); // reset members instrument_ = QuantLib::ext::shared_ptr(); legs_.clear(); diff --git a/OREData/ored/portfolio/trade.hpp b/OREData/ored/portfolio/trade.hpp index 429ed3bdf6..06ccce7de4 100644 --- a/OREData/ored/portfolio/trade.hpp +++ b/OREData/ored/portfolio/trade.hpp @@ -246,6 +246,12 @@ class Trade : public XMLSerializable { const std::string& configuration, const bool includePastCashflows) const; + /* set build status, this flag is maintained in buildTrade() and Trade::reset(), i.e. _not_ in Trade::build() */ + void setBuilt(const bool b = true) const { isBuilt_ = b; } + + /* get build status */ + bool isBuilt() const { return isBuilt_; } + protected: string tradeType_; // class name of the derived class QuantLib::ext::shared_ptr instrument_; @@ -294,6 +300,7 @@ class Trade : public XMLSerializable { string id_; Envelope envelope_; TradeActions tradeActions_; + mutable bool isBuilt_ = false; }; template From 1c7fb035ee78e89f7f192a6141f11deffd414e25 Mon Sep 17 00:00:00 2001 From: Peter Caspers Date: Tue, 4 Nov 2025 14:59:22 +0100 Subject: [PATCH 2/4] align submodule --- ORE-SWIG/QuantLib-SWIG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ORE-SWIG/QuantLib-SWIG b/ORE-SWIG/QuantLib-SWIG index 9b1d648856..18203bf0af 160000 --- a/ORE-SWIG/QuantLib-SWIG +++ b/ORE-SWIG/QuantLib-SWIG @@ -1 +1 @@ -Subproject commit 9b1d6488567f1cc84ab55d4c08cfef7ea7d1550b +Subproject commit 18203bf0af4639a51a08c705e7b07bc864d2116b From 8a9852ccbdab3f765508bde10d6d945184bda357 Mon Sep 17 00:00:00 2001 From: Zetterberg <119352036+oszette@users.noreply.github.com> Date: Mon, 8 Dec 2025 12:47:44 +0100 Subject: [PATCH 3/4] Add support for payment lag for xccy fix-float helpers Introduces support for fixedPaymentLag and floatPaymentLag parameters in CrossCcyFixFloatSwapConvention, CrossCcyFixFloatSwapHelper, and CrossCcyFixFloatMtMResetSwapHelper classes. Updates constructors, member variables, XML serialization, and swap initialization logic to handle payment lags for both fixed and floating legs. --- OREData/ored/configuration/conventions.cpp | 12 ++++++++++-- OREData/ored/configuration/conventions.hpp | 9 ++++++++- OREData/ored/marketdata/yieldcurve.cpp | 6 ++++-- .../crossccyfixfloatmtmresetswaphelper.cpp | 12 +++++++----- .../crossccyfixfloatmtmresetswaphelper.hpp | 5 ++++- .../termstructures/crossccyfixfloatswaphelper.cpp | 13 ++++++++----- .../termstructures/crossccyfixfloatswaphelper.hpp | 5 ++++- 7 files changed, 45 insertions(+), 17 deletions(-) diff --git a/OREData/ored/configuration/conventions.cpp b/OREData/ored/configuration/conventions.cpp index ca1b60fdff..97a45d693b 100644 --- a/OREData/ored/configuration/conventions.cpp +++ b/OREData/ored/configuration/conventions.cpp @@ -1157,14 +1157,14 @@ CrossCcyFixFloatSwapConvention::CrossCcyFixFloatSwapConvention( const string& fixedConvention, const string& fixedDayCounter, const string& index, const string& eom, const std::string& strIsResettable, const std::string& strFloatIndexIsResettable, const string& strIncludeSpread, const string& strLookback, const string& strFixingDays, const string& strRateCutoff, - const string& strIsAveraged) + const string& strIsAveraged, const string& strFixedPaymentLag, const string& strFloatPaymentLag) : Convention(id, Type::CrossCcyFixFloat), strSettlementDays_(settlementDays), strSettlementCalendar_(settlementCalendar), strSettlementConvention_(settlementConvention), strFixedCurrency_(fixedCurrency), strFixedFrequency_(fixedFrequency), strFixedConvention_(fixedConvention), strFixedDayCounter_(fixedDayCounter), strIndex_(index), strEom_(eom), strIsResettable_(strIsResettable), strFloatIndexIsResettable_(strFloatIndexIsResettable), strIncludeSpread_(strIncludeSpread), strLookback_(strLookback), strFixingDays_(strFixingDays), strRateCutoff_(strRateCutoff), - strIsAveraged_(strIsAveraged) { + strIsAveraged_(strIsAveraged), strFixedPaymentLag_(strFixedPaymentLag), strFloatPaymentLag_(strFloatPaymentLag) { build(); } @@ -1191,6 +1191,8 @@ void CrossCcyFixFloatSwapConvention::build() { rateCutoff_ = parseInteger(strRateCutoff_); if (!strIsAveraged_.empty()) isAveraged_ = parseBool(strIsAveraged_); + fixedPaymentLag_ = strFixedPaymentLag_.empty() ? 0 : lexical_cast(strFixedPaymentLag_); + floatPaymentLag_ = strFloatPaymentLag_.empty() ? 0 : lexical_cast(strFloatPaymentLag_); } void CrossCcyFixFloatSwapConvention::fromXML(XMLNode* node) { @@ -1212,6 +1214,8 @@ void CrossCcyFixFloatSwapConvention::fromXML(XMLNode* node) { strEom_ = XMLUtils::getChildValue(node, "EOM", false); strIsResettable_ = XMLUtils::getChildValue(node, "IsResettable", false); strFloatIndexIsResettable_ = XMLUtils::getChildValue(node, "FloatIndexIsResettable", false); + strFixedPaymentLag_ = XMLUtils::getChildValue(node, "FixedPaymentLag", false); + strFloatPaymentLag_ = XMLUtils::getChildValue(node, "FloatPaymentLag", false); // OIS specific conventions @@ -1254,6 +1258,10 @@ XMLNode* CrossCcyFixFloatSwapConvention::toXML(XMLDocument& doc) const { XMLUtils::addChild(doc, node, "SpreadRateCutoff", strRateCutoff_); if (!strIsAveraged_.empty()) XMLUtils::addChild(doc, node, "SpreadIsAveraged", strIsAveraged_); + if (!strFixedPaymentLag_.empty()) + XMLUtils::addChild(doc, node, "FixedPaymentLag", strFixedPaymentLag_); + if (!strFloatPaymentLag_.empty()) + XMLUtils::addChild(doc, node, "FloatPaymentLag", strFloatPaymentLag_); return node; } diff --git a/OREData/ored/configuration/conventions.hpp b/OREData/ored/configuration/conventions.hpp index 40c83d8bf2..c5c5a78691 100644 --- a/OREData/ored/configuration/conventions.hpp +++ b/OREData/ored/configuration/conventions.hpp @@ -1004,7 +1004,8 @@ class CrossCcyFixFloatSwapConvention : public Convention { const std::string& strFloatIndexIsResettable = "", const string& strIncludeSpread = "", const string& strLookback = "", const string& strFixingDays = "", const string& strRateCutoff = "", - const string& strIsAveraged = ""); + const string& strIsAveraged = "", const string& strFixedPaymentLag = "", + const string& strFloatPaymentLag = ""); //@} //! \name Inspectors @@ -1020,6 +1021,8 @@ class CrossCcyFixFloatSwapConvention : public Convention { bool eom() const { return eom_; } bool isResettable() const { return isResettable_; } bool floatIndexIsResettable() const { return floatIndexIsResettable_; } + QuantLib::Natural fixedPaymentLag() const { return fixedPaymentLag_; } + QuantLib::Natural floatPaymentLag() const { return floatPaymentLag_; } // only OIS QuantLib::ext::optional includeSpread() const { return includeSpread_; } @@ -1051,6 +1054,8 @@ class CrossCcyFixFloatSwapConvention : public Convention { bool eom_; bool isResettable_; bool floatIndexIsResettable_; + QuantLib::Natural fixedPaymentLag_; + QuantLib::Natural floatPaymentLag_; // Strings to store the inputs std::string strSettlementDays_; @@ -1071,6 +1076,8 @@ class CrossCcyFixFloatSwapConvention : public Convention { std::string strFixingDays_; std::string strRateCutoff_; std::string strIsAveraged_; + std::string strFixedPaymentLag_; + std::string strFloatPaymentLag_; // OIS Only QuantLib::ext::optional includeSpread_; diff --git a/OREData/ored/marketdata/yieldcurve.cpp b/OREData/ored/marketdata/yieldcurve.cpp index e3e4c65249..ade541a206 100644 --- a/OREData/ored/marketdata/yieldcurve.cpp +++ b/OREData/ored/marketdata/yieldcurve.cpp @@ -3043,7 +3043,8 @@ void YieldCurve::addCrossCcyFixFloatSwaps(const std::size_t index, currency_[index], swapConvention->fixedFrequency(), swapConvention->fixedConvention(), swapConvention->fixedDayCounter(), floatIndex, floatLegDisc, Handle(), swapConvention->eom(),true, segment->pillarChoice(), swapConvention->includeSpread(), swapConvention->lookback(), - swapConvention->fixingDays(), swapConvention->rateCutoff(), swapConvention->isAveraged()); + swapConvention->fixingDays(), swapConvention->rateCutoff(), swapConvention->isAveraged(), + swapConvention->fixedPaymentLag(), swapConvention->floatPaymentLag()); } else { bool resetsOnFloatLeg = swapConvention->floatIndexIsResettable(); helper = QuantLib::ext::make_shared( @@ -3053,7 +3054,8 @@ void YieldCurve::addCrossCcyFixFloatSwaps(const std::size_t index, swapConvention->fixedDayCounter(), floatIndex, floatLegDisc, Handle(), swapConvention->eom(), true, resetsOnFloatLeg, segment->pillarChoice(), swapConvention->includeSpread(), swapConvention->lookback(), - swapConvention->fixingDays(), swapConvention->rateCutoff(), swapConvention->isAveraged()); + swapConvention->fixingDays(), swapConvention->rateCutoff(), swapConvention->isAveraged(), + swapConvention->fixedPaymentLag(), swapConvention->floatPaymentLag()); } instruments.push_back(helper); } diff --git a/QuantExt/qle/termstructures/crossccyfixfloatmtmresetswaphelper.cpp b/QuantExt/qle/termstructures/crossccyfixfloatmtmresetswaphelper.cpp index 3aca4926ac..d3e6cb00fb 100644 --- a/QuantExt/qle/termstructures/crossccyfixfloatmtmresetswaphelper.cpp +++ b/QuantExt/qle/termstructures/crossccyfixfloatmtmresetswaphelper.cpp @@ -35,14 +35,15 @@ CrossCcyFixFloatMtMResetSwapHelper::CrossCcyFixFloatMtMResetSwapHelper( const Handle& spread, bool endOfMonth, bool resetsOnFloatLeg, bool telescopicValueDates, const QuantLib::Pillar::Choice pillarChoice, QuantLib::ext::optional includeSpread, QuantLib::ext::optional lookback, QuantLib::ext::optional fixingDays, - QuantLib::ext::optional rateCutoff, QuantLib::ext::optional isAveraged) + QuantLib::ext::optional rateCutoff, QuantLib::ext::optional isAveraged, QuantLib::ext::optional fixedPaymentLag, + QuantLib::ext::optional floatPaymentLag) : RelativeDateRateHelper(rate), spotFx_(spotFx), settlementDays_(settlementDays), paymentCalendar_(paymentCalendar), paymentConvention_(paymentConvention), tenor_(tenor), fixedCurrency_(fixedCurrency), fixedFrequency_(fixedFrequency), fixedConvention_(fixedConvention), fixedDayCount_(fixedDayCount), index_(index), floatDiscount_(floatDiscount), spread_(spread), endOfMonth_(endOfMonth), resetsOnFloatLeg_(resetsOnFloatLeg), telescopicValueDates_(telescopicValueDates), pillarChoice_(pillarChoice), includeSpread_(includeSpread), lookback_(lookback), fixingDays_(fixingDays), - rateCutoff_(rateCutoff), isAveraged_(isAveraged) { + rateCutoff_(rateCutoff), isAveraged_(isAveraged), fixedPaymentLag_(fixedPaymentLag), floatPaymentLag_(floatPaymentLag_) { QL_REQUIRE(!spotFx_.empty(), "Spot FX quote cannot be empty."); QL_REQUIRE(fixedCurrency_ != index_->currency(), "Fixed currency should not equal float leg currency."); @@ -74,7 +75,8 @@ void CrossCcyFixFloatMtMResetSwapHelper::initializeDates() { Real nominal = 1.0; // build an FX index for forward rate projection (TODO - review settlement and calendar) - Natural paymentLag = 0; + Natural fixedPaymentLag = fixedPaymentLag_ ? *fixedPaymentLag_ : 0; + Natural floatPaymentLag = floatPaymentLag_ ? *floatPaymentLag_ : 0; Spread floatSpread = spread_.empty() ? 0.0 : spread_->value(); QuantLib::ext::shared_ptr fxIdx; if (resetsOnFloatLeg_) { @@ -86,8 +88,8 @@ void CrossCcyFixFloatMtMResetSwapHelper::initializeDates() { } swap_ = QuantLib::ext::make_shared(nominal, fixedCurrency_, fixedSchedule, 0.0, fixedDayCount_, paymentConvention_, - paymentLag, paymentCalendar_, index_->currency(), floatSchedule, index_, floatSpread, paymentConvention_, - paymentLag, paymentCalendar_, fxIdx, resetsOnFloatLeg_, true, includeSpread_, lookback_, fixingDays_, rateCutoff_, isAveraged_); + fixedPaymentLag, paymentCalendar_, index_->currency(), floatSchedule, index_, floatSpread, paymentConvention_, + floatPaymentLag, paymentCalendar_, fxIdx, resetsOnFloatLeg_, true, includeSpread_, lookback_, fixingDays_, rateCutoff_, isAveraged_); // Attach engine QuantLib::ext::shared_ptr engine = QuantLib::ext::make_shared( diff --git a/QuantExt/qle/termstructures/crossccyfixfloatmtmresetswaphelper.hpp b/QuantExt/qle/termstructures/crossccyfixfloatmtmresetswaphelper.hpp index 224b5c31d8..42b4470937 100644 --- a/QuantExt/qle/termstructures/crossccyfixfloatmtmresetswaphelper.hpp +++ b/QuantExt/qle/termstructures/crossccyfixfloatmtmresetswaphelper.hpp @@ -64,7 +64,8 @@ class CrossCcyFixFloatMtMResetSwapHelper : public RelativeDateRateHelper { bool telescopicValueDates = false, const QuantLib::Pillar::Choice pillarChoice = QuantLib::Pillar::LastRelevantDate, QuantLib::ext::optional includeSpread = QuantLib::ext::nullopt, QuantLib::ext::optional lookback = QuantLib::ext::nullopt, QuantLib::ext::optional fixingDays = QuantLib::ext::nullopt, QuantLib::ext::optional rateCutoff = QuantLib::ext::nullopt, - QuantLib::ext::optional isAveraged = QuantLib::ext::nullopt); + QuantLib::ext::optional isAveraged = QuantLib::ext::nullopt, QuantLib::ext::optional fixedPaymenyLag = QuantLib::ext::nullopt, + QuantLib::ext::optional floatPaymentLag = QuantLib::ext::nullopt); //! \name RateHelper interface //@{ Real impliedQuote() const override; @@ -107,6 +108,8 @@ class CrossCcyFixFloatMtMResetSwapHelper : public RelativeDateRateHelper { QuantLib::ext::optional fixingDays_; QuantLib::ext::optional rateCutoff_; QuantLib::ext::optional isAveraged_; + QuantLib::ext::optional fixedPaymentLag_; + QuantLib::ext::optional floatPaymentLag_; QuantLib::ext::shared_ptr swap_; diff --git a/QuantExt/qle/termstructures/crossccyfixfloatswaphelper.cpp b/QuantExt/qle/termstructures/crossccyfixfloatswaphelper.cpp index aebd194b7b..54c20f0605 100644 --- a/QuantExt/qle/termstructures/crossccyfixfloatswaphelper.cpp +++ b/QuantExt/qle/termstructures/crossccyfixfloatswaphelper.cpp @@ -40,14 +40,15 @@ CrossCcyFixFloatSwapHelper::CrossCcyFixFloatSwapHelper( const QuantLib::ext::shared_ptr& index, const Handle& floatDiscount, const Handle& spread, bool endOfMonth, bool telescopicValueDates, QuantLib::Pillar::Choice pillarChoice, QuantLib::ext::optional includeSpread, QuantLib::ext::optional lookback, QuantLib::ext::optional fixingDays, - QuantLib::ext::optional rateCutoff, QuantLib::ext::optional isAveraged) + QuantLib::ext::optional rateCutoff, QuantLib::ext::optional isAveraged, + QuantLib::ext::optional fixedPaymentLag, QuantLib::ext::optional floatPaymentLag) : RelativeDateRateHelper(rate), spotFx_(spotFx), settlementDays_(settlementDays), paymentCalendar_(paymentCalendar), paymentConvention_(paymentConvention), tenor_(tenor), fixedCurrency_(fixedCurrency), fixedFrequency_(fixedFrequency), fixedConvention_(fixedConvention), fixedDayCount_(fixedDayCount), index_(index), floatDiscount_(floatDiscount), spread_(spread), endOfMonth_(endOfMonth), telescopicValueDates_(telescopicValueDates), pillarChoice_(pillarChoice), includeSpread_(includeSpread), lookback_(lookback), fixingDays_(fixingDays), rateCutoff_(rateCutoff), - isAveraged_(isAveraged) { + isAveraged_(isAveraged), fixedPaymentLag_(fixedPaymentLag), floatPaymentLag_(floatPaymentLag) { QL_REQUIRE(!spotFx_.empty(), "Spot FX quote cannot be empty."); QL_REQUIRE(fixedCurrency_ != index_->currency(), "Fixed currency should not equal float leg currency."); @@ -114,12 +115,14 @@ void CrossCcyFixFloatSwapHelper::initializeDates() { DateGeneration::Backward, endOfMonth_); // Create the swap - Natural paymentLag = 0; + Natural fixedPaymentLag = fixedPaymentLag_ ? *fixedPaymentLag_ : 0; + Natural floatPaymentLag = floatPaymentLag_ ? *floatPaymentLag_ : 0; Spread floatSpread = spread_.empty() ? 0.0 : spread_->value(); swap_.reset(new CrossCcyFixFloatSwap(CrossCcyFixFloatSwap::Payer, fixedNominal, fixedCurrency_, fixedSchedule, 0.0, - fixedDayCount_, paymentConvention_, paymentLag, paymentCalendar_, floatNominal, + fixedDayCount_, paymentConvention_, fixedPaymentLag, paymentCalendar_, + floatNominal, index_->currency(), floatSchedule, index_, floatSpread, paymentConvention_, - paymentLag, paymentCalendar_, telescopicValueDates_, includeSpread_, lookback_, + floatPaymentLag, paymentCalendar_, telescopicValueDates_, includeSpread_, lookback_, fixingDays_, rateCutoff_, isAveraged_)); earliestDate_ = swap_->startDate(); diff --git a/QuantExt/qle/termstructures/crossccyfixfloatswaphelper.hpp b/QuantExt/qle/termstructures/crossccyfixfloatswaphelper.hpp index 122a1ab80b..862ad32064 100644 --- a/QuantExt/qle/termstructures/crossccyfixfloatswaphelper.hpp +++ b/QuantExt/qle/termstructures/crossccyfixfloatswaphelper.hpp @@ -50,7 +50,8 @@ class CrossCcyFixFloatSwapHelper : public RelativeDateRateHelper { const QuantLib::Pillar::Choice pillarChoice = QuantLib::Pillar::LastRelevantDate, QuantLib::ext::optional includeSpread = QuantLib::ext::nullopt, QuantLib::ext::optional lookback = QuantLib::ext::nullopt, QuantLib::ext::optional fixingDays = QuantLib::ext::nullopt, QuantLib::ext::optional rateCutoff = QuantLib::ext::nullopt, - QuantLib::ext::optional isAveraged = QuantLib::ext::nullopt); + QuantLib::ext::optional isAveraged = QuantLib::ext::nullopt, QuantLib::ext::optional fixedPaymentLag = QuantLib::ext::nullopt, + QuantLib::ext::optional floatPaymentLag = QuantLib::ext::nullopt); //! \name Observer interface //@{ @@ -99,6 +100,8 @@ class CrossCcyFixFloatSwapHelper : public RelativeDateRateHelper { QuantLib::ext::optional fixingDays_; QuantLib::ext::optional rateCutoff_; QuantLib::ext::optional isAveraged_; + QuantLib::ext::optional fixedPaymentLag_; + QuantLib::ext::optional floatPaymentLag_; QuantLib::ext::shared_ptr swap_; QuantLib::RelinkableHandle termStructureHandle_; From adb5bc79249ef258db735738c25f48b44c35195d Mon Sep 17 00:00:00 2001 From: Zetterberg <119352036+oszette@users.noreply.github.com> Date: Mon, 8 Dec 2025 12:50:26 +0100 Subject: [PATCH 4/4] Update conventions.xsd --- xsd/conventions.xsd | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/xsd/conventions.xsd b/xsd/conventions.xsd index a101ee3d4a..746f7d8812 100755 --- a/xsd/conventions.xsd +++ b/xsd/conventions.xsd @@ -248,6 +248,13 @@ + + + + + + +