Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Public Member Functions | List of all members
BlackVolatilitySurfaceDelta Class Reference

#include <qle/termstructures/blackvolsurfacedelta.hpp>

+ Inheritance diagram for BlackVolatilitySurfaceDelta:
+ Collaboration diagram for BlackVolatilitySurfaceDelta:

Public Member Functions

 BlackVolatilitySurfaceDelta (Date referenceDate, const std::vector< Date > &dates, const std::vector< Real > &putDeltas, const std::vector< Real > &callDeltas, bool hasAtm, const Matrix &blackVolMatrix, const DayCounter &dayCounter, const Calendar &cal, const Handle< Quote > &spot, const Handle< YieldTermStructure > &domesticTS, const Handle< YieldTermStructure > &foreignTS, DeltaVolQuote::DeltaType dt=DeltaVolQuote::DeltaType::Spot, DeltaVolQuote::AtmType at=DeltaVolQuote::AtmType::AtmDeltaNeutral, boost::optional< QuantLib::DeltaVolQuote::DeltaType > atmDeltaType=boost::none, const Period &switchTenor=0 *Days, DeltaVolQuote::DeltaType ltdt=DeltaVolQuote::DeltaType::Fwd, DeltaVolQuote::AtmType ltat=DeltaVolQuote::AtmType::AtmDeltaNeutral, boost::optional< QuantLib::DeltaVolQuote::DeltaType > longTermAtmDeltaType=boost::none, InterpolatedSmileSection::InterpolationMethod interpolationMethod=InterpolatedSmileSection::InterpolationMethod::Linear, bool flatExtrapolation=true)
 
TermStructure interface
Date maxDate () const override
 
VolatilityTermStructure interface
Real minStrike () const override
 
Real maxStrike () const override
 
Visitability
virtual void accept (AcyclicVisitor &) override
 

Inspectors

std::vector< Date > dates_
 
std::vector< Time > times_
 
std::vector< Real > putDeltas_
 
std::vector< Real > callDeltas_
 
bool hasAtm_
 
std::vector< QuantLib::ext::shared_ptr< BlackVarianceCurve > > interpolators_
 
Handle< Quote > spot_
 
Handle< YieldTermStructure > domesticTS_
 
Handle< YieldTermStructure > foreignTS_
 
DeltaVolQuote::DeltaType dt_
 
DeltaVolQuote::AtmType at_
 
boost::optional< QuantLib::DeltaVolQuote::DeltaType > atmDeltaType_
 
Period switchTenor_
 
DeltaVolQuote::DeltaType ltdt_
 
DeltaVolQuote::AtmType ltat_
 
boost::optional< QuantLib::DeltaVolQuote::DeltaType > longTermAtmDeltaType_
 
InterpolatedSmileSection::InterpolationMethod interpolationMethod_
 
bool flatExtrapolation_
 
Real switchTime_
 
const std::vector< QuantLib::Date > & dates () const
 
QuantLib::ext::shared_ptr< FxSmileSectionblackVolSmile (Time t) const
 Return an FxSmile for the time t. More...
 
QuantLib::ext::shared_ptr< FxSmileSectionblackVolSmile (const QuantLib::Date &d) const
 
virtual Volatility blackVolImpl (Time t, Real strike) const override
 
Real forward (Time t) const
 

Detailed Description

Abstract Black volatility surface based on delta

Definition at line 84 of file blackvolsurfacedelta.hpp.

Constructor & Destructor Documentation

◆ BlackVolatilitySurfaceDelta()

BlackVolatilitySurfaceDelta ( Date  referenceDate,
const std::vector< Date > &  dates,
const std::vector< Real > &  putDeltas,
const std::vector< Real > &  callDeltas,
bool  hasAtm,
const Matrix &  blackVolMatrix,
const DayCounter &  dayCounter,
const Calendar &  cal,
const Handle< Quote > &  spot,
const Handle< YieldTermStructure > &  domesticTS,
const Handle< YieldTermStructure > &  foreignTS,
DeltaVolQuote::DeltaType  dt = DeltaVolQuote::DeltaType::Spot,
DeltaVolQuote::AtmType  at = DeltaVolQuote::AtmType::AtmDeltaNeutral,
boost::optional< QuantLib::DeltaVolQuote::DeltaType >  atmDeltaType = boost::none,
const Period &  switchTenor = 0 * Days,
DeltaVolQuote::DeltaType  ltdt = DeltaVolQuote::DeltaType::Fwd,
DeltaVolQuote::AtmType  ltat = DeltaVolQuote::AtmType::AtmDeltaNeutral,
boost::optional< QuantLib::DeltaVolQuote::DeltaType >  longTermAtmDeltaType = boost::none,
InterpolatedSmileSection::InterpolationMethod  interpolationMethod = InterpolatedSmileSection::InterpolationMethod::Linear,
bool  flatExtrapolation = true 
)

Definition at line 64 of file blackvolsurfacedelta.cpp.

72 : BlackVolatilityTermStructure(referenceDate, cal, Following, dayCounter), dates_(dates), times_(dates.size(), 0),
73 putDeltas_(putDeltas), callDeltas_(callDeltas), hasAtm_(hasAtm), spot_(spot), domesticTS_(domesticTS),
74 foreignTS_(foreignTS), dt_(dt), at_(at), atmDeltaType_(atmDeltaType), switchTenor_(switchTenor), ltdt_(ltdt),
75 ltat_(ltat), longTermAtmDeltaType_(longTermAtmDeltaType), interpolationMethod_(im),
76 flatExtrapolation_(flatExtrapolation) {
77
78 // If ATM delta type is not given, set it to dt
79 if (!atmDeltaType_)
83
84 // set switch time
85 switchTime_ = switchTenor_ == 0 * Days ? QL_MAX_REAL : timeFromReference(optionDateFromTenor(switchTenor));
86
87 QL_REQUIRE(dates.size() > 1, "at least 1 date required");
88 // this has already been done for dates
89 for (Size i = 0; i < dates.size(); i++) {
90 QL_REQUIRE(referenceDate < dates[i], "Dates must be greater than reference date");
91 times_[i] = timeFromReference(dates[i]);
92 if (i > 0) {
93 QL_REQUIRE(times_[i] > times_[i - 1], "dates must be sorted unique!");
94 }
95 }
96
97 // check size of matrix
98 Size n = putDeltas.size() + (hasAtm ? 1 : 0) + callDeltas.size();
99 QL_REQUIRE(n > 0, "Need at least one delta");
100 QL_REQUIRE(blackVolMatrix.columns() == n, "Invalid number of columns in blackVolMatrix, got "
101 << blackVolMatrix.columns() << " but have " << n << " deltas");
102 QL_REQUIRE(blackVolMatrix.rows() == dates.size(), "Invalid number of rows in blackVolMatrix, got "
103 << blackVolMatrix.rows() << " but have " << dates.size()
104 << " dates");
105
106 // build interpolators for each delta
107 // TODO: template this so it can be changed
108 bool forceMonotoneVariance = false;
109 for (Size i = 0; i < n; i++) {
110 vector<Volatility> vols(dates.size());
111 for (Size j = 0; j < dates.size(); j++) {
112 vols[j] = blackVolMatrix[j][i];
113 }
114
115 // BlackVarianceCurve will make a local copy of vols and dates
116 interpolators_.push_back(
117 QuantLib::ext::make_shared<BlackVarianceCurve>(referenceDate, dates, vols, dayCounter, forceMonotoneVariance));
118 }
119
120 // register
121 registerWith(spot_);
122 registerWith(domesticTS_);
123 registerWith(foreignTS_);
124}
boost::optional< QuantLib::DeltaVolQuote::DeltaType > atmDeltaType_
std::vector< QuantLib::ext::shared_ptr< BlackVarianceCurve > > interpolators_
Handle< YieldTermStructure > domesticTS_
boost::optional< QuantLib::DeltaVolQuote::DeltaType > longTermAtmDeltaType_
InterpolatedSmileSection::InterpolationMethod interpolationMethod_
const std::vector< QuantLib::Date > & dates() const
+ Here is the call graph for this function:

Member Function Documentation

◆ maxDate()

Date maxDate ( ) const
override

Definition at line 104 of file blackvolsurfacedelta.hpp.

104{ return Date::maxDate(); }

◆ minStrike()

Real minStrike ( ) const
override

Definition at line 108 of file blackvolsurfacedelta.hpp.

108{ return 0; }

◆ maxStrike()

Real maxStrike ( ) const
override

Definition at line 109 of file blackvolsurfacedelta.hpp.

109{ return QL_MAX_REAL; }

◆ accept()

void accept ( AcyclicVisitor &  v)
overridevirtual

Definition at line 166 of file blackvolsurfacedelta.hpp.

166 {
167 Visitor<BlackVolatilitySurfaceDelta>* v1 = dynamic_cast<Visitor<BlackVolatilitySurfaceDelta>*>(&v);
168 if (v1 != 0)
169 v1->visit(*this);
170 else
171 BlackVolatilityTermStructure::accept(v);
172}

◆ dates()

const std::vector< QuantLib::Date > & dates ( ) const

Definition at line 118 of file blackvolsurfacedelta.hpp.

118{ return dates_; }
+ Here is the caller graph for this function:

◆ blackVolSmile() [1/2]

QuantLib::ext::shared_ptr< FxSmileSection > blackVolSmile ( Time  t) const

Return an FxSmile for the time t.

Note the smile does not observe the spot or YTS handles, it will not update when they change.

This is not really FX specific

Definition at line 126 of file blackvolsurfacedelta.cpp.

126 {
127
128 Real spot = spot_->value();
129 DiscountFactor dDiscount = domesticTS_->discount(t);
130 DiscountFactor fDiscount = foreignTS_->discount(t);
131
132 DeltaVolQuote::AtmType at;
133 DeltaVolQuote::DeltaType dt;
134 DeltaVolQuote::DeltaType atmDt;
135 if (t < switchTime_ && !close_enough(t, switchTime_)) {
136 at = at_;
137 dt = dt_;
138 atmDt = *atmDeltaType_;
139 } else {
140 at = ltat_;
141 dt = ltdt_;
142 atmDt = *longTermAtmDeltaType_;
143 }
144
145 // Store smile section in map. Use strikes as key and vols as values for automatic sorting by strike.
146 // If we have already have a strike from a previous delta, we do not overwrite it.
147 auto comp = [](Real a, Real b) { return !close(a, b) && a < b; };
148 map<Real, Real, decltype(comp)> smileSection(comp);
149 Size i = 0;
150 for (Real delta : putDeltas_) {
151 Real vol = interpolators_.at(i)->blackVol(t, 1, true);
152 try {
153 BlackDeltaCalculator bdc(Option::Put, dt, spot, dDiscount, fDiscount, vol * sqrt(t));
154 Real strike = bdc.strikeFromDelta(delta);
155 if (smileSection.count(strike) == 0)
156 smileSection[strike] = vol;
157 } catch (const std::exception& e) {
158 QL_FAIL("BlackVolatilitySurfaceDelta: Error during calculating put strike at delta " << delta << ": "
159 << e.what());
160 }
161 i++;
162 }
163 if (hasAtm_) {
164 Real vol = interpolators_.at(i)->blackVol(t, 1, true);
165 try {
166 BlackDeltaCalculator bdc(Option::Put, atmDt, spot, dDiscount, fDiscount, vol * sqrt(t));
167 Real strike = bdc.atmStrike(at);
168 if (smileSection.count(strike) == 0)
169 smileSection[strike] = vol;
170 } catch (const std::exception& e) {
171 QL_FAIL("BlackVolatilitySurfaceDelta: Error during calculating atm strike: " << e.what());
172 }
173 i++;
174 }
175 for (Real delta : callDeltas_) {
176 Real vol = interpolators_.at(i)->blackVol(t, 1, true);
177 try {
178 BlackDeltaCalculator bdc(Option::Call, dt, spot, dDiscount, fDiscount, vol * sqrt(t));
179 Real strike = bdc.strikeFromDelta(delta);
180 if (smileSection.count(strike) == 0)
181 smileSection[strike] = vol;
182 } catch (const std::exception& e) {
183 QL_FAIL("BlackVolatilitySurfaceDelta: Error during calculating call strike at delta " << delta << ": "
184 << e.what());
185 }
186 i++;
187 }
188
189 // sort and extract to vectors
190 vector<Real> strikes;
191 strikes.reserve(smileSection.size());
192 vector<Real> vols;
193 vols.reserve(smileSection.size());
194 for (const auto& kv : smileSection) {
195 strikes.push_back(kv.first);
196 vols.push_back(kv.second);
197 }
198
199 // now build smile from strikes and vols
200 QL_REQUIRE(!vols.empty(),
201 "BlackVolatilitySurfaceDelta::blackVolSmile(" << t << "): no strikes given, this is unexpected.");
202 if (vols.size() == 1) {
203 // handle the situation that we only have one strike (might occur for e.g. t=0)
204 return QuantLib::ext::make_shared<ConstantSmileSection>(vols.front());
205 } else {
206 // we have at least two strikes
207 return QuantLib::ext::make_shared<InterpolatedSmileSection>(spot, dDiscount, fDiscount, t, strikes, vols,
209 }
210}
RandomVariable sqrt(RandomVariable x)
Filter close_enough(const RandomVariable &x, const RandomVariable &y)
vector< Real > strikes
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ blackVolSmile() [2/2]

QuantLib::ext::shared_ptr< FxSmileSection > blackVolSmile ( const QuantLib::Date &  d) const

◆ blackVolImpl()

Volatility blackVolImpl ( Time  t,
Real  strike 
) const
overrideprotectedvirtual

Definition at line 220 of file blackvolsurfacedelta.cpp.

220 {
221 // Only flat extrapolation allowed
222 Time tme = t <= times_.back() ? t : times_.back();
223 // If asked for strike == 0, just return the ATM value.
224 if (strike == 0 || strike == Null<Real>()) {
225 if (hasAtm_) {
226 // ask the ATM interpolator directly
227 return interpolators_[putDeltas_.size()]->blackVol(tme, Null<Real>(), true);
228 } else {
229 // set strike to be fwd and we will return ATMF
230 strike = forward(tme);
231 }
232 }
233 return blackVolSmile(tme)->volatility(strike);
234}
QuantLib::ext::shared_ptr< FxSmileSection > blackVolSmile(Time t) const
Return an FxSmile for the time t.
+ Here is the call graph for this function:

◆ forward()

Real forward ( Time  t) const
private

Definition at line 216 of file blackvolsurfacedelta.cpp.

216 {
217 return spot_->value() * foreignTS_->discount(t) / domesticTS_->discount(t); // TODO
218}
+ Here is the caller graph for this function:

Member Data Documentation

◆ dates_

std::vector<Date> dates_
private

Definition at line 135 of file blackvolsurfacedelta.hpp.

◆ times_

std::vector<Time> times_
private

Definition at line 136 of file blackvolsurfacedelta.hpp.

◆ putDeltas_

std::vector<Real> putDeltas_
private

Definition at line 138 of file blackvolsurfacedelta.hpp.

◆ callDeltas_

std::vector<Real> callDeltas_
private

Definition at line 139 of file blackvolsurfacedelta.hpp.

◆ hasAtm_

bool hasAtm_
private

Definition at line 140 of file blackvolsurfacedelta.hpp.

◆ interpolators_

std::vector<QuantLib::ext::shared_ptr<BlackVarianceCurve> > interpolators_
private

Definition at line 141 of file blackvolsurfacedelta.hpp.

◆ spot_

Handle<Quote> spot_
private

Definition at line 143 of file blackvolsurfacedelta.hpp.

◆ domesticTS_

Handle<YieldTermStructure> domesticTS_
private

Definition at line 144 of file blackvolsurfacedelta.hpp.

◆ foreignTS_

Handle<YieldTermStructure> foreignTS_
private

Definition at line 145 of file blackvolsurfacedelta.hpp.

◆ dt_

DeltaVolQuote::DeltaType dt_
private

Definition at line 147 of file blackvolsurfacedelta.hpp.

◆ at_

DeltaVolQuote::AtmType at_
private

Definition at line 148 of file blackvolsurfacedelta.hpp.

◆ atmDeltaType_

boost::optional<QuantLib::DeltaVolQuote::DeltaType> atmDeltaType_
private

Definition at line 149 of file blackvolsurfacedelta.hpp.

◆ switchTenor_

Period switchTenor_
private

Definition at line 150 of file blackvolsurfacedelta.hpp.

◆ ltdt_

DeltaVolQuote::DeltaType ltdt_
private

Definition at line 151 of file blackvolsurfacedelta.hpp.

◆ ltat_

DeltaVolQuote::AtmType ltat_
private

Definition at line 152 of file blackvolsurfacedelta.hpp.

◆ longTermAtmDeltaType_

boost::optional<QuantLib::DeltaVolQuote::DeltaType> longTermAtmDeltaType_
private

Definition at line 153 of file blackvolsurfacedelta.hpp.

◆ interpolationMethod_

InterpolatedSmileSection::InterpolationMethod interpolationMethod_
private

Definition at line 155 of file blackvolsurfacedelta.hpp.

◆ flatExtrapolation_

bool flatExtrapolation_
private

Definition at line 156 of file blackvolsurfacedelta.hpp.

◆ switchTime_

Real switchTime_
private

Definition at line 158 of file blackvolsurfacedelta.hpp.