Coverage Report

Created: 2026-08-14 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/instruments/floatfloatswap.hpp
Line
Count
Source
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2013 Peter Caspers
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
/*! \file floatfloatswap.hpp
21
    \brief swap exchanging capped floored Libor or CMS coupons with quite
22
           general specification. If no payment convention is given, the
23
           respective leg schedule convention is used. The interest rate
24
           indices should be linked to valid forwarding and in case of
25
           swap indices discounting curves
26
*/
27
28
#ifndef quantlib_floatfloat_swap_hpp
29
#define quantlib_floatfloat_swap_hpp
30
31
#include <ql/instruments/swap.hpp>
32
#include <ql/instruments/vanillaswap.hpp>
33
#include <ql/time/daycounter.hpp>
34
#include <ql/time/schedule.hpp>
35
#include <ql/optional.hpp>
36
37
namespace QuantLib {
38
39
    class InterestRateIndex;
40
41
    //! float float swap
42
43
    class FloatFloatSwap : public Swap {
44
      public:
45
        class arguments;
46
        class results;
47
        class engine;
48
        FloatFloatSwap(
49
            Swap::Type type,
50
            Real nominal1,
51
            Real nominal2,
52
            Schedule schedule1,
53
            ext::shared_ptr<InterestRateIndex> index1,
54
            DayCounter dayCount1,
55
            Schedule schedule2,
56
            ext::shared_ptr<InterestRateIndex> index2,
57
            DayCounter dayCount2,
58
            bool intermediateCapitalExchange = false,
59
            bool finalCapitalExchange = false,
60
            Real gearing1 = 1.0,
61
            Real spread1 = 0.0,
62
            Real cappedRate1 = Null<Real>(),
63
            Real flooredRate1 = Null<Real>(),
64
            Real gearing2 = 1.0,
65
            Real spread2 = 0.0,
66
            Real cappedRate2 = Null<Real>(),
67
            Real flooredRate2 = Null<Real>(),
68
            const std::optional<BusinessDayConvention>& paymentConvention1 = std::nullopt,
69
            const std::optional<BusinessDayConvention>& paymentConvention2 = std::nullopt);
70
71
        FloatFloatSwap(
72
            Swap::Type type,
73
            std::vector<Real> nominal1,
74
            std::vector<Real> nominal2,
75
            Schedule schedule1,
76
            ext::shared_ptr<InterestRateIndex> index1,
77
            DayCounter dayCount1,
78
            Schedule schedule2,
79
            ext::shared_ptr<InterestRateIndex> index2,
80
            DayCounter dayCount2,
81
            bool intermediateCapitalExchange = false,
82
            bool finalCapitalExchange = false,
83
            std::vector<Real> gearing1 = std::vector<Real>(),
84
            std::vector<Real> spread1 = std::vector<Real>(),
85
            std::vector<Real> cappedRate1 = std::vector<Real>(),
86
            std::vector<Real> flooredRate1 = std::vector<Real>(),
87
            std::vector<Real> gearing2 = std::vector<Real>(),
88
            std::vector<Real> spread2 = std::vector<Real>(),
89
            std::vector<Real> cappedRate2 = std::vector<Real>(),
90
            std::vector<Real> flooredRate2 = std::vector<Real>(),
91
            const std::optional<BusinessDayConvention>& paymentConvention1 = std::nullopt,
92
            const std::optional<BusinessDayConvention>& paymentConvention2 = std::nullopt);
93
94
        //! \name Inspectors
95
        //@{
96
        Swap::Type type() const;
97
        const std::vector<Real> &nominal1() const;
98
        const std::vector<Real> &nominal2() const;
99
100
        const Schedule &schedule1() const;
101
        const Schedule &schedule2() const;
102
103
        const ext::shared_ptr<InterestRateIndex> &index1() const;
104
        const ext::shared_ptr<InterestRateIndex> &index2() const;
105
106
        std::vector<Real> spread1() const;
107
        std::vector<Real> spread2() const;
108
109
        std::vector<Real> gearing1() const;
110
        std::vector<Real> gearing2() const;
111
112
        std::vector<Rate> cappedRate1() const;
113
        std::vector<Rate> flooredRate1() const;
114
        std::vector<Rate> cappedRate2() const;
115
        std::vector<Rate> flooredRate2() const;
116
117
        const DayCounter &dayCount1() const;
118
        const DayCounter &dayCount2() const;
119
120
        BusinessDayConvention paymentConvention1() const;
121
        BusinessDayConvention paymentConvention2() const;
122
123
        const Leg &leg1() const;
124
        const Leg &leg2() const;
125
        //@}
126
127
        //! \name Results
128
        //@{
129
        Spread fairSpread1() const;
130
        Spread fairSpread2() const;
131
        //@}
132
        // other
133
        void setupArguments(PricingEngine::arguments* args) const override;
134
        void fetchResults(const PricingEngine::results*) const override;
135
136
      private:
137
        void init(std::optional<BusinessDayConvention> paymentConvention1,
138
                  std::optional<BusinessDayConvention> paymentConvention2);
139
        void setupExpired() const override;
140
        Swap::Type type_;
141
        std::vector<Real> nominal1_, nominal2_;
142
        Schedule schedule1_, schedule2_;
143
        ext::shared_ptr<InterestRateIndex> index1_, index2_;
144
        std::vector<Real> gearing1_, gearing2_, spread1_, spread2_;
145
        std::vector<Real> cappedRate1_, flooredRate1_, cappedRate2_,
146
            flooredRate2_;
147
        DayCounter dayCount1_, dayCount2_;
148
        std::vector<bool> isRedemptionFlow1_, isRedemptionFlow2_;
149
        BusinessDayConvention paymentConvention1_, paymentConvention2_;
150
        const bool intermediateCapitalExchange_, finalCapitalExchange_;
151
        // results
152
        mutable Spread fairSpread1_, fairSpread2_;
153
    };
154
155
    //! %Arguments for float float swap calculation
156
    class FloatFloatSwap::arguments : public Swap::arguments {
157
      public:
158
        arguments() = default;
159
        Swap::Type type = Swap::Receiver;
160
        std::vector<Real> nominal1, nominal2;
161
162
        std::vector<Date> leg1ResetDates, leg1FixingDates, leg1PayDates;
163
        std::vector<Date> leg2ResetDates, leg2FixingDates, leg2PayDates;
164
165
        std::vector<Real> leg1Spreads, leg2Spreads, leg1Gearings, leg2Gearings;
166
        std::vector<Real> leg1CappedRates, leg1FlooredRates, leg2CappedRates,
167
            leg2FlooredRates;
168
169
        std::vector<Real> leg1Coupons, leg2Coupons;
170
        std::vector<Real> leg1AccrualTimes, leg2AccrualTimes;
171
172
        ext::shared_ptr<InterestRateIndex> index1, index2;
173
174
        std::vector<bool> leg1IsRedemptionFlow, leg2IsRedemptionFlow;
175
176
        void validate() const override;
177
    };
178
179
    //! %Results from float float swap calculation
180
    class FloatFloatSwap::results : public Swap::results {
181
      public:
182
        Spread fairSpread1;
183
        Spread fairSpread2;
184
        void reset() override;
185
    };
186
187
    class FloatFloatSwap::engine
188
        : public GenericEngine<FloatFloatSwap::arguments,
189
                               FloatFloatSwap::results> {};
190
191
    // inline definitions
192
193
0
    inline Swap::Type FloatFloatSwap::type() const { return type_; }
194
195
0
    inline const std::vector<Real> &FloatFloatSwap::nominal1() const {
196
0
        return nominal1_;
197
0
    }
198
199
0
    inline const std::vector<Real> &FloatFloatSwap::nominal2() const {
200
0
        return nominal2_;
201
0
    }
202
203
0
    inline const Schedule &FloatFloatSwap::schedule1() const {
204
0
        return schedule1_;
205
0
    }
206
207
0
    inline const Schedule &FloatFloatSwap::schedule2() const {
208
0
        return schedule2_;
209
0
    }
210
211
    inline const ext::shared_ptr<InterestRateIndex> &
212
0
    FloatFloatSwap::index1() const {
213
0
        return index1_;
214
0
    }
215
216
    inline const ext::shared_ptr<InterestRateIndex> &
217
0
    FloatFloatSwap::index2() const {
218
0
        return index2_;
219
0
    }
220
221
0
    inline std::vector<Real> FloatFloatSwap::spread1() const { return spread1_; }
222
223
0
    inline std::vector<Real> FloatFloatSwap::spread2() const { return spread2_; }
224
225
0
    inline std::vector<Real> FloatFloatSwap::gearing1() const { return gearing1_; }
226
227
0
    inline std::vector<Real> FloatFloatSwap::gearing2() const { return gearing2_; }
228
229
0
    inline std::vector<Real> FloatFloatSwap::cappedRate1() const { return cappedRate1_; }
230
231
0
    inline std::vector<Real> FloatFloatSwap::cappedRate2() const { return cappedRate2_; }
232
233
0
    inline std::vector<Real> FloatFloatSwap::flooredRate1() const { return flooredRate1_; }
234
235
0
    inline std::vector<Real> FloatFloatSwap::flooredRate2() const { return flooredRate2_; }
236
237
0
    inline const DayCounter &FloatFloatSwap::dayCount1() const {
238
0
        return dayCount1_;
239
0
    }
240
241
0
    inline const DayCounter &FloatFloatSwap::dayCount2() const {
242
0
        return dayCount2_;
243
0
    }
244
245
0
    inline BusinessDayConvention FloatFloatSwap::paymentConvention1() const {
246
0
        return paymentConvention1_;
247
0
    }
248
249
0
    inline BusinessDayConvention FloatFloatSwap::paymentConvention2() const {
250
0
        return paymentConvention2_;
251
0
    }
252
253
0
    inline const Leg &FloatFloatSwap::leg1() const { return legs_[0]; }
254
255
0
    inline const Leg &FloatFloatSwap::leg2() const { return legs_[1]; }
256
}
257
258
#endif