20#include <ql/utilities/null_deleter.hpp>
22using QuantLib::AcyclicVisitor;
23using QuantLib::Calendar;
25using QuantLib::Handle;
26using QuantLib::Natural;
29using QuantLib::Visitor;
36 const QuantLib::ext::shared_ptr<CommodityIndex>& index,
39 const QuantLib::ext::shared_ptr<FutureExpiryCalculator>& calc,
40 const QuantLib::ext::shared_ptr<CommodityIndex>& peakIndex,
41 const Calendar& peakCalendar,
42 Natural peakHoursPerDay)
44 init(index, start, end, calc, peakIndex, peakCalendar, peakHoursPerDay);
47AverageOffPeakPowerHelper::AverageOffPeakPowerHelper(Real price,
48 const QuantLib::ext::shared_ptr<CommodityIndex>& index,
51 const QuantLib::ext::shared_ptr<FutureExpiryCalculator>& calc,
52 const QuantLib::ext::shared_ptr<CommodityIndex>& peakIndex,
53 const Calendar& peakCalendar,
54 Natural peakHoursPerDay)
56 init(index, start, end, calc, peakIndex, peakCalendar, peakHoursPerDay);
59void AverageOffPeakPowerHelper::init(
const QuantLib::ext::shared_ptr<CommodityIndex>& index,
60 const Date& start,
const Date& end,
const QuantLib::ext::shared_ptr<FutureExpiryCalculator>& calc,
61 const QuantLib::ext::shared_ptr<CommodityIndex>& peakIndex,
const Calendar& peakCalendar,
62 Natural peakHoursPerDay) {
64 QL_REQUIRE(peakHoursPerDay <= 24,
"AverageOffPeakPowerHelper: peak hours per day should not be greater than 24.");
65 Natural ophpd = 24 - peakHoursPerDay;
69 auto indexClone = index->clone(Date(), termStructureHandle_);
73 indexClone->unregisterWith(termStructureHandle_);
74 registerWith(indexClone);
77 bool useBusinessDays =
true;
78 businessOffPeak_ = QuantLib::ext::make_shared<CommodityIndexedAverageCashFlow>(1.0, start, end, end, indexClone,
79 peakCalendar, 0.0, 1.0,
true, 0, 0, calc,
true,
false, useBusinessDays);
80 peakDays_ = businessOffPeak_->indices().size();
83 useBusinessDays =
false;
84 holidayOffPeak_ = QuantLib::ext::make_shared<CommodityIndexedAverageCashFlow>(ophpd / 24.0, start, end, end, indexClone,
85 peakCalendar, 0.0, 1.0,
true, 0, 0, calc,
true,
false, useBusinessDays);
86 nonPeakDays_ = holidayOffPeak_->indices().size();
89 holidayPeak_ = QuantLib::ext::make_shared<CommodityIndexedAverageCashFlow>(peakHoursPerDay / 24.0, start, end, end,
90 peakIndex, peakCalendar, 0.0, 1.0,
true, 0, 0, calc,
true,
false, useBusinessDays);
95 const auto& mpBop = businessOffPeak_->indices();
96 const auto& mpHop = holidayOffPeak_->indices();
97 earliestDate_ =
min(mpBop.begin()->second->expiryDate(), mpHop.begin()->second->expiryDate());
98 pillarDate_ =
max(mpBop.rbegin()->second->expiryDate(), mpHop.rbegin()->second->expiryDate());
101Real AverageOffPeakPowerHelper::impliedQuote()
const {
102 QL_REQUIRE(termStructure_,
"AverageFuturePriceHelper term structure not set.");
103 businessOffPeak_->update();
104 holidayOffPeak_->update();
105 holidayPeak_->update();
106 return (peakDays_ * businessOffPeak_->amount() + nonPeakDays_ * (holidayOffPeak_->amount()
107 + holidayPeak_->amount())) / (peakDays_ + nonPeakDays_);
111 QuantLib::ext::shared_ptr<PriceTermStructure> temp(ts, null_deleter());
113 termStructureHandle_.linkTo(temp,
false);
114 PriceHelper::setTermStructure(ts);
117void AverageOffPeakPowerHelper::accept(AcyclicVisitor& v) {
118 if (
auto vis =
dynamic_cast<Visitor<AverageOffPeakPowerHelper>*
>(&v))
121 PriceHelper::accept(v);
124void AverageOffPeakPowerHelper::deepUpdate() {
125 if (businessOffPeak_)
126 businessOffPeak_->update();
128 holidayOffPeak_->update();
130 holidayPeak_->update();
Price helper for average of off-peak electricity prices over a period.
AverageOffPeakPowerHelper(const QuantLib::Handle< QuantLib::Quote > &price, const QuantLib::ext::shared_ptr< CommodityIndex > &index, const QuantLib::Date &start, const QuantLib::Date &end, const ext::shared_ptr< FutureExpiryCalculator > &calc, const QuantLib::ext::shared_ptr< CommodityIndex > &peakIndex, const QuantLib::Calendar &peakCalendar, QuantLib::Natural peakHoursPerDay=16)
CompiledFormula min(CompiledFormula x, const CompiledFormula &y)
CompiledFormula max(CompiledFormula x, const CompiledFormula &y)