/src/quantlib/ql/instruments/constnotionalcrosscurrencybasisswap.hpp
Line | Count | Source |
1 | | /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | |
3 | | /* |
4 | | Copyright (C) 2016 Quaternion Risk Management Ltd |
5 | | Copyright (C) 2025 Paolo D'Elia |
6 | | Copyright (C) 2026 Kyrylo Protsenko |
7 | | |
8 | | This file is part of QuantLib, a free-software/open-source library |
9 | | for financial quantitative analysts and developers - http://quantlib.org/ |
10 | | |
11 | | QuantLib is free software: you can redistribute it and/or modify it |
12 | | under the terms of the QuantLib license. You should have received a |
13 | | copy of the license along with this program; if not, please email |
14 | | <quantlib-dev@lists.sf.net>. The license is also available online at |
15 | | <https://www.quantlib.org/license.shtml>. |
16 | | |
17 | | This program is distributed in the hope that it will be useful, but WITHOUT |
18 | | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
19 | | FOR A PARTICULAR PURPOSE. See the license for more details. |
20 | | */ |
21 | | |
22 | | /*! \file constnotionalcrosscurrencybasisswap.hpp |
23 | | \brief Cross-currency basis swap |
24 | | */ |
25 | | |
26 | | #ifndef quantlib_cross_currency_basis_swap_hpp |
27 | | #define quantlib_cross_currency_basis_swap_hpp |
28 | | |
29 | | #include <ql/indexes/iborindex.hpp> |
30 | | #include <ql/cashflows/iborcoupon.hpp> |
31 | | #include <ql/cashflows/stubiborcoupon.hpp> |
32 | | #include <ql/cashflows/rateaveraging.hpp> |
33 | | #include <ql/optional.hpp> |
34 | | #include <ql/time/schedule.hpp> |
35 | | #include <ql/instruments/constnotionalcrosscurrencyswap.hpp> |
36 | | |
37 | | namespace QuantLib { |
38 | | |
39 | | //! Cross-currency basis swap |
40 | | /*! The first leg holds the pay currency cashflows and second leg holds |
41 | | the receive currency cashflows. |
42 | | |
43 | | \ingroup instruments |
44 | | */ |
45 | | class ConstNotionalCrossCurrencyBasisSwap : public ConstNotionalCrossCurrencySwap { |
46 | | public: |
47 | | class arguments; |
48 | | class results; |
49 | | |
50 | | //! \name Constructors |
51 | | //@{ |
52 | | /*! |
53 | | \brief Constructs a cross-currency basis swap. |
54 | | |
55 | | First leg holds the pay currency cashflows and the second leg holds the receive currency cashflows. |
56 | | |
57 | | Payment lags apply only to coupon payments. Notional exchanges remain |
58 | | on the effective and maturity dates, unless paymentLagOnNotionalExchanges |
59 | | is set, in which case each leg's exchanges are lagged by that leg's |
60 | | coupon payment lag: the final exchange settles together with the final |
61 | | coupon and the initial exchange falls on the lagged settlement date. |
62 | | |
63 | | \param payNominal Notional amount for the pay leg. |
64 | | \param payCurrency Currency of the pay leg. |
65 | | \param paySchedule Payment schedule for the pay leg. |
66 | | \param payIndex Floating rate index for the pay leg. |
67 | | \param paySpread Spread over the floating rate for the pay leg. |
68 | | \param payGearing Gearing factor for the pay leg. |
69 | | \param recNominal Notional amount for the receive leg. |
70 | | \param recCurrency Currency of the receive leg. |
71 | | \param recSchedule Payment schedule for the receive leg. |
72 | | \param recIndex Floating rate index for the receive leg. |
73 | | \param recSpread Spread over the floating rate for the receive leg. |
74 | | \param recGearing Gearing factor for the receive leg. |
75 | | \param payPaymentLag Coupon payment lag in days for the pay leg (default: 0). |
76 | | \param recPaymentLag Coupon payment lag in days for the receive leg (default: 0). |
77 | | \param payCompoundSpread Whether to compound the spread daily for the pay leg if overnight (default: false). |
78 | | \param payLookbackDays Lookback days for the pay leg if overnight (default: null). |
79 | | \param payObservationShift Whether the observation shift is applied for the pay leg if overnight (default: false). |
80 | | \param payLockoutDays Lockout period (in business days) for the pay leg if overnight (default: 0). |
81 | | \param payAveragingMethod Averaging method for the pay leg if overnight (default: compounding). |
82 | | \param recCompoundSpread Whether to compound the spread daily for the receive leg if overnight (default: false). |
83 | | \param recLookbackDays Lookback days for the receive leg if overnight (default: null). |
84 | | \param recObservationShift Whether the observation shift is applied for the receive leg if overnight (default: false). |
85 | | \param recLockoutDays Lockout period (in business days) for the receive leg if overnight (default: 0). |
86 | | \param recAveragingMethod Averaging method for the receive leg if overnight (default: compounding). |
87 | | \param telescopicValueDates Flag indicating whether telescopic value dates are used if overnight (default: false). |
88 | | \param useIndexedCoupons If provided, overrides the global IborCoupon setting for both legs. |
89 | | \param paymentLagOnNotionalExchanges Whether the notional exchanges are lagged by each leg's coupon payment lag (default: false). |
90 | | \param payStubIndexSelection Index selection applied to irregular coupons |
91 | | of the pay leg when it is an Ibor leg (see |
92 | | StubIndexSelection). The default prices broken |
93 | | periods off the leg's own index. |
94 | | \param recStubIndexSelection As payStubIndexSelection, for the receive leg. |
95 | | */ |
96 | | ConstNotionalCrossCurrencyBasisSwap( |
97 | | Real payNominal, Currency payCurrency, Schedule paySchedule, |
98 | | const ext::shared_ptr<IborIndex>& payIndex, Spread paySpread, Real payGearing, Real recNominal, |
99 | | Currency recCurrency, Schedule recSchedule, const ext::shared_ptr<IborIndex>& recIndex, |
100 | | Spread recSpread, Real recGearing, Integer payPaymentLag = 0, Integer recPaymentLag = 0, |
101 | | bool payCompoundSpread = false, Natural payLookbackDays = Null<Natural>(), bool payObservationShift = false, |
102 | | Natural payLockoutDays = 0, RateAveraging::Type payAveragingMethod = RateAveraging::Compound, |
103 | | bool recCompoundSpread = false, Natural recLookbackDays = Null<Natural>(), bool recObservationShift = false, |
104 | | Natural recLockoutDays = 0, RateAveraging::Type recAveragingMethod = RateAveraging::Compound, |
105 | | bool telescopicValueDates = false, |
106 | | std::optional<bool> useIndexedCoupons = std::nullopt, |
107 | | bool paymentLagOnNotionalExchanges = false, |
108 | | StubIndexSelection payStubIndexSelection = {}, |
109 | | StubIndexSelection recStubIndexSelection = {}); |
110 | | //@} |
111 | | //! \name Instrument interface |
112 | | //@{ |
113 | | void setupArguments(PricingEngine::arguments* args) const override; |
114 | | void fetchResults(const PricingEngine::results*) const override; |
115 | | //@} |
116 | | //! \name Inspectors |
117 | | //@{ |
118 | 0 | Real payNominal() const { return payNominal_; } |
119 | 0 | const Currency& payCurrency() const { return payCurrency_; } |
120 | 0 | const Schedule& paySchedule() const { return paySchedule_; } |
121 | 0 | const ext::shared_ptr<IborIndex>& payIndex() const { return payIndex_; } |
122 | 0 | Spread paySpread() const { return paySpread_; } |
123 | 0 | Real payGearing() const { return payGearing_; } |
124 | | |
125 | 0 | Real recNominal() const { return recNominal_; } |
126 | 0 | const Currency& recCurrency() const { return recCurrency_; } |
127 | 0 | const Schedule& recSchedule() const { return recSchedule_; } |
128 | 0 | const ext::shared_ptr<IborIndex>& recIndex() const { return recIndex_; } |
129 | 0 | Spread recSpread() const { return recSpread_; } |
130 | 0 | Real recGearing() const { return recGearing_; } |
131 | 0 | const StubIndexSelection& payStubIndexSelection() const { return payStubIndexSelection_; } |
132 | 0 | const StubIndexSelection& recStubIndexSelection() const { return recStubIndexSelection_; } |
133 | | //@} |
134 | | |
135 | | //! \name Additional interface |
136 | | //@{ |
137 | 0 | Spread fairPaySpread() const { |
138 | 0 | calculate(); |
139 | 0 | QL_REQUIRE(fairPaySpread_ != Null<Real>(), "Fair pay spread is not available"); |
140 | 0 | return fairPaySpread_; |
141 | 0 | } |
142 | 0 | Spread fairRecSpread() const { |
143 | 0 | calculate(); |
144 | 0 | QL_REQUIRE(fairRecSpread_ != Null<Real>(), "Fair pay spread is not available"); |
145 | 0 | return fairRecSpread_; |
146 | 0 | } |
147 | | //@} |
148 | | |
149 | | protected: |
150 | | //! \name Instrument interface |
151 | | //@{ |
152 | | void setupExpired() const override; |
153 | | //@} |
154 | | |
155 | | private: |
156 | | void initialize(); |
157 | | |
158 | | Real payNominal_; |
159 | | Currency payCurrency_; |
160 | | Schedule paySchedule_; |
161 | | ext::shared_ptr<IborIndex> payIndex_; |
162 | | Spread paySpread_; |
163 | | Real payGearing_; |
164 | | |
165 | | Real recNominal_; |
166 | | Currency recCurrency_; |
167 | | Schedule recSchedule_; |
168 | | ext::shared_ptr<IborIndex> recIndex_; |
169 | | Spread recSpread_; |
170 | | Real recGearing_; |
171 | | |
172 | | Integer payPaymentLag_; |
173 | | Integer recPaymentLag_; |
174 | | std::optional<bool> useIndexedCoupons_; |
175 | | bool paymentLagOnNotionalExchanges_; |
176 | | StubIndexSelection payStubIndexSelection_; |
177 | | StubIndexSelection recStubIndexSelection_; |
178 | | |
179 | | // OIS only |
180 | | bool payCompoundSpread_; |
181 | | Natural payLookbackDays_; |
182 | | bool payObservationShift_; |
183 | | Natural payLockoutDays_; |
184 | | RateAveraging::Type payAveragingMethod_; |
185 | | bool recCompoundSpread_; |
186 | | Natural recLookbackDays_; |
187 | | bool recObservationShift_; |
188 | | Natural recLockoutDays_; |
189 | | RateAveraging::Type recAveragingMethod_; |
190 | | bool telescopicValueDates_; |
191 | | |
192 | | mutable Spread fairPaySpread_; |
193 | | mutable Spread fairRecSpread_; |
194 | | }; |
195 | | |
196 | | |
197 | | class ConstNotionalCrossCurrencyBasisSwap::arguments : public ConstNotionalCrossCurrencySwap::arguments { |
198 | | public: |
199 | | Spread paySpread; |
200 | | Spread recSpread; |
201 | | void validate() const override; |
202 | | }; |
203 | | |
204 | | |
205 | | class ConstNotionalCrossCurrencyBasisSwap::results : public ConstNotionalCrossCurrencySwap::results { |
206 | | public: |
207 | | Spread fairPaySpread; |
208 | | Spread fairRecSpread; |
209 | | void reset() override; |
210 | | }; |
211 | | |
212 | | } |
213 | | |
214 | | #endif |