QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.38
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 [[fallthrough]];
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 for (Size i=1; i<dates_.size()-1; ++i)
380 dates_[i] = calendar_.adjust(Date::endOfMonth(dates_[i]), convention);
381 } else {
382 for (Size i=1; i<dates_.size()-1; ++i)
383 dates_[i] = calendar_.adjust(dates_[i], convention);
384 }
385
386 // Final safety checks to remove extra next-to-last date, if
387 // necessary. It can happen to be equal or later than the end
388 // date due to EOM adjustments (see the Schedule test suite
389 // for an example).
390 if (dates_.size() >= 2 && dates_[dates_.size()-2] >= dates_.back()) {
391 // there might be two dates only, then isRegular_ has size one
392 if (isRegular_.size() >= 2) {
393 isRegular_[isRegular_.size() - 2] =
394 (dates_[dates_.size() - 2] == dates_.back());
395 }
396 dates_[dates_.size() - 2] = dates_.back();
397 dates_.pop_back();
398 isRegular_.pop_back();
399 }
400 if (dates_.size() >= 2 && dates_[1] <= dates_.front()) {
401 isRegular_[1] =
402 (dates_[1] == dates_.front());
403 dates_[1] = dates_.front();
404 dates_.erase(dates_.begin());
405 isRegular_.erase(isRegular_.begin());
406 }
407
408 QL_ENSURE(dates_.size()>1,
409 "degenerate single date (" << dates_[0] << ") schedule" <<
410 "\n seed date: " << seed <<
411 "\n exit date: " << exitDate <<
412 "\n effective date: " << effectiveDate <<
413 "\n first date: " << first <<
414 "\n next to last date: " << nextToLast <<
415 "\n termination date: " << terminationDate <<
416 "\n generation rule: " << *rule_ <<
417 "\n end of month: " << *endOfMonth_);
418 }
419
420 Schedule Schedule::after(const Date& truncationDate) const {
421 Schedule result = *this;
422
423 QL_REQUIRE(truncationDate < result.dates_.back(),
424 "truncation date " << truncationDate <<
425 " must be before the last schedule date " <<
426 result.dates_.back());
427 if (truncationDate > result.dates_[0]) {
428 // remove earlier dates
429 while (result.dates_[0] < truncationDate) {
430 result.dates_.erase(result.dates_.begin());
431 if (!result.isRegular_.empty())
432 result.isRegular_.erase(result.isRegular_.begin());
433 }
434
435 // add truncationDate if missing
436 if (truncationDate != result.dates_.front()) {
437 result.dates_.insert(result.dates_.begin(), truncationDate);
438 result.isRegular_.insert(result.isRegular_.begin(), false);
440 }
441 else {
443 }
444
445 if (result.nextToLastDate_ <= truncationDate)
446 result.nextToLastDate_ = Date();
447 if (result.firstDate_ <= truncationDate)
448 result.firstDate_ = Date();
449 }
450
451 return result;
452 }
453
454 Schedule Schedule::until(const Date& truncationDate) const {
455 Schedule result = *this;
456
457 QL_REQUIRE(truncationDate>result.dates_[0],
458 "truncation date " << truncationDate <<
459 " must be later than schedule first date " <<
460 result.dates_[0]);
461 if (truncationDate<result.dates_.back()) {
462 // remove later dates
463 while (result.dates_.back()>truncationDate) {
464 result.dates_.pop_back();
465 if(!result.isRegular_.empty())
466 result.isRegular_.pop_back();
467 }
468
469 // add truncationDate if missing
470 if (truncationDate!=result.dates_.back()) {
471 result.dates_.push_back(truncationDate);
472 result.isRegular_.push_back(false);
474 } else {
476 }
477
478 if (result.nextToLastDate_>=truncationDate)
479 result.nextToLastDate_ = Date();
480 if (result.firstDate_>=truncationDate)
481 result.firstDate_ = Date();
482 }
483
484 return result;
485 }
486
487 std::vector<Date>::const_iterator
488 Schedule::lower_bound(const Date& refDate) const {
489 Date d = (refDate==Date() ?
491 refDate);
492 return std::lower_bound(dates_.begin(), dates_.end(), d);
493 }
494
495 Date Schedule::nextDate(const Date& refDate) const {
496 auto res = lower_bound(refDate);
497 if (res!=dates_.end())
498 return *res;
499 else
500 return {};
501 }
502
503 Date Schedule::previousDate(const Date& refDate) const {
504 auto res = lower_bound(refDate);
505 if (res!=dates_.begin())
506 return *(--res);
507 else
508 return {};
509 }
510
511 bool Schedule::hasIsRegular() const { return !isRegular_.empty(); }
512
513 bool Schedule::isRegular(Size i) const {
515 "full interface (isRegular) not available");
516 QL_REQUIRE(i<=isRegular_.size() && i>0,
517 "index (" << i << ") must be in [1, " <<
518 isRegular_.size() <<"]");
519 return isRegular_[i-1];
520 }
521
522 const std::vector<bool>& Schedule::isRegular() const {
523 QL_REQUIRE(!isRegular_.empty(), "full interface (isRegular) not available");
524 return isRegular_;
525 }
526
527 MakeSchedule& MakeSchedule::from(const Date& effectiveDate) {
528 effectiveDate_ = effectiveDate;
529 return *this;
530 }
531
532 MakeSchedule& MakeSchedule::to(const Date& terminationDate) {
533 terminationDate_ = terminationDate;
534 return *this;
535 }
536
538 tenor_ = tenor;
539 return *this;
540 }
541
543 tenor_ = Period(frequency);
544 return *this;
545 }
546
548 calendar_ = calendar;
549 return *this;
550 }
551
553 convention_ = conv;
554 return *this;
555 }
556
560 return *this;
561 }
562
564 rule_ = r;
565 return *this;
566 }
567
570 return *this;
571 }
572
575 return *this;
576 }
577
579 endOfMonth_ = flag;
580 return *this;
581 }
582
584 firstDate_ = d;
585 return *this;
586 }
587
590 return *this;
591 }
592
593 MakeSchedule::operator Schedule() const {
594 // check for mandatory arguments
595 QL_REQUIRE(effectiveDate_ != Date(), "effective date not provided");
596 QL_REQUIRE(terminationDate_ != Date(), "termination date not provided");
597 QL_REQUIRE(tenor_, "tenor/frequency not provided");
598
599 // set dynamic defaults:
600 BusinessDayConvention convention;
601 // if a convention was set, we use it.
602 if (convention_) { // NOLINT(readability-implicit-bool-conversion)
603 convention = *convention_;
604 } else {
605 if (!calendar_.empty()) {
606 // ...if we set a calendar, we probably want it to be used;
607 convention = Following;
608 } else {
609 // if not, we don't care.
610 convention = Unadjusted;
611 }
612 }
613
614 BusinessDayConvention terminationDateConvention;
615 // if set explicitly, we use it;
616 if (terminationDateConvention_) { // NOLINT(readability-implicit-bool-conversion)
617 terminationDateConvention = *terminationDateConvention_;
618 } else {
619 // Unadjusted as per ISDA specification
620 terminationDateConvention = convention;
621 }
622
623 Calendar calendar = calendar_;
624 // if no calendar was set...
625 if (calendar.empty()) {
626 // ...we use a null one.
627 calendar = NullCalendar();
628 }
629
630 return Schedule(effectiveDate_, terminationDate_, *tenor_, calendar,
631 convention, terminationDateConvention,
632 rule_, endOfMonth_, firstDate_, nextToLastDate_);
633 }
634
636 Date result = Date(20, d.month(), d.year());
637 if (result > d)
638 result -= 1 * Months;
639 if (rule == DateGeneration::TwentiethIMM ||
640 rule == DateGeneration::OldCDS ||
641 rule == DateGeneration::CDS ||
642 rule == DateGeneration::CDS2015) {
643 Month m = result.month();
644 if (m % 3 != 0) { // not a main IMM nmonth
645 Integer skip = m % 3;
646 result -= skip * Months;
647 }
648 }
649 return result;
650 }
651
652}
calendar class
Definition: calendar.hpp:61
bool isEndOfMonth(const Date &d) const
Definition: calendar.hpp:257
bool empty() const
Returns whether or not the calendar is initialized.
Definition: calendar.hpp:208
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
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:424
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:552
ext::optional< BusinessDayConvention > convention_
Definition: schedule.hpp:148
MakeSchedule & withTerminationDateConvention(BusinessDayConvention)
Definition: schedule.cpp:557
ext::optional< Period > tenor_
Definition: schedule.hpp:147
ext::optional< BusinessDayConvention > terminationDateConvention_
Definition: schedule.hpp:149
MakeSchedule & withRule(DateGeneration::Rule)
Definition: schedule.cpp:563
MakeSchedule & backwards()
Definition: schedule.cpp:573
MakeSchedule & to(const Date &terminationDate)
Definition: schedule.cpp:532
MakeSchedule & withTenor(const Period &)
Definition: schedule.cpp:537
DateGeneration::Rule rule_
Definition: schedule.hpp:150
MakeSchedule & withFirstDate(const Date &d)
Definition: schedule.cpp:583
MakeSchedule & from(const Date &effectiveDate)
Definition: schedule.cpp:527
MakeSchedule & endOfMonth(bool flag=true)
Definition: schedule.cpp:578
MakeSchedule & withFrequency(Frequency)
Definition: schedule.cpp:542
MakeSchedule & forwards()
Definition: schedule.cpp:568
MakeSchedule & withNextToLastDate(const Date &d)
Definition: schedule.cpp:588
MakeSchedule & withCalendar(const Calendar &)
Definition: schedule.cpp:547
Calendar for reproducing theoretical calculations.
Integer length() const
Definition: period.hpp:50
Payment schedule.
Definition: schedule.hpp:40
Calendar calendar_
Definition: schedule.hpp:113
Date nextDate(const Date &refDate) const
Definition: schedule.cpp:495
ext::optional< Period > tenor_
Definition: schedule.hpp:112
ext::optional< BusinessDayConvention > terminationDateConvention_
Definition: schedule.hpp:115
std::vector< Date > dates_
Definition: schedule.hpp:119
const std::vector< Date > & dates() const
Definition: schedule.hpp:73
std::vector< bool > isRegular_
Definition: schedule.hpp:120
Date previousDate(const Date &refDate) const
Definition: schedule.cpp:503
bool endOfMonth() const
Definition: schedule.hpp:237
BusinessDayConvention convention_
Definition: schedule.hpp:114
ext::optional< bool > endOfMonth_
Definition: schedule.hpp:117
ext::optional< DateGeneration::Rule > rule_
Definition: schedule.hpp:116
Schedule after(const Date &truncationDate) const
truncated schedule
Definition: schedule.cpp:420
DateGeneration::Rule rule() const
Definition: schedule.hpp:228
const_iterator lower_bound(const Date &d=Date()) const
Definition: schedule.cpp:488
const std::vector< bool > & isRegular() const
Definition: schedule.cpp:522
const Date & date(Size i) const
Definition: schedule.hpp:162
bool hasIsRegular() const
Definition: schedule.cpp:511
Schedule until(const Date &truncationDate) const
Definition: schedule.cpp:454
const Period & tenor() const
Definition: schedule.hpp:202
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
BusinessDayConvention convention_
#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:37
Date previousTwentieth(const Date &d, DateGeneration::Rule rule)
Definition: schedule.cpp:635
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