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

#include <qle/termstructures/creditvolcurve.hpp>

+ Inheritance diagram for InterpolatingCreditVolCurve:
+ Collaboration diagram for InterpolatingCreditVolCurve:

Public Member Functions

 InterpolatingCreditVolCurve (const QuantLib::Natural settlementDays, const QuantLib::Calendar &cal, QuantLib::BusinessDayConvention bdc, const QuantLib::DayCounter &dc, const std::vector< QuantLib::Period > &terms, const std::vector< QuantLib::Handle< CreditCurve > > &termCurves, const std::map< std::tuple< QuantLib::Date, QuantLib::Period, QuantLib::Real >, QuantLib::Handle< QuantLib::Quote > > &quotes, const Type &type)
 
 InterpolatingCreditVolCurve (const QuantLib::Date &referenceDate, const QuantLib::Calendar &cal, QuantLib::BusinessDayConvention bdc, const QuantLib::DayCounter &dc, const std::vector< QuantLib::Period > &terms, const std::vector< QuantLib::Handle< CreditCurve > > &termCurves, const std::map< std::tuple< QuantLib::Date, QuantLib::Period, QuantLib::Real >, QuantLib::Handle< QuantLib::Quote > > &quotes, const Type &type)
 
QuantLib::Real volatility (const QuantLib::Date &exerciseDate, const QuantLib::Real underlyingLength, const QuantLib::Real strike, const Type &targetType) const override
 
- Public Member Functions inherited from CreditVolCurve
 CreditVolCurve (QuantLib::BusinessDayConvention bdc, const QuantLib::DayCounter &dc, const std::vector< QuantLib::Period > &terms, const std::vector< QuantLib::Handle< CreditCurve > > &termCurves, const Type &type)
 
 CreditVolCurve (const QuantLib::Natural settlementDays, const QuantLib::Calendar &cal, QuantLib::BusinessDayConvention bdc, const QuantLib::DayCounter &dc, const std::vector< QuantLib::Period > &terms, const std::vector< QuantLib::Handle< CreditCurve > > &termCurves, const Type &type)
 
 CreditVolCurve (const QuantLib::Date &referenceDate, const QuantLib::Calendar &cal, QuantLib::BusinessDayConvention bdc, const QuantLib::DayCounter &dc, const std::vector< QuantLib::Period > &terms, const std::vector< QuantLib::Handle< CreditCurve > > &termCurves, const Type &type)
 
QuantLib::Real volatility (const QuantLib::Date &exerciseDate, const QuantLib::Period &underlyingTerm, const QuantLib::Real strike, const Type &targetType) const
 
virtual QuantLib::Real volatility (const QuantLib::Date &exerciseDate, const QuantLib::Real underlyingLength, const QuantLib::Real strike, const Type &targetType) const =0
 
QuantLib::Real volatility (const QuantLib::Real exerciseTime, const QuantLib::Real underlyingLength, const QuantLib::Real strike, const Type &targetType) const
 
virtual const std::vector< QuantLib::Period > & terms () const
 
virtual const std::vector< QuantLib::Handle< CreditCurve > > & termCurves () const
 
const Typetype () const
 
QuantLib::Real atmStrike (const QuantLib::Date &expiry, const QuantLib::Period &term) const
 
QuantLib::Real atmStrike (const QuantLib::Date &expiry, const QuantLib::Real underlyingLength) const
 
QuantLib::Real minStrike () const override
 
QuantLib::Real maxStrike () const override
 
QuantLib::Date maxDate () const override
 

Private Types

using Smile = std::pair< QuantLib::Real, QuantLib::ext::shared_ptr< QuantLib::Interpolation > >
 
using Key = std::pair< QuantLib::Date, QuantLib::Period >
 

Private Member Functions

void init ()
 
void performCalculations () const override
 
void createSmile (const QuantLib::Date &expiry, const QuantLib::Period &term, const QuantLib::Date &expiry_m, const QuantLib::Date &expiry_p) const
 

Private Attributes

std::map< std::tuple< QuantLib::Date, QuantLib::Period, QuantLib::Real >, QuantLib::Handle< QuantLib::Quote > > quotes_
 
std::vector< QuantLib::Period > smileTerms_
 
std::vector< QuantLib::Date > smileExpiries_
 
std::vector< QuantLib::Real > smileTermLengths_
 
std::vector< QuantLib::Real > smileExpiryTimes_
 
std::map< Key, std::vector< QuantLib::Real > > strikes_
 
std::map< Key, std::vector< QuantLib::Real > > vols_
 
std::map< Key, Smilesmiles_
 

Additional Inherited Members

- Public Types inherited from CreditVolCurve
enum class  Type { Price , Spread }
 
- Protected Member Functions inherited from CreditVolCurve
void init ()
 
void update () override
 
void performCalculations () const override
 
QuantLib::Real moneyness (const QuantLib::Real strike, const QuantLib::Real atmStrike) const
 
QuantLib::Real strike (const QuantLib::Real moneyness, const QuantLib::Real atmStrike) const
 
- Protected Attributes inherited from CreditVolCurve
std::vector< QuantLib::Period > terms_
 
std::vector< QuantLib::Handle< CreditCurve > > termCurves_
 
Type type_
 
std::map< std::pair< QuantLib::Date, double >, double > atmStrikeCache_
 

Detailed Description

Definition at line 87 of file creditvolcurve.hpp.

Member Typedef Documentation

◆ Smile

using Smile = std::pair<QuantLib::Real, QuantLib::ext::shared_ptr<QuantLib::Interpolation> >
private

Definition at line 108 of file creditvolcurve.hpp.

◆ Key

using Key = std::pair<QuantLib::Date, QuantLib::Period>
private

Definition at line 109 of file creditvolcurve.hpp.

Constructor & Destructor Documentation

◆ InterpolatingCreditVolCurve() [1/2]

InterpolatingCreditVolCurve ( const QuantLib::Natural  settlementDays,
const QuantLib::Calendar &  cal,
QuantLib::BusinessDayConvention  bdc,
const QuantLib::DayCounter &  dc,
const std::vector< QuantLib::Period > &  terms,
const std::vector< QuantLib::Handle< CreditCurve > > &  termCurves,
const std::map< std::tuple< QuantLib::Date, QuantLib::Period, QuantLib::Real >, QuantLib::Handle< QuantLib::Quote > > &  quotes,
const Type type 
)

◆ InterpolatingCreditVolCurve() [2/2]

InterpolatingCreditVolCurve ( const QuantLib::Date &  referenceDate,
const QuantLib::Calendar &  cal,
QuantLib::BusinessDayConvention  bdc,
const QuantLib::DayCounter &  dc,
const std::vector< QuantLib::Period > &  terms,
const std::vector< QuantLib::Handle< CreditCurve > > &  termCurves,
const std::map< std::tuple< QuantLib::Date, QuantLib::Period, QuantLib::Real >, QuantLib::Handle< QuantLib::Quote > > &  quotes,
const Type type 
)

Member Function Documentation

◆ volatility()

Real volatility ( const QuantLib::Date &  exerciseDate,
const QuantLib::Real  underlyingLength,
const QuantLib::Real  strike,
const Type targetType 
) const
overridevirtual

Implements CreditVolCurve.

Definition at line 284 of file creditvolcurve.cpp.

285 {
286
287 calculate();
288
289 QL_REQUIRE(targetType == type(), "InterpolatingCreditVolCurve: Vol type conversion between strike types 'Price' "
290 "and 'Spread' is not supported. The vol "
291 "surface used to price an option must have the same strike type as the option.");
292
293 Real effStrike = strike == Null<Real>() ? atmStrike(expiry, underlyingLength) : strike;
294
295 // term interpolation
296
297 Size termIndex_m, termIndex_p;
298 Real term_alpha;
299 std::tie(termIndex_m, termIndex_p, term_alpha) = interpolationIndices(smileTermLengths_, underlyingLength);
300
301 // expiry interpolation
302
303 Size expiryIndex_m, expiryIndex_p;
304 Real expiry_alpha;
305 Real t = timeFromReference(expiry);
306 std::tie(expiryIndex_m, expiryIndex_p, expiry_alpha) = interpolationIndices(smileExpiryTimes_, t);
307
308 // smiles by expiry / term
309
310 const Smile& smile_1_1 = smiles_[std::make_pair(smileExpiries_[expiryIndex_m], smileTerms_[termIndex_m])];
311 const Smile& smile_1_2 = smiles_[std::make_pair(smileExpiries_[expiryIndex_m], smileTerms_[termIndex_p])];
312 const Smile& smile_2_1 = smiles_[std::make_pair(smileExpiries_[expiryIndex_p], smileTerms_[termIndex_m])];
313 const Smile& smile_2_2 = smiles_[std::make_pair(smileExpiries_[expiryIndex_p], smileTerms_[termIndex_p])];
314
315 // atm levels by expiry / term
316
317 Real atm_1_1 = smile_1_1.first;
318 Real atm_1_2 = smile_1_2.first;
319 Real atm_2_1 = smile_2_1.first;
320 Real atm_2_2 = smile_2_2.first;
321
322 // vols at target moneyness
323
324 Real m = moneyness(effStrike, atmStrike(expiry, underlyingLength));
325 Real vol_1_1 = smile_1_1.second->operator()(this->strike(m, atm_1_1));
326 Real vol_1_2 = smile_1_2.second->operator()(this->strike(m, atm_1_2));
327 Real vol_2_1 = smile_2_1.second->operator()(this->strike(m, atm_2_1));
328 Real vol_2_2 = smile_2_2.second->operator()(this->strike(m, atm_2_2));
329
330 // interpolate in term direction
331
332 Real vol_1 = term_alpha * vol_1_1 + (1.0 - term_alpha) * vol_1_2;
333 Real vol_2 = term_alpha * vol_2_1 + (1.0 - term_alpha) * vol_2_2;
334
335 // interpolate in expiry direction
336
337 return std::sqrt((expiry_alpha * (vol_1 * vol_1 * smileExpiryTimes_[expiryIndex_m]) +
338 (1.0 - expiry_alpha) * (vol_2 * vol_2 * smileExpiryTimes_[expiryIndex_p])) /
339 t);
340}
QuantLib::Real moneyness(const QuantLib::Real strike, const QuantLib::Real atmStrike) const
QuantLib::Real atmStrike(const QuantLib::Date &expiry, const QuantLib::Period &term) const
QuantLib::Real strike(const QuantLib::Real moneyness, const QuantLib::Real atmStrike) const
const Type & type() const
std::vector< QuantLib::Date > smileExpiries_
std::pair< QuantLib::Real, QuantLib::ext::shared_ptr< QuantLib::Interpolation > > Smile
std::vector< QuantLib::Real > smileTermLengths_
std::vector< QuantLib::Real > smileExpiryTimes_
std::vector< QuantLib::Period > smileTerms_
std::tuple< Size, Size, Real > interpolationIndices(const T &x, const Real v)
+ Here is the call graph for this function:

◆ init()

void init ( )
private

Definition at line 279 of file creditvolcurve.cpp.

279 {
280 for (auto const& q : quotes_)
281 registerWith(q.second);
282}
std::map< std::tuple< QuantLib::Date, QuantLib::Period, QuantLib::Real >, QuantLib::Handle< QuantLib::Quote > > quotes_

◆ performCalculations()

void performCalculations ( ) const
overrideprivate

Definition at line 342 of file creditvolcurve.cpp.

342 {
343
345
346 QL_REQUIRE(!quotes_.empty(), "InterpolatingCreditVolCurve: no quotes given, can not build a volatility curve.");
347
348 // For each term and option expiry create an interpolation object representing a vol smile.
349
350 smileTerms_.clear();
351 smileExpiries_.clear();
352 smileTermLengths_.clear();
353 smileExpiryTimes_.clear();
354 strikes_.clear();
355 vols_.clear();
356 smiles_.clear();
357
358 Period currentTerm = 0 * Days;
359 Date currentExpiry = Null<Date>();
360 std::vector<Real> currentStrikes;
361 std::vector<Real> currentVols;
362 Date expiry;
363 Period term;
364 Real strike;
365 Real vol;
366
367 auto q = quotes_.begin();
368 for (Size i = 0; i <= quotes_.size(); ++i) {
369 if (i < quotes_.size()) {
370 expiry = std::get<0>(q->first);
371 term = std::get<1>(q->first);
372 strike = std::get<2>(q->first);
373 vol = q->second->value();
374 ++q;
375 } else {
376 currentTerm = term;
377 currentExpiry = expiry;
378 }
379 if (term != currentTerm || expiry != currentExpiry || i == quotes_.size()) {
380 if (!currentStrikes.empty()) {
381 if (currentStrikes.size() == 1) {
382 currentStrikes.push_back(currentStrikes.back() + 0.01);
383 currentVols.push_back(currentVols.back());
384 }
385 auto key = std::make_pair(currentExpiry, currentTerm);
386 auto s = strikes_.insert(std::make_pair(key, currentStrikes)).first;
387 auto v = vols_.insert(std::make_pair(key, currentVols)).first;
388 auto tmp = QuantLib::ext::make_shared<FlatExtrapolation>(
389 QuantLib::ext::make_shared<LinearInterpolation>(s->second.begin(), s->second.end(), v->second.begin()));
390 tmp->enableExtrapolation();
391 smiles_[key] = std::make_pair(atmStrike(currentExpiry, currentTerm), tmp);
392 currentStrikes.clear();
393 currentVols.clear();
394 smileTerms_.push_back(currentTerm);
395 smileExpiries_.push_back(currentExpiry);
396 }
397 currentTerm = term;
398 currentExpiry = expiry;
399 }
400 if (i < quotes_.size()) {
401 currentStrikes.push_back(strike);
402 currentVols.push_back(vol);
403 }
404 }
405
406 // populate times vectors
407
408 for (auto const& p : smileTerms_)
409 smileTermLengths_.push_back(periodToTime(p));
410 for (auto const& d : smileExpiries_)
411 smileExpiryTimes_.push_back(timeFromReference(d));
412
413 /* For each term, add missing option expiries that we saw for other terms by creating an interpolated smile.
414 We interpolate in terms of
415 - absolute moneyness (Type = Spread)
416 - log-moneyness (Type = Price)
417 */
418
419 for (auto const& term : smileTerms_) {
420 for (auto const& expiry : smileExpiries_) {
421 auto key = std::make_pair(expiry, term);
422 if (smiles_.find(key) == smiles_.end()) {
423
424 // search neighboured expiries for same term
425
426 Date expiry_m = Null<Date>();
427 Date expiry_p = Null<Date>();
428 for (auto const& s : smiles_) {
429 if (s.first.second != term)
430 continue;
431 if (s.first.first >= expiry) {
432 expiry_p = s.first.first;
433 break;
434 }
435 expiry_m = s.first.first;
436 }
437
438 // if we have a smile for the expiry and term already, there is nothing to do
439
440 if (expiry_m == expiry || expiry_p == expiry)
441 continue;
442
443 // otherwise build an interpolated / extrapoalted smile
444
445 if (expiry_m == Null<Date>() && expiry_p != Null<Date>()) {
446 // expiry <= smallest expiry for that term = expiry_p
447 createSmile(expiry, term, expiry_p, expiry_m);
448 } else if (expiry_m != Null<Date>() && expiry_p != Null<Date>()) {
449 // expiry_m < expiry < expiry_p
450 createSmile(expiry, term, expiry_m, expiry_p);
451 } else if (expiry_m != Null<Date>() && expiry_p == Null<Date>()) {
452 // expiry >= largest expiry for that term = expiry_m
453 createSmile(expiry, term, expiry_p, expiry_m);
454 } else {
455 QL_FAIL("InterpolatingCreditVolCurve: internal error, expiry_m = expiry_p = null, i.e. there are "
456 "no smiles for term "
457 << term);
458 }
459 }
460 }
461 }
462}
void performCalculations() const override
std::map< Key, std::vector< QuantLib::Real > > strikes_
std::map< Key, std::vector< QuantLib::Real > > vols_
void createSmile(const QuantLib::Date &expiry, const QuantLib::Period &term, const QuantLib::Date &expiry_m, const QuantLib::Date &expiry_p) const
Real periodToTime(const Period &p)
Definition: time.cpp:37
+ Here is the call graph for this function:

◆ createSmile()

void createSmile ( const QuantLib::Date &  expiry,
const QuantLib::Period &  term,
const QuantLib::Date &  expiry_m,
const QuantLib::Date &  expiry_p 
) const
private

Definition at line 470 of file creditvolcurve.cpp.

471 {
472 Real thisAtm = atmStrike(expiry, term);
473 if (expiry_p == Null<Date>()) {
474 auto key = std::make_pair(expiry_m, term);
475 const Smile& smile = smiles_[key];
476 std::vector<Real> strikes;
477 std::vector<Real> vols;
478 for (auto const& k : strikes_[key]) {
479 strikes.push_back(strike(moneyness(k, smile.first), thisAtm));
480 }
481 for (auto const& k : strikes)
482 vols.push_back(smile.second->operator()(k));
483 auto s = strikes_.insert(std::make_pair(key, strikes));
484 auto v = vols_.insert(std::make_pair(key, vols));
485 auto tmp = QuantLib::ext::make_shared<FlatExtrapolation>(QuantLib::ext::make_shared<LinearInterpolation>(
486 s.first->second.begin(), s.first->second.end(), v.first->second.begin()));
487 tmp->enableExtrapolation();
488 smiles_[std::make_pair(expiry, term)] = std::make_pair(thisAtm, tmp);
489 } else if (expiry_m == Null<Date>()) {
490 auto key = std::make_pair(expiry_p, term);
491 const Smile& smile = smiles_[key];
492 std::vector<Real> strikes;
493 std::vector<Real> vols;
494 for (auto const& k : strikes_[key]) {
495 strikes.push_back(strike(moneyness(k, smile.first), thisAtm));
496 }
497 for (auto const& k : strikes)
498 vols.push_back(smile.second->operator()(k));
499 auto s = strikes_.insert(std::make_pair(key, strikes));
500 auto v = vols_.insert(std::make_pair(key, vols));
501 auto tmp = QuantLib::ext::make_shared<FlatExtrapolation>(QuantLib::ext::make_shared<LinearInterpolation>(
502 s.first->second.begin(), s.first->second.end(), v.first->second.begin()));
503 tmp->enableExtrapolation();
504 smiles_[std::make_pair(expiry, term)] = std::make_pair(thisAtm, tmp);
505 } else {
506 auto key_m = std::make_pair(expiry_m, term);
507 auto key_p = std::make_pair(expiry_p, term);
508 const Smile& smile_m = smiles_[key_m];
509 const Smile& smile_p = smiles_[key_p];
510 std::set<Real, CompClose> strikes_set;
511 for (auto const& k : strikes_[key_m]) {
512 strikes_set.insert(strike(moneyness(k, smile_m.first), thisAtm));
513 }
514 for (auto const& k : strikes_[key_p]) {
515 strikes_set.insert(strike(moneyness(k, smile_p.first), thisAtm));
516 }
517 std::vector<Real> strikes(strikes_set.begin(), strikes_set.end());
518 std::vector<Real> vols;
519 Real t = timeFromReference(expiry);
520 Real t_m = timeFromReference(expiry_m);
521 Real t_p = timeFromReference(expiry_m);
522 Real alpha = (t_p - t) / (t_p - t_m);
523 for (auto const& k : strikes) {
524 Real vol_m = smile_m.second->operator()(k);
525 Real vol_p = smile_p.second->operator()(k);
526 vols.push_back(std::sqrt((alpha * (vol_m * vol_m * t_m) + (1.0 - alpha) * (vol_p * vol_p * t_p)) / t));
527 }
528 auto s = strikes_.insert(std::make_pair(std::make_pair(expiry, term), strikes));
529 auto v = vols_.insert(std::make_pair(std::make_pair(expiry, term), vols));
530 auto tmp = QuantLib::ext::make_shared<FlatExtrapolation>(QuantLib::ext::make_shared<LinearInterpolation>(
531 s.first->second.begin(), s.first->second.end(), v.first->second.begin()));
532 tmp->enableExtrapolation();
533 smiles_[std::make_pair(expiry, term)] = std::make_pair(thisAtm, tmp);
534 }
535}
vector< Real > strikes
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Data Documentation

◆ quotes_

std::map<std::tuple<QuantLib::Date, QuantLib::Period, QuantLib::Real>, QuantLib::Handle<QuantLib::Quote> > quotes_
private

Definition at line 116 of file creditvolcurve.hpp.

◆ smileTerms_

std::vector<QuantLib::Period> smileTerms_
mutableprivate

Definition at line 118 of file creditvolcurve.hpp.

◆ smileExpiries_

std::vector<QuantLib::Date> smileExpiries_
mutableprivate

Definition at line 119 of file creditvolcurve.hpp.

◆ smileTermLengths_

std::vector<QuantLib::Real> smileTermLengths_
mutableprivate

Definition at line 120 of file creditvolcurve.hpp.

◆ smileExpiryTimes_

std::vector<QuantLib::Real> smileExpiryTimes_
mutableprivate

Definition at line 121 of file creditvolcurve.hpp.

◆ strikes_

std::map<Key, std::vector<QuantLib::Real> > strikes_
mutableprivate

Definition at line 123 of file creditvolcurve.hpp.

◆ vols_

std::map<Key, std::vector<QuantLib::Real> > vols_
mutableprivate

Definition at line 124 of file creditvolcurve.hpp.

◆ smiles_

std::map<Key, Smile> smiles_
mutableprivate

Definition at line 125 of file creditvolcurve.hpp.