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

lballabio / QuantLib / 23014668432

12 Mar 2026 05:17PM UTC coverage: 74.223% (-0.04%) from 74.259%
23014668432

Pull #2368

github

web-flow
Merge 859f97bcc into 0a02cced0
Pull Request #2368: Fx options utils - `BlackVolatilitySurfaceDelta` class

113 of 195 new or added lines in 5 files covered. (57.95%)

220 existing lines in 21 files now uncovered.

57858 of 77952 relevant lines covered (74.22%)

8737358.76 hits per line

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

61.26
/ql/instruments/makevanillaswap.cpp
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2

3
/*
4
 Copyright (C) 2006, 2007, 2010, 2014, 2015 Ferdinando Ametrano
5
 Copyright (C) 2006 Katiuscia Manzoni
6
 Copyright (C) 2006 StatPro Italia srl
7
 Copyright (C) 2015 Paolo Mazzocchi
8
 Copyright (C) 2018 Matthias Groncki
9

10
 This file is part of QuantLib, a free-software/open-source library
11
 for financial quantitative analysts and developers - http://quantlib.org/
12

13
 QuantLib is free software: you can redistribute it and/or modify it
14
 under the terms of the QuantLib license.  You should have received a
15
 copy of the license along with this program; if not, please email
16
 <quantlib-dev@lists.sf.net>. The license is also available online at
17
 <https://www.quantlib.org/license.shtml>.
18

19
 This program is distributed in the hope that it will be useful, but WITHOUT
20
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
21
 FOR A PARTICULAR PURPOSE.  See the license for more details.
22
*/
23

24
#include <ql/instruments/makevanillaswap.hpp>
25
#include <ql/pricingengines/swap/discountingswapengine.hpp>
26
#include <ql/time/daycounters/thirty360.hpp>
27
#include <ql/time/daycounters/actual360.hpp>
28
#include <ql/time/daycounters/actual365fixed.hpp>
29
#include <ql/indexes/iborindex.hpp>
30
#include <ql/time/schedule.hpp>
31
#include <ql/currencies/america.hpp>
32
#include <ql/currencies/asia.hpp>
33
#include <ql/currencies/europe.hpp>
34
#include <ql/currencies/oceania.hpp>
35
#include <ql/utilities/null.hpp>
36
#include <ql/optional.hpp>
37

38
namespace QuantLib {
39

40
    MakeVanillaSwap::MakeVanillaSwap(const Period& swapTenor,
36,223✔
41
                                     const ext::shared_ptr<IborIndex>& index,
42
                                     Rate fixedRate,
43
                                     const Period& forwardStart)
36,223✔
44
    : swapTenor_(swapTenor), iborIndex_(index), fixedRate_(fixedRate), forwardStart_(forwardStart),
36,223✔
45
      fixedCalendar_(index->fixingCalendar()), floatCalendar_(index->fixingCalendar()),
36,223✔
46
      floatTenor_(index->tenor()),
36,223✔
47
      floatConvention_(index->businessDayConvention()),
72,446✔
48
      floatTerminationDateConvention_(index->businessDayConvention()),
36,223✔
49

50
      floatDayCount_(index->dayCounter()) {}
144,892✔
51

52
    MakeVanillaSwap::operator VanillaSwap() const {
8,053✔
53
        ext::shared_ptr<VanillaSwap> swap = *this;
8,053✔
54
        return *swap;
16,106✔
55
    }
56

57
    MakeVanillaSwap::operator ext::shared_ptr<VanillaSwap>() const {
36,223✔
58

59
        Date startDate;
36,223✔
60
        if (effectiveDate_ != Date())
36,223✔
61
            startDate = effectiveDate_;
26,964✔
62
        else {
63
            Date refDate = Settings::instance().evaluationDate();
9,259✔
64
            // if the evaluation date is not a business day
65
            // then move to the next business day
66
            refDate = floatCalendar_.adjust(refDate);
9,259✔
67
            // use index valueDate interface wherever possible to estimate spot date.
68
            // Unless we pass an explicit settlementDays_ which does not match the index-defined number of fixing days.
69
            Date spotDate;
9,259✔
70
            if (settlementDays_ == Null<Natural>())
9,259✔
71
                spotDate = iborIndex_->valueDate(refDate);
9,234✔
72
            else
73
                spotDate = floatCalendar_.advance(refDate, settlementDays_ * Days);
25✔
74
            startDate = spotDate+forwardStart_;
9,259✔
75
            if (forwardStart_.length()<0)
9,259✔
76
                startDate = floatCalendar_.adjust(startDate,
×
77
                                                  Preceding);
78
            else if (forwardStart_.length()>0)
9,259✔
79
                startDate = floatCalendar_.adjust(startDate,
×
80
                                                  Following);
81
            // no explicit date adjustment needed for forwardStart_.length()==0 (already handled by spotDate arithmetic above)
82
        }
83

84
        Date endDate = terminationDate_;
36,223✔
85
        if (endDate == Date()) {
36,223✔
86
            endDate = startDate + swapTenor_;
33,693✔
87
            bool maturityEndOfMonth =
88
                maturityEndOfMonth_ ? *maturityEndOfMonth_ : floatEndOfMonth_;
33,693✔
89
            if (maturityEndOfMonth && allowsEndOfMonth(swapTenor_) &&
33,693✔
UNCOV
90
                floatCalendar_.isEndOfMonth(startDate))
×
UNCOV
91
                endDate = floatCalendar_.endOfMonth(endDate);
×
92
        }
93

94
        const Currency& curr = iborIndex_->currency();
36,223✔
95
        Period fixedTenor;
36,223✔
96
        if (fixedTenor_ != Period())
36,223✔
97
            fixedTenor = fixedTenor_;
33,127✔
98
        else {
99
            if ((curr == EURCurrency()) ||
6,192✔
100
                (curr == USDCurrency()) ||
3,096✔
101
                (curr == CHFCurrency()) ||
3,096✔
102
                (curr == SEKCurrency()) ||
6,192✔
103
                (curr == GBPCurrency() && swapTenor_ <= 1 * Years))
3,096✔
104
                fixedTenor = Period(1, Years);
3,096✔
UNCOV
105
            else if ((curr == GBPCurrency() && swapTenor_ > 1 * Years) ||
×
106
                (curr == JPYCurrency()) ||
×
107
                (curr == AUDCurrency() && swapTenor_ >= 4 * Years))
×
108
                fixedTenor = Period(6, Months);
×
109
            else if ((curr == HKDCurrency() ||
×
110
                     (curr == AUDCurrency() && swapTenor_ < 4 * Years)))
×
111
                fixedTenor = Period(3, Months);
×
112
            else
UNCOV
113
                QL_FAIL("unknown fixed leg default tenor for " << curr);
×
114
        }
115

116
        Schedule fixedSchedule(startDate, endDate,
117
                               fixedTenor, fixedCalendar_,
118
                               fixedConvention_,
36,223✔
119
                               fixedTerminationDateConvention_,
36,223✔
120
                               fixedRule_, fixedEndOfMonth_,
36,223✔
121
                               fixedFirstDate_, fixedNextToLastDate_);
36,223✔
122

123
        Schedule floatSchedule(startDate, endDate,
124
                               floatTenor_, floatCalendar_,
36,223✔
125
                               floatConvention_,
36,223✔
126
                               floatTerminationDateConvention_,
36,223✔
127
                               floatRule_, floatEndOfMonth_,
36,223✔
128
                               floatFirstDate_, floatNextToLastDate_);
36,223✔
129

130
        DayCounter fixedDayCount;
36,223✔
131
        if (fixedDayCount_ != DayCounter())
72,446✔
132
            fixedDayCount = fixedDayCount_;
133
        else {
134
            if (curr == USDCurrency())
6,192✔
UNCOV
135
                fixedDayCount = Actual360();
×
136
            else if (curr == EURCurrency() || curr == CHFCurrency() ||
9,288✔
137
                     curr == SEKCurrency())
3,096✔
138
                fixedDayCount = Thirty360(Thirty360::BondBasis);
6,192✔
UNCOV
139
            else if (curr == GBPCurrency() || curr == JPYCurrency() ||
×
140
                     curr == AUDCurrency() || curr == HKDCurrency() ||
×
141
                     curr == THBCurrency())
×
142
                fixedDayCount = Actual365Fixed();
×
143
            else
UNCOV
144
                QL_FAIL("unknown fixed leg day counter for " << curr);
×
145
        }
146

147
        Rate usedFixedRate = fixedRate_;
36,223✔
148
        if (fixedRate_ == Null<Rate>()) {
36,223✔
UNCOV
149
            VanillaSwap temp(type_, 100.00, fixedSchedule,
×
150
                             0.0, // fixed rate
UNCOV
151
                             fixedDayCount, floatSchedule, iborIndex_, floatSpread_, floatDayCount_,
×
152
                             paymentConvention_, useIndexedCoupons_);
×
153
            if (engine_ == nullptr) {
×
154
                Handle<YieldTermStructure> disc =
UNCOV
155
                                        iborIndex_->forwardingTermStructure();
×
156
                QL_REQUIRE(!disc.empty(),
×
157
                           "null term structure set to this instance of " <<
158
                           iborIndex_->name());
159
                bool includeSettlementDateFlows = false;
160
                ext::shared_ptr<PricingEngine> engine(new
UNCOV
161
                    DiscountingSwapEngine(disc, includeSettlementDateFlows));
×
162
                temp.setPricingEngine(engine);
×
163
            } else
UNCOV
164
                temp.setPricingEngine(engine_);
×
165

UNCOV
166
            usedFixedRate = temp.fairRate();
×
167
        }
×
168

169
        ext::shared_ptr<VanillaSwap> swap(new VanillaSwap(
170
            type_, nominal_, fixedSchedule, usedFixedRate, fixedDayCount, floatSchedule, iborIndex_,
36,223✔
171
            floatSpread_, floatDayCount_, paymentConvention_, useIndexedCoupons_));
108,669✔
172

173
        if (engine_ == nullptr) {
36,223✔
174
            Handle<YieldTermStructure> disc =
175
                                    iborIndex_->forwardingTermStructure();
31,751✔
176
            bool includeSettlementDateFlows = false;
177
            ext::shared_ptr<PricingEngine> engine(new
178
                DiscountingSwapEngine(disc, includeSettlementDateFlows));
31,751✔
179
            swap->setPricingEngine(engine);
31,751✔
180
        } else
181
            swap->setPricingEngine(engine_);
4,472✔
182

183
        return swap;
36,223✔
184
    }
36,223✔
185

186
    MakeVanillaSwap& MakeVanillaSwap::receiveFixed(bool flag) {
561✔
187
        type_ = flag ? Swap::Receiver : Swap::Payer ;
561✔
188
        return *this;
561✔
189
    }
190

191
    MakeVanillaSwap& MakeVanillaSwap::withType(Swap::Type type) {
11,382✔
192
        type_ = type;
11,382✔
193
        return *this;
11,382✔
194
    }
195

196
    MakeVanillaSwap& MakeVanillaSwap::withNominal(Real n) {
2,645✔
197
        nominal_ = n;
2,645✔
198
        return *this;
2,645✔
199
    }
200

201
    MakeVanillaSwap& MakeVanillaSwap::withSettlementDays(Natural settlementDays) {
1,418✔
202
        settlementDays_ = settlementDays;
1,418✔
203
        effectiveDate_ = Date();
1,418✔
204
        return *this;
1,418✔
205
    }
206

207
    MakeVanillaSwap&
208
    MakeVanillaSwap::withEffectiveDate(const Date& effectiveDate) {
28,352✔
209
        effectiveDate_ = effectiveDate;
28,352✔
210
        return *this;
28,352✔
211
    }
212

213
    MakeVanillaSwap&
214
    MakeVanillaSwap::withTerminationDate(const Date& terminationDate) {
3,918✔
215
        terminationDate_ = terminationDate;
3,918✔
216
        if (terminationDate != Date())
3,918✔
217
            swapTenor_ = Period();
2,530✔
218
        return *this;
3,918✔
219
    }
220

UNCOV
221
    MakeVanillaSwap& MakeVanillaSwap::withRule(DateGeneration::Rule r) {
×
222
        fixedRule_ = r;
×
223
        floatRule_ = r;
×
224
        return *this;
×
225
    }
226

UNCOV
227
    MakeVanillaSwap& MakeVanillaSwap::withPaymentConvention(BusinessDayConvention bdc) {
×
228
        paymentConvention_ = bdc;
×
229
        return *this;
×
230
    }
231

232
    MakeVanillaSwap& MakeVanillaSwap::withDiscountingTermStructure(
4,472✔
233
                                        const Handle<YieldTermStructure>& d) {
234
        bool includeSettlementDateFlows = false;
235
        engine_ = ext::shared_ptr<PricingEngine>(new
13,416✔
236
            DiscountingSwapEngine(d, includeSettlementDateFlows));
8,944✔
237
        return *this;
4,472✔
238
    }
239

UNCOV
240
    MakeVanillaSwap& MakeVanillaSwap::withPricingEngine(
×
241
                             const ext::shared_ptr<PricingEngine>& engine) {
UNCOV
242
        engine_ = engine;
×
243
        return *this;
×
244
    }
245

246
    MakeVanillaSwap& MakeVanillaSwap::withFixedLegTenor(const Period& t) {
33,127✔
247
        fixedTenor_ = t;
33,127✔
248
        return *this;
33,127✔
249
    }
250

251
    MakeVanillaSwap&
252
    MakeVanillaSwap::withFixedLegCalendar(const Calendar& cal) {
16,357✔
253
        fixedCalendar_ = cal;
254
        return *this;
16,357✔
255
    }
256

257
    MakeVanillaSwap&
258
    MakeVanillaSwap::withFixedLegConvention(BusinessDayConvention bdc) {
16,549✔
259
        fixedConvention_ = bdc;
16,549✔
260
        return *this;
16,549✔
261
    }
262

263
    MakeVanillaSwap&
264
    MakeVanillaSwap::withFixedLegTerminationDateConvention(BusinessDayConvention bdc) {
16,543✔
265
        fixedTerminationDateConvention_ = bdc;
16,543✔
266
        return *this;
16,543✔
267
    }
268

UNCOV
269
    MakeVanillaSwap& MakeVanillaSwap::withFixedLegRule(DateGeneration::Rule r) {
×
270
        fixedRule_ = r;
×
271
        return *this;
×
272
    }
273

274
    MakeVanillaSwap& MakeVanillaSwap::withFixedLegEndOfMonth(bool flag) {
1,393✔
275
        fixedEndOfMonth_ = flag;
1,393✔
276
        return *this;
1,393✔
277
    }
278

UNCOV
279
    MakeVanillaSwap& MakeVanillaSwap::withFixedLegFirstDate(const Date& d) {
×
280
        fixedFirstDate_ = d;
×
281
        return *this;
×
282
    }
283

284
    MakeVanillaSwap&
UNCOV
285
    MakeVanillaSwap::withFixedLegNextToLastDate(const Date& d) {
×
286
        fixedNextToLastDate_ = d;
×
287
        return *this;
×
288
    }
289

290
    MakeVanillaSwap&
291
    MakeVanillaSwap::withFixedLegDayCount(const DayCounter& dc) {
33,127✔
292
        fixedDayCount_ = dc;
293
        return *this;
33,127✔
294
    }
295

UNCOV
296
    MakeVanillaSwap& MakeVanillaSwap::withFloatingLegTenor(const Period& t) {
×
297
        floatTenor_ = t;
×
298
        return *this;
×
299
    }
300

301
    MakeVanillaSwap&
302
    MakeVanillaSwap::withFloatingLegCalendar(const Calendar& cal) {
1,414✔
303
        floatCalendar_ = cal;
304
        return *this;
1,414✔
305
    }
306

307
    MakeVanillaSwap&
UNCOV
308
    MakeVanillaSwap::withFloatingLegConvention(BusinessDayConvention bdc) {
×
309
        floatConvention_ = bdc;
×
310
        return *this;
×
311
    }
312

313
    MakeVanillaSwap&
UNCOV
314
    MakeVanillaSwap::withFloatingLegTerminationDateConvention(BusinessDayConvention bdc) {
×
315
        floatTerminationDateConvention_ = bdc;
×
316
        return *this;
×
317
    }
318

UNCOV
319
    MakeVanillaSwap& MakeVanillaSwap::withFloatingLegRule(DateGeneration::Rule r) {
×
320
        floatRule_ = r;
×
321
        return *this;
×
322
    }
323

324
    MakeVanillaSwap& MakeVanillaSwap::withFloatingLegEndOfMonth(bool flag) {
1,393✔
325
        floatEndOfMonth_ = flag;
1,393✔
326
        return *this;
1,393✔
327
    }
328

UNCOV
329
    MakeVanillaSwap& MakeVanillaSwap::withMaturityEndOfMonth(bool flag) {
×
UNCOV
330
        maturityEndOfMonth_ = flag;
×
331
        return *this;
×
332
    }
333

334
    MakeVanillaSwap&
UNCOV
335
    MakeVanillaSwap::withFloatingLegFirstDate(const Date& d) {
×
UNCOV
336
        floatFirstDate_ = d;
×
337
        return *this;
×
338
    }
339

340
    MakeVanillaSwap&
UNCOV
341
    MakeVanillaSwap::withFloatingLegNextToLastDate(const Date& d) {
×
UNCOV
342
        floatNextToLastDate_ = d;
×
343
        return *this;
×
344
    }
345

346
    MakeVanillaSwap&
UNCOV
347
    MakeVanillaSwap::withFloatingLegDayCount(const DayCounter& dc) {
×
348
        floatDayCount_ = dc;
UNCOV
349
        return *this;
×
350
    }
351

352
    MakeVanillaSwap& MakeVanillaSwap::withFloatingLegSpread(Spread sp) {
8,737✔
353
        floatSpread_ = sp;
8,737✔
354
        return *this;
8,737✔
355
    }
356

357
    MakeVanillaSwap& MakeVanillaSwap::withIndexedCoupons(const ext::optional<bool>& b) {
1,497✔
358
        useIndexedCoupons_ = b;
1,497✔
359
        return *this;
1,497✔
360
    }
361

UNCOV
362
    MakeVanillaSwap& MakeVanillaSwap::withAtParCoupons(bool b) {
×
UNCOV
363
        useIndexedCoupons_ = !b;
×
UNCOV
364
        return *this;
×
365
    }
366

367
}
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