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
30namespace QuantLib {
31
32 class TermStructure;
33
34 //! base class for commodity indexes
35 class CommodityIndex : public Observable,
36 public Observer {
37 public:
38 CommodityIndex(const std::string& name,
39 CommodityType commodityType,
40 Currency currency,
41 UnitOfMeasure unitOfMeasure,
42 Calendar calendar,
43 Real lotQuantity,
44 ext::shared_ptr<CommodityCurve> forwardCurve,
45 ext::shared_ptr<ExchangeContracts> exchangeContracts,
46 int nearbyOffset);
47 //! \name Index interface
48 //@{
49 std::string name() const;
50 //@}
51 //! \name Observer interface
52 //@{
53 void update() override;
54 //@}
55 //! \name Inspectors
56 //@{
57 const CommodityType& commodityType() const;
58 const Currency& currency() const;
59 const UnitOfMeasure& unitOfMeasure() const;
60 const Calendar& calendar() const;
61 const ext::shared_ptr<CommodityCurve>& forwardCurve() const;
62 Real lotQuantity() const;
63
64 Real price(const Date& date);
65 Real forwardPrice(const Date& date) const;
66 Date lastQuoteDate() const;
67 //@}
68 void addQuote(const Date& quoteDate, Real quote);
69
70 void addQuotes(const std::map<Date, Real>& quotes) {
71 std::string tag = name();
72 quotes_ = IndexManager::instance().getHistory(name: tag);
73 for (auto quote : quotes) {
74 quotes_[quote.first] = quote.second;
75 }
76 IndexManager::instance().setHistory(name: tag, history: quotes_);
77 }
78
79 void clearQuotes() const;
80 //! returns TRUE if the quote date is valid
81 bool isValidQuoteDate(const Date& quoteDate) const;
82 bool empty() const;
83 bool forwardCurveEmpty() const;
84 const TimeSeries<Real>& quotes() const;
85
86 friend std::ostream& operator<<(std::ostream&, const CommodityIndex&);
87 protected:
88 std::string name_;
89 CommodityType commodityType_;
90 UnitOfMeasure unitOfMeasure_;
91 Currency currency_;
92 Calendar calendar_;
93 Real lotQuantity_;
94 TimeSeries<Real> quotes_;
95 ext::shared_ptr<CommodityCurve> forwardCurve_;
96 Real forwardCurveUomConversionFactor_ = 1;
97 ext::shared_ptr<ExchangeContracts> exchangeContracts_;
98 Integer nearbyOffset_;
99 };
100
101
102 // inline definitions
103
104 inline bool operator==(const CommodityIndex& i1, const CommodityIndex& i2) {
105 return i1.name() == i2.name();
106 }
107
108 inline void CommodityIndex::update() {
109 notifyObservers();
110 }
111
112 inline std::string CommodityIndex::name() const {
113 return name_;
114 }
115
116 inline const CommodityType& CommodityIndex::commodityType() const {
117 return commodityType_;
118 }
119
120 inline const UnitOfMeasure& CommodityIndex::unitOfMeasure() const {
121 return unitOfMeasure_;
122 }
123
124 inline const Currency& CommodityIndex::currency() const {
125 return currency_;
126 }
127
128 inline const Calendar& CommodityIndex::calendar() const {
129 return calendar_;
130 }
131
132 inline Real CommodityIndex::lotQuantity() const {
133 return lotQuantity_;
134 }
135
136 inline const ext::shared_ptr<CommodityCurve>&
137 CommodityIndex::forwardCurve() const {
138 return forwardCurve_;
139 }
140
141 inline const TimeSeries<Real>& CommodityIndex::quotes() const {
142 return quotes_;
143 }
144
145 inline Real CommodityIndex::price(const Date& date) {
146 auto hq = quotes_.find(d: date);
147 if (hq->second == Null<Real>()) {
148 ++hq;
149 if (hq == quotes_.end())
150 //if (hq->second == Null<Real>())
151 return Null<Real>();
152 }
153 return hq->second;
154 }
155
156 inline Real CommodityIndex::forwardPrice(const Date& date) const {
157 try {
158 Real forwardPrice =
159 forwardCurve_->price(d: date, exchangeContracts: exchangeContracts_, nearbyOffset: nearbyOffset_);
160 return forwardPrice * forwardCurveUomConversionFactor_;
161 } catch (const std::exception& e) {
162 QL_FAIL("error fetching forward price for index " << name_
163 << ": " << e.what());
164 }
165 }
166
167 inline Date CommodityIndex::lastQuoteDate() const {
168 if (quotes_.empty())
169 return Date::minDate();
170 return quotes_.lastDate();
171 }
172
173 inline bool CommodityIndex::empty() const {
174 return quotes_.empty();
175 }
176
177 inline bool CommodityIndex::forwardCurveEmpty() const {
178 if (forwardCurve_ != nullptr)
179 return forwardCurve_->empty();
180 return false;
181 }
182
183 inline void CommodityIndex::addQuote(const Date& quoteDate, Real quote) {
184 //QL_REQUIRE(isValidQuoteDate(quoteDate),
185 // "Quote date " << quoteDate.weekday() << ", " <<
186 // quoteDate << " is not valid");
187 std::string tag = name();
188 quotes_ = IndexManager::instance().getHistory(name: tag);
189 quotes_[quoteDate] = quote;
190 IndexManager::instance().setHistory(name: tag, history: quotes_);
191 }
192
193 inline void CommodityIndex::clearQuotes() const {
194 IndexManager::instance().clearHistory(name: name());
195 }
196
197 inline bool CommodityIndex::isValidQuoteDate(const Date& quoteDate) const {
198 return calendar().isBusinessDay(d: quoteDate);
199 }
200
201}
202
203#endif
204

source code of quantlib/ql/experimental/commodities/commodityindex.hpp