| 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 StatPro Italia srl |
| 6 | Copyright (C) 2007, 2008 Ferdinando Ametrano |
| 7 | Copyright (C) 2007 Chiara Fornarola |
| 8 | |
| 9 | This file is part of QuantLib, a free-software/open-source library |
| 10 | for financial quantitative analysts and developers - http://quantlib.org/ |
| 11 | |
| 12 | QuantLib is free software: you can redistribute it and/or modify it |
| 13 | under the terms of the QuantLib license. You should have received a |
| 14 | copy of the license along with this program; if not, please email |
| 15 | <quantlib-dev@lists.sf.net>. The license is also available online at |
| 16 | <http://quantlib.org/license.shtml>. |
| 17 | |
| 18 | This program is distributed in the hope that it will be useful, but WITHOUT |
| 19 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
| 20 | FOR A PARTICULAR PURPOSE. See the license for more details. |
| 21 | */ |
| 22 | |
| 23 | /*! \file index.hpp |
| 24 | \brief virtual base class for indexes |
| 25 | */ |
| 26 | |
| 27 | #ifndef quantlib_index_hpp |
| 28 | #define quantlib_index_hpp |
| 29 | |
| 30 | #include <ql/indexes/indexmanager.hpp> |
| 31 | #include <ql/math/comparison.hpp> |
| 32 | #include <ql/time/calendar.hpp> |
| 33 | |
| 34 | namespace QuantLib { |
| 35 | |
| 36 | //! purely virtual base class for indexes |
| 37 | /*! \warning this class performs no check that the |
| 38 | provided/requested fixings are for dates in the past, |
| 39 | i.e. for dates less than or equal to the evaluation |
| 40 | date. It is up to the client code to take care of |
| 41 | possible inconsistencies due to "seeing in the |
| 42 | future" |
| 43 | */ |
| 44 | class Index : public Observable { |
| 45 | public: |
| 46 | ~Index() override = default; |
| 47 | //! Returns the name of the index. |
| 48 | /*! \warning This method is used for output and comparison |
| 49 | between indexes. It is <b>not</b> meant to be |
| 50 | used for writing switch-on-type code. |
| 51 | */ |
| 52 | virtual std::string name() const = 0; |
| 53 | //! returns the calendar defining valid fixing dates |
| 54 | virtual Calendar fixingCalendar() const = 0; |
| 55 | //! returns TRUE if the fixing date is a valid one |
| 56 | virtual bool isValidFixingDate(const Date& fixingDate) const = 0; |
| 57 | //! returns whether a historical fixing was stored for the given date |
| 58 | bool hasHistoricalFixing(const Date& fixingDate) const; |
| 59 | //! returns the fixing at the given date |
| 60 | /*! the date passed as arguments must be the actual calendar |
| 61 | date of the fixing; no settlement days must be used. |
| 62 | */ |
| 63 | virtual Real fixing(const Date& fixingDate, bool forecastTodaysFixing = false) const = 0; |
| 64 | //! returns the fixing TimeSeries |
| 65 | const TimeSeries<Real>& timeSeries() const { |
| 66 | return IndexManager::instance().getHistory(name: name()); |
| 67 | } |
| 68 | //! check if index allows for native fixings. |
| 69 | /*! If this returns false, calls to addFixing and similar |
| 70 | methods will raise an exception. |
| 71 | */ |
| 72 | virtual bool allowsNativeFixings() { return true; } |
| 73 | //! stores the historical fixing at the given date |
| 74 | /*! the date passed as arguments must be the actual calendar |
| 75 | date of the fixing; no settlement days must be used. |
| 76 | */ |
| 77 | virtual void addFixing(const Date& fixingDate, Real fixing, bool forceOverwrite = false); |
| 78 | //! stores historical fixings from a TimeSeries |
| 79 | /*! the dates in the TimeSeries must be the actual calendar |
| 80 | dates of the fixings; no settlement days must be used. |
| 81 | */ |
| 82 | void addFixings(const TimeSeries<Real>& t, bool forceOverwrite = false); |
| 83 | //! stores historical fixings at the given dates |
| 84 | /*! the dates passed as arguments must be the actual calendar |
| 85 | dates of the fixings; no settlement days must be used. |
| 86 | */ |
| 87 | template <class DateIterator, class ValueIterator> |
| 88 | void addFixings(DateIterator dBegin, |
| 89 | DateIterator dEnd, |
| 90 | ValueIterator vBegin, |
| 91 | bool forceOverwrite = false) { |
| 92 | checkNativeFixingsAllowed(); |
| 93 | std::string tag = name(); |
| 94 | TimeSeries<Real> h = IndexManager::instance().getHistory(name: tag); |
| 95 | bool noInvalidFixing = true, noDuplicatedFixing = true; |
| 96 | Date invalidDate, duplicatedDate; |
| 97 | Real nullValue = Null<Real>(); |
| 98 | Real invalidValue = Null<Real>(); |
| 99 | Real duplicatedValue = Null<Real>(); |
| 100 | while (dBegin != dEnd) { |
| 101 | bool validFixing = isValidFixingDate(fixingDate: *dBegin); |
| 102 | Real currentValue = h[*dBegin]; |
| 103 | bool missingFixing = forceOverwrite || currentValue == nullValue; |
| 104 | if (validFixing) { |
| 105 | if (missingFixing) |
| 106 | h[*(dBegin++)] = *(vBegin++); |
| 107 | else if (close(currentValue, *(vBegin))) { |
| 108 | ++dBegin; |
| 109 | ++vBegin; |
| 110 | } else { |
| 111 | noDuplicatedFixing = false; |
| 112 | duplicatedDate = *(dBegin++); |
| 113 | duplicatedValue = *(vBegin++); |
| 114 | } |
| 115 | } else { |
| 116 | noInvalidFixing = false; |
| 117 | invalidDate = *(dBegin++); |
| 118 | invalidValue = *(vBegin++); |
| 119 | } |
| 120 | } |
| 121 | IndexManager::instance().setHistory(name: tag, history: h); |
| 122 | QL_REQUIRE(noInvalidFixing, "At least one invalid fixing provided: " |
| 123 | << invalidDate.weekday() << " " << invalidDate << ", " |
| 124 | << invalidValue); |
| 125 | QL_REQUIRE(noDuplicatedFixing, "At least one duplicated fixing provided: " |
| 126 | << duplicatedDate << ", " << duplicatedValue |
| 127 | << " while " << h[duplicatedDate] |
| 128 | << " value is already present" ); |
| 129 | } |
| 130 | //! clears all stored historical fixings |
| 131 | void clearFixings(); |
| 132 | |
| 133 | private: |
| 134 | //! check if index allows for native fixings |
| 135 | void checkNativeFixingsAllowed(); |
| 136 | }; |
| 137 | |
| 138 | inline bool Index::hasHistoricalFixing(const Date& fixingDate) const { |
| 139 | return IndexManager::instance().hasHistoricalFixing(name: name(), fixingDate); |
| 140 | } |
| 141 | |
| 142 | } |
| 143 | |
| 144 | #endif |
| 145 | |