• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lballabio / QuantLib / 23006928006

12 Mar 2026 02:27PM UTC coverage: 74.274% (+0.03%) from 74.242%
23006928006

Pull #2474

github

web-flow
Merge 65a6878ed into 0a02cced0
Pull Request #2474: Add MultipleResetsSwap instrument and rate helper

137 of 186 new or added lines in 3 files covered. (73.66%)

86 existing lines in 5 files now uncovered.

57898 of 77952 relevant lines covered (74.27%)

8738073.7 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

76.6
/ql/instruments/makemultipleresetsswap.cpp
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2

3
/*
4
 Copyright (C) 2026 Zain Mughal
5

6
 This file is part of QuantLib, a free-software/open-source library
7
 for financial quantitative analysts and developers - http://quantlib.org/
8

9
 QuantLib is free software: you can redistribute it and/or modify it
10
 under the terms of the QuantLib license.  You should have received a
11
 copy of the license along with this program; if not, please email
12
 <quantlib-dev@lists.sf.net>. The license is also available online at
13
 <https://www.quantlib.org/license.shtml>.
14

15
 This program is distributed in the hope that it will be useful, but WITHOUT
16
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
 FOR A PARTICULAR PURPOSE.  See the license for more details.
18
*/
19

20
#include <ql/indexes/iborindex.hpp>
21
#include <ql/instruments/makemultipleresetsswap.hpp>
22
#include <ql/pricingengines/swap/discountingswapengine.hpp>
23
#include <ql/settings.hpp>
24
#include <ql/time/schedule.hpp>
25

26
namespace QuantLib {
27

28
    MakeMultipleResetsSwap::MakeMultipleResetsSwap(const Period& tenor,
13✔
29
                                                   const ext::shared_ptr<IborIndex>& iborIndex,
30
                                                   Size resetsPerCoupon)
13✔
31
    : tenor_(tenor), iborIndex_(iborIndex), resetsPerCoupon_(resetsPerCoupon),
13✔
32
      fixedDayCount_(iborIndex->dayCounter()) {}
26✔
33

NEW
34
    MakeMultipleResetsSwap::operator MultipleResetsSwap() const {
×
NEW
35
        ext::shared_ptr<MultipleResetsSwap> swap = *this;
×
NEW
36
        return *swap;
×
37
    }
38

39
    MakeMultipleResetsSwap::operator ext::shared_ptr<MultipleResetsSwap>() const {
13✔
40
        Calendar cal = iborIndex_->fixingCalendar();
13✔
41
        BusinessDayConvention bdc = iborIndex_->businessDayConvention();
13✔
42

43
        QL_REQUIRE(effectiveDate_ == Date() || settlementDays_ == Null<Natural>(),
13✔
44
                   "withEffectiveDate and withSettlementDays are mutually exclusive");
45

46
        Date startDate;
13✔
47
        if (effectiveDate_ != Date()) {
13✔
NEW
48
            startDate = effectiveDate_;
×
49
        } else {
50
            Natural settlDays =
51
                settlementDays_ != Null<Natural>() ? settlementDays_ : iborIndex_->fixingDays();
13✔
52
            Date refDate = Settings::instance().evaluationDate();
13✔
53
            startDate = cal.advance(cal.adjust(refDate), settlDays * Days);
13✔
54
            startDate = cal.advance(startDate, forwardStart_,
26✔
55
                                    forwardStart_.length() < 0 ? Preceding : Following);
56
        }
57

58
        Date endDate =
59
            terminationDate_ != Date() ? terminationDate_ : cal.advance(startDate, tenor_, bdc);
13✔
60

61
        Period resetTenor = iborIndex_->tenor();
13✔
62
        Frequency fixedFreq = fixedFrequency_;
13✔
63
        if (fixedFreq == NoFrequency) {
13✔
64
            Period couponTenor(resetsPerCoupon_ * resetTenor.length(), resetTenor.units());
13✔
65
            fixedFreq = couponTenor.frequency();
13✔
66
        }
67

68
        Schedule fixedSchedule(startDate, endDate, Period(fixedFreq), cal, fixedConvention_,
26✔
69
                               fixedConvention_, DateGeneration::Backward, false);
26✔
70

71
        Schedule fullResetSchedule(startDate, endDate, resetTenor, cal, bdc, bdc,
72
                                   DateGeneration::Backward, false);
26✔
73

74
        Rate usedFixedRate = fixedRate_;
13✔
75
        if (fixedRate_ == Null<Rate>()) {
13✔
76
            MultipleResetsSwap temp(type_, nominal_, fixedSchedule, 0.0, fixedDayCount_,
1✔
77
                                    fullResetSchedule, iborIndex_, resetsPerCoupon_, spread_,
1✔
78
                                    averagingMethod_);
3✔
79
            if (engine_ == nullptr) {
1✔
80
                Handle<YieldTermStructure> disc = iborIndex_->forwardingTermStructure();
1✔
81
                QL_REQUIRE(!disc.empty(),
1✔
82
                           "null term structure set to this instance of " << iborIndex_->name());
83
                temp.setPricingEngine(ext::make_shared<DiscountingSwapEngine>(disc, false));
2✔
84
            } else {
NEW
85
                temp.setPricingEngine(engine_);
×
86
            }
87
            usedFixedRate = temp.fairRate();
1✔
88
        }
1✔
89

90
        auto swap = ext::make_shared<MultipleResetsSwap>(
91
            type_, nominal_, fixedSchedule, usedFixedRate, fixedDayCount_, fullResetSchedule,
13✔
92
            iborIndex_, resetsPerCoupon_, spread_, averagingMethod_);
13✔
93

94
        if (engine_ == nullptr) {
13✔
95
            Handle<YieldTermStructure> disc = iborIndex_->forwardingTermStructure();
7✔
96
            if (!disc.empty())
7✔
97
                swap->setPricingEngine(ext::make_shared<DiscountingSwapEngine>(disc, false));
14✔
98
        } else {
99
            swap->setPricingEngine(engine_);
6✔
100
        }
101

102
        return swap;
13✔
103
    }
13✔
104

NEW
105
    MakeMultipleResetsSwap& MakeMultipleResetsSwap::receiveFixed(bool flag) {
×
NEW
106
        type_ = flag ? Swap::Receiver : Swap::Payer;
×
NEW
107
        return *this;
×
108
    }
109

110
    MakeMultipleResetsSwap& MakeMultipleResetsSwap::withType(Swap::Type type) {
2✔
111
        type_ = type;
2✔
112
        return *this;
2✔
113
    }
114

115
    MakeMultipleResetsSwap& MakeMultipleResetsSwap::withNominal(Real n) {
10✔
116
        nominal_ = n;
10✔
117
        return *this;
10✔
118
    }
119

120
    MakeMultipleResetsSwap& MakeMultipleResetsSwap::withFixedRate(Rate fixedRate) {
12✔
121
        fixedRate_ = fixedRate;
12✔
122
        return *this;
12✔
123
    }
124

125
    MakeMultipleResetsSwap& MakeMultipleResetsSwap::withSettlementDays(Natural settlementDays) {
13✔
126
        settlementDays_ = settlementDays;
13✔
127
        return *this;
13✔
128
    }
129

NEW
130
    MakeMultipleResetsSwap& MakeMultipleResetsSwap::withEffectiveDate(const Date& d) {
×
NEW
131
        effectiveDate_ = d;
×
NEW
132
        return *this;
×
133
    }
134

NEW
135
    MakeMultipleResetsSwap& MakeMultipleResetsSwap::withTerminationDate(const Date& d) {
×
NEW
136
        terminationDate_ = d;
×
NEW
137
        if (d != Date())
×
NEW
138
            tenor_ = Period();
×
NEW
139
        return *this;
×
140
    }
141

NEW
142
    MakeMultipleResetsSwap& MakeMultipleResetsSwap::withForwardStart(const Period& fwdStart) {
×
NEW
143
        forwardStart_ = fwdStart;
×
NEW
144
        return *this;
×
145
    }
146

147
    MakeMultipleResetsSwap& MakeMultipleResetsSwap::withFixedLegFrequency(Frequency f) {
3✔
148
        fixedFrequency_ = f;
3✔
149
        return *this;
3✔
150
    }
151

152
    MakeMultipleResetsSwap& MakeMultipleResetsSwap::withFixedLegDayCount(const DayCounter& dc) {
3✔
153
        fixedDayCount_ = dc;
154
        return *this;
3✔
155
    }
156

157
    MakeMultipleResetsSwap&
158
    MakeMultipleResetsSwap::withFixedLegConvention(BusinessDayConvention bdc) {
3✔
159
        fixedConvention_ = bdc;
3✔
160
        return *this;
3✔
161
    }
162

163
    MakeMultipleResetsSwap& MakeMultipleResetsSwap::withFloatingLegSpread(Spread sp) {
3✔
164
        spread_ = sp;
3✔
165
        return *this;
3✔
166
    }
167

168
    MakeMultipleResetsSwap& MakeMultipleResetsSwap::withAveragingMethod(RateAveraging::Type m) {
7✔
169
        averagingMethod_ = m;
7✔
170
        return *this;
7✔
171
    }
172

173
    MakeMultipleResetsSwap&
174
    MakeMultipleResetsSwap::withDiscountingTermStructure(const Handle<YieldTermStructure>& d) {
6✔
175
        engine_ = ext::make_shared<DiscountingSwapEngine>(d, false);
6✔
176
        return *this;
6✔
177
    }
178

179
    MakeMultipleResetsSwap&
NEW
180
    MakeMultipleResetsSwap::withPricingEngine(const ext::shared_ptr<PricingEngine>& engine) {
×
NEW
181
        engine_ = engine;
×
NEW
182
        return *this;
×
183
    }
184

185
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc