1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 3 /* 4 Copyright (C) 2008 J. Erik Radmall 5 6 This file is part of QuantLib, a free-software/open-source library 7 for financial quantitative analysts and developers - http://quantlib.org/ 8 9 QuantLib is free software: you can redistribute it and/or modify it 10 under the terms of the QuantLib license. You should have received a 11 copy of the license along with this program; if not, please email 12 <quantlib-dev@lists.sf.net>. The license is also available online at 13 <http://quantlib.org/license.shtml>. 14 15 This program is distributed in the hope that it will be useful, but WITHOUT 16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 17 FOR A PARTICULAR PURPOSE. See the license for more details. 18 */ 19 20 /*! \file commodityindex.hpp 21 \brief Commodity index 22 */ 23 24 #ifndef quantlib_commodity_index_hpp 25 #define quantlib_commodity_index_hpp 26 27 #include <ql/experimental/commodities/commoditycurve.hpp> 28 #include <ql/indexes/indexmanager.hpp> 29 30 namespace QuantLib { 31 32 class TermStructure; 33 34 //! base class for commodity indexes 35 class CommodityIndex : public Observable, 36 public Observer { 37 public: 38 CommodityIndex( 39 const std::string& name, 40 const CommodityType& commodityType, 41 const Currency& currency, 42 const UnitOfMeasure& unitOfMeasure, 43 const Calendar& calendar, 44 Real lotQuantity, 45 const ext::shared_ptr<CommodityCurve>& forwardCurve, 46 const ext::shared_ptr<ExchangeContracts>& exchangeContracts, 47 int nearbyOffset); 48 //! \name Index interface 49 //@{ 50 std::string name() const; 51 //@} 52 //! \name Observer interface 53 //@{ 54 void update(); 55 //@} 56 //! \name Inspectors 57 //@{ 58 const CommodityType& commodityType() const; 59 const Currency& currency() const; 60 const UnitOfMeasure& unitOfMeasure() const; 61 const Calendar& calendar() const; 62 const ext::shared_ptr<CommodityCurve>& forwardCurve() const; 63 Real lotQuantity() const; 64 65 Real price(const Date& date); 66 Real forwardPrice(const Date& date) const; 67 Date lastQuoteDate() const; 68 //@} 69 void addQuote(const Date& quoteDate, Real quote); 70 addQuotes(const std::map<Date,Real> & quotes)71 void addQuotes(const std::map<Date, Real>& quotes) { 72 std::string tag = name(); 73 quotes_ = IndexManager::instance().getHistory(tag); 74 for (std::map<Date, Real>::const_iterator ii = quotes.begin(); 75 ii != quotes.end (); ++ii) { 76 quotes_[ii->first] = ii->second; 77 } 78 IndexManager::instance().setHistory(tag, quotes_); 79 } 80 81 void clearQuotes() const; 82 //! returns TRUE if the quote date is valid 83 bool isValidQuoteDate(const Date& quoteDate) const; 84 bool empty() const; 85 bool forwardCurveEmpty() const; 86 const TimeSeries<Real>& quotes() const; 87 88 friend std::ostream& operator<<(std::ostream&, const CommodityIndex&); 89 protected: 90 std::string name_; 91 CommodityType commodityType_; 92 UnitOfMeasure unitOfMeasure_; 93 Currency currency_; 94 Calendar calendar_; 95 Real lotQuantity_; 96 TimeSeries<Real> quotes_; 97 ext::shared_ptr<CommodityCurve> forwardCurve_; 98 Real forwardCurveUomConversionFactor_; 99 ext::shared_ptr<ExchangeContracts> exchangeContracts_; 100 Integer nearbyOffset_; 101 }; 102 103 104 // inline definitions 105 operator ==(const CommodityIndex & i1,const CommodityIndex & i2)106 inline bool operator==(const CommodityIndex& i1, const CommodityIndex& i2) { 107 return i1.name() == i2.name(); 108 } 109 update()110 inline void CommodityIndex::update() { 111 notifyObservers(); 112 } 113 name() const114 inline std::string CommodityIndex::name() const { 115 return name_; 116 } 117 commodityType() const118 inline const CommodityType& CommodityIndex::commodityType() const { 119 return commodityType_; 120 } 121 unitOfMeasure() const122 inline const UnitOfMeasure& CommodityIndex::unitOfMeasure() const { 123 return unitOfMeasure_; 124 } 125 currency() const126 inline const Currency& CommodityIndex::currency() const { 127 return currency_; 128 } 129 calendar() const130 inline const Calendar& CommodityIndex::calendar() const { 131 return calendar_; 132 } 133 lotQuantity() const134 inline Real CommodityIndex::lotQuantity() const { 135 return lotQuantity_; 136 } 137 138 inline const ext::shared_ptr<CommodityCurve>& forwardCurve() const139 CommodityIndex::forwardCurve() const { 140 return forwardCurve_; 141 } 142 quotes() const143 inline const TimeSeries<Real>& CommodityIndex::quotes() const { 144 return quotes_; 145 } 146 price(const Date & date)147 inline Real CommodityIndex::price(const Date& date) { 148 std::map<Date, Real>::const_iterator hq = quotes_.find(date); 149 if (hq->second == Null<Real>()) { 150 ++hq; 151 if (hq == quotes_.end()) 152 //if (hq->second == Null<Real>()) 153 return Null<Real>(); 154 } 155 return hq->second; 156 } 157 forwardPrice(const Date & date) const158 inline Real CommodityIndex::forwardPrice(const Date& date) const { 159 try { 160 Real forwardPrice = 161 forwardCurve_->price(date, exchangeContracts_, nearbyOffset_); 162 return forwardPrice * forwardCurveUomConversionFactor_; 163 } catch (const std::exception& e) { 164 QL_FAIL("error fetching forward price for index " << name_ 165 << ": " << e.what()); 166 } 167 } 168 lastQuoteDate() const169 inline Date CommodityIndex::lastQuoteDate() const { 170 if (quotes_.empty()) 171 return Date::minDate(); 172 return quotes_.lastDate(); 173 } 174 empty() const175 inline bool CommodityIndex::empty() const { 176 return quotes_.empty(); 177 } 178 forwardCurveEmpty() const179 inline bool CommodityIndex::forwardCurveEmpty() const { 180 if (forwardCurve_ != 0) 181 return forwardCurve_->empty(); 182 return false; 183 } 184 addQuote(const Date & quoteDate,Real quote)185 inline void CommodityIndex::addQuote(const Date& quoteDate, Real quote) { 186 //QL_REQUIRE(isValidQuoteDate(quoteDate), 187 // "Quote date " << quoteDate.weekday() << ", " << 188 // quoteDate << " is not valid"); 189 std::string tag = name(); 190 quotes_ = IndexManager::instance().getHistory(tag); 191 quotes_[quoteDate] = quote; 192 IndexManager::instance().setHistory(tag, quotes_); 193 } 194 clearQuotes() const195 inline void CommodityIndex::clearQuotes() const { 196 IndexManager::instance().clearHistory(name()); 197 } 198 isValidQuoteDate(const Date & quoteDate) const199 inline bool CommodityIndex::isValidQuoteDate(const Date& quoteDate) const { 200 return calendar().isBusinessDay(quoteDate); 201 } 202 203 } 204 205 #endif 206