Coverage Report

Created: 2025-10-14 06:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/instruments/bonds/btp.hpp
Line
Count
Source
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2010, 2011 Ferdinando Ametrano
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 btp.hpp
21
    \brief Italian BTP (Buoni Poliennali del Tesoro) fixed rate bond
22
*/
23
24
#ifndef quantlib_btp_hpp
25
#define quantlib_btp_hpp
26
27
#include <ql/instruments/bonds/fixedratebond.hpp>
28
#include <ql/instruments/bonds/floatingratebond.hpp>
29
#include <ql/indexes/ibor/euribor.hpp>
30
#include <ql/instruments/vanillaswap.hpp>
31
32
#include <numeric>
33
34
namespace QuantLib {
35
36
    /*! Italian CCTEU (Certificato di credito del tesoro)
37
        Euribor6M indexed floating rate bond
38
    
39
        \ingroup instruments
40
41
    */
42
    class CCTEU : public FloatingRateBond {
43
      public:
44
        CCTEU(const Date& maturityDate,
45
              Spread spread,
46
              const Handle<YieldTermStructure>& fwdCurve =
47
                                    Handle<YieldTermStructure>(),
48
              const Date& startDate = Date(),
49
              const Date& issueDate = Date());
50
        //! \name Bond interface
51
        //@{
52
        //! accrued amount at a given date
53
        /*! The default bond settlement is used if no date is given. */
54
        Real accruedAmount(Date d = Date()) const override;
55
        //@}
56
    };
57
58
    //! Italian BTP (Buono Poliennali del Tesoro) fixed rate bond
59
    /*! \ingroup instruments
60
61
    */
62
    class BTP : public FixedRateBond {
63
      public:
64
        BTP(const Date& maturityDate,
65
            Rate fixedRate,
66
            const Date& startDate = Date(),
67
            const Date& issueDate = Date());
68
        /*! constructor needed for legacy non-par redemption BTPs.
69
            As of today the only remaining one is IT123456789012
70
            that will redeem 99.999 on xx-may-2037 */
71
        BTP(const Date& maturityDate,
72
            Rate fixedRate,
73
            Real redemption,
74
            const Date& startDate = Date(),
75
            const Date& issueDate = Date());
76
        //! \name Bond interface
77
        //@{
78
        //! accrued amount at a given date
79
        /*! The default bond settlement is used if no date is given. */
80
        Real accruedAmount(Date d = Date()) const override;
81
        //@}
82
        //! BTP yield given a (clean) price and settlement date
83
        /*! The default BTP conventions are used: Actual/Actual (ISMA),
84
            Compounded, Annual.
85
            The default bond settlement is used if no date is given. */
86
        Rate yield(Real cleanPrice,
87
                   Date settlementDate = Date(),
88
                   Real accuracy = 1.0e-8,
89
                   Size maxEvaluations = 100) const;
90
    };
91
92
    class RendistatoBasket : public Observer,
93
                             public Observable {
94
      public:
95
        RendistatoBasket(const std::vector<ext::shared_ptr<BTP> >& btps,
96
                         const std::vector<Real>& outstandings,
97
                         std::vector<Handle<Quote> > cleanPriceQuotes);
98
        //! \name Inspectors
99
        //@{
100
0
        Size size() const { return n_;}
101
        const std::vector<ext::shared_ptr<BTP> >& btps() const;
102
        const std::vector<Handle<Quote> >& cleanPriceQuotes() const;
103
0
        const std::vector<Real>& outstandings() const { return outstandings_;}
104
0
        const std::vector<Real>& weights() const { return weights_;}
105
0
        Real outstanding() const { return outstanding_;}
106
        //@}
107
        //! \name Observer interface
108
        //@{
109
0
        void update() override { notifyObservers(); }
110
        //@}
111
      private:
112
        std::vector<ext::shared_ptr<BTP> > btps_;
113
        std::vector<Real> outstandings_;
114
        std::vector<Handle<Quote> > quotes_;
115
        Real outstanding_;
116
        Size n_;
117
        std::vector<Real> weights_;
118
    };
119
120
    class RendistatoCalculator : public LazyObject {
121
      public:
122
        RendistatoCalculator(ext::shared_ptr<RendistatoBasket> basket,
123
                             ext::shared_ptr<Euribor> euriborIndex,
124
                             Handle<YieldTermStructure> discountCurve);
125
        //! \name Calculations
126
        //@{
127
        Rate yield() const;
128
        Time duration() const;
129
        // bonds
130
        const std::vector<Rate>& yields() const;
131
        const std::vector<Time>& durations() const;
132
        // swaps
133
        const std::vector<Time>& swapLengths() const;
134
        const std::vector<Rate>& swapRates() const;
135
        const std::vector<Rate>& swapYields() const;
136
        const std::vector<Time>& swapDurations() const;
137
        //@}
138
        //! \name Equivalent Swap proxy
139
        //@{
140
        ext::shared_ptr<VanillaSwap> equivalentSwap() const;
141
        Rate equivalentSwapRate() const;
142
        Rate equivalentSwapYield() const;
143
        Time equivalentSwapDuration() const;
144
        Time equivalentSwapLength() const;
145
        Spread equivalentSwapSpread() const;
146
        //@}
147
      protected:
148
        //! \name LazyObject interface
149
        //@{
150
        void performCalculations() const override;
151
        //@}
152
      private:
153
        ext::shared_ptr<RendistatoBasket> basket_;
154
        ext::shared_ptr<Euribor> euriborIndex_;
155
        Handle<YieldTermStructure> discountCurve_;
156
157
        mutable std::vector<Rate> yields_;
158
        mutable std::vector<Time> durations_;
159
        mutable Time duration_;
160
        mutable Size equivalentSwapIndex_;
161
162
        Size nSwaps_ = 15;
163
        mutable std::vector<ext::shared_ptr<VanillaSwap> > swaps_;
164
        std::vector<Time> swapLengths_;
165
        mutable std::vector<Time> swapBondDurations_;
166
        mutable std::vector<Rate> swapBondYields_, swapRates_;
167
    };
168
169
    //! RendistatoCalculator equivalent swap lenth Quote adapter
170
    class RendistatoEquivalentSwapLengthQuote : public Quote {
171
      public:
172
        RendistatoEquivalentSwapLengthQuote(ext::shared_ptr<RendistatoCalculator> r);
173
        Real value() const override;
174
        bool isValid() const override;
175
176
      private:
177
        ext::shared_ptr<RendistatoCalculator> r_;
178
    };
179
180
    //! RendistatoCalculator equivalent swap spread Quote adapter
181
    class RendistatoEquivalentSwapSpreadQuote : public Quote {
182
      public:
183
        RendistatoEquivalentSwapSpreadQuote(ext::shared_ptr<RendistatoCalculator> r);
184
        Real value() const override;
185
        bool isValid() const override;
186
187
      private:
188
        ext::shared_ptr<RendistatoCalculator> r_;
189
    };
190
191
    // inline
192
193
0
    inline Real CCTEU::accruedAmount(Date d) const {
194
0
        Real result = FloatingRateBond::accruedAmount(d);
195
0
        return ClosestRounding(5)(result);
196
0
    }
197
198
0
    inline Real BTP::accruedAmount(Date d) const {
199
0
        Real result = FixedRateBond::accruedAmount(d);
200
0
        return ClosestRounding(5)(result);
201
0
    }
202
203
    inline const std::vector<ext::shared_ptr<BTP> >&
204
0
    RendistatoBasket::btps() const {
205
0
        return btps_;
206
0
    }
207
208
    inline const std::vector<Handle<Quote> >&
209
0
    RendistatoBasket::cleanPriceQuotes() const {
210
0
        return quotes_;
211
0
    }
212
213
0
    inline Rate RendistatoCalculator::yield() const {
214
0
        return std::inner_product(basket_->weights().begin(),
215
0
                                  basket_->weights().end(),
216
0
                                  yields().begin(), Real(0.0));
217
0
    }
218
219
0
    inline Time RendistatoCalculator::duration() const {
220
0
        calculate();
221
0
        return duration_;
222
0
    }
223
224
0
    inline const std::vector<Rate>& RendistatoCalculator::yields() const {
225
0
        calculate();
226
0
        return yields_;
227
0
    }
228
229
0
    inline const std::vector<Time>& RendistatoCalculator::durations() const {
230
0
        calculate();
231
0
        return durations_;
232
0
    }
233
234
0
    inline const std::vector<Time>& RendistatoCalculator::swapLengths() const {
235
0
        return swapLengths_;
236
0
    }
237
238
0
    inline const std::vector<Rate>& RendistatoCalculator::swapRates() const {
239
0
        calculate();
240
0
        return swapRates_;
241
0
    }
242
243
0
    inline const std::vector<Rate>& RendistatoCalculator::swapYields() const {
244
0
        calculate();
245
0
        return swapBondYields_;
246
0
    }
247
248
0
    inline const std::vector<Time>& RendistatoCalculator::swapDurations() const {
249
0
        calculate();
250
0
        return swapBondDurations_;
251
0
    }
252
253
    inline ext::shared_ptr<VanillaSwap>
254
0
    RendistatoCalculator::equivalentSwap() const {
255
0
        calculate();
256
0
        return swaps_[equivalentSwapIndex_];
257
0
    }
258
259
0
    inline Rate RendistatoCalculator::equivalentSwapRate() const {
260
0
        calculate();
261
0
        return swapRates_[equivalentSwapIndex_];
262
0
    }
263
264
0
    inline Rate RendistatoCalculator::equivalentSwapYield() const {
265
0
        calculate();
266
0
        return swapBondYields_[equivalentSwapIndex_];
267
0
    }
268
269
0
    inline Time RendistatoCalculator::equivalentSwapDuration() const {
270
0
        calculate();
271
0
        return swapBondDurations_[equivalentSwapIndex_];
272
0
    }
273
274
0
    inline Time RendistatoCalculator::equivalentSwapLength() const {
275
0
        calculate();
276
0
        return swapLengths_[equivalentSwapIndex_];
277
0
    }
278
279
0
    inline Spread RendistatoCalculator::equivalentSwapSpread() const {
280
0
        return yield() - equivalentSwapRate();
281
0
    }
282
283
0
    inline Real RendistatoEquivalentSwapLengthQuote::value() const {
284
0
        return r_->equivalentSwapLength();
285
0
    }
286
287
0
    inline Real RendistatoEquivalentSwapSpreadQuote::value() const {
288
0
        return r_->equivalentSwapSpread();
289
0
    }
290
291
}
292
293
#endif