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>
28using boost::algorithm::to_upper_copy;
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),
38 Date(38735), Date(38756), Date(38784), Date(38819), Date(38847), Date(38883),
39 Date(38910), Date(38938), Date(38966), Date(39001), Date(39029),
41 Date(39099), Date(39127), Date(39155), Date(39190), Date(39217), Date(39246),
42 Date(39274), Date(39302), Date(39337), Date(39365), Date(39400),
44 Date(39463), Date(39491), Date(39519), Date(39554), Date(39582), Date(39610),
45 Date(39638), Date(39673), Date(39701), Date(39729), Date(39764),
47 Date(39834), Date(39855), Date(39883), Date(39911), Date(39946), Date(39974),
48 Date(40002), Date(40037), Date(40065), Date(40100), Date(40128),
50 Date(40198), Date(40219), Date(40247), Date(40282), Date(40310), Date(40345),
51 Date(40373), Date(40401), Date(40429), Date(40464), Date(40492),
53 Date(40562), Date(40583), Date(40611), Date(40646), Date(40674), Date(40709),
54 Date(40737), Date(40765), Date(40800), Date(40828), Date(40856),
57 Date(40926), Date(40954), Date(40982), Date(41010), Date(41038), Date(41073),
58 Date(41101), Date(41129), Date(41164), Date(41192), Date(41227),
60 Date(41290), Date(41318), Date(41346), Date(41374), Date(41402), Date(41437),
61 Date(41465), Date(41493), Date(41528), Date(41556), Date(41591),
64 Date(41654), Date(41682), Date(41710), Date(41738), Date(41773), Date(41801),
65 Date(41829), Date(41864), Date(41892), Date(41920), Date(41955),
68 Date(42032), Date(42074), Date(42116), Date(42165), Date(42207), Date(42256),
72 Date(42396), Date(42445), Date(42487), Date(42529), Date(42578), Date(42627),
76 Date(42760), Date(42809), Date(42858), Date(42900), Date(42942), Date(42991),
83 return detail::ecbKnownDateSet;
87 detail::ecbKnownDateSet.insert(d);
91 detail::ecbKnownDateSet.erase(d);
95 const Date& refDate) {
98 ecbCode <<
" is not a valid ECB code");
100 string code = to_upper_copy(ecbCode);
101 string monthString =
code.substr(0, 3);
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)");
117 Year y = std::stoi(
code.substr(3, 2));
118 Date referenceDate = (refDate !=
Date() ?
121 Year referenceYear = (referenceDate.
year() % 100);
122 y += referenceDate.
year() - referenceYear;
132 ecbDate <<
" is not a valid ECB date");
134 std::ostringstream ECBcode;
135 unsigned int y = ecbDate.
year() % 100;
139 switch(ecbDate.
month()) {
141 ECBcode <<
"JAN" << padding << y;
144 ECBcode <<
"FEB" << padding << y;
147 ECBcode <<
"MAR" << padding << y;
150 ECBcode <<
"APR" << padding << y;
153 ECBcode <<
"MAY" << padding << y;
156 ECBcode <<
"JUN" << padding << y;
159 ECBcode <<
"JUL" << padding << y;
162 ECBcode <<
"AUG" << padding << y;
165 ECBcode <<
"SEP" << padding << y;
168 ECBcode <<
"OCT" << padding << y;
171 ECBcode <<
"NOV" << padding << y;
174 ECBcode <<
"DEC" << padding << y;
177 QL_FAIL(
"not an ECB month (and it should have been)");
180 #if defined(QL_EXTRA_SAFETY_CHECKS)
182 "the result " << ECBcode.str() <<
183 " is an invalid ECB code");
185 return ECBcode.str();
198 "ECB dates after " << *
knownDates().rbegin() <<
" are unknown");
210 "ECB dates after " << *
knownDates().rbegin() <<
" are unknown");
211 return std::vector<Date>(i,
knownDates().end());
217 if (ecbCode.length() != 5)
220 string code = to_upper_copy(ecbCode);
222 string str1(
"0123456789");
223 string::size_type loc = str1.find(
code.substr(3, 1), 0);
224 if (loc == string::npos)
226 loc = str1.find(
code.substr(4, 1), 0);
227 if (loc == string::npos)
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;
248 ecbCode <<
" is not a valid ECB code");
250 string code = to_upper_copy(ecbCode);
251 std::ostringstream result;
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;
271 result <<
"JAN" << padding << y;
272 }
else QL_FAIL(
"not an ECB month (and it should have been)");
275 #if defined(QL_EXTRA_SAFETY_CHECKS)
277 "the result " << result.str() <<
278 " is an invalid ECB code");
static Date minDate()
earliest allowed date
DateProxy & evaluationDate()
the date at which pricing is to be performed.
static Settings & instance()
access to the unique instance
static void removeDate(const Date &d)
static std::vector< Date > nextDates(const Date &d=Date())
next maintenance period start dates following the given date
static void addDate(const Date &d)
static std::string nextCode(const Date &d=Date())
next ECB code following the given date
static const std::set< Date > & knownDates()
static bool isECBcode(const std::string &in)
returns whether or not the given string is an ECB code
static Date date(Month m, Year y)
maintenance period start date in the given month/year
static std::string code(const Date &ecbDate)
static Date nextDate(const Date &d=Date())
next maintenance period start date following the given date
static bool isECBdate(const Date &d)