• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lballabio / QuantLib / 8467932009

28 Mar 2024 01:18PM UTC coverage: 72.497% (+0.07%) from 72.426%
8467932009

Pull #1593

github

web-flow
Merge 9b4efa33c into d6f6c13a5
Pull Request #1593: allow swaptions to take OvernightIndexedSwap

103 of 127 new or added lines in 13 files covered. (81.1%)

373 existing lines in 21 files now uncovered.

54966 of 75818 relevant lines covered (72.5%)

8708317.57 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/ql/instruments/bonds/btp.cpp
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
 <http://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
#include <ql/instruments/bonds/btp.hpp>
21
#include <ql/instruments/makevanillaswap.hpp>
22
#include <ql/pricingengines/bond/bondfunctions.hpp>
23
#include <ql/time/calendars/nullcalendar.hpp>
24
#include <ql/time/calendars/target.hpp>
25
#include <ql/time/daycounters/actual360.hpp>
26
#include <ql/time/daycounters/actualactual.hpp>
27
#include <ql/time/schedule.hpp>
28
#include <ql/utilities/dataformatters.hpp>
29
#include <utility>
30

31
namespace QuantLib {
32

33
    CCTEU::CCTEU(const Date& maturityDate,
×
34
                 Spread spread,
35
                 const Handle<YieldTermStructure>& fwdCurve,
36
                 const Date& startDate,
37
                 const Date& issueDate)
×
38
    : FloatingRateBond(2, 100.0,
39
                       Schedule(startDate,
×
40
                                maturityDate, 6*Months,
×
41
                                NullCalendar(), Unadjusted, Unadjusted,
×
42
                                DateGeneration::Backward, true),
43
                       ext::make_shared<Euribor6M>(fwdCurve),
×
44
                       Actual360(),
×
45
                       Following,
46
                       Euribor6M().fixingDays(),
×
47
                       std::vector<Real>(1, 1.0), // gearing
×
48
                       std::vector<Spread>(1, spread),
×
49
                       std::vector<Rate>(), // caps
×
50
                       std::vector<Rate>(), // floors
×
51
                       false, // in arrears
52
                       100.0, // redemption
53
                       issueDate) {}
×
54

55
    BTP::BTP(const Date& maturityDate,
×
56
             Rate fixedRate,
57
             const Date& startDate,
58
             const Date& issueDate)
×
59
    : FixedRateBond(2, 100.0,
60
                    Schedule(startDate,
×
61
                             maturityDate, 6*Months,
×
62
                             NullCalendar(), Unadjusted, Unadjusted,
×
63
                             DateGeneration::Backward, true),
64
                    std::vector<Rate>(1, fixedRate),
×
65
                    ActualActual(ActualActual::ISMA),
×
66
                    ModifiedFollowing, 100.0, issueDate, TARGET()) {}
×
67

68
    BTP::BTP(const Date& maturityDate,
×
69
             Rate fixedRate,
70
             Real redemption,
71
             const Date& startDate,
72
             const Date& issueDate)
×
73
    : FixedRateBond(2, 100.0,
74
                    Schedule(startDate,
×
75
                             maturityDate, 6*Months,
×
76
                             NullCalendar(), Unadjusted, Unadjusted,
×
77
                             DateGeneration::Backward, true),
78
                    std::vector<Rate>(1, fixedRate),
×
79
                    ActualActual(ActualActual::ISMA),
×
80
                    ModifiedFollowing, redemption, issueDate, TARGET()) {}
×
81

82
    Rate BTP::yield(Real cleanPrice,
×
83
                    Date settlementDate,
84
                    Real accuracy,
85
                    Size maxEvaluations) const {
86
        return Bond::yield({cleanPrice, Bond::Price::Clean},
×
UNCOV
87
                           ActualActual(ActualActual::ISMA), Compounded, Annual, settlementDate,
×
88
                           accuracy, maxEvaluations);
×
89
    }
90

91

92
    RendistatoBasket::RendistatoBasket(const std::vector<ext::shared_ptr<BTP> >& btps,
×
93
                                       const std::vector<Real>& outstandings,
94
                                       std::vector<Handle<Quote> > cleanPriceQuotes)
×
95
    : btps_(btps), outstandings_(outstandings), quotes_(std::move(cleanPriceQuotes)) {
×
96

97
        QL_REQUIRE(!btps_.empty(), "empty RendistatoCalculator Basket");
×
98
        Size k = btps_.size();
99

100
        QL_REQUIRE(outstandings_.size()==k,
×
101
                   "mismatch between number of BTPs (" << k <<
102
                   ") and number of outstandings (" <<
103
                   outstandings_.size() << ")");
104
        QL_REQUIRE(quotes_.size()==k,
×
105
                   "mismatch between number of BTPs (" << k <<
106
                   ") and number of clean prices quotes (" <<
107
                   quotes_.size() << ")");
108

109
        // require non-negative outstanding
110
        for (Size i=0; i<k; ++i) {
×
111
            QL_REQUIRE(outstandings[i]>=0,
×
112
                       "negative outstanding for " << io::ordinal(i) <<
113
                       " bond, maturity " << btps[i]->maturityDate());
114
            // add check for prices ??
115
        }
116

117
        // TODO: filter out expired bonds, zero outstanding bond, etc
118

119
        QL_REQUIRE(!btps_.empty(), "invalid bonds only in RendistatoCalculator Basket");
120
        n_ = btps_.size();
×
121

122
        outstanding_ = 0.0;
×
123
        for (Size i=0; i<n_; ++i)
×
124
            outstanding_ += outstandings[i];
×
125

126
        weights_.resize(n_);
×
127
        for (Size i=0; i<n_; ++i) {
×
128
            weights_[i] = outstandings[i]/outstanding_;
×
129
            registerWith(quotes_[i]);
×
130
        }
131
    }
×
132

133

134
    RendistatoCalculator::RendistatoCalculator(ext::shared_ptr<RendistatoBasket> basket,
×
135
                                               ext::shared_ptr<Euribor> euriborIndex,
136
                                               Handle<YieldTermStructure> discountCurve)
×
137
    : basket_(std::move(basket)), euriborIndex_(std::move(euriborIndex)),
×
138
      discountCurve_(std::move(discountCurve)), yields_(basket_->size(), 0.05),
×
139
      durations_(basket_->size()),
×
140
      // TODO: generalize number of swaps and their lengths
141
      swaps_(nSwaps_), swapLengths_(nSwaps_), swapBondDurations_(nSwaps_, Null<Time>()),
×
142
      swapBondYields_(nSwaps_, 0.05), swapRates_(nSwaps_, Null<Rate>()) {
×
143
        registerWith(basket_);
×
144
        registerWith(euriborIndex_);
×
145
        registerWith(discountCurve_);
×
146

147
        Rate dummyRate = 0.05;
148
        for (Size i=0; i<nSwaps_; ++i) {
×
149
            swapLengths_[i] = static_cast<Real>(i+1);
×
150
            swaps_[i] = MakeVanillaSwap(
×
151
                swapLengths_[i]*Years, euriborIndex_, dummyRate, 1*Days)
×
152
                                .withDiscountingTermStructure(discountCurve_);
×
153
        }
154
    }
×
155

156
    void RendistatoCalculator::performCalculations() const {
×
157

158
        const std::vector<ext::shared_ptr<BTP> >& btps = basket_->btps();
×
159
        const std::vector<Handle<Quote> >& quotes = basket_->cleanPriceQuotes();
×
160
        Date bondSettlementDate = btps[0]->settlementDate();
×
161
        for (Size i=0; i<basket_->size(); ++i) {
×
162
            yields_[i] = BondFunctions::yield(
×
163
                *btps[i], {quotes[i]->value(), Bond::Price::Clean},
×
164
                ActualActual(ActualActual::ISMA), Compounded, Annual, bondSettlementDate,
×
165
                // accuracy, maxIterations, guess
166
                1.0e-10, 100, yields_[i]);
UNCOV
167
            durations_[i] = BondFunctions::duration(
×
168
                *btps[i], yields_[i],
×
169
                ActualActual(ActualActual::ISMA), Compounded, Annual,
×
170
                Duration::Modified, bondSettlementDate);
171
        }
UNCOV
172
        duration_ = std::inner_product(basket_->weights().begin(),
×
173
                                       basket_->weights().end(),
×
174
                                       durations_.begin(), Real(0.0));
175

176
        Natural settlDays = 2;
UNCOV
177
        DayCounter fixedDayCount = swaps_[0]->fixedDayCount();
×
178
        equivalentSwapIndex_ = nSwaps_-1;
×
179
        swapRates_[0]= swaps_[0]->fairRate();
×
180
        FixedRateBond swapBond(settlDays,
181
                               100.0,      // faceAmount
UNCOV
182
                               swaps_[0]->fixedSchedule(),
×
183
                               std::vector<Rate>(1, swapRates_[0]),
×
184
                               fixedDayCount,
185
                               Following, // paymentConvention
UNCOV
186
                               100.0);    // redemption
×
187
        swapBondYields_[0] = BondFunctions::yield(swapBond,
×
188
            {100.0, Bond::Price::Clean}, // floating leg NPV including end payment
UNCOV
189
            ActualActual(ActualActual::ISMA), Compounded, Annual,
×
190
            bondSettlementDate,
191
            // accuracy, maxIterations, guess
192
            1.0e-10, 100, swapBondYields_[0]);
UNCOV
193
        swapBondDurations_[0] = BondFunctions::duration(
×
194
            swapBond, swapBondYields_[0],
UNCOV
195
            ActualActual(ActualActual::ISMA), Compounded, Annual,
×
196
            Duration::Modified, bondSettlementDate);
UNCOV
197
        for (Size i=1; i<nSwaps_; ++i) {
×
198
            swapRates_[i]= swaps_[i]->fairRate();
×
199
            FixedRateBond swapBond(settlDays,
200
                                   100.0,      // faceAmount
UNCOV
201
                                   swaps_[i]->fixedSchedule(),
×
202
                                   std::vector<Rate>(1, swapRates_[i]),
×
203
                                   fixedDayCount,
204
                                   Following, // paymentConvention
UNCOV
205
                                   100.0);    // redemption
×
206
            swapBondYields_[i] = BondFunctions::yield(swapBond,
×
207
                {100.0, Bond::Price::Clean}, // floating leg NPV including end payment
UNCOV
208
                ActualActual(ActualActual::ISMA), Compounded, Annual,
×
209
                bondSettlementDate,
210
                // accuracy, maxIterations, guess
211
                1.0e-10, 100, swapBondYields_[i]);
UNCOV
212
            swapBondDurations_[i] = BondFunctions::duration(
×
213
                swapBond, swapBondYields_[i],
UNCOV
214
                ActualActual(ActualActual::ISMA), Compounded, Annual,
×
215
                Duration::Modified, bondSettlementDate);
UNCOV
216
            if (swapBondDurations_[i] > duration_) {
×
217
                equivalentSwapIndex_ = i-1;
×
218
                break; // exit the loop
219
            }
UNCOV
220
        }
×
221
    }
×
222

UNCOV
223
    RendistatoEquivalentSwapLengthQuote::RendistatoEquivalentSwapLengthQuote(
×
224
        ext::shared_ptr<RendistatoCalculator> r)
×
225
    : r_(std::move(r)) {}
×
226

UNCOV
227
    bool RendistatoEquivalentSwapLengthQuote::isValid() const {
×
228
        try {
UNCOV
229
            value();
×
230
            return true;
UNCOV
231
        } catch (...) {
×
232
            return false;
UNCOV
233
        }
×
234
    }
235

UNCOV
236
    RendistatoEquivalentSwapSpreadQuote::RendistatoEquivalentSwapSpreadQuote(
×
237
        ext::shared_ptr<RendistatoCalculator> r)
×
238
    : r_(std::move(r)) {}
×
239

UNCOV
240
    bool RendistatoEquivalentSwapSpreadQuote::isValid() const {
×
241
        try {
UNCOV
242
            value();
×
243
            return true;
UNCOV
244
        } catch (...) {
×
245
            return false;
UNCOV
246
        }
×
247
    }
248
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc