QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
ecb.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2009, 2011 Ferdinando Ametrano
5 Copyright (C) 2015 Paolo Mazzocchi
6
7 This file is part of QuantLib, a free-software/open-source library
8 for financial quantitative analysts and developers - http://quantlib.org/
9
10 QuantLib is free software: you can redistribute it and/or modify it
11 under the terms of the QuantLib license. You should have received a
12 copy of the license along with this program; if not, please email
13 <quantlib-dev@lists.sf.net>. The license is also available online at
14 <http://quantlib.org/license.shtml>.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the license for more details.
19*/
20
21#include <ql/time/ecb.hpp>
22#include <ql/settings.hpp>
23#include <ql/utilities/dataparsers.hpp>
24#include <boost/algorithm/string/case_conv.hpp>
25#include <algorithm>
26#include <string>
27
28using boost::algorithm::to_upper_copy;
29using std::string;
30
31namespace QuantLib {
32
33 namespace detail {
34 static std::set<Date> ecbKnownDateSet = {
35 Date(38371), Date(38391), Date(38420), Date(38455), Date(38483), Date(38511),
36 Date(38546), Date(38574), Date(38602), Date(38637), Date(38665),
37 Date(38692), // 2005
38 Date(38735), Date(38756), Date(38784), Date(38819), Date(38847), Date(38883),
39 Date(38910), Date(38938), Date(38966), Date(39001), Date(39029),
40 Date(39064), // 2006
41 Date(39099), Date(39127), Date(39155), Date(39190), Date(39217), Date(39246),
42 Date(39274), Date(39302), Date(39337), Date(39365), Date(39400),
43 Date(39428), // 2007
44 Date(39463), Date(39491), Date(39519), Date(39554), Date(39582), Date(39610),
45 Date(39638), Date(39673), Date(39701), Date(39729), Date(39764),
46 Date(39792), // 2008
47 Date(39834), Date(39855), Date(39883), Date(39911), Date(39946), Date(39974),
48 Date(40002), Date(40037), Date(40065), Date(40100), Date(40128),
49 Date(40155), // 2009
50 Date(40198), Date(40219), Date(40247), Date(40282), Date(40310), Date(40345),
51 Date(40373), Date(40401), Date(40429), Date(40464), Date(40492),
52 Date(40520), // 2010
53 Date(40562), Date(40583), Date(40611), Date(40646), Date(40674), Date(40709),
54 Date(40737), Date(40765), Date(40800), Date(40828), Date(40856),
55 Date(40891), // 2011
56 // http://www.ecb.europa.eu/press/pr/date/2011/html/pr110520.en.html
57 Date(40926), Date(40954), Date(40982), Date(41010), Date(41038), Date(41073),
58 Date(41101), Date(41129), Date(41164), Date(41192), Date(41227),
59 Date(41255), // 2012
60 Date(41290), Date(41318), Date(41346), Date(41374), Date(41402), Date(41437),
61 Date(41465), Date(41493), Date(41528), Date(41556), Date(41591),
62 Date(41619), // 2013
63 // http://www.ecb.europa.eu/press/pr/date/2013/html/pr130610.en.html
64 Date(41654), Date(41682), Date(41710), Date(41738), Date(41773), Date(41801),
65 Date(41829), Date(41864), Date(41892), Date(41920), Date(41955),
66 Date(41983), // 2014
67 // http://www.ecb.europa.eu/press/pr/date/2014/html/pr140717_1.en.html
68 Date(42032), Date(42074), Date(42116), Date(42165), Date(42207), Date(42256),
69 Date(42305),
70 Date(42347), // 2015
71 // https://www.ecb.europa.eu/press/pr/date/2015/html/pr150622.en.html
72 Date(42396), Date(42445), Date(42487), Date(42529), Date(42578), Date(42627),
73 Date(42669),
74 Date(42718), // 2016
75 // https://www.ecb.europa.eu/press/calendars/reserve/html/index.en.html
76 Date(42760), Date(42809), Date(42858), Date(42900), Date(42942), Date(42991),
77 Date(43040),
78 Date(43089) // 2017
79 };
80 }
81
82 const std::set<Date>& ECB::knownDates() {
83 return detail::ecbKnownDateSet;
84 }
85
86 void ECB::addDate(const Date& d) {
87 detail::ecbKnownDateSet.insert(d);
88 }
89
90 void ECB::removeDate(const Date& d) {
91 detail::ecbKnownDateSet.erase(d);
92 }
93
94 Date ECB::date(const string& ecbCode,
95 const Date& refDate) {
96
97 QL_REQUIRE(isECBcode(ecbCode),
98 ecbCode << " is not a valid ECB code");
99
100 string code = to_upper_copy(ecbCode);
101 string monthString = code.substr(0, 3);
102 Month m;
103 if (monthString=="JAN") m = January;
104 else if (monthString=="FEB") m = February;
105 else if (monthString=="MAR") m = March;
106 else if (monthString=="APR") m = April;
107 else if (monthString=="MAY") m = May;
108 else if (monthString=="JUN") m = June;
109 else if (monthString=="JUL") m = July;
110 else if (monthString=="AUG") m = August;
111 else if (monthString=="SEP") m = September;
112 else if (monthString=="OCT") m = October;
113 else if (monthString=="NOV") m = November;
114 else if (monthString=="DEC") m = December;
115 else QL_FAIL("not an ECB month (and it should have been)");
116
117 Year y = std::stoi(code.substr(3, 2));
118 Date referenceDate = (refDate != Date() ?
119 refDate :
120 Date(Settings::instance().evaluationDate()));
121 Year referenceYear = (referenceDate.year() % 100);
122 y += referenceDate.year() - referenceYear;
123 if (y<Date::minDate().year())
125
126 return ECB::nextDate(Date(1, m, y) - 1);
127 }
128
129 string ECB::code(const Date& ecbDate) {
130
131 QL_REQUIRE(isECBdate(ecbDate),
132 ecbDate << " is not a valid ECB date");
133
134 std::ostringstream ECBcode;
135 unsigned int y = ecbDate.year() % 100;
136 string padding;
137 if (y < 10)
138 padding = "0";
139 switch(ecbDate.month()) {
140 case January:
141 ECBcode << "JAN" << padding << y;
142 break;
143 case February:
144 ECBcode << "FEB" << padding << y;
145 break;
146 case March:
147 ECBcode << "MAR" << padding << y;
148 break;
149 case April:
150 ECBcode << "APR" << padding << y;
151 break;
152 case May:
153 ECBcode << "MAY" << padding << y;
154 break;
155 case June:
156 ECBcode << "JUN" << padding << y;
157 break;
158 case July:
159 ECBcode << "JUL" << padding << y;
160 break;
161 case August:
162 ECBcode << "AUG" << padding << y;
163 break;
164 case September:
165 ECBcode << "SEP" << padding << y;
166 break;
167 case October:
168 ECBcode << "OCT" << padding << y;
169 break;
170 case November:
171 ECBcode << "NOV" << padding << y;
172 break;
173 case December:
174 ECBcode << "DEC" << padding << y;
175 break;
176 default:
177 QL_FAIL("not an ECB month (and it should have been)");
178 }
179
180 #if defined(QL_EXTRA_SAFETY_CHECKS)
181 QL_ENSURE(isECBcode(ECBcode.str()),
182 "the result " << ECBcode.str() <<
183 " is an invalid ECB code");
184 #endif
185 return ECBcode.str();
186 }
187
188
189
190 Date ECB::nextDate(const Date& date) {
191 Date d = (date == Date() ?
193 date);
194
195 auto i = std::upper_bound(knownDates().begin(), knownDates().end(), d);
196
197 QL_REQUIRE(i != knownDates().end(),
198 "ECB dates after " << *knownDates().rbegin() << " are unknown");
199 return *i;
200 }
201
202 std::vector<Date> ECB::nextDates(const Date& date) {
203 Date d = (date == Date() ?
205 date);
206
207 auto i = std::upper_bound(knownDates().begin(), knownDates().end(), d);
208
209 QL_REQUIRE(i != knownDates().end(),
210 "ECB dates after " << *knownDates().rbegin() << " are unknown");
211 return std::vector<Date>(i, knownDates().end());
212 }
213
214
215 bool ECB::isECBcode(const std::string& ecbCode) {
216
217 if (ecbCode.length() != 5)
218 return false;
219
220 string code = to_upper_copy(ecbCode);
221
222 string str1("0123456789");
223 string::size_type loc = str1.find(code.substr(3, 1), 0);
224 if (loc == string::npos)
225 return false;
226 loc = str1.find(code.substr(4, 1), 0);
227 if (loc == string::npos)
228 return false;
229
230 string monthString = code.substr(0, 3);
231 if (monthString=="JAN") return true;
232 else if (monthString=="FEB") return true;
233 else if (monthString=="MAR") return true;
234 else if (monthString=="APR") return true;
235 else if (monthString=="MAY") return true;
236 else if (monthString=="JUN") return true;
237 else if (monthString=="JUL") return true;
238 else if (monthString=="AUG") return true;
239 else if (monthString=="SEP") return true;
240 else if (monthString=="OCT") return true;
241 else if (monthString=="NOV") return true;
242 else if (monthString=="DEC") return true;
243 else return false;
244 }
245
246 string ECB::nextCode(const std::string& ecbCode) {
247 QL_REQUIRE(isECBcode(ecbCode),
248 ecbCode << " is not a valid ECB code");
249
250 string code = to_upper_copy(ecbCode);
251 std::ostringstream result;
252
253 string monthString = code.substr(0, 3);
254 if (monthString=="JAN") result << "FEB" << code.substr(3, 2);
255 else if (monthString=="FEB") result << "MAR" << code.substr(3, 2);
256 else if (monthString=="MAR") result << "APR" << code.substr(3, 2);
257 else if (monthString=="APR") result << "MAY" << code.substr(3, 2);
258 else if (monthString=="MAY") result << "JUN" << code.substr(3, 2);
259 else if (monthString=="JUN") result << "JUL" << code.substr(3, 2);
260 else if (monthString=="JUL") result << "AUG" << code.substr(3, 2);
261 else if (monthString=="AUG") result << "SEP" << code.substr(3, 2);
262 else if (monthString=="SEP") result << "OCT" << code.substr(3, 2);
263 else if (monthString=="OCT") result << "NOV" << code.substr(3, 2);
264 else if (monthString=="NOV") result << "DEC" << code.substr(3, 2);
265 else if (monthString=="DEC") {
266 unsigned int y = (std::stoi(code.substr(3, 2)) + 1) % 100;
267 string padding;
268 if (y < 10)
269 padding = "0";
270
271 result << "JAN" << padding << y;
272 } else QL_FAIL("not an ECB month (and it should have been)");
273
274
275 #if defined(QL_EXTRA_SAFETY_CHECKS)
276 QL_ENSURE(isECBcode(result.str()),
277 "the result " << result.str() <<
278 " is an invalid ECB code");
279 #endif
280 return result.str();
281 }
282
283}
Concrete date class.
Definition: date.hpp:125
static Date minDate()
earliest allowed date
Definition: date.cpp:766
Month month() const
Definition: date.cpp:82
Year year() const
Definition: date.cpp:93
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
Integer Year
Year number.
Definition: date.hpp:87
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
Definition: any.hpp:35
static void removeDate(const Date &d)
Definition: ecb.cpp:90
static std::vector< Date > nextDates(const Date &d=Date())
next maintenance period start dates following the given date
Definition: ecb.cpp:202
static void addDate(const Date &d)
Definition: ecb.cpp:86
static std::string nextCode(const Date &d=Date())
next ECB code following the given date
Definition: ecb.hpp:90
static const std::set< Date > & knownDates()
Definition: ecb.cpp:82
static bool isECBcode(const std::string &in)
returns whether or not the given string is an ECB code
Definition: ecb.cpp:215
static Date date(Month m, Year y)
maintenance period start date in the given month/year
Definition: ecb.hpp:41
static std::string code(const Date &ecbDate)
Definition: ecb.cpp:129
static Date nextDate(const Date &d=Date())
next maintenance period start date following the given date
Definition: ecb.cpp:190
static bool isECBdate(const Date &d)
Definition: ecb.hpp:81