Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions OREData/ored/configuration/conventions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand All @@ -1191,6 +1191,8 @@ void CrossCcyFixFloatSwapConvention::build() {
rateCutoff_ = parseInteger(strRateCutoff_);
if (!strIsAveraged_.empty())
isAveraged_ = parseBool(strIsAveraged_);
fixedPaymentLag_ = strFixedPaymentLag_.empty() ? 0 : lexical_cast<Natural>(strFixedPaymentLag_);
floatPaymentLag_ = strFloatPaymentLag_.empty() ? 0 : lexical_cast<Natural>(strFloatPaymentLag_);
}

void CrossCcyFixFloatSwapConvention::fromXML(XMLNode* node) {
Expand All @@ -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
Expand Down Expand Up @@ -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;
}

Expand Down
9 changes: 8 additions & 1 deletion OREData/ored/configuration/conventions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<bool> includeSpread() const { return includeSpread_; }
Expand Down Expand Up @@ -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_;
Expand All @@ -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<bool> includeSpread_;
Expand Down
6 changes: 4 additions & 2 deletions OREData/ored/marketdata/yieldcurve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3043,7 +3043,8 @@ void YieldCurve::addCrossCcyFixFloatSwaps(const std::size_t index,
currency_[index], swapConvention->fixedFrequency(), swapConvention->fixedConvention(),
swapConvention->fixedDayCounter(), floatIndex, floatLegDisc, Handle<Quote>(), 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<CrossCcyFixFloatMtMResetSwapHelper>(
Expand All @@ -3053,7 +3054,8 @@ void YieldCurve::addCrossCcyFixFloatSwaps(const std::size_t index,
swapConvention->fixedDayCounter(), floatIndex, floatLegDisc, Handle<Quote>(), 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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,15 @@ CrossCcyFixFloatMtMResetSwapHelper::CrossCcyFixFloatMtMResetSwapHelper(
const Handle<Quote>& spread, bool endOfMonth, bool resetsOnFloatLeg, bool telescopicValueDates,
const QuantLib::Pillar::Choice pillarChoice,
QuantLib::ext::optional<bool> includeSpread, QuantLib::ext::optional<Period> lookback, QuantLib::ext::optional<Size> fixingDays,
QuantLib::ext::optional<Size> rateCutoff, QuantLib::ext::optional<bool> isAveraged)
QuantLib::ext::optional<Size> rateCutoff, QuantLib::ext::optional<bool> isAveraged, QuantLib::ext::optional<Natural> fixedPaymentLag,
QuantLib::ext::optional<Natural> 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.");
Expand Down Expand Up @@ -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<FxIndex> fxIdx;
if (resetsOnFloatLeg_) {
Expand All @@ -86,8 +88,8 @@ void CrossCcyFixFloatMtMResetSwapHelper::initializeDates() {
}

swap_ = QuantLib::ext::make_shared<CrossCcyFixFloatMtMResetSwap>(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<PricingEngine> engine = QuantLib::ext::make_shared<CrossCcySwapEngine>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ class CrossCcyFixFloatMtMResetSwapHelper : public RelativeDateRateHelper {
bool telescopicValueDates = false, const QuantLib::Pillar::Choice pillarChoice = QuantLib::Pillar::LastRelevantDate,
QuantLib::ext::optional<bool> includeSpread = QuantLib::ext::nullopt, QuantLib::ext::optional<Period> lookback = QuantLib::ext::nullopt,
QuantLib::ext::optional<Size> fixingDays = QuantLib::ext::nullopt, QuantLib::ext::optional<Size> rateCutoff = QuantLib::ext::nullopt,
QuantLib::ext::optional<bool> isAveraged = QuantLib::ext::nullopt);
QuantLib::ext::optional<bool> isAveraged = QuantLib::ext::nullopt, QuantLib::ext::optional<Natural> fixedPaymenyLag = QuantLib::ext::nullopt,
QuantLib::ext::optional<Natural> floatPaymentLag = QuantLib::ext::nullopt);
//! \name RateHelper interface
//@{
Real impliedQuote() const override;
Expand Down Expand Up @@ -107,6 +108,8 @@ class CrossCcyFixFloatMtMResetSwapHelper : public RelativeDateRateHelper {
QuantLib::ext::optional<Size> fixingDays_;
QuantLib::ext::optional<Size> rateCutoff_;
QuantLib::ext::optional<bool> isAveraged_;
QuantLib::ext::optional<Natural> fixedPaymentLag_;
QuantLib::ext::optional<Natural> floatPaymentLag_;

QuantLib::ext::shared_ptr<CrossCcyFixFloatMtMResetSwap> swap_;

Expand Down
13 changes: 8 additions & 5 deletions QuantExt/qle/termstructures/crossccyfixfloatswaphelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,15 @@ CrossCcyFixFloatSwapHelper::CrossCcyFixFloatSwapHelper(
const QuantLib::ext::shared_ptr<IborIndex>& index, const Handle<YieldTermStructure>& floatDiscount,
const Handle<Quote>& spread, bool endOfMonth, bool telescopicValueDates, QuantLib::Pillar::Choice pillarChoice,
QuantLib::ext::optional<bool> includeSpread, QuantLib::ext::optional<Period> lookback, QuantLib::ext::optional<Size> fixingDays,
QuantLib::ext::optional<Size> rateCutoff, QuantLib::ext::optional<bool> isAveraged)
QuantLib::ext::optional<Size> rateCutoff, QuantLib::ext::optional<bool> isAveraged,
QuantLib::ext::optional<Natural> fixedPaymentLag, QuantLib::ext::optional<Natural> 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.");
Expand Down Expand Up @@ -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();
Expand Down
5 changes: 4 additions & 1 deletion QuantExt/qle/termstructures/crossccyfixfloatswaphelper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ class CrossCcyFixFloatSwapHelper : public RelativeDateRateHelper {
const QuantLib::Pillar::Choice pillarChoice = QuantLib::Pillar::LastRelevantDate,
QuantLib::ext::optional<bool> includeSpread = QuantLib::ext::nullopt, QuantLib::ext::optional<Period> lookback = QuantLib::ext::nullopt,
QuantLib::ext::optional<Size> fixingDays = QuantLib::ext::nullopt, QuantLib::ext::optional<Size> rateCutoff = QuantLib::ext::nullopt,
QuantLib::ext::optional<bool> isAveraged = QuantLib::ext::nullopt);
QuantLib::ext::optional<bool> isAveraged = QuantLib::ext::nullopt, QuantLib::ext::optional<Natural> fixedPaymentLag = QuantLib::ext::nullopt,
QuantLib::ext::optional<Natural> floatPaymentLag = QuantLib::ext::nullopt);

//! \name Observer interface
//@{
Expand Down Expand Up @@ -99,6 +100,8 @@ class CrossCcyFixFloatSwapHelper : public RelativeDateRateHelper {
QuantLib::ext::optional<Size> fixingDays_;
QuantLib::ext::optional<Size> rateCutoff_;
QuantLib::ext::optional<bool> isAveraged_;
QuantLib::ext::optional<Natural> fixedPaymentLag_;
QuantLib::ext::optional<Natural> floatPaymentLag_;

QuantLib::ext::shared_ptr<CrossCcyFixFloatSwap> swap_;
QuantLib::RelinkableHandle<QuantLib::YieldTermStructure> termStructureHandle_;
Expand Down
7 changes: 7 additions & 0 deletions xsd/conventions.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,13 @@
<xs:element type="bool" name="EOM" minOccurs="0" maxOccurs="1"/>
<xs:element type="bool" name="IsResettable" minOccurs="0" maxOccurs="1"/>
<xs:element type="bool" name="FloatIndexIsResettable" minOccurs="0" maxOccurs="1"/>
<xs:element type="bool" name="IncludeSpread" minOccurs="0" maxOccurs="1"/>
<xs:element type="xs:string" name="Lookback" minOccurs="0" maxOccurs="1"/>
<xs:element type="xs:integer" name="FixingDays" minOccurs="0" maxOccurs="1"/>
<xs:element type="xs:integer" name="RateCutoff" minOccurs="0" maxOccurs="1"/>
<xs:element type="bool" name="IsAveraged" minOccurs="0" maxOccurs="1"/>
<xs:element type="xs:integer" name="FixedPaymentLag" minOccurs="0" maxOccurs="1"/>
<xs:element type="xs:integer" name="FloatPaymentLag" minOccurs="0" maxOccurs="1"/>
</xs:all>
</xs:complexType>

Expand Down