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

Abstract base class for the option stripper. More...

#include <qle/termstructures/eqcommoptionsurfacestripper.hpp>

+ Inheritance diagram for OptionSurfaceStripper:
+ Collaboration diagram for OptionSurfaceStripper:

Classes

class  PriceError
 Function object used in solving. More...
 

Public Member Functions

 OptionSurfaceStripper (const QuantLib::ext::shared_ptr< OptionInterpolatorBase > &callSurface, const QuantLib::ext::shared_ptr< OptionInterpolatorBase > &putSurface, const QuantLib::Calendar &calendar, const QuantLib::DayCounter &dayCounter, QuantLib::Exercise::Type type=QuantLib::Exercise::European, bool lowerStrikeConstExtrap=true, bool upperStrikeConstExtrap=true, bool timeFlatExtrapolation=false, bool preferOutOfTheMoney=false, Solver1DOptions solverOptions={})
 

LazyObject interface

QuantLib::ext::shared_ptr< OptionInterpolatorBasecallSurface_
 
QuantLib::ext::shared_ptr< OptionInterpolatorBaseputSurface_
 
const QuantLib::Calendar & calendar_
 
const QuantLib::DayCounter & dayCounter_
 
QuantLib::Exercise::Type type_
 
bool lowerStrikeConstExtrap_
 
bool upperStrikeConstExtrap_
 
bool timeFlatExtrapolation_
 
bool preferOutOfTheMoney_
 
QuantLib::ext::shared_ptr< QuantLib::BlackVolTermStructure > volSurface_
 
Brent brent_
 Solver used when implying volatility from price. More...
 
Solver1DOptions solverOptions_
 
bool havePrices_
 Set to true if we must strip volatilities from prices. More...
 
std::function< Real(const PriceError &)> solver_
 Store the function that will be called each time to solve for volatility. More...
 
void performCalculations () const override
 
QuantLib::ext::shared_ptr< QuantLib::BlackVolTermStructure > volSurface ()
 Return the stripped volatility structure. More...
 
virtual QuantLib::ext::shared_ptr< QuantLib::GeneralizedBlackScholesProcess > process (const QuantLib::ext::shared_ptr< QuantLib::SimpleQuote > &volatilityQuote) const =0
 Generate the relevant Black Scholes process for the underlying. More...
 
virtual QuantLib::Real forward (const QuantLib::Date &date) const =0
 Return the forward price at a given date. More...
 
std::vector< QuantLib::Real > strikes (const QuantLib::Date &expiry, bool isCall) const
 Retrieve the vector of strikes at a given expiry date. More...
 
QuantLib::Real implyVol (QuantLib::Date expiry, QuantLib::Real strike, QuantLib::Option::Type type, QuantLib::ext::shared_ptr< QuantLib::PricingEngine > engine, QuantLib::SimpleQuote &volQuote) const
 
void setUpSolver ()
 

Detailed Description

Abstract base class for the option stripper.

Definition at line 64 of file eqcommoptionsurfacestripper.hpp.

Constructor & Destructor Documentation

◆ OptionSurfaceStripper()

OptionSurfaceStripper ( const QuantLib::ext::shared_ptr< OptionInterpolatorBase > &  callSurface,
const QuantLib::ext::shared_ptr< OptionInterpolatorBase > &  putSurface,
const QuantLib::Calendar &  calendar,
const QuantLib::DayCounter &  dayCounter,
QuantLib::Exercise::Type  type = QuantLib::Exercise::European,
bool  lowerStrikeConstExtrap = true,
bool  upperStrikeConstExtrap = true,
bool  timeFlatExtrapolation = false,
bool  preferOutOfTheMoney = false,
Solver1DOptions  solverOptions = {} 
)

Definition at line 84 of file eqcommoptionsurfacestripper.cpp.

95 : callSurface_(callSurface),
96 putSurface_(putSurface),
97 calendar_(calendar),
98 dayCounter_(dayCounter),
99 type_(type),
100 lowerStrikeConstExtrap_(lowerStrikeConstExtrap),
101 upperStrikeConstExtrap_(upperStrikeConstExtrap),
102 timeFlatExtrapolation_(timeFlatExtrapolation),
103 preferOutOfTheMoney_(preferOutOfTheMoney),
104 solverOptions_(solverOptions),
105 havePrices_(QuantLib::ext::dynamic_pointer_cast<OptionPriceSurface>(callSurface_)) {
106
107 QL_REQUIRE(callSurface_->referenceDate() == putSurface_->referenceDate(),
108 "Mismatch between Call and Put reference dates in OptionSurfaceStripper");
109
110 registerWith(Settings::instance().evaluationDate());
111
112 // Set up that is only needed if we have price based surfaces and we are stripping volatilities.
113 if (havePrices_) {
114
115 // Check that there is also a put price surface
116 QL_REQUIRE(QuantLib::ext::dynamic_pointer_cast<OptionPriceSurface>(putSurface_),
117 "OptionSurfaceStripper: call price surface provided but no put price surface.");
118
119 setUpSolver();
120 }
121}
const QuantLib::DayCounter & dayCounter_
bool havePrices_
Set to true if we must strip volatilities from prices.
QuantLib::ext::shared_ptr< OptionInterpolatorBase > putSurface_
QuantLib::ext::shared_ptr< OptionInterpolatorBase > callSurface_
+ Here is the call graph for this function:

Member Function Documentation

◆ performCalculations()

void performCalculations ( ) const
override

Definition at line 141 of file eqcommoptionsurfacestripper.cpp.

141 {
142
143 // Create a set of all expiries
144 auto tmp = callSurface_->expiries();
145 set<Date> allExpiries(tmp.begin(), tmp.end());
146 tmp = putSurface_->expiries();
147 allExpiries.insert(tmp.begin(), tmp.end());
148
149 QuantLib::ext::shared_ptr<BlackVarianceSurfaceSparse> callVolSurface;
150 QuantLib::ext::shared_ptr<BlackVarianceSurfaceSparse> putVolSurface;
151
152 // Switch based on whether surface is direct volatilities or prices to be stripped.
153 QuantLib::ext::shared_ptr<PricingEngine> engine;
154 QuantLib::ext::shared_ptr<SimpleQuote> volQuote = QuantLib::ext::make_shared<SimpleQuote>(0.1);
155 if (havePrices_) {
156
157 // a black scholes process
158 QuantLib::ext::shared_ptr<GeneralizedBlackScholesProcess> gbsp = process(volQuote);
159
160 // hard code the engines here
161 if (type_ == Exercise::American) {
162 engine = QuantLib::ext::make_shared<QuantExt::BaroneAdesiWhaleyApproximationEngine>(gbsp);
163 } else if (type_ == Exercise::European) {
164 engine = QuantLib::ext::make_shared<QuantExt::AnalyticEuropeanEngine>(gbsp);
165 } else {
166 QL_FAIL("Unsupported exercise type for option stripping");
167 }
168
169 } else {
170 // we have variance surfaces, explicitly cast so we can look up vol later
171 callVolSurface = QuantLib::ext::dynamic_pointer_cast<BlackVarianceSurfaceSparse>(callSurface_);
172 putVolSurface = QuantLib::ext::dynamic_pointer_cast<BlackVarianceSurfaceSparse>(putSurface_);
173 }
174
175 // Need to populate these below to feed to BlackVarianceSurfaceSparse
176 vector<Real> volStrikes;
177 vector<Real> volData;
178 vector<Date> volExpiries;
179
180 // Loop over each expiry
181 for (const Date& expiry : allExpiries) {
182
183 // Get the forward price at expiry
184 Real fwd = forward(expiry);
185
186 // Get the call and put strikes at the expiry date. Each may be empty.
187 vector<Real> callStrikes = strikes(expiry, true);
188 vector<Real> putStrikes = strikes(expiry, false);
189
190 // We want a set of prices both sides of ATM forward
191 // If preferOutOfTheMoney_ is false, we take calls where strike < atm and puts where strike > atm.
192 // If preferOutOfTheMoney_ is true, we take calls where strike > atm and puts where strike < atm.
193 auto relevantStrikes = createStrikes(fwd, callStrikes, putStrikes, preferOutOfTheMoney_);
194 for (const auto& kv : relevantStrikes) {
195 if (havePrices_) {
196 // Only use the volatility if the root finding was successful
197 Real v = implyVol(expiry, kv.first, kv.second, engine, *volQuote);
198 if (v != Null<Real>()) {
199 volExpiries.push_back(expiry);
200 volStrikes.push_back(kv.first);
201 volData.push_back(v);
202 }
203 } else {
204 volExpiries.push_back(expiry);
205 volStrikes.push_back(kv.first);
206 Real v = kv.second == Option::Call ? callVolSurface->blackVol(expiry, kv.first) :
207 putVolSurface->blackVol(expiry, kv.first);
208 volData.push_back(v);
209 }
210 }
211 }
212
213 // Populate the variance surface.
214 volSurface_ = QuantLib::ext::make_shared<BlackVarianceSurfaceSparse>(
215 callSurface_->referenceDate(), calendar_, volExpiries, volStrikes, volData, dayCounter_,
217}
virtual QuantLib::ext::shared_ptr< QuantLib::GeneralizedBlackScholesProcess > process(const QuantLib::ext::shared_ptr< QuantLib::SimpleQuote > &volatilityQuote) const =0
Generate the relevant Black Scholes process for the underlying.
QuantLib::ext::shared_ptr< QuantLib::BlackVolTermStructure > volSurface_
virtual QuantLib::Real forward(const QuantLib::Date &date) const =0
Return the forward price at a given date.
QuantLib::Real implyVol(QuantLib::Date expiry, QuantLib::Real strike, QuantLib::Option::Type type, QuantLib::ext::shared_ptr< QuantLib::PricingEngine > engine, QuantLib::SimpleQuote &volQuote) const
vector< Real > strikes
+ Here is the call graph for this function:

◆ volSurface()

QuantLib::ext::shared_ptr< BlackVolTermStructure > volSurface ( )

Return the stripped volatility structure.

Definition at line 307 of file eqcommoptionsurfacestripper.cpp.

307 {
308 calculate();
309 return volSurface_;
310}

◆ process()

virtual QuantLib::ext::shared_ptr< QuantLib::GeneralizedBlackScholesProcess > process ( const QuantLib::ext::shared_ptr< QuantLib::SimpleQuote > &  volatilityQuote) const
protectedpure virtual

Generate the relevant Black Scholes process for the underlying.

Implemented in EquityOptionSurfaceStripper, and CommodityOptionSurfaceStripper.

+ Here is the caller graph for this function:

◆ forward()

virtual QuantLib::Real forward ( const QuantLib::Date &  date) const
protectedpure virtual

Return the forward price at a given date.

Implemented in EquityOptionSurfaceStripper, and CommodityOptionSurfaceStripper.

+ Here is the caller graph for this function:

◆ strikes()

vector< Real > strikes ( const QuantLib::Date &  expiry,
bool  isCall 
) const
private

Retrieve the vector of strikes at a given expiry date.

Definition at line 219 of file eqcommoptionsurfacestripper.cpp.

219 {
220
221 const QuantLib::ext::shared_ptr<OptionInterpolatorBase>& surface = isCall ? callSurface_ : putSurface_;
222 auto expiries = surface->expiries();
223 auto it = find(expiries.begin(), expiries.end(), expiry);
224
225 if (it != expiries.end()) {
226 return surface->strikes().at(distance(expiries.begin(), it));
227 } else {
228 return {};
229 }
230
231}

◆ implyVol()

Real implyVol ( QuantLib::Date  expiry,
QuantLib::Real  strike,
QuantLib::Option::Type  type,
QuantLib::ext::shared_ptr< QuantLib::PricingEngine >  engine,
QuantLib::SimpleQuote &  volQuote 
) const
private

Imply the volatility at a given expiry and strike for the given option type. The exercise type is indicated by the member variable type_ and the target price is read off the relevant price surface i.e. either callSurface_ or putSurface_.

If the root finding fails, a Null<Real>() is returned.

Definition at line 233 of file eqcommoptionsurfacestripper.cpp.

234 {
235
236 // Create the option instrument used in the solver.
237 QuantLib::ext::shared_ptr<StrikedTypePayoff> payoff = QuantLib::ext::make_shared<PlainVanillaPayoff>(type, strike);
238 QuantLib::ext::shared_ptr<Exercise> exercise;
239 if (type_ == Exercise::American) {
240 exercise = QuantLib::ext::make_shared<AmericanExercise>(expiry);
241 } else if (type_ == Exercise::European) {
242 exercise = QuantLib::ext::make_shared<EuropeanExercise>(expiry);
243 } else {
244 QL_FAIL("OptionSurfaceStripper: unsupported exercise type for option stripping.");
245 }
246 VanillaOption option(payoff, exercise);
247 option.setPricingEngine(engine);
248
249 // Get the target price from the surface.
250 Real targetPrice = type == Option::Call ? callSurface_->getValue(expiry, strike)
251 : putSurface_->getValue(expiry, strike);
252
253 // Attempt to calculate the implied volatility.
254 Real vol = Null<Real>();
255 try {
256 PriceError f(option, volQuote, targetPrice);
257 vol = solver_(f);
258 } catch (const Error&) {
259 }
260
261 return vol;
262}
std::function< Real(const PriceError &)> solver_
Store the function that will be called each time to solve for volatility.
+ Here is the caller graph for this function:

◆ setUpSolver()

void setUpSolver ( )
private

Definition at line 264 of file eqcommoptionsurfacestripper.cpp.

264 {
265
266 // Check that enough solver options have been provided.
267 const Real& guess = solverOptions_.initialGuess;
268 QL_REQUIRE(guess != Null<Real>(), "OptionSurfaceStripper: need a valid initial " <<
269 "guess for a price based surface.");
270
271 const Real& accuracy = solverOptions_.accuracy;
272 QL_REQUIRE(accuracy != Null<Real>(), "OptionSurfaceStripper: need a valid accuracy " <<
273 "for a price based surface.");
274
275 // Set maximum evaluations if provided.
276 if (solverOptions_.maxEvaluations != Null<Size>())
277 brent_.setMaxEvaluations(solverOptions_.maxEvaluations);
278
279 // Check and set the lower bound and upper bound
280 if (solverOptions_.lowerBound != Null<Real>() && solverOptions_.upperBound != Null<Real>()) {
281 QL_REQUIRE(solverOptions_.lowerBound < solverOptions_.upperBound, "OptionSurfaceStripper: lowerBound (" <<
282 solverOptions_.lowerBound << ") should be less than upperBound (" << solverOptions_.upperBound << ")");
283 }
284
285 if (solverOptions_.lowerBound != Null<Real>())
286 brent_.setLowerBound(solverOptions_.lowerBound);
287 if (solverOptions_.upperBound != Null<Real>())
288 brent_.setUpperBound(solverOptions_.upperBound);
289
290 // Choose a min/max or step solver based on parameters provided, favouring the min/max based version.
291 const Real& min = solverOptions_.minMax.first;
292 const Real& max = solverOptions_.minMax.second;
293 const Real& step = solverOptions_.step;
294 using std::placeholders::_1;
295 if (min != Null<Real>() && max != Null<Real>()) {
296 typedef Real (Brent::* MinMaxSolver)(const PriceError&, Real, Real, Real, Real) const;
297 solver_ = std::bind(static_cast<MinMaxSolver>(&Brent::solve), &brent_, _1, accuracy, guess, min, max);
298 } else if (step != Null<Real>()) {
299 typedef Real(Brent::* StepSolver)(const PriceError&, Real, Real, Real) const;
300 solver_ = std::bind(static_cast<StepSolver>(&Brent::solve), &brent_, _1, accuracy, guess, step);
301 } else {
302 QL_FAIL("OptionSurfaceStripper: need a valid step size or (min, max) pair for a price based surface.");
303 }
304
305}
Brent brent_
Solver used when implying volatility from price.
CompiledFormula min(CompiledFormula x, const CompiledFormula &y)
CompiledFormula max(CompiledFormula x, const CompiledFormula &y)
std::pair< QuantLib::Real, QuantLib::Real > minMax
Set the minimum and maximum search.
QuantLib::Real accuracy
The accuracy for the search.
QuantLib::Real initialGuess
The initial guess for the search.
QuantLib::Real upperBound
The upper bound of the search domain. A Null<Real>() indicates that the bound should not be set.
QuantLib::Real lowerBound
The lower bound of the search domain. A Null<Real>() indicates that the bound should not be set.
QuantLib::Real step
Set the step size for the search.
QuantLib::Size maxEvaluations
The maximum number of evaluations. Default used if not set.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Data Documentation

◆ callSurface_

QuantLib::ext::shared_ptr<OptionInterpolatorBase> callSurface_
protected

Definition at line 94 of file eqcommoptionsurfacestripper.hpp.

◆ putSurface_

QuantLib::ext::shared_ptr<OptionInterpolatorBase> putSurface_
protected

Definition at line 95 of file eqcommoptionsurfacestripper.hpp.

◆ calendar_

const QuantLib::Calendar& calendar_
protected

Definition at line 96 of file eqcommoptionsurfacestripper.hpp.

◆ dayCounter_

const QuantLib::DayCounter& dayCounter_
protected

Definition at line 97 of file eqcommoptionsurfacestripper.hpp.

◆ type_

QuantLib::Exercise::Type type_
protected

Definition at line 98 of file eqcommoptionsurfacestripper.hpp.

◆ lowerStrikeConstExtrap_

bool lowerStrikeConstExtrap_
protected

Definition at line 99 of file eqcommoptionsurfacestripper.hpp.

◆ upperStrikeConstExtrap_

bool upperStrikeConstExtrap_
protected

Definition at line 100 of file eqcommoptionsurfacestripper.hpp.

◆ timeFlatExtrapolation_

bool timeFlatExtrapolation_
protected

Definition at line 101 of file eqcommoptionsurfacestripper.hpp.

◆ preferOutOfTheMoney_

bool preferOutOfTheMoney_
protected

Definition at line 102 of file eqcommoptionsurfacestripper.hpp.

◆ volSurface_

QuantLib::ext::shared_ptr<QuantLib::BlackVolTermStructure> volSurface_
mutableprivate

Definition at line 137 of file eqcommoptionsurfacestripper.hpp.

◆ brent_

Brent brent_
private

Solver used when implying volatility from price.

Definition at line 140 of file eqcommoptionsurfacestripper.hpp.

◆ solverOptions_

Solver1DOptions solverOptions_
private

Definition at line 141 of file eqcommoptionsurfacestripper.hpp.

◆ havePrices_

bool havePrices_
private

Set to true if we must strip volatilities from prices.

Definition at line 144 of file eqcommoptionsurfacestripper.hpp.

◆ solver_

std::function<Real(const PriceError&)> solver_
private

Store the function that will be called each time to solve for volatility.

Definition at line 147 of file eqcommoptionsurfacestripper.hpp.