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

lballabio / QuantLib / 30578125804

30 Jul 2026 08:11PM UTC coverage: 74.901% (-0.006%) from 74.907%
30578125804

push

github

web-flow
Add Singapore exchange holidays for 2027 (#2687)

0 of 8 new or added lines in 1 file covered. (0.0%)

1 existing line in 1 file now uncovered.

60041 of 80161 relevant lines covered (74.9%)

8685474.73 hits per line

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

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

3
/*
4
 Copyright (C) 2009, 2014, 2015 Ferdinando Ametrano
5
 Copyright (C) 2015 Paolo Mazzocchi
6
 Copyright (C) 2017 Joseph Jeisman
7
 Copyright (C) 2017 Fabrice Lecuyer
8
 Copyright (C) 2026 Sergio Araujo
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/makeois.hpp>
25
#include <ql/pricingengines/swap/discountingswapengine.hpp>
26
#include <ql/indexes/iborindex.hpp>
27
#include <ql/time/schedule.hpp>
28
#include <ql/indexes/ibor/sonia.hpp>
29
#include <ql/indexes/ibor/corra.hpp>
30

31
namespace QuantLib {
32

33
    MakeOIS::MakeOIS(const Period& swapTenor,
1,632✔
34
                     const ext::shared_ptr<OvernightIndex>& overnightIndex,
35
                     Rate fixedRate,
36
                     const Period& forwardStart)
1,632✔
37
    : swapTenor_(swapTenor), overnightIndex_(overnightIndex), fixedRate_(fixedRate),
1,632✔
38
      forwardStart_(forwardStart),
1,632✔
39
      fixedCalendar_(overnightIndex->fixingCalendar()),
1,632✔
40
      overnightCalendar_(overnightIndex->fixingCalendar()),
1,632✔
41
      fixedDayCount_(overnightIndex->dayCounter()) {}
4,896✔
42

43
    MakeOIS::operator OvernightIndexedSwap() const {
30✔
44
        ext::shared_ptr<OvernightIndexedSwap> ois = *this;
30✔
45
        return *ois;
60✔
46
    }
47

48
    MakeOIS::operator ext::shared_ptr<OvernightIndexedSwap>() const {
1,632✔
49

50
        QL_REQUIRE(effectiveDate_ == Date() || settlementDays_ == Null<Natural>(),
1,636✔
51
                   "cannot set both an explicit effective date and settlement days; "
52
                   "use one or the other");
53

54
        Date startDate;
1,630✔
55
        if (effectiveDate_ != Date())
1,630✔
56
            startDate = effectiveDate_;
1,182✔
57
        else {
58
            // settlement days: override if set, else fallback to default by index name
59
            Natural settlementDays = settlementDays_;
448✔
60
            if (settlementDays == Null<Natural>()) {
448✔
61
                if (ext::dynamic_pointer_cast<Sonia>(overnightIndex_)) {
34✔
62
                    settlementDays = 0; 
63
                }
64
                else if (ext::dynamic_pointer_cast<Corra>(overnightIndex_)) {
30✔
65
                    settlementDays = 1;
66
                }
67
                else {
68
                    settlementDays = 2;
69
                }
70
            }            
71

72
            Date refDate = Settings::instance().evaluationDate();
448✔
73
            // settlement days are counted from the actual evaluation
74
            // date, even when it is not a business day (see issue #753)
75
            const Calendar& settlementCalendar =
76
                settlementCalendar_.empty() ? overnightCalendar_ : settlementCalendar_;
448✔
77
            Date spotDate = settlementCalendar.advance(refDate,
448✔
78
                                                       settlementDays*Days);
448✔
79
            startDate = spotDate+forwardStart_;
448✔
80
            if (forwardStart_.length()<0)
448✔
81
                startDate = overnightCalendar_.adjust(startDate, Preceding);
×
82
            else
83
                startDate = overnightCalendar_.adjust(startDate, Following);
448✔
84
        }
85

86
        bool fixedEndOfMonth, overnightEndOfMonth, maturityEndOfMonth;
87
        if (isDefaultEOM_)
1,630✔
88
            fixedEndOfMonth = overnightEndOfMonth = maturityEndOfMonth =
89
                overnightCalendar_.isEndOfMonth(startDate);
1,629✔
90
        else {
91
            fixedEndOfMonth = fixedEndOfMonth_;
1✔
92
            overnightEndOfMonth = overnightEndOfMonth_;
1✔
93
            maturityEndOfMonth = maturityEndOfMonth_ ? *maturityEndOfMonth_ : overnightEndOfMonth_;
1✔
94
        }
95

96
        Date endDate = terminationDate_;
1,630✔
97
        if (endDate == Date()) {
1,630✔
98
            endDate = startDate + swapTenor_;
1,624✔
99
            if (maturityEndOfMonth && allowsEndOfMonth(swapTenor_) &&
1,625✔
100
                overnightCalendar_.isEndOfMonth(startDate))
1✔
UNCOV
101
                endDate = overnightCalendar_.endOfMonth(endDate);
×
102
        }
103

104
        Frequency fixedPaymentFrequency, overnightPaymentFrequency;
105
        DateGeneration::Rule fixedRule, overnightRule;
106
        if (fixedPaymentFrequency_ == Once || fixedRule_ == DateGeneration::Zero) {
1,630✔
107
            fixedPaymentFrequency = Once;
108
            fixedRule = DateGeneration::Zero;
109
        } else {
110
            fixedPaymentFrequency = fixedPaymentFrequency_;
111
            fixedRule = fixedRule_;
112
        }
113
        if (overnightPaymentFrequency_ == Once || overnightRule_ == DateGeneration::Zero) {
1,630✔
114
            overnightPaymentFrequency = Once;
115
            overnightRule = DateGeneration::Zero;
116
        } else {
117
            overnightPaymentFrequency = overnightPaymentFrequency_;
118
            overnightRule = overnightRule_;
119
        }
120

121
        Schedule fixedSchedule(startDate, endDate,
122
                               Period(fixedPaymentFrequency),
3,260✔
123
                               fixedCalendar_,
124
                               fixedConvention_,
1,630✔
125
                               fixedTerminationDateConvention_,
1,630✔
126
                               fixedRule,
127
                               fixedEndOfMonth);
3,260✔
128

129
        Schedule overnightSchedule(startDate, endDate,
130
                                   Period(overnightPaymentFrequency),
3,260✔
131
                                   overnightCalendar_,
132
                                   overnightConvention_,
1,630✔
133
                                   overnightTerminationDateConvention_,
1,630✔
134
                                   overnightRule,
135
                                   overnightEndOfMonth);
3,260✔
136

137
        Rate usedFixedRate = fixedRate_;
1,630✔
138
        if (fixedRate_ == Null<Rate>()) {
1,630✔
139
            OvernightIndexedSwap temp(type_, nominal_,
2✔
140
                                      fixedSchedule,
141
                                      0.0, // fixed rate
142
                                      fixedDayCount_,
143
                                      overnightSchedule,
144
                                      overnightIndex_, overnightSpread_,
2✔
145
                                      paymentLag_, paymentAdjustment_,
2✔
146
                                      paymentCalendar_, telescopicValueDates_,
2✔
147
                                      averagingMethod_, lookbackDays_,
2✔
148
                                      lockoutDays_, applyObservationShift_,
2✔
149
                                      roundingPrecision_);
4✔
150
            if (engine_ == nullptr) {
2✔
151
                Handle<YieldTermStructure> disc =
152
                                    overnightIndex_->forwardingTermStructure();
1✔
153
                QL_REQUIRE(!disc.empty(),
1✔
154
                           "null term structure set to this instance of " <<
155
                           overnightIndex_->name());
156
                bool includeSettlementDateFlows = false;
157
                ext::shared_ptr<PricingEngine> engine(new
158
                    DiscountingSwapEngine(disc, includeSettlementDateFlows));
2✔
159
                temp.setPricingEngine(engine);
1✔
160
            } else
161
                temp.setPricingEngine(engine_);
1✔
162

163
            usedFixedRate = temp.fairRate();
2✔
164
        }
2✔
165

166
        ext::shared_ptr<OvernightIndexedSwap> ois(new
167
            OvernightIndexedSwap(type_, nominal_,
1,630✔
168
                                 fixedSchedule,
169
                                 usedFixedRate, fixedDayCount_,
170
                                 overnightSchedule,
171
                                 overnightIndex_, overnightSpread_,
1,630✔
172
                                 paymentLag_, paymentAdjustment_,
1,630✔
173
                                 paymentCalendar_, telescopicValueDates_,
1,630✔
174
                                 averagingMethod_, lookbackDays_,
1,630✔
175
                                 lockoutDays_, applyObservationShift_,
1,630✔
176
                                 roundingPrecision_));
3,266✔
177

178
        if (engine_ == nullptr) {
1,628✔
179
            Handle<YieldTermStructure> disc =
180
                                overnightIndex_->forwardingTermStructure();
612✔
181
            bool includeSettlementDateFlows = false;
182
            ext::shared_ptr<PricingEngine> engine(new
183
                DiscountingSwapEngine(disc, includeSettlementDateFlows));
1,224✔
184
            ois->setPricingEngine(engine);
612✔
185
        } else
186
            ois->setPricingEngine(engine_);
1,016✔
187

188
        return ois;
1,628✔
189
    }
1,632✔
190

191
    MakeOIS& MakeOIS::receiveFixed(bool flag) {
×
192
        type_ = flag ? Swap::Receiver : Swap::Payer ;
×
193
        return *this;
×
194
    }
195

196
    MakeOIS& MakeOIS::withType(Swap::Type type) {
576✔
197
        type_ = type;
576✔
198
        return *this;
576✔
199
    }
200

201
    MakeOIS& MakeOIS::withNominal(Real n) {
598✔
202
        nominal_ = n;
598✔
203
        return *this;
598✔
204
    }
205

206
    MakeOIS& MakeOIS::withSettlementDays(Natural settlementDays) {
433✔
207
        settlementDays_ = settlementDays;
433✔
208
        return *this;
433✔
209
    }
210

211
    MakeOIS& MakeOIS::withSettlementCalendar(const Calendar& cal) {
1✔
212
        settlementCalendar_ = cal;
213
        return *this;
1✔
214
    }
215

216
    MakeOIS& MakeOIS::withEffectiveDate(const Date& effectiveDate) {
1,598✔
217
        effectiveDate_ = effectiveDate;
1,598✔
218
        return *this;
1,598✔
219
    }
220

221
    MakeOIS& MakeOIS::withTerminationDate(const Date& terminationDate) {
420✔
222
        terminationDate_ = terminationDate;
420✔
223
        if (terminationDate != Date())
420✔
224
            swapTenor_ = Period();
6✔
225
        return *this;
420✔
226
    }
227

228
    MakeOIS& MakeOIS::withPaymentFrequency(Frequency f) {
997✔
229
        return withFixedLegPaymentFrequency(f).withOvernightLegPaymentFrequency(f);
997✔
230
    }
231

232
    MakeOIS& MakeOIS::withFixedLegPaymentFrequency(Frequency f) {
997✔
233
        fixedPaymentFrequency_ = f;
997✔
234
        return *this;
997✔
235
    }
236

237
    MakeOIS& MakeOIS::withOvernightLegPaymentFrequency(Frequency f) {
997✔
238
        overnightPaymentFrequency_ = f;
997✔
239
        return *this;
997✔
240
    }
241

242
    MakeOIS& MakeOIS::withPaymentAdjustment(BusinessDayConvention convention) {
420✔
243
        paymentAdjustment_ = convention;
420✔
244
        return *this;
420✔
245
    }
246

247
    MakeOIS& MakeOIS::withPaymentLag(Integer lag) {
1,018✔
248
        paymentLag_ = lag;
1,018✔
249
        return *this;
1,018✔
250
    }
251

252
    MakeOIS& MakeOIS::withPaymentCalendar(const Calendar& cal) {
420✔
253
        paymentCalendar_ = cal;
254
        return *this;
420✔
255
    }
256

257
    MakeOIS& MakeOIS::withCalendar(const Calendar& cal) {
×
258
        return withFixedLegCalendar(cal).withOvernightLegCalendar(cal);
×
259
    }
260

261
    MakeOIS& MakeOIS::withFixedLegCalendar(const Calendar& cal) {
3✔
262
        fixedCalendar_ = cal;
263
        return *this;
3✔
264
    }
265

266
    MakeOIS& MakeOIS::withOvernightLegCalendar(const Calendar& cal) {
3✔
267
        overnightCalendar_ = cal;
268
        return *this;
3✔
269
    }
270

271
    MakeOIS& MakeOIS::withRule(DateGeneration::Rule r) {
420✔
272
        return withFixedLegRule(r).withOvernightLegRule(r);
420✔
273
    }
274

275
    MakeOIS& MakeOIS::withFixedLegRule(DateGeneration::Rule r) {
420✔
276
        fixedRule_ = r;
420✔
277
        return *this;
420✔
278
    }
279

280
    MakeOIS& MakeOIS::withOvernightLegRule(DateGeneration::Rule r) {
420✔
281
        overnightRule_ = r;
420✔
282
        return *this;
420✔
283
    }
284

285
    MakeOIS& MakeOIS::withDiscountingTermStructure(
1,018✔
286
                                        const Handle<YieldTermStructure>& d) {
287
        bool includeSettlementDateFlows = false;
288
        engine_ = ext::shared_ptr<PricingEngine>(new
1,018✔
289
            DiscountingSwapEngine(d, includeSettlementDateFlows));
3,054✔
290
        return *this;
1,018✔
291
    }
292

293
    MakeOIS& MakeOIS::withPricingEngine(
×
294
                             const ext::shared_ptr<PricingEngine>& engine) {
295
        engine_ = engine;
×
296
        return *this;
×
297
    }
298

299
    MakeOIS& MakeOIS::withFixedLegDayCount(const DayCounter& dc) {
577✔
300
        fixedDayCount_ = dc;
301
        return *this;
577✔
302
    }
303

304
    MakeOIS& MakeOIS::withConvention(BusinessDayConvention bdc) {
420✔
305
        return withFixedLegConvention(bdc).withOvernightLegConvention(bdc);
420✔
306
    }
307

308
    MakeOIS& MakeOIS::withFixedLegConvention(BusinessDayConvention bdc) {
420✔
309
        fixedConvention_ = bdc;
420✔
310
        return *this;
420✔
311
    }
312

313
    MakeOIS& MakeOIS::withOvernightLegConvention(BusinessDayConvention bdc) {
420✔
314
        overnightConvention_ = bdc;
420✔
315
        return *this;
420✔
316
    }
317

318
    MakeOIS& MakeOIS::withTerminationDateConvention(BusinessDayConvention bdc) {
420✔
319
        withFixedLegTerminationDateConvention(bdc);
420✔
320
        return withOvernightLegTerminationDateConvention(bdc);
420✔
321
    }
322

323
    MakeOIS& MakeOIS::withFixedLegTerminationDateConvention(BusinessDayConvention bdc) {
420✔
324
        fixedTerminationDateConvention_ = bdc;
420✔
325
        return *this;
420✔
326
    }
327

328
    MakeOIS& MakeOIS::withOvernightLegTerminationDateConvention(BusinessDayConvention bdc) {
420✔
329
        overnightTerminationDateConvention_ = bdc;
420✔
330
        return *this;
420✔
331
    }
332

333
    MakeOIS& MakeOIS::withEndOfMonth(bool flag) {
1✔
334
        return withFixedLegEndOfMonth(flag).withOvernightLegEndOfMonth(flag);
1✔
335
    }
336

337
    MakeOIS& MakeOIS::withFixedLegEndOfMonth(bool flag) {
1✔
338
        fixedEndOfMonth_ = flag;
1✔
339
        isDefaultEOM_ = false;
1✔
340
        return *this;
1✔
341
    }
342

343
    MakeOIS& MakeOIS::withOvernightLegEndOfMonth(bool flag) {
1✔
344
        overnightEndOfMonth_ = flag;
1✔
345
        isDefaultEOM_ = false;
1✔
346
        return *this;
1✔
347
    }
348

349
    MakeOIS& MakeOIS::withMaturityEndOfMonth(bool flag) {
×
350
        maturityEndOfMonth_ = flag;
×
351
        isDefaultEOM_ = false;
×
352
        return *this;
×
353
    }
354

355
    MakeOIS& MakeOIS::withOvernightLegSpread(Spread sp) {
400✔
356
        overnightSpread_ = sp;
400✔
357
        return *this;
400✔
358
    }
359

360
    MakeOIS& MakeOIS::withTelescopicValueDates(bool telescopicValueDates) {
1,018✔
361
        telescopicValueDates_ = telescopicValueDates;
1,018✔
362
        return *this;
1,018✔
363
    }
364

365
    MakeOIS& MakeOIS::withAveragingMethod(RateAveraging::Type averagingMethod) {
820✔
366
        averagingMethod_ = averagingMethod;
820✔
367
        return *this;
820✔
368
    }
369

370
    MakeOIS& MakeOIS::withLookbackDays(Natural lookbackDays) {
618✔
371
        lookbackDays_ = lookbackDays;
618✔
372
        return *this;
618✔
373
    }
374

375
    MakeOIS& MakeOIS::withLockoutDays(Natural lockoutDays) {
618✔
376
        lockoutDays_ = lockoutDays;
618✔
377
        return *this;
618✔
378
    }
379

380
    MakeOIS& MakeOIS::withObservationShift(bool applyObservationShift) {
618✔
381
        applyObservationShift_ = applyObservationShift;
618✔
382
        return *this;
618✔
383
    }
384

385
    MakeOIS& MakeOIS::withRoundingPrecision(const std::optional<Integer>& roundingPrecision) {
400✔
386
        roundingPrecision_ = roundingPrecision;
400✔
387
        return *this;
400✔
388
    }
389

390
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc