/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 |