Financial analysis often involves the analysis of numerical data given at specific times. This data can consist of returns or exchange rates or any other quantity that varies with time. Such data is known as a time series and **QuantLib** provides a special class for handling such data. The **TimeSeries** class encapsulates time series data by storing pairs of **Date** objects and values. **TimeSeries** is a templated class. The type of values stored are given by the first template parameter. An optional second template parameter specifies the underlying data structure for storing the fate value pairs.

**TimeSeries** defines the following constructors.

TimeSeries(); template<class DateIterator, class ValueIterator> TimeSeries(DateIterator dBegin, DateIterator dEnd, ValueIterator vBegin); template<class ValueIterator> TimeSeries(const Date& firstDate, ValueIterator begin, ValueIterator end)

The first constructor creates an empty time series. This time series can be filled with data later on. The second constructor creates a time series from a collection of dates and a collection of values. The dates are given by a pair of iterators, an iterator pointing to the first date and one pointing behind the last date. These iterators can be the usual iterators from any STL collection. The values are passed by another iterator pointing to the first value. No end iterator is supplied here as the range is specified by the two date iterators. It is assumed that there are enough values. Otherwise the constructor will fail.

The third constructor takes a starting date and an iterator interval for the values. Here is is assumed that all the data points lie on consecutive dates, I.e. each data point is one day after the previous.

Here is an example of how a time series can be initialized.

double values[5] ={1.1, 1.5, 2.3, 1.7 2.8}; std::list dates; dates.push_back(Date(12,Nov, 2012)); dates.push_back(Date(13,Nov, 2012)); dates.push_back(Date(14,Nov, 2012)); dates.push_back(Date(15,Nov, 2012)); dates.push_back(Date(16,Nov, 2012)); TimeSeries series(dates.begin(), dates.end(), values); TimeSeries series2(Date(12, November, 2012), values, &values[5]);

Both time series in the above example will contain the same data.

The elements of the time series can be accessed via the index operators.

T operator[](const Date& d) const; T& operator[](const Date& d);

Let’s continue the above example.

std:: cout << series[Date(14, November, 2012)] << std:: endl;

The **TimeSeries** class offers a number of inspection methods.

Date firstDate() const; Date lastDate() const; Size size() const; bool empty() const;

The **firstDate()** method returns the earliest date for which a data point is given, and **lastDate()** returns the latest such date. **size()** will return the number of data points contained in the time series and **empty()** will return true if the time series contains no data and false in case it does.

Access to the elements over the time series is also available through the usual STL style **begin()** and **end()** methods.

const_iterator cbegin() const; const_iterator cend() const; const_iterator begin() const; const_iterator end() const; const_reverse_iterator crbegin() const; const_reverse_iterator crend() const; const_reverse_iterator rbegin() const; const_reverse_iterator rend() const;

Note how all these methods return constant iterators only. This means that it is impossible to modify the data stored in the time series through the iterators. The iterators returned by these methods are in fact just the constant iterators of the underlying container. This means that the dereferenced iterator returns a key value pair.

for (TimeSeries::iterator it=series.begin (); it! = series.end(); ++it) { std:: cout << it->first << " " << it->second << std:: endl; }

This example will print out the date-value pairs contained in the series. One can also access the values or the times individually. The following methods return the iterators for this access.

const_value_iterator cbegin_values() const; const_value_iterator cend_values() const; const_reverse_value_iterator crbegin_values() const; const_time_iterator cbegin_time() const; const_time_iterator cend_time() const; const_reverse_time_iterator crbegin_time() const; const_reverse_time_iterator crend_time() const;

As before only constant iterators are returned and the values in the time series may not be modified through the iterators.

Finally, **TimeSeries** defines a couple of utility methods to find a particular data point or to convert the data contained within the time series into **std::vector** objects.

const_iterator find(const Date&); std::vector dates() const; std::vector values() const;

The **find()** method attempts to find the data for a particular date and returns an iterator that points to that data, **dates()** returns a **std::vector** containing all the dates for which data is stored, and values returns a **std::vector** of all the values stored within the time series.

JohnPaulAnd here is the equivalent method in QLNet (C# version of QuantLib) :

Date d1 = new Date(12, 11, 2012);

Date d2 = new Date(13, 11, 2012);

Date d3 = new Date(14, 11, 2012);

Date d4 = new Date(15, 11, 2012);

Date d5 = new Date(16, 11, 2012);

Date d6 = new Date(17, 11, 2012);

double[] values = {1.1, 1.5, 2.3, 1.7, 2.8};

TimeSeries series = new TimeSeries();

series.Add(d1, values[0]);

series.Add(d2, values[1]);

series.Add(d3, values[2]);

series.Add(d4, values[3]);

series.Add(d5, values[4]);

double getValue;

series.TryGetValue(d5, out getValue);