24#ifndef quantext_commodity_basis_price_curve_hpp
25#define quantext_commodity_basis_price_curve_hpp
27#include <ql/math/comparison.hpp>
28#include <ql/patterns/lazyobject.hpp>
29#include <ql/quote.hpp>
30#include <ql/termstructures/interpolatedcurve.hpp>
31#include <ql/time/calendars/nullcalendar.hpp>
32#include <ql/utilities/dataformatters.hpp>
52template <
class Interpolator>
54 public QuantLib::LazyObject,
55 protected QuantLib::InterpolatedCurve<Interpolator> {
61 const std::map<QuantLib::Date, QuantLib::Handle<QuantLib::Quote>>& basisData,
62 const QuantLib::ext::shared_ptr<FutureExpiryCalculator>& basisFec,
63 const QuantLib::ext::shared_ptr<CommodityIndex>&
baseIndex,
64 const QuantLib::ext::shared_ptr<FutureExpiryCalculator>& baseFec,
bool addBasis =
true,
65 QuantLib::Size
monthOffset = 0,
bool priceAsHistFixing =
true,
66 const Interpolator& interpolator = Interpolator());
81 QuantLib::Date
maxDate()
const override;
82 QuantLib::Time
maxTime()
const override;
87 QuantLib::Time
minTime()
const override;
88 std::vector<QuantLib::Date>
pillarDates()
const override;
89 const QuantLib::Currency&
currency()
const override {
return baseIndex_->priceCurve()->currency(); }
94 const std::vector<QuantLib::Time>&
times()
const {
return this->times_; }
95 const std::vector<QuantLib::Real>&
prices()
const {
return this->data_; }
101 QuantLib::Real
priceImpl(QuantLib::Time t)
const override;
105 std::map<QuantLib::Date, QuantLib::Handle<QuantLib::Quote>>
basisData_;
116 std::map<QuantLib::Date, QuantLib::ext::shared_ptr<CashFlow>>
baseLeg_;
124template <
class Interpolator>
126 const QuantLib::Date& referenceDate,
const std::map<QuantLib::Date, QuantLib::Handle<QuantLib::Quote>>& basisData,
127 const QuantLib::ext::shared_ptr<FutureExpiryCalculator>& basisFec,
const QuantLib::ext::shared_ptr<CommodityIndex>& baseIndex,
128 const QuantLib::ext::shared_ptr<FutureExpiryCalculator>& baseFec,
bool addBasis, QuantLib::Size monthOffset,
129 bool priceAsHistFixing,
const Interpolator& interpolator)
132 QuantLib::InterpolatedCurve<Interpolator>(interpolator), basisData_(basisData) {
134 "CommodityBasisPriceCurve requires baseIndex with priceCurve");
135 using QuantLib::Date;
136 using QuantLib::Schedule;
137 using QuantLib::io::iso_date;
138 using QuantLib::io::ordinal;
148 if (it->first < referenceDate) {
153 dates_.push_back(it->first);
154 basisTimes_.push_back(timeFromReference(it->first));
159 registerWith(it->second);
171 Date basisExpiry =
basisFec_->nextExpiry(
true, referenceDate);
179 while (basisExpiry <= end) {
180 Date basisContractDate =
basisFec_->contractDate(basisExpiry);
181 basisContractDate = Date(1, basisContractDate.month(), basisContractDate.year()) -
monthOffset_ * Months;
182 Date periodStart = basisContractDate -
monthOffset_ * Months;
183 Date periodEnd = (periodStart + 1 * Months) - 1 * Days;
189 this->times_.push_back(timeFromReference(basisExpiry));
190 dates_.push_back(basisExpiry);
193 basisExpiry =
basisFec_->nextExpiry(
true, basisExpiry + 1 * Days);
197 sort(this->times_.begin(), this->times_.end());
199 auto it = unique(this->times_.begin(), this->times_.end(), [](
double s,
double t) { return close(s, t); });
200 QL_REQUIRE(it == this->times_.end(),
"Unexpected duplicate time, " << *it <<
", in the times vector.");
201 this->data_.resize(this->times_.size());
204 QuantLib::InterpolatedCurve<Interpolator>::setupInterpolation();
213 for (
const auto& kv : basisData_) {
214 basisValues_[basisIdx] = addBasis_ ? kv.second->value() : -kv.second->value();
217 basisInterpolation_.update();
220 for (Size i = 0; i < this->times_.size(); i++) {
222 Real baseValue = 0.0;
223 auto it = baseLeg_.find(dates_[i]);
224 if (it != baseLeg_.end()) {
226 baseValue = it->second->amount();
230 baseValue = baseIndex_->priceCurve()->price(this->times_[i],
true);
235 if (this->times_[i] < basisTimes_.front()) {
236 basis = basisValues_.front();
237 }
else if (this->times_[i] > basisTimes_.back()) {
238 basis = basisValues_.back();
240 basis = basisInterpolation_(this->times_[i],
true);
244 this->data_[i] = baseValue + basis;
246 this->interpolation_.update();
250 return dates_.back();
254 return this->times_.back();
258 return this->times_.front();
267 return this->interpolation_(t,
true);
Commodity basis price curve.
QuantLib::Time minTime() const override
The minimum time for which the curve can return values.
void performCalculations() const override
const QuantLib::Currency & currency() const override
The currency in which prices are expressed.
std::vector< Time > basisTimes_
std::vector< QuantLib::Date > dates_
std::map< QuantLib::Size, QuantLib::Size > legIndexMap_
std::vector< Real > basisValues_
const std::vector< QuantLib::Time > & times() const
std::map< QuantLib::Date, QuantLib::ext::shared_ptr< CashFlow > > baseLeg_
The commodity cashflows will give the base curve prices.
std::map< QuantLib::Date, QuantLib::Handle< QuantLib::Quote > > basisData_
QuantLib::Date maxDate() const override
const std::vector< QuantLib::Real > & prices() const
std::vector< QuantLib::Date > pillarDates() const override
The pillar dates for the PriceTermStructure.
Interpolation basisInterpolation_
CommodityBasisPriceCurve(const QuantLib::Date &referenceDate, const std::map< QuantLib::Date, QuantLib::Handle< QuantLib::Quote > > &basisData, const QuantLib::ext::shared_ptr< FutureExpiryCalculator > &basisFec, const QuantLib::ext::shared_ptr< CommodityIndex > &baseIndex, const QuantLib::ext::shared_ptr< FutureExpiryCalculator > &baseFec, bool addBasis=true, QuantLib::Size monthOffset=0, bool priceAsHistFixing=true, const Interpolator &interpolator=Interpolator())
Curve constructed from dates and quotes.
QuantLib::Real priceImpl(QuantLib::Time t) const override
Price calculation.
QuantLib::Time maxTime() const override
bool averagingBaseCashflow_
QuantLib::Size monthOffset() const
QuantLib::ext::shared_ptr< FutureExpiryCalculator > baseFec_
const QuantLib::ext::shared_ptr< CommodityIndex > & baseIndex() const
QuantLib::Size monthOffset_
QuantLib::ext::shared_ptr< FutureExpiryCalculator > basisFec_
QuantLib::ext::shared_ptr< CommodityIndex > baseIndex_
some commodity related utilities.
An interface for a commodity price curve created from a base price curve and a collection of basis qu...
Cash flow dependent on the average commodity spot price or future's settlement price over a period....
Cash flow dependent on a single commodity spot price or future's settlement price.
Base class for classes that perform date calculations for future contracts.
QuantLib::ext::shared_ptr< CashFlow > makeCommodityCashflowForBasisFuture(const QuantLib::Date &start, const QuantLib::Date &end, const QuantLib::ext::shared_ptr< CommodityIndex > &baseIndex, const QuantLib::ext::shared_ptr< FutureExpiryCalculator > &baseFec, bool baseIsAveraging, const QuantLib::Date &paymentDate)
Make a commodity indexed cashflow.
CompiledFormula max(CompiledFormula x, const CompiledFormula &y)
Term structure of prices.