Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
List of all members
CDSVolCurve Class Reference

#include <ored/marketdata/cdsvolcurve.hpp>

+ Collaboration diagram for CDSVolCurve:

Public Member Functions

Constructors
 CDSVolCurve ()
 Default constructor. More...
 
 CDSVolCurve (QuantLib::Date asof, CDSVolatilityCurveSpec spec, const Loader &loader, const CurveConfigurations &curveConfigs, const std::map< std::string, QuantLib::ext::shared_ptr< CDSVolCurve > > &requiredCdsVolCurves={}, const std::map< std::string, QuantLib::ext::shared_ptr< DefaultCurve > > &requiredCdsCurves={})
 Detailed constructor. More...
 

Inspectors

CDSVolatilityCurveSpec spec_
 
QuantLib::ext::shared_ptr< QuantExt::CreditVolCurvevol_
 
QuantLib::Calendar calendar_
 
QuantLib::DayCounter dayCounter_
 
QuantExt::CreditVolCurve::Type strikeType_
 
const CDSVolatilityCurveSpecspec () const
 
const QuantLib::ext::shared_ptr< QuantExt::CreditVolCurve > & volTermStructure ()
 
void buildVolatility (const QuantLib::Date &asof, const CDSVolatilityCurveConfig &vc, const ConstantVolatilityConfig &cvc, const Loader &loader)
 Build a volatility structure from a single constant volatility quote. More...
 
void buildVolatility (const QuantLib::Date &asof, const CDSVolatilityCurveConfig &vc, const VolatilityCurveConfig &vcc, const Loader &loader)
 Build a volatility curve from a 1-D curve of volatility quotes. More...
 
void buildVolatility (const QuantLib::Date &asof, CDSVolatilityCurveConfig &vc, const VolatilityStrikeSurfaceConfig &vssc, const Loader &loader, const std::map< std::string, QuantLib::ext::shared_ptr< DefaultCurve > > &requiredCdsCurves)
 Build a volatility surface from a collection of expiry and absolute strike pairs. More...
 
void buildVolatility (const Date &asof, const CDSVolatilityCurveSpec &spec, const CDSVolatilityCurveConfig &vc, const CDSProxyVolatilityConfig &pvc, const std::map< std::string, QuantLib::ext::shared_ptr< CDSVolCurve > > &requiredCdsVolCurves, const std::map< std::string, QuantLib::ext::shared_ptr< DefaultCurve > > &requiredCdsCurves)
 
void buildVolatilityExplicit (const QuantLib::Date &asof, CDSVolatilityCurveConfig &vc, const VolatilityStrikeSurfaceConfig &vssc, const Loader &loader, const std::vector< QuantLib::Real > &configuredStrikes, const std::map< std::string, QuantLib::ext::shared_ptr< DefaultCurve > > &requiredCdsCurves)
 
QuantLib::Date getExpiry (const QuantLib::Date &asof, const QuantLib::ext::shared_ptr< Expiry > &expiry) const
 Get an explicit expiry date from a CDS option quote's Expiry. More...
 

Detailed Description

Class for building CDS option volatility structures

Definition at line 38 of file cdsvolcurve.hpp.

Constructor & Destructor Documentation

◆ CDSVolCurve() [1/2]

Default constructor.

Definition at line 43 of file cdsvolcurve.hpp.

43{}

◆ CDSVolCurve() [2/2]

CDSVolCurve ( QuantLib::Date  asof,
CDSVolatilityCurveSpec  spec,
const Loader loader,
const CurveConfigurations curveConfigs,
const std::map< std::string, QuantLib::ext::shared_ptr< CDSVolCurve > > &  requiredCdsVolCurves = {},
const std::map< std::string, QuantLib::ext::shared_ptr< DefaultCurve > > &  requiredCdsCurves = {} 
)

Detailed constructor.

Member Function Documentation

◆ spec()

const CDSVolatilityCurveSpec & spec ( ) const

Definition at line 54 of file cdsvolcurve.hpp.

54{ return spec_; }
CDSVolatilityCurveSpec spec_
Definition: cdsvolcurve.hpp:59
+ Here is the caller graph for this function:

◆ volTermStructure()

const QuantLib::ext::shared_ptr< QuantExt::CreditVolCurve > & volTermStructure ( )

Definition at line 55 of file cdsvolcurve.hpp.

55{ return vol_; }
QuantLib::ext::shared_ptr< QuantExt::CreditVolCurve > vol_
Definition: cdsvolcurve.hpp:60

◆ buildVolatility() [1/4]

void buildVolatility ( const QuantLib::Date &  asof,
const CDSVolatilityCurveConfig vc,
const ConstantVolatilityConfig cvc,
const Loader loader 
)
private

Build a volatility structure from a single constant volatility quote.

◆ buildVolatility() [2/4]

void buildVolatility ( const QuantLib::Date &  asof,
const CDSVolatilityCurveConfig vc,
const VolatilityCurveConfig vcc,
const Loader loader 
)
private

Build a volatility curve from a 1-D curve of volatility quotes.

Definition at line 116 of file cdsvolcurve.cpp.

117 {
118
119 LOG("CDSVolCurve: start building 1-D volatility curve");
120
121 // Must have at least one quote
122 QL_REQUIRE(vcc.quotes().size() > 0, "No quotes specified in config " << vc.curveID());
123
124 // Check if we are using a regular expression to select the quotes for the curve. If we are, the quotes should
125 // contain exactly one element.
126 auto wildcard = getUniqueWildcard(vcc.quotes());
127
128 // curveData will be populated with the expiry dates and volatility values.
129 std::map<std::tuple<QuantLib::Date, QuantLib::Period, QuantLib::Real>, QuantLib::Handle<QuantLib::Quote>> quotes;
130
131 // Different approaches depending on whether we are using a regex or searching for a list of explicit quotes.
132 if (wildcard) {
133
134 DLOG("Have single quote with pattern " << wildcard->pattern());
135
136 // Loop over quotes and process CDS option quotes matching pattern on asof
137 for (const auto& md : loader.get(*wildcard, asof)) {
138
139 QL_REQUIRE(md->asofDate() == asof, "MarketDatum asofDate '" << md->asofDate() << "' <> asof '" << asof << "'");
140
141 auto q = QuantLib::ext::dynamic_pointer_cast<IndexCDSOptionQuote>(md);
142 QL_REQUIRE(q, "Internal error: could not downcast MarketDatum '" << md->name() << "' to IndexCDSOptionQuote");
143
144 TLOG("The quote " << q->name() << " matched the pattern");
145
146 /* - We load quotes with empty term only if there is at most one term specified in the curve config.
147 - We load quotes with a term, if they match a term specified in the curve config or if no term is
148 specified in the curve config.
149 - Quotes with an empty term get the unique term of the curve config assigned, if the curve config
150 has no terms specified, 5 * Years. */
151 QuantLib::Period quoteTerm;
152 if (q->indexTerm().empty()) {
153 if (vc.terms().size() > 1)
154 continue;
155 quoteTerm = vc.terms().empty() ? 5 * Years : vc.terms().front();
156 } else {
157 quoteTerm = parsePeriod(q->indexTerm());
158 if (std::find(vc.terms().begin(), vc.terms().end(), quoteTerm) == vc.terms().end() &&
159 !vc.terms().empty())
160 continue;
161 }
162
163 Date expiryDate = getExpiry(asof, q->expiry());
164 if (expiryDate > asof) {
165 quotes[std::make_tuple(expiryDate, quoteTerm,
166 strikeType_ == CreditVolCurve::Type::Price ? 1.0 : 0.0)] = q->quote();
167 TLOG("Added quote " << q->name() << ": (" << io::iso_date(expiryDate) << "," << fixed
168 << setprecision(9) << q->quote()->value() << ")");
169 }
170 }
171
172 // Check that we have quotes in the end
173 QL_REQUIRE(quotes.size() > 0, "No quotes found matching regular expression " << vcc.quotes()[0]);
174
175 } else {
176
177 DLOG("Have " << vcc.quotes().size() << " explicit quotes");
178
179 // Loop over quotes and process CDS option quotes that are explicitly specified in the config
180 std::ostringstream ss;
182 Wildcard w(ss.str());
183 for (const auto& md : loader.get(w, asof)) {
184
185 QL_REQUIRE(md->asofDate() == asof, "MarketDatum asofDate '" << md->asofDate() << "' <> asof '" << asof << "'");
186
187 auto q = QuantLib::ext::dynamic_pointer_cast<IndexCDSOptionQuote>(md);
188 QL_REQUIRE(q, "Internal error: could not downcast MarketDatum '" << md->name() << "' to IndexCDSOptionQuote");
189
190 // Find quote name in configured quotes.
191 auto it = find(vcc.quotes().begin(), vcc.quotes().end(), q->name());
192 if (it != vcc.quotes().end()) {
193 TLOG("Found the configured quote " << q->name());
194
195 Date expiryDate = getExpiry(asof, q->expiry());
196 QL_REQUIRE(expiryDate > asof, "CDS volatility quote '" << q->name() << "' has expiry in the past ("
197 << io::iso_date(expiryDate) << ")");
198 // we load all quotes, just populate the term of empty quotes
199 QuantLib::Period quoteTerm;
200 if (q->indexTerm().empty()) {
201 quoteTerm = vc.terms().size() == 1 ? vc.terms().front() : 5 * Years;
202 } else {
203 quoteTerm = parsePeriod(q->indexTerm());
204 }
205 quotes[std::make_tuple(expiryDate, quoteTerm,
206 strikeType_ == CreditVolCurve::Type::Price ? 1.0 : 0.0)] = q->quote();
207 TLOG("Added quote " << q->name() << ": (" << io::iso_date(expiryDate) << "," << fixed
208 << setprecision(9) << q->quote()->value() << ")");
209 }
210 }
211
212 // Check that we have found all of the explicitly configured quotes
213 QL_REQUIRE(quotes.size() == vcc.quotes().size(), "Found " << quotes.size() << " quotes, but "
214 << vcc.quotes().size()
215 << " quotes were given in config.");
216 }
217
218 DLOG("Creating InterpolatingCreditVolCurve object.");
219 vol_ = QuantLib::ext::make_shared<QuantExt::InterpolatingCreditVolCurve>(
220 asof, calendar_, Following, dayCounter_, std::vector<QuantLib::Period>{},
221 std::vector<Handle<QuantExt::CreditCurve>>{}, quotes, strikeType_);
222
223 LOG("CDSVolCurve: finished building 1-D volatility curve");
224}
QuantLib::Date getExpiry(const QuantLib::Date &asof, const QuantLib::ext::shared_ptr< Expiry > &expiry) const
Get an explicit expiry date from a CDS option quote's Expiry.
QuantExt::CreditVolCurve::Type strikeType_
Definition: cdsvolcurve.hpp:63
QuantLib::Calendar calendar_
Definition: cdsvolcurve.hpp:61
QuantLib::DayCounter dayCounter_
Definition: cdsvolcurve.hpp:62
Period parsePeriod(const string &s)
Convert text to QuantLib::Period.
Definition: parsers.cpp:171
#define LOG(text)
Logging Macro (Level = Notice)
Definition: log.hpp:552
#define DLOG(text)
Logging Macro (Level = Debug)
Definition: log.hpp:554
#define TLOG(text)
Logging Macro (Level = Data)
Definition: log.hpp:556
boost::optional< Wildcard > getUniqueWildcard(const C &c)
checks if at most one element in C has a wild card and returns it in this case
Definition: wildcard.hpp:65
+ Here is the call graph for this function:

◆ buildVolatility() [3/4]

void buildVolatility ( const QuantLib::Date &  asof,
CDSVolatilityCurveConfig vc,
const VolatilityStrikeSurfaceConfig vssc,
const Loader loader,
const std::map< std::string, QuantLib::ext::shared_ptr< DefaultCurve > > &  requiredCdsCurves 
)
private

Build a volatility surface from a collection of expiry and absolute strike pairs.

◆ buildVolatility() [4/4]

void buildVolatility ( const Date &  asof,
const CDSVolatilityCurveSpec spec,
const CDSVolatilityCurveConfig vc,
const CDSProxyVolatilityConfig pvc,
const std::map< std::string, QuantLib::ext::shared_ptr< CDSVolCurve > > &  requiredCdsVolCurves,
const std::map< std::string, QuantLib::ext::shared_ptr< DefaultCurve > > &  requiredCdsCurves 
)
private

Definition at line 372 of file cdsvolcurve.cpp.

375 {
376 LOG("CDSVolCurve: start building proxy volatility surface");
377 auto proxyVolCurve = requiredCdsVolCurves.find(CDSVolatilityCurveSpec(pvc.cdsVolatilityCurve()).name());
378 QL_REQUIRE(proxyVolCurve != requiredCdsVolCurves.end(), "CDSVolCurve: Failed to find cds vol curve '"
379 << pvc.cdsVolatilityCurve() << "' when building '"
380 << spec.name() << "'");
381 std::vector<QuantLib::Period> effTerms;
382 std::vector<QuantLib::Handle<CreditCurve>> termCurves;
383 for (Size i = 0; i < vc.termCurves().size(); ++i) {
384 if (vc.termCurves()[i].empty())
385 continue;
386 auto t = requiredCdsCurves.find(vc.termCurves()[i]);
387 QL_REQUIRE(t != requiredCdsCurves.end(), "CDSVolCurve: required cds curve '"
388 << vc.termCurves()[i]
389 << "' was not found during vol curve building.");
390 termCurves.push_back(Handle<QuantExt::CreditCurve>(t->second->creditCurve()));
391 effTerms.push_back(vc.terms()[i]);
392 }
393 LOG("Will use " << termCurves.size()
394 << " term curves in target surface to determine atm levels and moneyness-adjustments");
395 vol_ = QuantLib::ext::make_shared<QuantExt::ProxyCreditVolCurve>(
396 Handle<CreditVolCurve>(proxyVolCurve->second->volTermStructure()), effTerms, termCurves);
397 LOG("CDSVolCurve: finished building proxy volatility surface");
398}
const CDSVolatilityCurveSpec & spec() const
Definition: cdsvolcurve.hpp:54
string name() const
returns the unique curve name
Definition: curvespec.hpp:78
Size size(const ValueType &v)
Definition: value.cpp:145
+ Here is the call graph for this function:

◆ buildVolatilityExplicit()

void buildVolatilityExplicit ( const QuantLib::Date &  asof,
CDSVolatilityCurveConfig vc,
const VolatilityStrikeSurfaceConfig vssc,
const Loader loader,
const std::vector< QuantLib::Real > &  configuredStrikes,
const std::map< std::string, QuantLib::ext::shared_ptr< DefaultCurve > > &  requiredCdsCurves 
)
private

Build a volatility surface from a collection of expiry and absolute strike pairs where the strikes and expiries are both explicitly configured i.e. where wild cards are not used for either the strikes or the expiries.

Definition at line 400 of file cdsvolcurve.cpp.

403 {
404
405 LOG("CDSVolCurve: start building 2-D volatility absolute strike surface with explicit strikes and expiries");
406
407 // Store quotes by expiry, term, strike in a map
408 std::map<std::tuple<QuantLib::Date, QuantLib::Period, QuantLib::Real>, QuantLib::Handle<QuantLib::Quote>> quotes;
409
410 // Count the number of quotes added. We check at the end that we have added all configured quotes.
411 Size quotesAdded = 0;
412
413 // Loop over quotes and process CDS option quotes that have been requested
414 std::ostringstream ss;
416 Wildcard w(ss.str());
417 for (const auto& md : loader.get(w, asof)) {
418
419 QL_REQUIRE(md->asofDate() == asof, "MarketDatum asofDate '" << md->asofDate() << "' <> asof '" << asof << "'");
420
421 // Go to next quote if not a CDS option quote.
422 auto q = QuantLib::ext::dynamic_pointer_cast<IndexCDSOptionQuote>(md);
423 QL_REQUIRE(q, "Internal error: could not downcast MarketDatum '" << md->name() << "' to IndexCDSOptionQuote");
424
425 // This surface is for absolute strikes only.
426 auto strike = QuantLib::ext::dynamic_pointer_cast<AbsoluteStrike>(q->strike());
427 if (!strike)
428 continue;
429
430 QuantLib::Period quoteTerm;
431 if (q->indexTerm().empty()) {
432 if (vc.terms().size() > 1)
433 continue;
434 quoteTerm = vc.terms().empty() ? 5 * Years : vc.terms().front();
435 } else {
436 quoteTerm = parsePeriod(q->indexTerm());
437 if (std::find(vc.terms().begin(), vc.terms().end(), quoteTerm) == vc.terms().end() && !vc.terms().empty())
438 continue;
439 }
440
441 // Add quote to surface
442 quotes[std::make_tuple(getExpiry(asof, q->expiry()), quoteTerm, strike->strike() / vc.strikeFactor())] =
443 q->quote();
444 quotesAdded++;
445
446 TLOG("Added quote " << q->name() << ": (" << q->expiry() << "," << fixed << setprecision(9) << strike->strike()
447 << "," << q->quote()->value() << ")")
448 }
449
450 LOG("CDSVolCurve: added " << quotesAdded << " quotes in building explicit absolute strike surface.");
451
452 QL_REQUIRE(vc.quotes().size() == quotesAdded,
453 "Found " << quotesAdded << " quotes, but " << vc.quotes().size() << " quotes required by config.");
454
455 DLOG("Creating the CreditVolCurve object");
456
457 std::vector<QuantLib::Period> effTerms;
458 std::vector<QuantLib::Handle<CreditCurve>> termCurves;
459 for (Size i = 0; i < vc.termCurves().size(); ++i) {
460 if (vc.termCurves()[i].empty())
461 continue;
462 auto t = requiredCdsCurves.find(vc.termCurves()[i]);
463 QL_REQUIRE(t != requiredCdsCurves.end(), "CDSVolCurve: required cds curve '"
464 << vc.termCurves()[i]
465 << "' was not found during vol curve building.");
466 termCurves.push_back(Handle<QuantExt::CreditCurve>(t->second->creditCurve()));
467 effTerms.push_back(vc.terms()[i]);
468 }
469
470 vol_ = QuantLib::ext::make_shared<QuantExt::InterpolatingCreditVolCurve>(asof, calendar_, Following, dayCounter_, effTerms,
471 termCurves, quotes, strikeType_);
472 vol_->enableExtrapolation();
473
474 LOG("CDSVolCurve: finished building 2-D volatility absolute strike "
475 << "surface with explicit strikes and expiries");
476}
+ Here is the call graph for this function:

◆ getExpiry()

Date getExpiry ( const QuantLib::Date &  asof,
const QuantLib::ext::shared_ptr< Expiry > &  expiry 
) const
private

Get an explicit expiry date from a CDS option quote's Expiry.

Definition at line 478 of file cdsvolcurve.cpp.

478 {
479
480 Date result;
481
482 if (auto expiryDate = QuantLib::ext::dynamic_pointer_cast<ExpiryDate>(expiry)) {
483 result = expiryDate->expiryDate();
484 } else if (auto expiryPeriod = QuantLib::ext::dynamic_pointer_cast<ExpiryPeriod>(expiry)) {
485 // We may need more conventions here eventually.
486 result = calendar_.adjust(asof + expiryPeriod->expiryPeriod());
487 } else if (auto fcExpiry = QuantLib::ext::dynamic_pointer_cast<FutureContinuationExpiry>(expiry)) {
488 QL_FAIL("CDSVolCurve::getExpiry: future continuation expiry not supported for CDS volatility quotes.");
489 } else {
490 QL_FAIL("CDSVolCurve::getExpiry: cannot determine expiry type.");
491 }
492
493 return result;
494}
+ Here is the caller graph for this function:

Member Data Documentation

◆ spec_

CDSVolatilityCurveSpec spec_
private

Definition at line 59 of file cdsvolcurve.hpp.

◆ vol_

QuantLib::ext::shared_ptr<QuantExt::CreditVolCurve> vol_
private

Definition at line 60 of file cdsvolcurve.hpp.

◆ calendar_

QuantLib::Calendar calendar_
private

Definition at line 61 of file cdsvolcurve.hpp.

◆ dayCounter_

QuantLib::DayCounter dayCounter_
private

Definition at line 62 of file cdsvolcurve.hpp.

◆ strikeType_

QuantExt::CreditVolCurve::Type strikeType_
private

Definition at line 63 of file cdsvolcurve.hpp.