Coverage Report

Created: 2026-09-28 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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