24#ifndef quantext_dynamic_black_volatility_termstructure_hpp
25#define quantext_dynamic_black_volatility_termstructure_hpp
30#include <ql/termstructures/volatility/equityfx/blackvoltermstructure.hpp>
31#include <ql/termstructures/yieldtermstructure.hpp>
33#include <ql/math/comparison.hpp>
76 const Handle<YieldTermStructure>& riskfree = Handle<YieldTermStructure>(),
77 const Handle<YieldTermStructure>& dividend = Handle<YieldTermStructure>(),
78 const Handle<Quote>& spot = Handle<Quote>(),
79 const std::vector<Real> initialForwardGrid = std::vector<Real>());
94 Volatility
blackVolImpl(Time t, Real strike)
const override;
111template <
typename mode>
113 Natural settlementDays,
const Calendar& calendar,
115 const Handle<YieldTermStructure>& riskfree,
116 const Handle<YieldTermStructure>& dividend,
117 const Handle<Quote>& spot,
118 const std::vector<Real> forwardCurveSampleGrid)
119 :
BlackVolTermStructure(settlementDays, calendar, source->businessDayConvention(), source->dayCounter()),
120 source_(source), decayMode_(decayMode), stickyness_(stickyness), riskfree_(riskfree), dividend_(dividend),
121 spot_(spot), originalReferenceDate_(source->referenceDate()),
122 atmKnown_(!riskfree.empty() && !dividend.empty() && !spot.empty()),
123 forwardCurveSampleGrid_(forwardCurveSampleGrid) {
126 "stickiness (" << stickyness <<
") not supported");
128 "reaction to time decay (" << decayMode <<
") not supported");
130 registerWith(source);
133 QL_REQUIRE(
atmKnown_,
"for stickiness other than strike, the term "
134 "structures and spot must be given");
136 "at construction time the reference dates of the volatility "
138 << source->referenceDate() <<
") and the risk free yield term structure ("
139 <<
riskfree_->referenceDate() <<
") must be the same");
141 "at construction time the reference dates of the volatility "
143 << source->referenceDate() <<
") and the dividend term structure (" <<
riskfree_->referenceDate()
144 <<
") must be the same");
153 Real tmp[] = { 0.0, 0.25, 0.5, 0.75, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0,
154 8.0, 9.0, 10.0, 12.0, 15.0, 20.0, 25.0, 30.0, 40.0, 50.0, 60.0 };
162 "forward curve sample grid must have increasing times (at "
170 initialForwardCurve_ = QuantLib::ext::make_shared<FlatExtrapolation>(QuantLib::ext::make_shared<LinearInterpolation>(
180 return source_->maxDate();
183 return Date(std::min(Date::maxDate().serialNumber(), referenceDate().serialNumber() -
184 originalReferenceDate_.serialNumber() +
185 source_->maxDate().serialNumber()));
187 QL_FAIL(
"unexpected decay mode (" << decayMode_ <<
")");
192 return source_->minStrike();
200 QL_FAIL(
"unexpected stickiness (" << stickyness_ <<
")");
205 return source_->maxStrike();
211 QL_FAIL(
"unexpected stickiness (" << stickyness_ <<
")");
215 Real tmp = std::max(1.0E-6, t);
216 return std::sqrt(blackVarianceImpl(tmp, strike) / tmp);
220 return blackVarianceImplTag(t, strike, mode());
223template <
typename mode>
225 if (strike == Null<Real>()) {
226 QL_REQUIRE(atmKnown_,
"can not calculate atm level (null strike is "
227 "given) because a curve or the spot is missing");
228 strike = spot_->value() / riskfree_->discount(t) * dividend_->discount(t);
230 Real scenarioT0 = 0.0, scenarioT1 = t;
231 Real scenarioStrike0 = strike, scenarioStrike1 = strike;
233 scenarioT0 = source_->timeFromReference(referenceDate());
234 scenarioT1 = scenarioT0 + t;
237 Real forward = spot_->value() / riskfree_->discount(t) * dividend_->discount(t);
238 scenarioStrike1 = initialForwardCurve_->operator()(scenarioT1) / forward * strike;
239 scenarioStrike0 = initialForwardCurve_->operator()(scenarioT0) / spot_->value() * strike;
241 return std::max(0.0, source_->blackVariance(scenarioT1, scenarioStrike1,
true) -
242 source_->blackVariance(scenarioT0, scenarioStrike0,
true));
245template <
typename mode>
248 Real scenarioT0 = source_->timeFromReference(referenceDate());
249 Real scenarioT1 = scenarioT0 + t;
250 return std::max(0.0, source_->blackVariance(scenarioT1, strike,
true) - source_->blackVariance(scenarioT0, strike,
true));
252 return source_->blackVariance(t, strike,
true);
Takes a BlackVolTermStructure with fixed reference date and turns it into a floating reference date t...
const Handle< Quote > spot_
const Handle< YieldTermStructure > dividend_
const Handle< YieldTermStructure > riskfree_
Real blackVarianceImplTag(Time t, Real strike, tag::curve) const
Real minStrike() const override
DynamicBlackVolTermStructure(const Handle< BlackVolTermStructure > &source, Natural settlementDays, const Calendar &calendar, ReactionToTimeDecay decayMode=ConstantVariance, Stickyness stickyness=StickyLogMoneyness, const Handle< YieldTermStructure > &riskfree=Handle< YieldTermStructure >(), const Handle< YieldTermStructure > ÷nd=Handle< YieldTermStructure >(), const Handle< Quote > &spot=Handle< Quote >(), const std::vector< Real > initialForwardGrid=std::vector< Real >())
ReactionToTimeDecay decayMode_
Date maxDate() const override
QuantLib::ext::shared_ptr< Interpolation > initialForwardCurve_
const Date originalReferenceDate_
Real blackVarianceImpl(Time t, Real strike) const override
std::vector< Real > forwardCurveSampleGrid_
Volatility blackVolImpl(Time t, Real strike) const override
std::vector< Real > initialForwards_
Real maxStrike() const override
const Handle< BlackVolTermStructure > source_
dynamics type definitions
ReactionToTimeDecay
Reaction to Time Decay.