QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
schedule.cpp
Go to the documentation of this file.
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2006, 2007, 2008, 2010, 2011, 2015 Ferdinando Ametrano
5 Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl
6 Copyright (C) 2009, 2012 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 <http://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#include <ql/optional.hpp>
23#include <ql/settings.hpp>
24#include <ql/time/imm.hpp>
25#include <ql/time/schedule.hpp>
26#include <algorithm>
27#include <utility>
28
29namespace QuantLib {
30
31 namespace {
32
33 Date nextTwentieth(const Date& d, DateGeneration::Rule rule) {
34 Date result = Date(20, d.month(), d.year());
35 if (result < d)
36 result += 1*Months;
37 if (rule == DateGeneration::TwentiethIMM ||
38 rule == DateGeneration::OldCDS ||
39 rule == DateGeneration::CDS ||
41 Month m = result.month();
42 if (m % 3 != 0) { // not a main IMM nmonth
43 Integer skip = 3 - m%3;
44 result += skip*Months;
45 }
46 }
47 return result;
48 }
49
50 bool allowsEndOfMonth(const Period& tenor) {
51 return (tenor.units() == Months || tenor.units() == Years)
52 && tenor >= 1*Months;
53 }
54
55 }
56
57
58 Schedule::Schedule(const std::vector<Date>& dates,
59 Calendar calendar,
60 BusinessDayConvention convention,
61 const ext::optional<BusinessDayConvention>& terminationDateConvention,
62 const ext::optional<Period>& tenor,
63 const ext::optional<DateGeneration::Rule>& rule,
64 const ext::optional<bool>& endOfMonth,
65 std::vector<bool> isRegular)
66 : tenor_(tenor), calendar_(std::move(calendar)), convention_(convention),
67 terminationDateConvention_(terminationDateConvention), rule_(rule), dates_(dates),
68 isRegular_(std::move(isRegular)) {
69
70 if (tenor && !allowsEndOfMonth(*tenor))
71 endOfMonth_ = false;
72 else
74
75 QL_REQUIRE(isRegular_.empty() || isRegular_.size() == dates.size() - 1,
76 "isRegular size (" << isRegular_.size()
77 << ") must be zero or equal to the number of dates minus 1 ("
78 << dates.size() - 1 << ")");
79 }
80
81 Schedule::Schedule(Date effectiveDate,
82 const Date& terminationDate,
83 const Period& tenor,
84 Calendar cal,
85 BusinessDayConvention convention,
86 BusinessDayConvention terminationDateConvention,
88 bool endOfMonth,
89 const Date& first,
90 const Date& nextToLast)
91 : tenor_(tenor), calendar_(std::move(cal)), convention_(convention),
92 terminationDateConvention_(terminationDateConvention), rule_(rule),
93 endOfMonth_(allowsEndOfMonth(tenor) ? endOfMonth : false),
94 firstDate_(first == effectiveDate ? Date() : first),
95 nextToLastDate_(nextToLast == terminationDate ? Date() : nextToLast) {
96 // sanity checks
97 QL_REQUIRE(terminationDate != Date(), "null termination date");
98
99 // in many cases (e.g. non-expired bonds) the effective date is not
100 // really necessary. In these cases a decent placeholder is enough
101 if (effectiveDate==Date() && first==Date()
104 QL_REQUIRE(evalDate < terminationDate, "null effective date");
105 Natural y;
106 if (nextToLast != Date()) {
107 y = (nextToLast - evalDate)/366 + 1;
108 effectiveDate = nextToLast - y*Years;
109 } else {
110 y = (terminationDate - evalDate)/366 + 1;
111 effectiveDate = terminationDate - y*Years;
112 }
113 } else
114 QL_REQUIRE(effectiveDate != Date(), "null effective date");
115
116 QL_REQUIRE(effectiveDate < terminationDate,
117 "effective date (" << effectiveDate
118 << ") later than or equal to termination date ("
119 << terminationDate << ")");
120
121 if (tenor.length()==0)
123 else
125 "non positive tenor (" << tenor << ") not allowed");
126
127 if (firstDate_ != Date()) {
128 switch (*rule_) {
131 QL_REQUIRE(firstDate_ > effectiveDate &&
132 firstDate_ <= terminationDate,
133 "first date (" << firstDate_ <<
134 ") out of effective-termination date range (" <<
135 effectiveDate << ", " << terminationDate << "]");
136 // we should ensure that the above condition is still
137 // verified after adjustment
138 break;
141 "first date (" << firstDate_ <<
142 ") is not an IMM date");
143 break;
150 QL_FAIL("first date incompatible with " << *rule_ <<
151 " date generation rule");
152 default:
153 QL_FAIL("unknown rule (" << Integer(*rule_) << ")");
154 }
155 }
156 if (nextToLastDate_ != Date()) {
157 switch (*rule_) {
160 QL_REQUIRE(nextToLastDate_ >= effectiveDate &&
161 nextToLastDate_ < terminationDate,
162 "next to last date (" << nextToLastDate_ <<
163 ") out of effective-termination date range [" <<
164 effectiveDate << ", " << terminationDate << ")");
165 // we should ensure that the above condition is still
166 // verified after adjustment
167 break;
170 "next-to-last date (" << nextToLastDate_ <<
171 ") is not an IMM date");
172 break;
179 QL_FAIL("next to last date incompatible with " << *rule_ <<
180 " date generation rule");
181 default:
182 QL_FAIL("unknown rule (" << Integer(*rule_) << ")");
183 }
184 }
185
186
187 // calendar needed for endOfMonth adjustment
188 Calendar nullCalendar = NullCalendar();
189 Integer periods = 1;
190 Date seed, exitDate;
191 switch (*rule_) {
192
194 tenor_ = 0*Years;
195 dates_.push_back(effectiveDate);
196 dates_.push_back(terminationDate);
197 isRegular_.push_back(true);
198 break;
199
201
202 dates_.push_back(terminationDate);
203
204 seed = terminationDate;
205 if (nextToLastDate_ != Date()) {
206 dates_.push_back(nextToLastDate_);
207 Date temp = nullCalendar.advance(seed,
208 -periods*(*tenor_), convention, *endOfMonth_);
209 isRegular_.push_back(temp == nextToLastDate_);
210 seed = nextToLastDate_;
211 }
212
213 exitDate = effectiveDate;
214 if (firstDate_ != Date())
215 exitDate = firstDate_;
216
217 for (;;) {
218 Date temp = nullCalendar.advance(seed,
219 -periods*(*tenor_), convention, *endOfMonth_);
220 if (temp < exitDate) {
221 if (firstDate_ != Date() &&
222 (calendar_.adjust(dates_.back(),convention)!=
223 calendar_.adjust(firstDate_,convention))) {
224 dates_.push_back(firstDate_);
225 isRegular_.push_back(false);
226 }
227 break;
228 } else {
229 // skip dates that would result in duplicates
230 // after adjustment
231 if (calendar_.adjust(dates_.back(),convention)!=
232 calendar_.adjust(temp,convention)) {
233 dates_.push_back(temp);
234 isRegular_.push_back(true);
235 }
236 ++periods;
237 }
238 }
239
240 if (calendar_.adjust(dates_.back(),convention)!=
241 calendar_.adjust(effectiveDate,convention)) {
242 dates_.push_back(effectiveDate);
243 isRegular_.push_back(false);
244 }
245 std::reverse(dates_.begin(), dates_.end());
246 std::reverse(isRegular_.begin(), isRegular_.end());
247 break;
248
257 "endOfMonth convention incompatible with " << *rule_ <<
258 " date generation rule");
259 // fall through
261
263 Date prev20th = previousTwentieth(effectiveDate, *rule_);
264 if (calendar_.adjust(prev20th, convention) > effectiveDate) {
265 dates_.push_back(prev20th - 3 * Months);
266 isRegular_.push_back(true);
267 }
268 dates_.push_back(prev20th);
269 } else {
270 dates_.push_back(effectiveDate);
271 }
272
273 seed = dates_.back();
274
275 if (firstDate_!=Date()) {
276 dates_.push_back(firstDate_);
277 Date temp = nullCalendar.advance(seed, periods*(*tenor_),
278 convention, *endOfMonth_);
279 if (temp!=firstDate_)
280 isRegular_.push_back(false);
281 else
282 isRegular_.push_back(true);
283 seed = firstDate_;
284 } else if (*rule_ == DateGeneration::Twentieth ||
289 Date next20th = nextTwentieth(effectiveDate, *rule_);
291 // distance rule inforced in natural days
292 static const Date::serial_type stubDays = 30;
293 if (next20th - effectiveDate < stubDays) {
294 // +1 will skip this one and get the next
295 next20th = nextTwentieth(next20th + 1, *rule_);
296 }
297 }
298 if (next20th != effectiveDate) {
299 dates_.push_back(next20th);
301 seed = next20th;
302 }
303 }
304
305 exitDate = terminationDate;
306 if (nextToLastDate_ != Date())
307 exitDate = nextToLastDate_;
308 for (;;) {
309 Date temp = nullCalendar.advance(seed, periods*(*tenor_),
310 convention, *endOfMonth_);
311 if (temp > exitDate) {
312 if (nextToLastDate_ != Date() &&
313 (calendar_.adjust(dates_.back(),convention)!=
314 calendar_.adjust(nextToLastDate_,convention))) {
315 dates_.push_back(nextToLastDate_);
316 isRegular_.push_back(false);
317 }
318 break;
319 } else {
320 // skip dates that would result in duplicates
321 // after adjustment
322 if (calendar_.adjust(dates_.back(),convention)!=
323 calendar_.adjust(temp,convention)) {
324 dates_.push_back(temp);
325 isRegular_.push_back(true);
326 }
327 ++periods;
328 }
329 }
330
331 if (calendar_.adjust(dates_.back(),terminationDateConvention)!=
332 calendar_.adjust(terminationDate,terminationDateConvention)) {
338 dates_.push_back(nextTwentieth(terminationDate, *rule_));
339 isRegular_.push_back(true);
340 } else {
341 dates_.push_back(terminationDate);
342 isRegular_.push_back(false);
343 }
344 }
345
346 break;
347
348 default:
349 QL_FAIL("unknown rule (" << Integer(*rule_) << ")");
350 }
351
352 // adjustments
354 for (Size i=1; i<dates_.size()-1; ++i)
356 dates_[i].month(),
357 dates_[i].year());
359 for (auto& date : dates_)
361
362 // first date not adjusted for old CDS schedules
363 if (convention != Unadjusted && *rule_ != DateGeneration::OldCDS)
364 dates_.front() = calendar_.adjust(dates_.front(), convention);
365
366 // termination date is NOT adjusted as per ISDA
367 // specifications, unless otherwise specified in the
368 // confirmation of the deal or unless we're creating a CDS
369 // schedule
370 if (terminationDateConvention != Unadjusted
373 dates_.back() = calendar_.adjust(dates_.back(),
374 terminationDateConvention);
375 }
376
377 if (*endOfMonth_ && calendar_.isEndOfMonth(seed)) {
378 // adjust to end of month
379 if (convention == Unadjusted) {
380 for (Size i=1; i<dates_.size()-1; ++i)
382 } else {
383 for (Size i=1; i<dates_.size()-1; ++i)
385 }
386 } else {
387 for (Size i=1; i<dates_.size()-1; ++i)
388 dates_[i] = calendar_.adjust(dates_[i], convention);
389 }
390
391 // Final safety checks to remove extra next-to-last date, if
392 // necessary. It can happen to be equal or later than the end
393 // date due to EOM adjustments (see the Schedule test suite
394 // for an example).
395 if (dates_.size() >= 2 && dates_[dates_.size()-2] >= dates_.back()) {
396 // there might be two dates only, then isRegular_ has size one
397 if (isRegular_.size() >= 2) {
398 isRegular_[isRegular_.size() - 2] =
399 (dates_[dates_.size() - 2] == dates_.back());
400 }
401 dates_[dates_.size() - 2] = dates_.back();
402 dates_.pop_back();
403 isRegular_.pop_back();
404 }
405 if (dates_.size() >= 2 && dates_[1] <= dates_.front()) {
406 isRegular_[1] =
407 (dates_[1] == dates_.front());
408 dates_[1] = dates_.front();
409 dates_.erase(dates_.begin());
410 isRegular_.erase(isRegular_.begin());
411 }
412
413 QL_ENSURE(dates_.size()>1,
414 "degenerate single date (" << dates_[0] << ") schedule" <<
415 "\n seed date: " << seed <<
416 "\n exit date: " << exitDate <<
417 "\n effective date: " << effectiveDate <<
418 "\n first date: " << first <<
419 "\n next to last date: " << nextToLast <<
420 "\n termination date: " << terminationDate <<
421 "\n generation rule: " << *rule_ <<
422 "\n end of month: " << *endOfMonth_);
423 }
424
425 Schedule Schedule::after(const Date& truncationDate) const {
426 Schedule result = *this;
427
428 QL_REQUIRE(truncationDate < result.dates_.back(),
429 "truncation date " << truncationDate <<
430 " must be before the last schedule date " <<
431 result.dates_.back());
432 if (truncationDate > result.dates_[0]) {
433 // remove earlier dates
434 while (result.dates_[0] < truncationDate) {
435 result.dates_.erase(result.dates_.begin());
436 if (!result.isRegular_.empty())
437 result.isRegular_.erase(result.isRegular_.begin());
438 }
439
440 // add truncationDate if missing
441 if (truncationDate != result.dates_.front()) {
442 result.dates_.insert(result.dates_.begin(), truncationDate);
443 result.isRegular_.insert(result.isRegular_.begin(), false);
445 }
446 else {
448 }
449
450 if (result.nextToLastDate_ <= truncationDate)
451 result.nextToLastDate_ = Date();
452 if (result.firstDate_ <= truncationDate)
453 result.firstDate_ = Date();
454 }
455
456 return result;
457 }
458
459 Schedule Schedule::until(const Date& truncationDate) const {
460 Schedule result = *this;
461
462 QL_REQUIRE(truncationDate>result.dates_[0],
463 "truncation date " << truncationDate <<
464 " must be later than schedule first date " <<
465 result.dates_[0]);
466 if (truncationDate<result.dates_.back()) {
467 // remove later dates
468 while (result.dates_.back()>truncationDate) {
469 result.dates_.pop_back();
470 if(!result.isRegular_.empty())
471 result.isRegular_.pop_back();
472 }
473
474 // add truncationDate if missing
475 if (truncationDate!=result.dates_.back()) {
476 result.dates_.push_back(truncationDate);
477 result.isRegular_.push_back(false);
479 } else {
481 }
482
483 if (result.nextToLastDate_>=truncationDate)
484 result.nextToLastDate_ = Date();
485 if (result.firstDate_>=truncationDate)
486 result.firstDate_ = Date();
487 }
488
489 return result;
490 }
491
492 std::vector<Date>::const_iterator
493 Schedule::lower_bound(const Date& refDate) const {
494 Date d = (refDate==Date() ?
496 refDate);
497 return std::lower_bound(dates_.begin(), dates_.end(), d);
498 }
499
500 Date Schedule::nextDate(const Date& refDate) const {
501 auto res = lower_bound(refDate);
502 if (res!=dates_.end())
503 return *res;
504 else
505 return {};
506 }
507
508 Date Schedule::previousDate(const Date& refDate) const {
509 auto res = lower_bound(refDate);
510 if (res!=dates_.begin())
511 return *(--res);
512 else
513 return {};
514 }
515
516 bool Schedule::hasIsRegular() const { return !isRegular_.empty(); }
517
518 bool Schedule::isRegular(Size i) const {
520 "full interface (isRegular) not available");
521 QL_REQUIRE(i<=isRegular_.size() && i>0,
522 "index (" << i << ") must be in [1, " <<
523 isRegular_.size() <<"]");
524 return isRegular_[i-1];
525 }
526
527 const std::vector<bool>& Schedule::isRegular() const {
528 QL_REQUIRE(!isRegular_.empty(), "full interface (isRegular) not available");
529 return isRegular_;
530 }
531
532 MakeSchedule& MakeSchedule::from(const Date& effectiveDate) {
533 effectiveDate_ = effectiveDate;
534 return *this;
535 }
536
537 MakeSchedule& MakeSchedule::to(const Date& terminationDate) {
538 terminationDate_ = terminationDate;
539 return *this;
540 }
541
543 tenor_ = tenor;
544 return *this;
545 }
546
548 tenor_ = Period(frequency);
549 return *this;
550 }
551
553 calendar_ = calendar;
554 return *this;
555 }
556
558 convention_ = conv;
559 return *this;
560 }
561
565 return *this;
566 }
567
569 rule_ = r;
570 return *this;
571 }
572
575 return *this;
576 }
577
580 return *this;
581 }
582
584 endOfMonth_ = flag;
585 return *this;
586 }
587
589 firstDate_ = d;
590 return *this;
591 }
592
595 return *this;
596 }
597
598 MakeSchedule::operator Schedule() const {
599 // check for mandatory arguments
600 QL_REQUIRE(effectiveDate_ != Date(), "effective date not provided");
601 QL_REQUIRE(terminationDate_ != Date(), "termination date not provided");
602 QL_REQUIRE(tenor_, "tenor/frequency not provided");
603
604 // set dynamic defaults:
605 BusinessDayConvention convention;
606 // if a convention was set, we use it.
607 if (convention_) { // NOLINT(readability-implicit-bool-conversion)
608 convention = *convention_;
609 } else {
610 if (!calendar_.empty()) {
611 // ...if we set a calendar, we probably want it to be used;
612 convention = Following;
613 } else {
614 // if not, we don't care.
615 convention = Unadjusted;
616 }
617 }
618
619 BusinessDayConvention terminationDateConvention;
620 // if set explicitly, we use it;
621 if (terminationDateConvention_) { // NOLINT(readability-implicit-bool-conversion)
622 terminationDateConvention = *terminationDateConvention_;
623 } else {
624 // Unadjusted as per ISDA specification
625 terminationDateConvention = convention;
626 }
627
628 Calendar calendar = calendar_;
629 // if no calendar was set...
630 if (calendar.empty()) {
631 // ...we use a null one.
632 calendar = NullCalendar();
633 }
634
635 return Schedule(effectiveDate_, terminationDate_, *tenor_, calendar,
636 convention, terminationDateConvention,
637 rule_, endOfMonth_, firstDate_, nextToLastDate_);
638 }
639
641 Date result = Date(20, d.month(), d.year());
642 if (result > d)
643 result -= 1 * Months;
644 if (rule == DateGeneration::TwentiethIMM ||
645 rule == DateGeneration::OldCDS ||
646 rule == DateGeneration::CDS ||
647 rule == DateGeneration::CDS2015) {
648 Month m = result.month();
649 if (m % 3 != 0) { // not a main IMM nmonth
650 Integer skip = m % 3;
651 result -= skip * Months;
652 }
653 }
654 return result;
655 }
656
657}
calendar class
Definition: calendar.hpp:61
bool isEndOfMonth(const Date &d) const
Definition: calendar.hpp:243
bool empty() const
Returns whether or not the calendar is initialized.
Definition: calendar.hpp:202
Date adjust(const Date &, BusinessDayConvention convention=Following) const
Definition: calendar.cpp:84
Date advance(const Date &, Integer n, TimeUnit unit, BusinessDayConvention convention=Following, bool endOfMonth=false) const
Definition: calendar.cpp:130
Date endOfMonth(const Date &d) const
last business day of the month to which the given date belongs
Definition: calendar.hpp:247
Concrete date class.
Definition: date.hpp:125
Month month() const
Definition: date.cpp:82
Year year() const
Definition: date.cpp:93
static Date endOfMonth(const Date &d)
last day of the month to which the given date belongs
Definition: date.hpp:428
std::int_fast32_t serial_type
serial number type
Definition: date.hpp:128
static Date nthWeekday(Size n, Weekday w, Month m, Year y)
n-th given weekday in the given month and year
Definition: date.cpp:802
MakeSchedule & withConvention(BusinessDayConvention)
Definition: schedule.cpp:557
ext::optional< BusinessDayConvention > convention_
Definition: schedule.hpp:146
MakeSchedule & withTerminationDateConvention(BusinessDayConvention)
Definition: schedule.cpp:562
ext::optional< Period > tenor_
Definition: schedule.hpp:145
ext::optional< BusinessDayConvention > terminationDateConvention_
Definition: schedule.hpp:147
MakeSchedule & withRule(DateGeneration::Rule)
Definition: schedule.cpp:568
MakeSchedule & backwards()
Definition: schedule.cpp:578
MakeSchedule & to(const Date &terminationDate)
Definition: schedule.cpp:537
MakeSchedule & withTenor(const Period &)
Definition: schedule.cpp:542
DateGeneration::Rule rule_
Definition: schedule.hpp:148
MakeSchedule & withFirstDate(const Date &d)
Definition: schedule.cpp:588
MakeSchedule & from(const Date &effectiveDate)
Definition: schedule.cpp:532
MakeSchedule & endOfMonth(bool flag=true)
Definition: schedule.cpp:583
MakeSchedule & withFrequency(Frequency)
Definition: schedule.cpp:547
MakeSchedule & forwards()
Definition: schedule.cpp:573
MakeSchedule & withNextToLastDate(const Date &d)
Definition: schedule.cpp:593
MakeSchedule & withCalendar(const Calendar &)
Definition: schedule.cpp:552
Calendar for reproducing theoretical calculations.
Integer length() const
Definition: period.hpp:50
Payment schedule.
Definition: schedule.hpp:40
Calendar calendar_
Definition: schedule.hpp:111
Date nextDate(const Date &refDate) const
Definition: schedule.cpp:500
ext::optional< Period > tenor_
Definition: schedule.hpp:110
ext::optional< BusinessDayConvention > terminationDateConvention_
Definition: schedule.hpp:113
std::vector< Date > dates_
Definition: schedule.hpp:117
const std::vector< Date > & dates() const
Definition: schedule.hpp:75
std::vector< bool > isRegular_
Definition: schedule.hpp:118
Date previousDate(const Date &refDate) const
Definition: schedule.cpp:508
bool endOfMonth() const
Definition: schedule.hpp:225
BusinessDayConvention convention_
Definition: schedule.hpp:112
ext::optional< bool > endOfMonth_
Definition: schedule.hpp:115
ext::optional< DateGeneration::Rule > rule_
Definition: schedule.hpp:114
Schedule after(const Date &truncationDate) const
truncated schedule
Definition: schedule.cpp:425
DateGeneration::Rule rule() const
Definition: schedule.hpp:216
const_iterator lower_bound(const Date &d=Date()) const
Definition: schedule.cpp:493
const std::vector< bool > & isRegular() const
Definition: schedule.cpp:527
const Date & date(Size i) const
Definition: schedule.hpp:160
bool hasIsRegular() const
Definition: schedule.cpp:516
Schedule until(const Date &truncationDate) const
Definition: schedule.cpp:459
const Period & tenor() const
Definition: schedule.hpp:190
DateProxy & evaluationDate()
the date at which pricing is to be performed.
Definition: settings.hpp:147
static Settings & instance()
access to the unique instance
Definition: singleton.hpp:104
#define QL_ENSURE(condition, message)
throw an error if the given post-condition is not verified
Definition: errors.hpp:130
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
#define QL_FAIL(message)
throw an error (possibly with file and line information)
Definition: errors.hpp:92
Date d
Frequency
Frequency of events.
Definition: frequency.hpp:37
Month
Month names.
Definition: date.hpp:57
BusinessDayConvention
Business Day conventions.
@ Wednesday
Definition: weekday.hpp:44
unsigned QL_INTEGER Natural
positive integer
Definition: types.hpp:43
QL_INTEGER Integer
integer number
Definition: types.hpp:35
std::size_t Size
size of a container
Definition: types.hpp:58
IMM-related date functions.
Definition: any.hpp:35
Date previousTwentieth(const Date &d, DateGeneration::Rule rule)
Definition: schedule.cpp:640
STL namespace.
Maps optional to either the boost or std implementation.
ext::shared_ptr< YieldTermStructure > r
date schedule
global repository for run-time library settings
static bool isIMMdate(const Date &d, bool mainCycle=true)
returns whether or not the given date is an IMM date
Definition: imm.cpp:34