diff --git a/OREData/ored/configuration/conventions.cpp b/OREData/ored/configuration/conventions.cpp index ca1b60fdf..97a45d693 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 40c83d8bf..c5c5a7869 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 e3e4c6524..ade541a20 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 3aca4926a..d3e6cb00f 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 224b5c31d..42b447093 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 aebd194b7..54c20f060 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 122a1ab80..862ad3206 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_; diff --git a/xsd/conventions.xsd b/xsd/conventions.xsd index a101ee3d4..746f7d881 100755 --- a/xsd/conventions.xsd +++ b/xsd/conventions.xsd @@ -248,6 +248,13 @@ + + + + + + +