QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
imm.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl
5 Copyright (C) 2003, 2004, 2005, 2006, 2007 StatPro Italia srl
6 Copyright (C) 2004, 2005, 2006 Ferdinando Ametrano
7 Copyright (C) 2006 Katiuscia Manzoni
8
9 This file is part of QuantLib, a free-software/open-source library
10 for financial quantitative analysts and developers - http://quantlib.org/
11
12 QuantLib is free software: you can redistribute it and/or modify it
13 under the terms of the QuantLib license. You should have received a
14 copy of the license along with this program; if not, please email
15 <quantlib-dev@lists.sf.net>. The license is also available online at
16 <http://quantlib.org/license.shtml>.
17
18 This program is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20 FOR A PARTICULAR PURPOSE. See the license for more details.
21*/
22
23#include <ql/time/imm.hpp>
24#include <ql/settings.hpp>
25#include <ql/utilities/dataparsers.hpp>
26#include <boost/algorithm/string/case_conv.hpp>
27#include <string>
28
29using boost::algorithm::to_upper_copy;
30using std::string;
31
32namespace QuantLib {
33
34 bool IMM::isIMMdate(const Date& date, bool mainCycle) {
35 if (date.weekday()!=Wednesday)
36 return false;
37
38 Day d = date.dayOfMonth();
39 if (d<15 || d>21)
40 return false;
41
42 if (!mainCycle) return true;
43
44 switch (date.month()) {
45 case March:
46 case June:
47 case September:
48 case December:
49 return true;
50 default:
51 return false;
52 }
53 }
54
55 bool IMM::isIMMcode(const std::string& in, bool mainCycle) {
56 if (in.length() != 2)
57 return false;
58
59 string str1("0123456789");
60 string::size_type loc = str1.find(in.substr(1,1), 0);
61 if (loc == string::npos)
62 return false;
63
64 if (mainCycle) str1 = "hmzuHMZU";
65 else str1 = "fghjkmnquvxzFGHJKMNQUVXZ";
66 loc = str1.find(in.substr(0,1), 0);
67 return loc != string::npos;
68 }
69
70 std::string IMM::code(const Date& date) {
71 QL_REQUIRE(isIMMdate(date, false),
72 date << " is not an IMM date");
73
74 std::ostringstream IMMcode;
75 unsigned int y = date.year() % 10;
76 switch(date.month()) {
77 case January:
78 IMMcode << 'F' << y;
79 break;
80 case February:
81 IMMcode << 'G' << y;
82 break;
83 case March:
84 IMMcode << 'H' << y;
85 break;
86 case April:
87 IMMcode << 'J' << y;
88 break;
89 case May:
90 IMMcode << 'K' << y;
91 break;
92 case June:
93 IMMcode << 'M' << y;
94 break;
95 case July:
96 IMMcode << 'N' << y;
97 break;
98 case August:
99 IMMcode << 'Q' << y;
100 break;
101 case September:
102 IMMcode << 'U' << y;
103 break;
104 case October:
105 IMMcode << 'V' << y;
106 break;
107 case November:
108 IMMcode << 'X' << y;
109 break;
110 case December:
111 IMMcode << 'Z' << y;
112 break;
113 default:
114 QL_FAIL("not an IMM month (and it should have been)");
115 }
116
117 #if defined(QL_EXTRA_SAFETY_CHECKS)
118 QL_ENSURE(isIMMcode(IMMcode.str(), false),
119 "the result " << IMMcode.str() <<
120 " is an invalid IMM code");
121 #endif
122 return IMMcode.str();
123 }
124
125 Date IMM::date(const std::string& immCode,
126 const Date& refDate) {
127 QL_REQUIRE(isIMMcode(immCode, false),
128 immCode << " is not a valid IMM code");
129
130 Date referenceDate = (refDate != Date() ?
131 refDate :
132 Date(Settings::instance().evaluationDate()));
133
134 std::string code = to_upper_copy(immCode);
135 std::string ms = code.substr(0,1);
137 if (ms=="F") m = January;
138 else if (ms=="G") m = February;
139 else if (ms=="H") m = March;
140 else if (ms=="J") m = April;
141 else if (ms=="K") m = May;
142 else if (ms=="M") m = June;
143 else if (ms=="N") m = July;
144 else if (ms=="Q") m = August;
145 else if (ms=="U") m = September;
146 else if (ms=="V") m = October;
147 else if (ms=="X") m = November;
148 else if (ms=="Z") m = December;
149 else QL_FAIL("invalid IMM month letter");
150
151 Year y = std::stoi(code.substr(1,1));
152 /* year<1900 are not valid QuantLib years: to avoid a run-time
153 exception few lines below we need to add 10 years right away */
154 if (y==0 && referenceDate.year()<=1909) y+=10;
155 Year referenceYear = (referenceDate.year() % 10);
156 y += referenceDate.year() - referenceYear;
157 Date result = IMM::nextDate(Date(1, m, y), false);
158 if (result<referenceDate)
159 return IMM::nextDate(Date(1, m, y+10), false);
160
161 return result;
162 }
163
164 Date IMM::nextDate(const Date& date, bool mainCycle) {
165 Date refDate = (date == Date() ?
166 Date(Settings::instance().evaluationDate()) :
167 date);
168 Year y = refDate.year();
169 QuantLib::Month m = refDate.month();
170
171 Size offset = mainCycle ? 3 : 1;
172 Size skipMonths = offset-(m%offset);
173 if (skipMonths != offset || refDate.dayOfMonth() > 21) {
174 skipMonths += Size(m);
175 if (skipMonths<=12) {
176 m = QuantLib::Month(skipMonths);
177 } else {
178 m = QuantLib::Month(skipMonths-12);
179 y += 1;
180 }
181 }
182
183 Date result = Date::nthWeekday(3, Wednesday, m, y);
184 if (result<=refDate)
185 result = nextDate(Date(22, m, y), mainCycle);
186 return result;
187 }
188
189 Date IMM::nextDate(const std::string& IMMcode,
190 bool mainCycle,
191 const Date& referenceDate) {
192 Date immDate = date(IMMcode, referenceDate);
193 return nextDate(immDate+1, mainCycle);
194 }
195
196 std::string IMM::nextCode(const Date& d,
197 bool mainCycle) {
198 Date date = nextDate(d, mainCycle);
199 return code(date);
200 }
201
202 std::string IMM::nextCode(const std::string& immCode,
203 bool mainCycle,
204 const Date& referenceDate) {
205 Date date = nextDate(immCode, mainCycle, referenceDate);
206 return code(date);
207 }
208
209}
Concrete date class.
Definition: date.hpp:125
Month month() const
Definition: date.cpp:82
Year year() const
Definition: date.cpp:93
Day dayOfMonth() const
Definition: date.hpp:400
Weekday weekday() const
Definition: date.hpp:395
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
static Settings & instance()
access to the unique instance
Definition: singleton.hpp:104
Integer Year
Year number.
Definition: date.hpp:87
Integer Day
Day number.
Definition: date.hpp:53
Month
Month names.
Definition: date.hpp:57
@ December
Definition: date.hpp:68
@ August
Definition: date.hpp:64
@ January
Definition: date.hpp:57
@ July
Definition: date.hpp:63
@ May
Definition: date.hpp:61
@ March
Definition: date.hpp:59
@ February
Definition: date.hpp:58
@ April
Definition: date.hpp:60
@ November
Definition: date.hpp:67
@ October
Definition: date.hpp:66
@ June
Definition: date.hpp:62
@ September
Definition: date.hpp:65
@ Wednesday
Definition: weekday.hpp:44
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
static std::string nextCode(const Date &d=Date(), bool mainCycle=true)
next IMM code following the given date
Definition: imm.cpp:196
static bool isIMMcode(const std::string &in, bool mainCycle=true)
returns whether or not the given string is an IMM code
Definition: imm.cpp:55
static Date date(const std::string &immCode, const Date &referenceDate=Date())
Definition: imm.cpp:125
static std::string code(const Date &immDate)
Definition: imm.cpp:70
static bool isIMMdate(const Date &d, bool mainCycle=true)
returns whether or not the given date is an IMM date
Definition: imm.cpp:34
static Date nextDate(const Date &d=Date(), bool mainCycle=true)
next IMM date following the given date
Definition: imm.cpp:164