diff --git a/OREData/ored/portfolio/legdata.cpp b/OREData/ored/portfolio/legdata.cpp index 2ead26e77b..7b4a7a44b2 100644 --- a/OREData/ored/portfolio/legdata.cpp +++ b/OREData/ored/portfolio/legdata.cpp @@ -1231,7 +1231,7 @@ Leg makeZCFixedLeg(const LegData& data, const QuantLib::Date& openEndDateReplace void applyStubInterpolation(Leg::iterator c, const std::string& shortIndexStr, const std::string& longIndexStr, const std::string& roundingTypeStr, const std::string& roundingPrecisionStr, const QuantLib::ext::shared_ptr& engineFactory, - const bool useOriginalIndexCurve, const Size accrualDays) { + const bool useOriginalIndexCurve, const Size accrualDays, const Size fixingDays) { if (shortIndexStr.empty() && longIndexStr.empty()) { return; } @@ -1253,6 +1253,7 @@ void applyStubInterpolation(Leg::iterator c, const std::string& shortIndexStr, c iborCpn = QuantLib::ext::dynamic_pointer_cast(*c); } QL_REQUIRE(iborCpn, "applyStubInterpolation(): unable to unpack coupon to ibor coupon"); + Size fDays = fixingDays == Null() ? iborCpn->fixingDays() : fixingDays; // ... replace it with an interpolated Ibor Coupon ... QuantLib::ext::shared_ptr idx1, idx2; if (!shortIndexStr.empty()) @@ -1269,7 +1270,7 @@ void applyStubInterpolation(Leg::iterator c, const std::string& shortIndexStr, c // actually no interpolation, only one index is given effectively, so we can use an Ibor Coupon tmp = QuantLib::ext::make_shared( iborCpn->date(), iborCpn->nominal(), iborCpn->accrualStartDate(), iborCpn->accrualEndDate(), - iborCpn->fixingDays(), + fDays, useOriginalIndexCurve ? idx1->clone(iborCpn->iborIndex()->forwardingTermStructure()) : idx1, iborCpn->gearing(), iborCpn->spread(), iborCpn->referencePeriodStart(), iborCpn->referencePeriodEnd(), iborCpn->dayCounter(), iborCpn->isInArrears(), iborCpn->exCouponDate()); @@ -1287,7 +1288,7 @@ void applyStubInterpolation(Leg::iterator c, const std::string& shortIndexStr, c useOriginalIndexCurve ? iborCpn->iborIndex()->forwardingTermStructure() : Handle()); tmp = QuantLib::ext::make_shared( iborCpn->date(), iborCpn->nominal(), iborCpn->accrualStartDate(), iborCpn->accrualEndDate(), - iborCpn->fixingDays(), interpolatedIndex, iborCpn->gearing(), iborCpn->spread(), + fDays, interpolatedIndex, iborCpn->gearing(), iborCpn->spread(), iborCpn->referencePeriodStart(), iborCpn->referencePeriodEnd(), iborCpn->dayCounter(), iborCpn->isInArrears(), iborCpn->exCouponDate(), iborCpn->iborIndex()); DLOG("created InterpolatedIborIndex for accrual period " @@ -1465,7 +1466,7 @@ Leg makeIborLeg(const LegData& data, const QuantLib::ext::shared_ptr& // front / back stub interpolation applyStubInterpolation(leg.begin(), floatData->frontStubShortIndex(), floatData->frontStubLongIndex(), floatData->frontStubRoundingType(), floatData->frontStubRoundingPrecision(), engineFactory, - floatData->stubUseOriginalCurve()); + floatData->stubUseOriginalCurve(), Null(), fixingDays); if (leg.size() == 1 && !floatData->frontStubShortIndex().empty() && !floatData->frontStubLongIndex().empty() && !floatData->backStubShortIndex().empty() && !floatData->backStubLongIndex().empty()) { @@ -1474,7 +1475,7 @@ Leg makeIborLeg(const LegData& data, const QuantLib::ext::shared_ptr& } else { applyStubInterpolation(leg.end() - 1, floatData->backStubShortIndex(), floatData->backStubLongIndex(), floatData->backStubRoundingType(), floatData->backStubRoundingPrecision(), engineFactory, - floatData->stubUseOriginalCurve()); + floatData->stubUseOriginalCurve(), Null(), fixingDays); } return leg; } @@ -1588,7 +1589,7 @@ Leg makeIborLeg(const LegData& data, const QuantLib::ext::shared_ptr& // front / back stub interpolation applyStubInterpolation(tmpLeg.begin(), floatData->frontStubShortIndex(), floatData->frontStubLongIndex(), floatData->frontStubRoundingType(), floatData->frontStubRoundingPrecision(), engineFactory, - floatData->stubUseOriginalCurve()); + floatData->stubUseOriginalCurve(), Null(), fixingDays); if (tmpLeg.size() == 1 && !floatData->frontStubShortIndex().empty() && !floatData->frontStubLongIndex().empty() && !floatData->backStubShortIndex().empty() && !floatData->backStubLongIndex().empty()) { @@ -1597,7 +1598,7 @@ Leg makeIborLeg(const LegData& data, const QuantLib::ext::shared_ptr& } else { applyStubInterpolation(tmpLeg.end() - 1, floatData->backStubShortIndex(), floatData->backStubLongIndex(), floatData->backStubRoundingType(), floatData->backStubRoundingPrecision(), engineFactory, - floatData->stubUseOriginalCurve()); + floatData->stubUseOriginalCurve(), Null(), fixingDays); } // return the leg diff --git a/OREData/ored/portfolio/legdata.hpp b/OREData/ored/portfolio/legdata.hpp index 1f89a483ea..a3dfcf02dc 100644 --- a/OREData/ored/portfolio/legdata.hpp +++ b/OREData/ored/portfolio/legdata.hpp @@ -1259,7 +1259,8 @@ Leg buildNotionalLeg(const LegData& data, const Leg& leg, RequiredFixings& requi void applyStubInterpolation(Leg::iterator c, const std::string& shortIndexStr, const std::string& longIndexStr, const std::string& roundingTypeStr, const std::string& roundingPrecisionStr, const QuantLib::ext::shared_ptr& engineFactory, - const bool useOriginalIndexCurve, const Size accrualDays = Null()); + const bool useOriginalIndexCurve, const Size accrualDays = Null(), + const Size fixingDays = Null()); } // namespace data } // namespace ore