Skip to content

Add MultipleResetsSwap instrument and rate helper#2474

Merged
lballabio merged 2 commits intolballabio:masterfrom
zippyg:feature/multiple-resets-swap
Mar 13, 2026
Merged

Add MultipleResetsSwap instrument and rate helper#2474
lballabio merged 2 commits intolballabio:masterfrom
zippyg:feature/multiple-resets-swap

Conversation

@zippyg
Copy link
Contributor

@zippyg zippyg commented Mar 8, 2026

Implements issue #2138: a fixed-vs-floating swap whose floating leg coupons are
determined by compounding or averaging multiple consecutive Ibor fixings within
each accrual period.

Adds MultipleResetsSwap (inheriting FixedVsFloatingSwap, giving fairRate(),
fairSpread(), and BPS methods for free), a MakeMultipleResetsSwap fluent builder,
and MultipleResetsSwapRateHelper for bootstrapping yield curves from
multiple-resets swap quotes. The floating leg is built via the existing
MultipleResetsLeg/coupon infrastructure. Tests cover fair-rate pricing,
payer/receiver leg NPV consistency, averaging vs. compounding differentiation,
and end-to-end bootstrapping at 1Y/2Y/3Y.

Relates to #2138.

@zippyg zippyg force-pushed the feature/multiple-resets-swap branch from 6644ae4 to d3def14 Compare March 8, 2026 16:35
Implements issue lballabio#2138: a fixed-vs-floating swap whose floating leg coupons are
determined by compounding or averaging multiple consecutive Ibor fixings within
each accrual period.

Adds MultipleResetsSwap (inheriting FixedVsFloatingSwap, giving fairRate(),
fairSpread(), and BPS methods for free), a MakeMultipleResetsSwap fluent builder,
and MultipleResetsSwapRateHelper for bootstrapping yield curves from
multiple-resets swap quotes. The floating leg is built via the existing
MultipleResetsLeg/coupon infrastructure. Tests cover fair-rate pricing,
payer/receiver leg NPV consistency, averaging vs. compounding differentiation,
and end-to-end bootstrapping at 1Y/2Y/3Y.

Relates to lballabio#2138.
@zippyg zippyg force-pushed the feature/multiple-resets-swap branch from d3def14 to 6a18dc9 Compare March 8, 2026 16:38
@coveralls
Copy link

coveralls commented Mar 8, 2026

Coverage Status

coverage: 74.274% (+0.03%) from 74.242%
when pulling 65a6878 on zippyg:feature/multiple-resets-swap
into 81d819d on lballabio:master.

Copy link
Owner

@lballabio lballabio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I left a few comments.

Comment on lines +44 to +45
Rate fixedRate = Null<Rate>(),
const Period& fwdStart = 0 * Days);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Being optional, these two could be moved to corresponding with methods.

Comment on lines +131 to +140
MakeMultipleResetsSwap& MakeMultipleResetsSwap::withSettlementDays(Natural settlementDays) {
settlementDays_ = settlementDays;
effectiveDate_ = Date();
return *this;
}

MakeMultipleResetsSwap& MakeMultipleResetsSwap::withEffectiveDate(const Date& d) {
effectiveDate_ = d;
return *this;
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a discussion going on about similar methods in other classes — see #1394. These might need to be modified in the same way.

// Cross-check: fixed-leg NPV + floating-leg NPV equals total NPV.
Real npvCheck = swap->fixedLegNPV() + swap->floatingLegNPV();
BOOST_CHECK_SMALL(npvCheck - swap->NPV(), 1.0e-10);
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you could also check that, if you use MakeMultipleResetsSwap without passing a rate, you get back a fair swap.

Move fixedRate and fwdStart out of the constructor into withFixedRate()
and withForwardStart() fluent methods, keeping the constructor to its
three mandatory parameters. Add a QL_REQUIRE guard so that
withEffectiveDate and withSettlementDays are mutually exclusive rather
than silently overriding each other. Add a test for the auto-fair-rate
path in MakeMultipleResetsSwap.
@zippyg
Copy link
Contributor Author

zippyg commented Mar 12, 2026

Thanks for the review, Luigi, implemented all three points:

  • Moved fixedRate and fwdStart out of the constructor into withFixedRate() and withForwardStart() fluent methods, so the constructor now takes only the three mandatory parameters. Updated all call sites in the rate helper and the tests accordingly.
  • Removed the silent effectiveDate_ = Date() clear from withSettlementDays, and added a QL_REQUIRE in operator() so that calling both withEffectiveDate and withSettlementDays on the same builder throws rather than silently overriding, consistent with the direction in MakeVanillaSwap / MakeOIS withSettlementDays clears an explicit effective date #1394.
  • Added a test at the end of testFairRate that builds a swap without calling withFixedRate() and checks that the NPV is zero, covering the auto-fair-rate computation path.

@lballabio lballabio added this to the Release 1.42 milestone Mar 13, 2026
@lballabio lballabio merged commit 529aef3 into lballabio:master Mar 13, 2026
43 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants