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

lballabio / QuantLib / 14626839209

23 Apr 2025 07:50PM UTC coverage: 73.316% (-0.001%) from 73.317%
14626839209

push

github

web-flow
Switch default to `std::any` and `std::optional` (#2205)

56258 of 76734 relevant lines covered (73.32%)

8667561.41 hits per line

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

62.23
/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
 <http://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,
34,391✔
41
                                     const ext::shared_ptr<IborIndex>& index,
42
                                     Rate fixedRate,
43
                                     const Period& forwardStart)
34,391✔
44
    : swapTenor_(swapTenor), iborIndex_(index), fixedRate_(fixedRate), forwardStart_(forwardStart),
34,391✔
45
      settlementDays_(Null<Natural>()), fixedCalendar_(index->fixingCalendar()),
34,391✔
46
      floatCalendar_(index->fixingCalendar()),
34,391✔
47

48
      floatTenor_(index->tenor()),
34,391✔
49

50
      floatConvention_(index->businessDayConvention()),
68,782✔
51
      floatTerminationDateConvention_(index->businessDayConvention()),
34,391✔
52

53
      floatDayCount_(index->dayCounter()) {}
137,564✔
54

55
    MakeVanillaSwap::operator VanillaSwap() const {
7,866✔
56
        ext::shared_ptr<VanillaSwap> swap = *this;
7,866✔
57
        return *swap;
15,732✔
58
    }
59

60
    MakeVanillaSwap::operator ext::shared_ptr<VanillaSwap>() const {
34,391✔
61

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

87
        Date endDate = terminationDate_;
34,391✔
88
        if (endDate == Date()) {
34,391✔
89
            if (floatEndOfMonth_)
31,861✔
90
                endDate = floatCalendar_.advance(startDate,
×
91
                                                 swapTenor_,
×
92
                                                 ModifiedFollowing,
93
                                                 floatEndOfMonth_);
94
            else
95
                endDate = startDate + swapTenor_;
31,861✔
96
        }
97

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

120
        Schedule fixedSchedule(startDate, endDate,
121
                               fixedTenor, fixedCalendar_,
122
                               fixedConvention_,
34,391✔
123
                               fixedTerminationDateConvention_,
34,391✔
124
                               fixedRule_, fixedEndOfMonth_,
34,391✔
125
                               fixedFirstDate_, fixedNextToLastDate_);
34,391✔
126

127
        Schedule floatSchedule(startDate, endDate,
128
                               floatTenor_, floatCalendar_,
34,391✔
129
                               floatConvention_,
34,391✔
130
                               floatTerminationDateConvention_,
34,391✔
131
                               floatRule_, floatEndOfMonth_,
34,391✔
132
                               floatFirstDate_, floatNextToLastDate_);
34,391✔
133

134
        DayCounter fixedDayCount;
34,391✔
135
        if (fixedDayCount_ != DayCounter())
68,782✔
136
            fixedDayCount = fixedDayCount_;
137
        else {
138
            if (curr == USDCurrency())
6,192✔
139
                fixedDayCount = Actual360();
×
140
            else if (curr == EURCurrency() || curr == CHFCurrency() ||
9,288✔
141
                     curr == SEKCurrency())
3,096✔
142
                fixedDayCount = Thirty360(Thirty360::BondBasis);
6,192✔
143
            else if (curr == GBPCurrency() || curr == JPYCurrency() ||
×
144
                     curr == AUDCurrency() || curr == HKDCurrency() ||
×
145
                     curr == THBCurrency())
×
146
                fixedDayCount = Actual365Fixed();
×
147
            else
148
                QL_FAIL("unknown fixed leg day counter for " << curr);
×
149
        }
150

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

170
            usedFixedRate = temp.fairRate();
×
171
        }
×
172

173
        ext::shared_ptr<VanillaSwap> swap(new VanillaSwap(
174
            type_, nominal_, fixedSchedule, usedFixedRate, fixedDayCount, floatSchedule, iborIndex_,
34,391✔
175
            floatSpread_, floatDayCount_, paymentConvention_, useIndexedCoupons_));
103,173✔
176

177
        if (engine_ == nullptr) {
34,391✔
178
            Handle<YieldTermStructure> disc =
179
                                    iborIndex_->forwardingTermStructure();
30,059✔
180
            bool includeSettlementDateFlows = false;
181
            ext::shared_ptr<PricingEngine> engine(new
182
                DiscountingSwapEngine(disc, includeSettlementDateFlows));
30,059✔
183
            swap->setPricingEngine(engine);
30,059✔
184
        } else
185
            swap->setPricingEngine(engine_);
4,332✔
186

187
        return swap;
34,391✔
188
    }
34,391✔
189

190
    MakeVanillaSwap& MakeVanillaSwap::receiveFixed(bool flag) {
561✔
191
        type_ = flag ? Swap::Receiver : Swap::Payer ;
561✔
192
        return *this;
561✔
193
    }
194

195
    MakeVanillaSwap& MakeVanillaSwap::withType(Swap::Type type) {
11,382✔
196
        type_ = type;
11,382✔
197
        return *this;
11,382✔
198
    }
199

200
    MakeVanillaSwap& MakeVanillaSwap::withNominal(Real n) {
2,645✔
201
        nominal_ = n;
2,645✔
202
        return *this;
2,645✔
203
    }
204

205
    MakeVanillaSwap& MakeVanillaSwap::withSettlementDays(Natural settlementDays) {
1,259✔
206
        settlementDays_ = settlementDays;
1,259✔
207
        effectiveDate_ = Date();
1,259✔
208
        return *this;
1,259✔
209
    }
210

211
    MakeVanillaSwap&
212
    MakeVanillaSwap::withEffectiveDate(const Date& effectiveDate) {
26,695✔
213
        effectiveDate_ = effectiveDate;
26,695✔
214
        return *this;
26,695✔
215
    }
216

217
    MakeVanillaSwap&
218
    MakeVanillaSwap::withTerminationDate(const Date& terminationDate) {
3,778✔
219
        terminationDate_ = terminationDate;
3,778✔
220
        if (terminationDate != Date())
3,778✔
221
            swapTenor_ = Period();
2,530✔
222
        return *this;
3,778✔
223
    }
224

225
    MakeVanillaSwap& MakeVanillaSwap::withRule(DateGeneration::Rule r) {
×
226
        fixedRule_ = r;
×
227
        floatRule_ = r;
×
228
        return *this;
×
229
    }
230

231
    MakeVanillaSwap& MakeVanillaSwap::withPaymentConvention(BusinessDayConvention bdc) {
×
232
        paymentConvention_ = bdc;
×
233
        return *this;
×
234
    }
235

236
    MakeVanillaSwap& MakeVanillaSwap::withDiscountingTermStructure(
4,332✔
237
                                        const Handle<YieldTermStructure>& d) {
238
        bool includeSettlementDateFlows = false;
239
        engine_ = ext::shared_ptr<PricingEngine>(new
12,996✔
240
            DiscountingSwapEngine(d, includeSettlementDateFlows));
8,664✔
241
        return *this;
4,332✔
242
    }
243

244
    MakeVanillaSwap& MakeVanillaSwap::withPricingEngine(
×
245
                             const ext::shared_ptr<PricingEngine>& engine) {
246
        engine_ = engine;
×
247
        return *this;
×
248
    }
249

250
    MakeVanillaSwap& MakeVanillaSwap::withFixedLegTenor(const Period& t) {
31,295✔
251
        fixedTenor_ = t;
31,295✔
252
        return *this;
31,295✔
253
    }
254

255
    MakeVanillaSwap&
256
    MakeVanillaSwap::withFixedLegCalendar(const Calendar& cal) {
14,712✔
257
        fixedCalendar_ = cal;
258
        return *this;
14,712✔
259
    }
260

261
    MakeVanillaSwap&
262
    MakeVanillaSwap::withFixedLegConvention(BusinessDayConvention bdc) {
14,873✔
263
        fixedConvention_ = bdc;
14,873✔
264
        return *this;
14,873✔
265
    }
266

267
    MakeVanillaSwap&
268
    MakeVanillaSwap::withFixedLegTerminationDateConvention(BusinessDayConvention bdc) {
14,867✔
269
        fixedTerminationDateConvention_ = bdc;
14,867✔
270
        return *this;
14,867✔
271
    }
272

273
    MakeVanillaSwap& MakeVanillaSwap::withFixedLegRule(DateGeneration::Rule r) {
×
274
        fixedRule_ = r;
×
275
        return *this;
×
276
    }
277

278
    MakeVanillaSwap& MakeVanillaSwap::withFixedLegEndOfMonth(bool flag) {
1,253✔
279
        fixedEndOfMonth_ = flag;
1,253✔
280
        return *this;
1,253✔
281
    }
282

283
    MakeVanillaSwap& MakeVanillaSwap::withFixedLegFirstDate(const Date& d) {
×
284
        fixedFirstDate_ = d;
×
285
        return *this;
×
286
    }
287

288
    MakeVanillaSwap&
289
    MakeVanillaSwap::withFixedLegNextToLastDate(const Date& d) {
×
290
        fixedNextToLastDate_ = d;
×
291
        return *this;
×
292
    }
293

294
    MakeVanillaSwap&
295
    MakeVanillaSwap::withFixedLegDayCount(const DayCounter& dc) {
31,295✔
296
        fixedDayCount_ = dc;
297
        return *this;
31,295✔
298
    }
299

300
    MakeVanillaSwap& MakeVanillaSwap::withFloatingLegTenor(const Period& t) {
×
301
        floatTenor_ = t;
×
302
        return *this;
×
303
    }
304

305
    MakeVanillaSwap&
306
    MakeVanillaSwap::withFloatingLegCalendar(const Calendar& cal) {
1,274✔
307
        floatCalendar_ = cal;
308
        return *this;
1,274✔
309
    }
310

311
    MakeVanillaSwap&
312
    MakeVanillaSwap::withFloatingLegConvention(BusinessDayConvention bdc) {
×
313
        floatConvention_ = bdc;
×
314
        return *this;
×
315
    }
316

317
    MakeVanillaSwap&
318
    MakeVanillaSwap::withFloatingLegTerminationDateConvention(BusinessDayConvention bdc) {
×
319
        floatTerminationDateConvention_ = bdc;
×
320
        return *this;
×
321
    }
322

323
    MakeVanillaSwap& MakeVanillaSwap::withFloatingLegRule(DateGeneration::Rule r) {
×
324
        floatRule_ = r;
×
325
        return *this;
×
326
    }
327

328
    MakeVanillaSwap& MakeVanillaSwap::withFloatingLegEndOfMonth(bool flag) {
1,253✔
329
        floatEndOfMonth_ = flag;
1,253✔
330
        return *this;
1,253✔
331
    }
332

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

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

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

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

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

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

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