1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2006 Joseph Wang
5 Copyright (C) 2010 Liquidnet Holdings, Inc.
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/*! \file timeseries.hpp
22 \brief Container for historical data
23*/
24
25#ifndef quantlib_timeseries_hpp
26#define quantlib_timeseries_hpp
27
28#include <ql/time/date.hpp>
29#include <ql/utilities/null.hpp>
30#include <ql/errors.hpp>
31#include <ql/functional.hpp>
32#include <boost/iterator/transform_iterator.hpp>
33#include <iterator>
34#include <algorithm>
35#include <map>
36#include <vector>
37#include <type_traits>
38
39namespace QuantLib {
40
41 //! Container for historical data
42 /*! This class acts as a generic repository for a set of
43 historical data. Any single datum can be accessed through its
44 date, while sets of consecutive data can be accessed through
45 iterators.
46
47 \pre The <c>Container</c> type must satisfy the requirements
48 set by the C++ standard for associative containers.
49 */
50 template <class T, class Container = std::map<Date, T> >
51 class TimeSeries {
52 public:
53 typedef Date key_type;
54 typedef T value_type;
55 private:
56 mutable Container values_;
57 public:
58 /*! Default constructor */
59 TimeSeries() = default;
60 /*! This constructor initializes the history with a set of
61 values passed as two sequences, the first containing dates
62 and the second containing corresponding values.
63 */
64 template <class DateIterator, class ValueIterator>
65 TimeSeries(DateIterator dBegin, DateIterator dEnd,
66 ValueIterator vBegin) {
67 while (dBegin != dEnd)
68 values_[*(dBegin++)] = *(vBegin++);
69 }
70 /*! This constructor initializes the history with a set of
71 values. Such values are assigned to a corresponding number
72 of consecutive dates starting from <b><i>firstDate</i></b>
73 included.
74 */
75 template <class ValueIterator>
76 TimeSeries(const Date& firstDate,
77 ValueIterator begin, ValueIterator end) {
78 Date d = firstDate;
79 while (begin != end)
80 values_[d++] = *(begin++);
81 }
82 //! \name Inspectors
83 //@{
84 //! returns the first date for which a historical datum exists
85 Date firstDate() const;
86 //! returns the last date for which a historical datum exists
87 Date lastDate() const;
88 //! returns the number of historical data including null ones
89 Size size() const;
90 //! returns whether the series contains any data
91 bool empty() const;
92 //@}
93 //! \name Historical data access
94 //@{
95 //! returns the (possibly null) datum corresponding to the given date
96 T operator[](const Date& d) const {
97 typename Container::const_iterator found = values_.find(d);
98 if (found == values_.cend())
99 return Null<T>();
100 return found->second;
101 }
102 T& operator[](const Date& d) {
103 auto found = values_.insert(std::pair<Date, T>(d, Null<T>())).first;
104 return found->second;
105 }
106 //@}
107
108 //! \name Iterators
109 //@{
110 typedef typename Container::const_iterator const_iterator;
111 typedef typename const_iterator::iterator_category iterator_category;
112
113 // Reverse iterators
114 // The following class makes compilation fail for the code
115 // that calls rbegin or rend with a container that does not
116 // support reverse iterators. All the rest TimeSeries class
117 // features should compile and work for this type of
118 // containers.
119 template <class container, class iterator_category>
120 struct reverse {
121 typedef std::reverse_iterator<typename container::const_iterator>
122 const_reverse_iterator;
123 reverse(const container& c) : c_(c) {}
124 const_reverse_iterator rbegin() const {
125 return const_reverse_iterator(c_.end());
126 }
127 const_reverse_iterator rend() const {
128 return const_reverse_iterator(c_.begin());
129 }
130 const container& c_;
131 };
132
133 // This class defines reverse iterator features via
134 // container's native calls.
135 template <class container>
136 struct reverse<container, std::bidirectional_iterator_tag> {
137 typedef typename container::const_reverse_iterator
138 const_reverse_iterator;
139 reverse(const container& c) : c_(c) {}
140 const_reverse_iterator rbegin() const { return c_.rbegin(); }
141 const_reverse_iterator rend() const { return c_.rend(); }
142 const container& c_;
143 };
144
145 // The following typedef enables reverse iterators for
146 // bidirectional_iterator_tag category.
147 typedef std::conditional_t<
148 std::is_same<iterator_category, std::bidirectional_iterator_tag>::value ||
149 std::is_base_of<std::bidirectional_iterator_tag, iterator_category>::value,
150 std::bidirectional_iterator_tag, std::input_iterator_tag> enable_reverse;
151
152 typedef typename
153 reverse<Container, enable_reverse>::const_reverse_iterator
154 const_reverse_iterator;
155
156 const_iterator cbegin() const;
157 const_iterator cend() const;
158 const_iterator begin() const { return cbegin(); }
159 const_iterator end() const { return cend(); }
160 const_reverse_iterator crbegin() const {
161 return reverse<Container, enable_reverse>(values_).rbegin();
162 }
163 const_reverse_iterator crend() const {
164 return reverse<Container, enable_reverse>(values_).rend();
165 }
166 const_reverse_iterator rbegin() const { return crbegin(); }
167 const_reverse_iterator rend() const { return crend(); }
168 //@}
169
170 private:
171 typedef typename Container::value_type container_value_type;
172 typedef ext::function<Date(const container_value_type&)>
173 projection_time;
174 typedef ext::function<T(const container_value_type&)>
175 projection_value;
176
177 public:
178 //! \name Projection iterators
179 //@{
180
181 /*! \deprecated Use const_iterator instead and access the `first` data member.
182 Deprecated in version 1.31.
183 */
184 [[deprecated("Use const_iterator instead and access the `first` data member.")]]
185 typedef boost::transform_iterator<projection_time, const_iterator> const_time_iterator;
186
187 /*! \deprecated Use const_iterator instead and access the `second` data member.
188 Deprecated in version 1.31.
189 */
190 [[deprecated("Use const_iterator instead and access the `second` data member.")]]
191 typedef boost::transform_iterator<projection_value, const_iterator> const_value_iterator;
192
193 /*! \deprecated Use const_reverse_iterator instead and access the `first` data member.
194 Deprecated in version 1.31.
195 */
196 [[deprecated("Use const_reverse_iterator instead and access the `first` data member.")]]
197 typedef boost::transform_iterator<projection_time, const_reverse_iterator> const_reverse_time_iterator;
198
199 /*! \deprecated Use const_reverse_iterator instead and access the `second` data member.
200 Deprecated in version 1.31.
201 */
202 [[deprecated("Use const_reverse_iterator instead and access the `second` data member.")]]
203 typedef boost::transform_iterator<projection_value, const_reverse_iterator> const_reverse_value_iterator;
204
205 QL_DEPRECATED_DISABLE_WARNING
206
207 /*! \deprecated Use cbegin instead and access the `second` data member.
208 Deprecated in version 1.31.
209 */
210 [[deprecated("Use cbegin instead and access the `second` data member.")]]
211 const_value_iterator cbegin_values() const {
212 return const_value_iterator(cbegin(), get_value);
213 }
214
215 /*! \deprecated Use cend instead and access the `second` data member.
216 Deprecated in version 1.31.
217 */
218 [[deprecated("Use cend instead and access the `second` data member.")]]
219 const_value_iterator cend_values() const {
220 return const_value_iterator(cend(), get_value);
221 }
222
223 /*! \deprecated Use crbegin instead and access the `second` data member.
224 Deprecated in version 1.31.
225 */
226 [[deprecated("Use crbegin instead and access the `second` data member.")]]
227 const_reverse_value_iterator crbegin_values() const {
228 return const_reverse_value_iterator(crbegin(), get_value);
229 }
230
231 /*! \deprecated Use crend instead and access the `second` data member.
232 Deprecated in version 1.31.
233 */
234 [[deprecated("Use crend instead and access the `second` data member.")]]
235 const_reverse_value_iterator crend_values() const {
236 return const_reverse_value_iterator(crend(), get_value);
237 }
238
239 /*! \deprecated Use cbegin instead and access the `first` data member.
240 Deprecated in version 1.31.
241 */
242 [[deprecated("Use cbegin instead and access the `first` data member.")]]
243 const_time_iterator cbegin_time() const {
244 return const_time_iterator(cbegin(), get_time);
245 }
246
247 /*! \deprecated Use cend instead and access the `first` data member.
248 Deprecated in version 1.31.
249 */
250 [[deprecated("Use cend instead and access the `first` data member.")]]
251 const_time_iterator cend_time() const {
252 return const_time_iterator(cend(), get_time);
253 }
254
255 /*! \deprecated Use crbegin instead and access the `first` data member.
256 Deprecated in version 1.31.
257 */
258 [[deprecated("Use crbegin instead and access the `first` data member.")]]
259 const_reverse_time_iterator crbegin_time() const {
260 return const_reverse_time_iterator(crbegin(), get_time);
261 }
262
263 /*! \deprecated Use crend instead and access the `first` data member.
264 Deprecated in version 1.31.
265 */
266 [[deprecated("Use crend instead and access the `first` data member.")]]
267 const_reverse_time_iterator crend_time() const {
268 return const_reverse_time_iterator(crend(), get_time);
269 }
270
271 QL_DEPRECATED_ENABLE_WARNING
272
273 //! \name Utilities
274 //@{
275 const_iterator find(const Date&);
276 //! returns the dates for which historical data exist
277 std::vector<Date> dates() const;
278 //! returns the historical data
279 std::vector<T> values() const;
280 //@}
281
282 private:
283 static const Date& get_time (const container_value_type& v) {
284 return v.first;
285 }
286 static const T& get_value (const container_value_type& v) {
287 return v.second;
288 }
289 };
290
291
292 // inline definitions
293
294 template <class T, class C>
295 inline Date TimeSeries<T,C>::firstDate() const {
296 QL_REQUIRE(!values_.empty(), "empty timeseries");
297 return values_.begin()->first;
298 }
299
300 template <class T, class C>
301 inline Date TimeSeries<T,C>::lastDate() const {
302 QL_REQUIRE(!values_.empty(), "empty timeseries");
303 return rbegin()->first;
304 }
305
306 template <class T, class C>
307 inline Size TimeSeries<T,C>::size() const {
308 return values_.size();
309 }
310
311 template <class T, class C>
312 inline bool TimeSeries<T,C>::empty() const {
313 return values_.empty();
314 }
315
316 template <class T, class C>
317 inline typename TimeSeries<T,C>::const_iterator
318 TimeSeries<T,C>::cbegin() const {
319 return values_.begin();
320 }
321
322 template <class T, class C>
323 inline typename TimeSeries<T,C>::const_iterator
324 TimeSeries<T,C>::cend() const {
325 return values_.end();
326 }
327
328 template <class T, class C>
329 inline typename TimeSeries<T,C>::const_iterator
330 TimeSeries<T,C>::find(const Date& d) {
331 const_iterator i = values_.find(d);
332 if (i == values_.end()) {
333 values_[d] = Null<T>();
334 i = values_.find(d);
335 }
336 return i;
337 }
338
339 template <class T, class C>
340 std::vector<Date> TimeSeries<T,C>::dates() const {
341 std::vector<Date> v;
342 v.reserve(n: size());
343 std::transform(cbegin(), cend(), std::back_inserter(x&: v),
344 TimeSeries<T,C>::get_time);
345 return v;
346 }
347
348 template <class T, class C>
349 std::vector<T> TimeSeries<T,C>::values() const {
350 std::vector<T> v;
351 v.reserve(size());
352 std::transform(cbegin(), cend(), std::back_inserter(v),
353 TimeSeries<T,C>::get_value);
354 return v;
355 }
356
357}
358
359#endif
360

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of quantlib/ql/timeseries.hpp