Coverage Report

Created: 2026-03-11 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/time/schedule.hpp
Line
Count
Source
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2006, 2007, 2011 Ferdinando Ametrano
5
 Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl
6
 Copyright (C) 2003, 2004, 2005, 2006, 2009 StatPro Italia srl
7
8
 This file is part of QuantLib, a free-software/open-source library
9
 for financial quantitative analysts and developers - http://quantlib.org/
10
11
 QuantLib is free software: you can redistribute it and/or modify it
12
 under the terms of the QuantLib license.  You should have received a
13
 copy of the license along with this program; if not, please email
14
 <quantlib-dev@lists.sf.net>. The license is also available online at
15
 <https://www.quantlib.org/license.shtml>.
16
17
 This program is distributed in the hope that it will be useful, but WITHOUT
18
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19
 FOR A PARTICULAR PURPOSE.  See the license for more details.
20
*/
21
22
/*! \file schedule.hpp
23
    \brief date schedule
24
*/
25
26
#ifndef quantlib_schedule_hpp
27
#define quantlib_schedule_hpp
28
29
#include <ql/time/calendars/nullcalendar.hpp>
30
#include <ql/utilities/null.hpp>
31
#include <ql/time/period.hpp>
32
#include <ql/time/dategenerationrule.hpp>
33
#include <ql/errors.hpp>
34
#include <ql/optional.hpp>
35
36
namespace QuantLib {
37
38
    //! Payment schedule
39
    /*! \ingroup datetime */
40
    class Schedule {
41
      public:
42
        /*! constructor that takes any list of dates, and optionally
43
            meta information that can be used by client classes. Note
44
            that neither the list of dates nor the meta information is
45
            checked for plausibility in any sense. */
46
        Schedule(
47
            const std::vector<Date>&,
48
            Calendar calendar = NullCalendar(),
49
            BusinessDayConvention convention = Unadjusted,
50
            const ext::optional<BusinessDayConvention>& terminationDateConvention = ext::nullopt,
51
            const ext::optional<Period>& tenor = ext::nullopt,
52
            const ext::optional<DateGeneration::Rule>& rule = ext::nullopt,
53
            const ext::optional<bool>& endOfMonth = ext::nullopt,
54
            std::vector<bool> isRegular = std::vector<bool>(0));
55
        /*! rule based constructor */
56
        Schedule(Date effectiveDate,
57
                 const Date& terminationDate,
58
                 const Period& tenor,
59
                 Calendar calendar,
60
                 BusinessDayConvention convention,
61
                 BusinessDayConvention terminationDateConvention,
62
                 DateGeneration::Rule rule,
63
                 bool endOfMonth,
64
                 const Date& firstDate = Date(),
65
                 const Date& nextToLastDate = Date());
66
71.5k
        Schedule() = default;
67
        //! \name Element access
68
        //@{
69
25.9M
        Size size() const { return dates_.size(); }
70
        const Date& operator[](Size i) const;
71
        const Date& at(Size i) const;
72
        const Date& date(Size i) const;
73
0
        const std::vector<Date>& dates() const { return dates_; }
74
71.5k
        bool empty() const { return dates_.empty(); }
75
        const Date& front() const;
76
        const Date& back() const;
77
        //@}
78
        //! \name Other inspectors
79
        //@{
80
        Date previousDate(const Date& refDate) const;
81
        Date nextDate(const Date& refDate) const;
82
        bool hasIsRegular() const;
83
        bool isRegular(Size i) const;
84
        const std::vector<bool>& isRegular() const;
85
        const Calendar& calendar() const;
86
        const Date& startDate() const;
87
        const Date& endDate() const;
88
        bool hasTenor() const;
89
        const Period& tenor() const;
90
        BusinessDayConvention businessDayConvention() const;
91
        bool hasTerminationDateBusinessDayConvention() const;
92
        BusinessDayConvention terminationDateBusinessDayConvention() const;
93
        bool hasRule() const;
94
        DateGeneration::Rule rule() const;
95
        bool hasEndOfMonth() const;
96
        bool endOfMonth() const;
97
        //@}
98
        //! \name Iterators
99
        //@{
100
        typedef std::vector<Date>::const_iterator const_iterator;
101
0
        const_iterator begin() const { return dates_.begin(); }
102
0
        const_iterator end() const { return dates_.end(); }
103
        const_iterator lower_bound(const Date& d = Date()) const;
104
        //@}
105
        //! \name Utilities
106
        //@{
107
        //! truncated schedule
108
        Schedule after(const Date& truncationDate) const;
109
        Schedule until(const Date& truncationDate) const;
110
        //@}
111
      private:
112
        ext::optional<Period> tenor_;
113
        Calendar calendar_;
114
        BusinessDayConvention convention_;
115
        ext::optional<BusinessDayConvention> terminationDateConvention_;
116
        ext::optional<DateGeneration::Rule> rule_;
117
        ext::optional<bool> endOfMonth_;
118
        Date firstDate_, nextToLastDate_;
119
        std::vector<Date> dates_;
120
        std::vector<bool> isRegular_;
121
    };
122
123
124
    //! helper class
125
    /*! This class provides a more comfortable interface to the
126
        argument list of Schedule's constructor.
127
    */
128
    class MakeSchedule {
129
      public:
130
        MakeSchedule& from(const Date& effectiveDate);
131
        MakeSchedule& to(const Date& terminationDate);
132
        MakeSchedule& withTenor(const Period&);
133
        MakeSchedule& withFrequency(Frequency);
134
        MakeSchedule& withCalendar(const Calendar&);
135
        MakeSchedule& withConvention(BusinessDayConvention);
136
        MakeSchedule& withTerminationDateConvention(BusinessDayConvention);
137
        MakeSchedule& withRule(DateGeneration::Rule);
138
        MakeSchedule& forwards();
139
        MakeSchedule& backwards();
140
        MakeSchedule& endOfMonth(bool flag=true);
141
        MakeSchedule& withFirstDate(const Date& d);
142
        MakeSchedule& withNextToLastDate(const Date& d);
143
        operator Schedule() const;
144
      private:
145
        Calendar calendar_;
146
        Date effectiveDate_, terminationDate_;
147
        ext::optional<Period> tenor_;
148
        ext::optional<BusinessDayConvention> convention_;
149
        ext::optional<BusinessDayConvention> terminationDateConvention_;
150
        DateGeneration::Rule rule_ = DateGeneration::Backward;
151
        bool endOfMonth_ = false;
152
        Date firstDate_, nextToLastDate_;
153
    };
154
155
    /*! Helper function for returning the date on or before date \p d that is the 20th of the month and obeserves the 
156
        given date generation \p rule if it is relevant.
157
    */
158
    Date previousTwentieth(const Date& d, DateGeneration::Rule rule);
159
160
    //! returns true for (non-zero) tenor with unit Months or Years
161
    bool allowsEndOfMonth(const Period& tenor);
162
163
    // inline definitions
164
165
25.8M
    inline const Date& Schedule::date(Size i) const {
166
25.8M
        return dates_.at(i);
167
25.8M
    }
168
169
0
    inline const Date& Schedule::operator[](Size i) const {
170
0
        #if defined(QL_EXTRA_SAFETY_CHECKS)
171
0
        return dates_.at(i);
172
0
        #else
173
0
        return dates_[i];
174
0
        #endif
175
0
    }
176
177
0
    inline const Date& Schedule::at(Size i) const {
178
0
        return dates_.at(i);
179
0
    }
180
181
0
    inline const Date& Schedule::front() const {
182
0
        QL_REQUIRE(!dates_.empty(), "no front date for empty schedule");
183
0
        return dates_.front();
184
0
    }
Unexecuted instantiation: QuantLib::Schedule::front() const
Unexecuted instantiation: QuantLib::Schedule::front() const
185
186
0
    inline const Date& Schedule::back() const {
187
0
        QL_REQUIRE(!dates_.empty(), "no back date for empty schedule");
188
0
        return dates_.back();
189
0
    }
Unexecuted instantiation: QuantLib::Schedule::back() const
Unexecuted instantiation: QuantLib::Schedule::back() const
190
191
143k
    inline const Calendar& Schedule::calendar() const {
192
143k
        return calendar_;
193
143k
    }
194
195
0
    inline const Date& Schedule::startDate() const {
196
0
        QL_REQUIRE(!dates_.empty(), "empty Schedule: no start date"); 
197
0
        return dates_.front();
198
0
    }
Unexecuted instantiation: QuantLib::Schedule::startDate() const
Unexecuted instantiation: QuantLib::Schedule::startDate() const
199
200
71.5k
    inline const Date &Schedule::endDate() const {
201
        // Checks to avoid segfault, issue #2302
202
71.5k
        QL_REQUIRE(!dates_.empty(), "empty Schedule: no end date"); 
203
71.5k
        return dates_.back(); 
204
71.5k
    }
205
206
143k
    inline bool Schedule::hasTenor() const {
207
143k
        return static_cast<bool>(tenor_);
208
143k
    }
209
210
71.5k
    inline const Period& Schedule::tenor() const {
211
71.5k
        QL_REQUIRE(hasTenor(),
212
71.5k
                   "full interface (tenor) not available");
213
71.5k
        return *tenor_;  // NOLINT(bugprone-unchecked-optional-access)
214
71.5k
    }
215
216
0
    inline BusinessDayConvention Schedule::businessDayConvention() const {
217
0
        return convention_;
218
0
    }
219
220
    inline bool
221
0
    Schedule::hasTerminationDateBusinessDayConvention() const {
222
0
        return static_cast<bool>(terminationDateConvention_);
223
0
    }
224
225
    inline BusinessDayConvention
226
0
    Schedule::terminationDateBusinessDayConvention() const {
227
0
        QL_REQUIRE(hasTerminationDateBusinessDayConvention(),
228
0
                   "full interface (termination date bdc) not available");
229
0
        return *terminationDateConvention_;  // NOLINT(bugprone-unchecked-optional-access)
230
0
    }
231
232
0
    inline bool Schedule::hasRule() const {
233
0
        return static_cast<bool>(rule_);
234
0
    }
235
236
0
    inline DateGeneration::Rule Schedule::rule() const {
237
0
        QL_REQUIRE(hasRule(), "full interface (rule) not available");
238
0
        return *rule_;  // NOLINT(bugprone-unchecked-optional-access)
239
0
    }
Unexecuted instantiation: QuantLib::Schedule::rule() const
Unexecuted instantiation: QuantLib::Schedule::rule() const
240
241
0
    inline bool Schedule::hasEndOfMonth() const {
242
0
        return static_cast<bool>(endOfMonth_);
243
0
    }
244
245
0
    inline bool Schedule::endOfMonth() const {
246
0
        QL_REQUIRE(hasEndOfMonth(),
247
0
                   "full interface (end of month) not available");
248
0
        return *endOfMonth_;  // NOLINT(bugprone-unchecked-optional-access)
249
0
    }
Unexecuted instantiation: QuantLib::Schedule::endOfMonth() const
Unexecuted instantiation: QuantLib::Schedule::endOfMonth() const
250
251
}
252
253
#endif