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