Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
todaysmarket.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2016 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
19/*! \file ored/marketdata/todaysmarket.cpp
20 \brief An concrete implementation of the Market class that loads todays market and builds the required curves
21 \ingroup
22*/
23
55
56#include <ql/tuple.hpp>
57
58#include <boost/graph/topological_sort.hpp>
59#include <boost/range/adaptor/map.hpp>
60#include <boost/range/adaptor/reversed.hpp>
61#include <boost/timer/timer.hpp>
62
63using namespace std;
64using namespace QuantLib;
65
72
73namespace ore {
74namespace data {
75
76TodaysMarket::TodaysMarket(const Date& asof, const QuantLib::ext::shared_ptr<TodaysMarketParameters>& params,
77 const QuantLib::ext::shared_ptr<Loader>& loader,
78 const QuantLib::ext::shared_ptr<CurveConfigurations>& curveConfigs, const bool continueOnError,
79 const bool loadFixings, const bool lazyBuild,
80 const QuantLib::ext::shared_ptr<ReferenceDataManager>& referenceData,
81 const bool preserveQuoteLinkage, const IborFallbackConfig& iborFallbackConfig,
82 const bool buildCalibrationInfo, const bool handlePseudoCurrencies)
83 : MarketImpl(handlePseudoCurrencies), params_(params), loader_(loader), curveConfigs_(curveConfigs),
84 continueOnError_(continueOnError), loadFixings_(loadFixings), lazyBuild_(lazyBuild),
85 preserveQuoteLinkage_(preserveQuoteLinkage), referenceData_(referenceData),
86 iborFallbackConfig_(iborFallbackConfig), buildCalibrationInfo_(buildCalibrationInfo) {
87 QL_REQUIRE(params_, "TodaysMarket: TodaysMarketParameters are null");
88 QL_REQUIRE(loader_, "TodaysMarket: Loader is null");
89 QL_REQUIRE(curveConfigs_, "TodaysMarket: CurveConfigurations are null");
90 initialise(asof);
91}
92
93namespace {
94struct Count {
95 void inc() { ++count; }
96 std::size_t count = 0;
97};
98} // namespace
99
100void TodaysMarket::initialise(const Date& asof) {
101
102 std::map<std::string, boost::timer::nanosecond_type> timings;
103 std::map<std::string, Count> counts;
104 boost::timer::cpu_timer timer;
105
106 asof_ = asof;
107
108 calibrationInfo_ = QuantLib::ext::make_shared<TodaysMarketCalibrationInfo>();
109 calibrationInfo_->asof = asof;
110
111 // Fixings
112
113 if (loadFixings_) {
114 // Apply them now in case a curve builder needs them
115 LOG("Todays Market Loading Fixings");
116 timer.start();
117 applyFixings(loader_->loadFixings());
118 timings["1 load fixings"] = timer.elapsed().wall;
119 LOG("Todays Market Loading Fixing done.");
120 }
121
122 // Dividends - apply them now in case a curve builder needs them
123
124 LOG("Todays Market Loading Dividends");
125 timer.start();
126 applyDividends(loader_->loadDividends());
127 timings["2 load dividends"] = timer.elapsed().wall;
128 LOG("Todays Market Loading Dividends done.");
129
130 // Add all FX quotes from the loader to Triangulation
131 timer.start();
132 if (loader_->hasQuotes(asof_)) {
133 std::map<std::string, Handle<Quote>> fxQuotes;
134 for (auto& md : loader_->get(Wildcard("FX/RATE/*"), asof_)) {
135 QuantLib::ext::shared_ptr<FXSpotQuote> q = QuantLib::ext::dynamic_pointer_cast<FXSpotQuote>(md);
136 QL_REQUIRE(q, "Failed to cast " << md->name() << " to FXSpotQuote");
137 fxQuotes[q->unitCcy() + q->ccy()] = q->quote();
138 }
139 fx_ = QuantLib::ext::make_shared<FXTriangulation>(fxQuotes);
140 } else {
141 WLOG("TodaysMarket::Initialise: no quotes available for date " << asof_);
142 return;
143 }
144 timings["3 add all fx quotes"] = timer.elapsed().wall;
145
146 // build the dependency graph for all configurations and build all FX Spots
147 timer.start();
149 map<string, string> buildErrors;
150
151 for (const auto& configuration : params_->configurations()) {
152 // Build the graph of objects to build for the current configuration
153 dg.buildDependencyGraph(configuration.first, buildErrors);
154 }
156 timings["4 build dep graphs"] = timer.elapsed().wall;
157
158 // if market is not build lazily, sort the dependency graph and build the objects
159
160 if (!lazyBuild_) {
161
162 // We need to build all discount curves first, since some curve builds ask for discount
163 // curves from specific configurations
164 timer.start();
165 for (const auto& configuration : params_->configurations()) {
166 map<string, string> discountCurves;
167 if (params_->hasMarketObject(MarketObject::DiscountCurve)) {
168 discountCurves = params_->mapping(MarketObject::DiscountCurve, configuration.first);
169 }
170 for (const auto& dc : discountCurves)
171 require(MarketObject::DiscountCurve, dc.first, configuration.first, true);
172 }
173 timings["6 build " + ore::data::to_string(MarketObject::DiscountCurve)] += timer.elapsed().wall;
174 counts["6 build " + ore::data::to_string(MarketObject::DiscountCurve)].inc();
175
176 for (const auto& configuration : params_->configurations()) {
177
178 LOG("Build objects in TodaysMarket configuration " << configuration.first);
179
180 // Sort the graph topologically
181
182 timer.start();
183 Graph& g = dependencies_[configuration.first];
184 IndexMap index = QuantLib::ext::get(boost::vertex_index, g);
185 std::vector<Vertex> order;
186 try {
187 boost::topological_sort(g, std::back_inserter(order));
188 } catch (const std::exception& e) {
189 // topological_sort() might have produced partial results, that we have to discard
190 order.clear();
191 // set error (most likely a circle), and output cycles if any
192 buildErrors["CurveDependencyGraph"] = "Topological sort of dependency graph failed for configuration " +
193 configuration.first + " (" + ore::data::to_string(e.what()) +
194 "). Got cycle(s): " + getCycles(g);
195 }
196 timings["5 topological sort dep graphs"] += timer.elapsed().wall;
197
198 TLOG("Can build objects in the following order:");
199 for (auto const& m : order) {
200 TLOG("vertex #" << index[m] << ": " << g[m]);
201 }
202
203 // Build the objects in the graph in topological order
204
205 Size countSuccess = 0, countError = 0;
206 for (auto const& m : order) {
207 timer.start();
208 try {
209 buildNode(configuration.first, g[m]);
210 ++countSuccess;
211 DLOG("built node " << g[m] << " in configuration " << configuration.first);
212 } catch (const std::exception& e) {
213 if (g[m].curveSpec)
214 buildErrors[g[m].curveSpec->name()] = e.what();
215 else
216 buildErrors[g[m].name] = e.what();
217 ++countError;
218 ALOG("error while building node " << g[m] << " in configuration " << configuration.first << ": "
219 << e.what());
220 }
221 timings["6 build " + ore::data::to_string(g[m].obj)] += timer.elapsed().wall;
222 counts["6 build " + ore::data::to_string(g[m].obj)].inc();
223 }
224
225 LOG("Loaded CurvesSpecs: success: " << countSuccess << ", error: " << countError);
226 }
227
228 } else {
229 LOG("Build objects in TodaysMarket lazily, i.e. when requested.");
230 }
231
232 // output stats on initialisation phase
233
234 LOG("TodaysMarket build stats:");
235 boost::timer::nanosecond_type sum = 0;
236 for (auto const& t : timings) {
237 std::size_t c = counts[t.first].count == 0 ? 1 : counts[t.first].count;
238 double timing = static_cast<double>(t.second) / 1.0E6;
239 LOG(std::left << std::setw(34) << t.first << ": " << std::right << std::setprecision(3) << std::setw(15)
240 << timing << " ms" << std::setw(10) << c << std::setw(15) << timing / c << " ms");
241 sum += t.second;
242 }
243 LOG("Total build time : " << std::setw(15) << static_cast<double>(sum) / 1.0E6 << " ms");
244
245 // output errors from initialisation phase
246
247 if (!buildErrors.empty()) {
248 for (auto const& error : buildErrors) {
249 StructuredCurveErrorMessage(error.first, "Failed to Build Curve", error.second).log();
250 }
251 if (!continueOnError_) {
252 string errStr;
253 for (auto const& error : buildErrors) {
254 errStr += "(" + error.first + ": " + error.second + "); ";
255 }
256 QL_FAIL("Cannot build all required curves! Building failed for: " << errStr);
257 }
258 }
259
260} // TodaysMarket::initialise()
261
262void TodaysMarket::buildNode(const std::string& configuration, Node& node) const {
263
264 // if the node is already built, there is nothing to do
265
266 if (node.built)
267 return;
268
269 if (node.curveSpec == nullptr) {
270
271 // not spec-based node, this can only be a SwapIndexCurve
272
273 QL_REQUIRE(node.obj == MarketObject::SwapIndexCurve,
274 "market object '" << node.obj << "' (" << node.name << ") without curve spec, this is unexpected.");
275 const string& swapIndexName = node.name;
276 const string& discountIndex = node.mapping;
277 addSwapIndex(swapIndexName, discountIndex, configuration);
278 DLOG("Added SwapIndex " << swapIndexName << " with DiscountingIndex " << discountIndex);
279 requiredSwapIndices_[configuration][swapIndexName] =
280 swapIndices_.at(std::make_pair(configuration, swapIndexName)).currentLink();
281
282 } else {
283
284 // spec-based node
285
286 auto spec = node.curveSpec;
287 switch (spec->baseType()) {
288
289 // Yield
291 QuantLib::ext::shared_ptr<YieldCurveSpec> ycspec = QuantLib::ext::dynamic_pointer_cast<YieldCurveSpec>(spec);
292 QL_REQUIRE(ycspec, "Failed to convert spec " << *spec << " to yield curve spec");
293
294 QuantLib::ext::shared_ptr<Conventions> conventions = InstrumentConventions::instance().conventions();
295
296 auto itr = requiredYieldCurves_.find(ycspec->name());
297 if (itr == requiredYieldCurves_.end()) {
298 DLOG("Building YieldCurve for asof " << asof_);
299 QuantLib::ext::shared_ptr<YieldCurve> yieldCurve = QuantLib::ext::make_shared<YieldCurve>(
302 calibrationInfo_->yieldCurveCalibrationInfo[ycspec->name()] = yieldCurve->calibrationInfo();
303 itr = requiredYieldCurves_.insert(make_pair(ycspec->name(), yieldCurve)).first;
304 DLOG("Added YieldCurve \"" << ycspec->name() << "\" to requiredYieldCurves map");
305 if (itr->second->currency().code() != ycspec->ccy()) {
306 WLOG("Warning: YieldCurve has ccy " << itr->second->currency() << " but spec has ccy "
307 << ycspec->ccy());
308 }
309 }
310
311 if (node.obj == MarketObject::DiscountCurve) {
312 DLOG("Adding DiscountCurve(" << node.name << ") with spec " << *ycspec << " to configuration "
313 << configuration);
314 yieldCurves_[make_tuple(configuration, YieldCurveType::Discount, node.name)] = itr->second->handle();
315
316 } else if (node.obj == MarketObject::YieldCurve) {
317 DLOG("Adding YieldCurve(" << node.name << ") with spec " << *ycspec << " to configuration "
318 << configuration);
319 yieldCurves_[make_tuple(configuration, YieldCurveType::Yield, node.name)] = itr->second->handle();
320
321 } else if (node.obj == MarketObject::IndexCurve) {
322 DLOG("Adding Index(" << node.name << ") with spec " << *ycspec << " to configuration "
323 << configuration);
324 // ibor fallback handling
325 auto tmpIndex = parseIborIndex(node.name, itr->second->handle());
327 auto fallbackData = iborFallbackConfig_.fallbackData(node.name);
328 QuantLib::ext::shared_ptr<IborIndex> rfrIndex;
329 auto f = iborIndices_.find(make_pair(configuration, fallbackData.rfrIndex));
330 if (f == iborIndices_.end()) {
331 f = iborIndices_.find(make_pair(Market::defaultConfiguration, fallbackData.rfrIndex));
332 QL_REQUIRE(f != iborIndices_.end(),
333 "Failed to build ibor fallback index '"
334 << node.name << "', did not find rfr index '" << fallbackData.rfrIndex
335 << "' in configuration '" << configuration
336 << "' or default - is the rfr index configuration in todays market parameters?");
337 }
338 auto oi = QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(*f->second);
339 QL_REQUIRE(oi,
340 "Found rfr index '"
341 << fallbackData.rfrIndex << "' as fallback for ibor index '" << node.name
342 << "', but this is not an overnight index. Are the fallback rules correct here?");
343 if (auto original = QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(tmpIndex))
344 tmpIndex = QuantLib::ext::make_shared<QuantExt::FallbackOvernightIndex>(
345 original, oi, fallbackData.spread, fallbackData.switchDate,
347 else
348 tmpIndex = QuantLib::ext::make_shared<QuantExt::FallbackIborIndex>(
349 tmpIndex, oi, fallbackData.spread, fallbackData.switchDate,
351 TLOG("built ibor fall back index for '" << node.name << "' in configuration " << configuration
352 << " using rfr index '" << fallbackData.rfrIndex
353 << "', spread " << fallbackData.spread
354 << ", will use rfr curve in t0 market: " << std::boolalpha
356 }
357 iborIndices_[make_pair(configuration, node.name)] = Handle<IborIndex>(tmpIndex);
358 } else {
359 QL_FAIL("unexpected market object type '"
360 << node.obj << "' for yield curve, should be DiscountCurve, YieldCurve, IndexCurve");
361 }
362 break;
363 }
364
365 // FX Spot
367 DLOG("Building FXSpot (" << node.name << ") does not require any action.");
368 break;
369 }
370
371 // FX Vol
373 QuantLib::ext::shared_ptr<FXVolatilityCurveSpec> fxvolspec =
374 QuantLib::ext::dynamic_pointer_cast<FXVolatilityCurveSpec>(spec);
375 QL_REQUIRE(fxvolspec, "Failed to convert spec " << *spec);
376
377 // have we built the curve already ?
378 auto itr = requiredFxVolCurves_.find(fxvolspec->name());
379 if (itr == requiredFxVolCurves_.end()) {
380 DLOG("Building FXVolatility for asof " << asof_);
381 QuantLib::ext::shared_ptr<FXVolCurve> fxVolCurve = QuantLib::ext::make_shared<FXVolCurve>(
384 calibrationInfo_->fxVolCalibrationInfo[fxvolspec->name()] = fxVolCurve->calibrationInfo();
385 itr = requiredFxVolCurves_.insert(make_pair(fxvolspec->name(), fxVolCurve)).first;
386 }
387
388 DLOG("Adding FXVol (" << node.name << ") with spec " << *fxvolspec << " to configuration "
389 << configuration);
390 fxVols_[make_pair(configuration, node.name)] =
391 Handle<BlackVolTermStructure>(itr->second->volTermStructure());
392 break;
393 }
394
395 // Swaption Vol
397 QuantLib::ext::shared_ptr<SwaptionVolatilityCurveSpec> swvolspec =
398 QuantLib::ext::dynamic_pointer_cast<SwaptionVolatilityCurveSpec>(spec);
399 QL_REQUIRE(swvolspec, "Failed to convert spec " << *spec);
400
401 auto itr = requiredGenericYieldVolCurves_.find(swvolspec->name());
402 if (itr == requiredGenericYieldVolCurves_.end()) {
403 DLOG("Building Swaption Volatility (" << node.name << ") for asof " << asof_);
404 QuantLib::ext::shared_ptr<SwaptionVolCurve> swaptionVolCurve = QuantLib::ext::make_shared<SwaptionVolCurve>(
405 asof_, *swvolspec, *loader_, *curveConfigs_, requiredSwapIndices_[configuration],
407 calibrationInfo_->irVolCalibrationInfo[swvolspec->name()] = swaptionVolCurve->calibrationInfo();
408 itr = requiredGenericYieldVolCurves_.insert(make_pair(swvolspec->name(), swaptionVolCurve)).first;
409 }
410
411 QuantLib::ext::shared_ptr<SwaptionVolatilityCurveConfig> cfg =
412 curveConfigs_->swaptionVolCurveConfig(swvolspec->curveConfigID());
413
414 DLOG("Adding SwaptionVol (" << node.name << ") with spec " << *swvolspec << " to configuration "
415 << configuration);
416 swaptionCurves_[make_pair(configuration, node.name)] =
417 Handle<SwaptionVolatilityStructure>(itr->second->volTermStructure());
418 swaptionIndexBases_[make_pair(configuration, node.name)] =
419 cfg->proxySourceCurveId().empty()
420 ? make_pair(cfg->shortSwapIndexBase(), cfg->swapIndexBase())
421 : make_pair(cfg->proxyTargetShortSwapIndexBase(), cfg->proxyTargetSwapIndexBase());
422 break;
423 }
424
425 // Yield Vol
427 QuantLib::ext::shared_ptr<YieldVolatilityCurveSpec> ydvolspec =
428 QuantLib::ext::dynamic_pointer_cast<YieldVolatilityCurveSpec>(spec);
429 QL_REQUIRE(ydvolspec, "Failed to convert spec " << *spec);
430 auto itr = requiredGenericYieldVolCurves_.find(ydvolspec->name());
431 if (itr == requiredGenericYieldVolCurves_.end()) {
432 DLOG("Building Yield Volatility for asof " << asof_);
433 QuantLib::ext::shared_ptr<YieldVolCurve> yieldVolCurve = QuantLib::ext::make_shared<YieldVolCurve>(
435 calibrationInfo_->irVolCalibrationInfo[ydvolspec->name()] = yieldVolCurve->calibrationInfo();
436 itr = requiredGenericYieldVolCurves_.insert(make_pair(ydvolspec->name(), yieldVolCurve)).first;
437 }
438 DLOG("Adding YieldVol (" << node.name << ") with spec " << *ydvolspec << " to configuration "
439 << configuration);
440 yieldVolCurves_[make_pair(configuration, node.name)] =
441 Handle<SwaptionVolatilityStructure>(itr->second->volTermStructure());
442 break;
443 }
444
445 // Cap Floor Vol
447 QuantLib::ext::shared_ptr<CapFloorVolatilityCurveSpec> cfVolSpec =
448 QuantLib::ext::dynamic_pointer_cast<CapFloorVolatilityCurveSpec>(spec);
449 QL_REQUIRE(cfVolSpec, "Failed to convert spec " << *spec);
450 QuantLib::ext::shared_ptr<CapFloorVolatilityCurveConfig> cfg =
451 curveConfigs_->capFloorVolCurveConfig(cfVolSpec->curveConfigID());
452
453 auto itr = requiredCapFloorVolCurves_.find(cfVolSpec->name());
454 if (itr == requiredCapFloorVolCurves_.end()) {
455 DLOG("Building cap/floor volatility for asof " << asof_);
456
457 // Firstly, need to retrieve ibor index and discount curve
458 // Ibor index
459 std::string iborIndexName = cfg->index();
460 QuantLib::Period rateComputationPeriod = cfg->rateComputationPeriod();
461 Handle<IborIndex> iborIndex = MarketImpl::iborIndex(iborIndexName, configuration);
462 Handle<YieldTermStructure> discountCurve;
463 // Discount curve
464 if (!cfg->discountCurve().empty()) {
465 auto it = requiredYieldCurves_.find(cfg->discountCurve());
466 QL_REQUIRE(it != requiredYieldCurves_.end(), "Discount curve with spec, "
467 << cfg->discountCurve()
468 << ", not found in loaded yield curves");
469 discountCurve = it->second->handle();
470 }
471
472 // for proxy curves we need the source and target indices
473 QuantLib::ext::shared_ptr<IborIndex> sourceIndex, targetIndex;
474 if (!cfg->proxySourceCurveId().empty()) {
475 if (!cfg->proxySourceIndex().empty())
476 sourceIndex = *MarketImpl::iborIndex(cfg->proxySourceIndex(), configuration);
477 if (!cfg->proxyTargetIndex().empty()) {
478 targetIndex = *MarketImpl::iborIndex(cfg->proxyTargetIndex(), configuration);
479 iborIndexName = cfg->proxyTargetIndex();
480 rateComputationPeriod = cfg->proxyTargetRateComputationPeriod();
481 }
482 }
483
484 // Now create cap/floor vol curve
485 QuantLib::ext::shared_ptr<CapFloorVolCurve> capFloorVolCurve = QuantLib::ext::make_shared<CapFloorVolCurve>(
486 asof_, *cfVolSpec, *loader_, *curveConfigs_, iborIndex.currentLink(), discountCurve, sourceIndex,
488 calibrationInfo_->irVolCalibrationInfo[cfVolSpec->name()] = capFloorVolCurve->calibrationInfo();
490 .insert(make_pair(
491 cfVolSpec->name(),
492 std::make_pair(capFloorVolCurve, std::make_pair(iborIndexName, rateComputationPeriod))))
493 .first;
494 }
495
496 DLOG("Adding CapFloorVol (" << node.name << ") with spec " << *cfVolSpec << " to configuration "
497 << configuration);
498 capFloorCurves_[make_pair(configuration, node.name)] =
499 Handle<OptionletVolatilityStructure>(itr->second.first->capletVolStructure());
500 capFloorIndexBase_[make_pair(configuration, node.name)] = itr->second.second;
501 break;
502 }
503
504 // Default Curve
506 QuantLib::ext::shared_ptr<DefaultCurveSpec> defaultspec = QuantLib::ext::dynamic_pointer_cast<DefaultCurveSpec>(spec);
507 QL_REQUIRE(defaultspec, "Failed to convert spec " << *spec);
508 auto itr = requiredDefaultCurves_.find(defaultspec->name());
509 if (itr == requiredDefaultCurves_.end()) {
510 // build the curve
511 DLOG("Building DefaultCurve for asof " << asof_);
512 QuantLib::ext::shared_ptr<DefaultCurve> defaultCurve = QuantLib::ext::make_shared<DefaultCurve>(
514 itr = requiredDefaultCurves_.insert(make_pair(defaultspec->name(), defaultCurve)).first;
515 }
516 DLOG("Adding DefaultCurve (" << node.name << ") with spec " << *defaultspec << " to configuration "
517 << configuration);
518 defaultCurves_[make_pair(configuration, node.name)] =
519 Handle<QuantExt::CreditCurve>(itr->second->creditCurve());
520 recoveryRates_[make_pair(configuration, node.name)] =
521 Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(itr->second->recoveryRate()));
522 break;
523 }
524
525 // CDS Vol
527 QuantLib::ext::shared_ptr<CDSVolatilityCurveSpec> cdsvolspec =
528 QuantLib::ext::dynamic_pointer_cast<CDSVolatilityCurveSpec>(spec);
529 QL_REQUIRE(cdsvolspec, "Failed to convert spec " << *spec);
530 auto itr = requiredCDSVolCurves_.find(cdsvolspec->name());
531 if (itr == requiredCDSVolCurves_.end()) {
532 DLOG("Building CDSVol for asof " << asof_);
533 QuantLib::ext::shared_ptr<CDSVolCurve> cdsVolCurve = QuantLib::ext::make_shared<CDSVolCurve>(
535 itr = requiredCDSVolCurves_.insert(make_pair(cdsvolspec->name(), cdsVolCurve)).first;
536 }
537 DLOG("Adding CDSVol (" << node.name << ") with spec " << *cdsvolspec << " to configuration "
538 << configuration);
539 cdsVols_[make_pair(configuration, node.name)] =
540 Handle<QuantExt::CreditVolCurve>(itr->second->volTermStructure());
541 break;
542 }
543
544 // Base Correlation
546 QuantLib::ext::shared_ptr<BaseCorrelationCurveSpec> baseCorrelationSpec =
547 QuantLib::ext::dynamic_pointer_cast<BaseCorrelationCurveSpec>(spec);
548 QL_REQUIRE(baseCorrelationSpec, "Failed to convert spec " << *spec);
549 auto itr = requiredBaseCorrelationCurves_.find(baseCorrelationSpec->name());
550 if (itr == requiredBaseCorrelationCurves_.end()) {
551 DLOG("Building BaseCorrelation for asof " << asof_);
552 QuantLib::ext::shared_ptr<BaseCorrelationCurve> baseCorrelationCurve = QuantLib::ext::make_shared<BaseCorrelationCurve>(
553 asof_, *baseCorrelationSpec, *loader_, *curveConfigs_, referenceData_);
554 itr =
555 requiredBaseCorrelationCurves_.insert(make_pair(baseCorrelationSpec->name(), baseCorrelationCurve))
556 .first;
557 }
558
559 DLOG("Adding Base Correlation (" << node.name << ") with spec " << *baseCorrelationSpec
560 << " to configuration " << configuration);
561 baseCorrelations_[make_pair(configuration, node.name)] =
562 Handle<QuantExt::BaseCorrelationTermStructure>(
563 itr->second->baseCorrelationTermStructure());
564 break;
565 }
566
567 // Inflation Curve
569 QuantLib::ext::shared_ptr<InflationCurveSpec> inflationspec = QuantLib::ext::dynamic_pointer_cast<InflationCurveSpec>(spec);
570 QL_REQUIRE(inflationspec, "Failed to convert spec " << *spec << " to inflation curve spec");
571 auto itr = requiredInflationCurves_.find(inflationspec->name());
572 if (itr == requiredInflationCurves_.end()) {
573 DLOG("Building InflationCurve " << inflationspec->name() << " for asof " << asof_);
574 QuantLib::ext::shared_ptr<InflationCurve> inflationCurve = QuantLib::ext::make_shared<InflationCurve>(
576 itr = requiredInflationCurves_.insert(make_pair(inflationspec->name(), inflationCurve)).first;
577 calibrationInfo_->inflationCurveCalibrationInfo[inflationspec->name()] =
578 inflationCurve->calibrationInfo();
579 }
580
582 DLOG("Adding ZeroInflationIndex (" << node.name << ") with spec " << *inflationspec
583 << " to configuration " << configuration);
584 QuantLib::ext::shared_ptr<ZeroInflationTermStructure> ts =
585 QuantLib::ext::dynamic_pointer_cast<ZeroInflationTermStructure>(itr->second->inflationTermStructure());
586 QL_REQUIRE(ts,
587 "expected zero inflation term structure for index " << node.name << ", but could not cast");
588 // index is not interpolated
589 auto tmp = parseZeroInflationIndex(node.name, Handle<ZeroInflationTermStructure>(ts));
590 zeroInflationIndices_[make_pair(configuration, node.name)] = Handle<ZeroInflationIndex>(tmp);
591 }
592
594 DLOG("Adding YoYInflationIndex (" << node.name << ") with spec " << *inflationspec
595 << " to configuration " << configuration);
596 QuantLib::ext::shared_ptr<YoYInflationTermStructure> ts =
597 QuantLib::ext::dynamic_pointer_cast<YoYInflationTermStructure>(itr->second->inflationTermStructure());
598 QL_REQUIRE(ts,
599 "expected yoy inflation term structure for index " << node.name << ", but could not cast");
600 yoyInflationIndices_[make_pair(configuration, node.name)] =
601 Handle<YoYInflationIndex>(QuantLib::ext::make_shared<QuantExt::YoYInflationIndexWrapper>(
602 parseZeroInflationIndex(node.name, Handle<ZeroInflationTermStructure>()), false,
603 Handle<YoYInflationTermStructure>(ts)));
604 }
605 break;
606 }
607
608 // Inflation Cap Floor Vol
610 QuantLib::ext::shared_ptr<InflationCapFloorVolatilityCurveSpec> infcapfloorspec =
611 QuantLib::ext::dynamic_pointer_cast<InflationCapFloorVolatilityCurveSpec>(spec);
612 QL_REQUIRE(infcapfloorspec, "Failed to convert spec " << *spec << " to inf cap floor spec");
613 auto itr = requiredInflationCapFloorVolCurves_.find(infcapfloorspec->name());
614 if (itr == requiredInflationCapFloorVolCurves_.end()) {
615 DLOG("Building InflationCapFloorVolatilitySurface for asof " << asof_);
616 QuantLib::ext::shared_ptr<InflationCapFloorVolCurve> inflationCapFloorVolCurve =
617 QuantLib::ext::make_shared<InflationCapFloorVolCurve>(asof_, *infcapfloorspec, *loader_, *curveConfigs_,
620 .insert(make_pair(infcapfloorspec->name(), inflationCapFloorVolCurve))
621 .first;
622 }
623
625 DLOG("Adding InflationCapFloorVol (" << node.name << ") with spec " << *infcapfloorspec
626 << " to configuration " << configuration);
627 cpiInflationCapFloorVolatilitySurfaces_[make_pair(configuration, node.name)] =
628 Handle<CPIVolatilitySurface>(itr->second->cpiInflationCapFloorVolSurface());
629 }
630
632 DLOG("Adding YoYOptionletVolatilitySurface (" << node.name << ") with spec " << *infcapfloorspec
633 << " to configuration " << configuration);
634 yoyCapFloorVolSurfaces_[make_pair(configuration, node.name)] =
635 Handle<QuantExt::YoYOptionletVolatilitySurface>(itr->second->yoyInflationCapFloorVolSurface());
636 }
637 break;
638 }
639
640 // Equity Spot
642 QuantLib::ext::shared_ptr<EquityCurveSpec> equityspec = QuantLib::ext::dynamic_pointer_cast<EquityCurveSpec>(spec);
643 QL_REQUIRE(equityspec, "Failed to convert spec " << *spec);
644 auto itr = requiredEquityCurves_.find(equityspec->name());
645 if (itr == requiredEquityCurves_.end()) {
646 DLOG("Building EquityCurve for asof " << asof_);
647 QuantLib::ext::shared_ptr<EquityCurve> equityCurve = QuantLib::ext::make_shared<EquityCurve>(
649 itr = requiredEquityCurves_.insert(make_pair(equityspec->name(), equityCurve)).first;
650 calibrationInfo_->dividendCurveCalibrationInfo[equityspec->name()] = equityCurve->calibrationInfo();
651 }
652
653 DLOG("Adding EquityCurve (" << node.name << ") with spec " << *equityspec << " to configuration "
654 << configuration);
655 yieldCurves_[make_tuple(configuration, YieldCurveType::EquityDividend, node.name)] =
656 itr->second->equityIndex()->equityDividendCurve();
657 equitySpots_[make_pair(configuration, node.name)] = itr->second->equityIndex()->equitySpot();
658 equityCurves_[make_pair(configuration, node.name)] = Handle<EquityIndex2>(itr->second->equityIndex());
659 IndexNameTranslator::instance().add(itr->second->equityIndex()->name(),
660 "EQ-" + itr->second->equityIndex()->name());
661 break;
662 }
663
664 // Equity Vol
666
667 QuantLib::ext::shared_ptr<EquityVolatilityCurveSpec> eqvolspec =
668 QuantLib::ext::dynamic_pointer_cast<EquityVolatilityCurveSpec>(spec);
669
670 QL_REQUIRE(eqvolspec, "Failed to convert spec " << *spec);
671 auto itr = requiredEquityVolCurves_.find(eqvolspec->name());
672 if (itr == requiredEquityVolCurves_.end()) {
673 LOG("Building EquityVol for asof " << asof_);
674 // First we need the Equity Index, we don't have a dependency for this in the graph, rather
675 // pull it directly from MarketImpl, which will trigger the build if necessary -
676 // this works, but contradicts the idea of managing the dependencies fully in a graph.
677 // The EQVol builder should rather get the index from the requiredEquityCurves_.
678 // In addition we should maybe specify the eqIndex name in the vol curve config explicitly
679 // instead of assuming that it has the same curve id as the vol curve to be build?
680 Handle<EquityIndex2> eqIndex = MarketImpl::equityCurve(eqvolspec->curveConfigID(), configuration);
681 QuantLib::ext::shared_ptr<EquityVolCurve> eqVolCurve = QuantLib::ext::make_shared<EquityVolCurve>(
682 asof_, *eqvolspec, *loader_, *curveConfigs_, eqIndex, requiredEquityCurves_,
685 itr = requiredEquityVolCurves_.insert(make_pair(eqvolspec->name(), eqVolCurve)).first;
686 calibrationInfo_->eqVolCalibrationInfo[eqvolspec->name()] = eqVolCurve->calibrationInfo();
687 }
688 string eqName = node.name;
689 DLOG("Adding EquityVol (" << eqName << ") with spec " << *eqvolspec << " to configuration "
690 << configuration);
691
692 QuantLib::ext::shared_ptr<BlackVolTermStructure> bvts(itr->second->volTermStructure());
693 // Wrap it in QuantExt::BlackVolatilityWithATM as TodaysMarket might be used
694 // for model calibration. This is not the ideal place to put this logic but
695 // it can't be in EquityVolCurve as there are implicit, configuration dependent,
696 // choices made already (e.g. what discount curve to use).
697 // We do this even if it is an ATM curve, it does no harm.
698 Handle<Quote> spot = equitySpot(eqName, configuration);
699 Handle<YieldTermStructure> yts = discountCurve(eqvolspec->ccy(), configuration);
700 Handle<YieldTermStructure> divYts = equityDividendCurve(eqName, configuration);
701 bvts = QuantLib::ext::make_shared<QuantExt::BlackVolatilityWithATM>(bvts, spot, yts, divYts);
702
703 equityVols_[make_pair(configuration, node.name)] = Handle<BlackVolTermStructure>(bvts);
704 break;
705 }
706
707 // Security spread, rr, cpr
709 QuantLib::ext::shared_ptr<SecuritySpec> securityspec = QuantLib::ext::dynamic_pointer_cast<SecuritySpec>(spec);
710 QL_REQUIRE(securityspec, "Failed to convert spec " << *spec << " to security spec");
711 auto itr = requiredSecurities_.find(securityspec->securityID());
712 if (itr == requiredSecurities_.end()) {
713 DLOG("Building Securities for asof " << asof_);
714 QuantLib::ext::shared_ptr<Security> security =
715 QuantLib::ext::make_shared<Security>(asof_, *securityspec, *loader_, *curveConfigs_);
716 itr = requiredSecurities_.insert(make_pair(securityspec->securityID(), security)).first;
717 }
718 DLOG("Adding Security (" << node.name << ") with spec " << *securityspec << " to configuration "
719 << configuration);
720 if (!itr->second->spread().empty())
721 securitySpreads_[make_pair(configuration, node.name)] = itr->second->spread();
722 if (!itr->second->recoveryRate().empty())
723 recoveryRates_[make_pair(configuration, node.name)] = itr->second->recoveryRate();
724 if (!itr->second->cpr().empty())
725 cprs_[make_pair(configuration, node.name)] = itr->second->cpr();
726 break;
727 }
728
729 // Commodity curve
731 QuantLib::ext::shared_ptr<CommodityCurveSpec> commodityCurveSpec =
732 QuantLib::ext::dynamic_pointer_cast<CommodityCurveSpec>(spec);
733 QL_REQUIRE(commodityCurveSpec, "Failed to convert spec, " << *spec << ", to CommodityCurveSpec");
734 auto itr = requiredCommodityCurves_.find(commodityCurveSpec->name());
735 if (itr == requiredCommodityCurves_.end()) {
736 DLOG("Building CommodityCurve " << commodityCurveSpec->name() << " for asof " << asof_);
737 QuantLib::ext::shared_ptr<CommodityCurve> commodityCurve =
738 QuantLib::ext::make_shared<CommodityCurve>(asof_, *commodityCurveSpec, *loader_, *curveConfigs_, *fx_,
740 itr = requiredCommodityCurves_.insert(make_pair(commodityCurveSpec->name(), commodityCurve)).first;
741 }
742
743 DLOG("Adding CommodityCurve, " << node.name << ", with spec " << *commodityCurveSpec << " to configuration "
744 << configuration);
745 Handle<CommodityIndex> commIdx(itr->second->commodityIndex());
746 commodityIndices_[make_pair(configuration, node.name)] = commIdx;
747 calibrationInfo_->commodityCurveCalibrationInfo[commodityCurveSpec->name()] = itr->second->calibrationInfo();
748 break;
749 }
750
751 // Commodity Vol
753
754 QuantLib::ext::shared_ptr<CommodityVolatilityCurveSpec> commodityVolSpec =
755 QuantLib::ext::dynamic_pointer_cast<CommodityVolatilityCurveSpec>(spec);
756 QL_REQUIRE(commodityVolSpec, "Failed to convert spec " << *spec << " to commodity volatility spec");
757 auto itr = requiredCommodityVolCurves_.find(commodityVolSpec->name());
758 if (itr == requiredCommodityVolCurves_.end()) {
759 DLOG("Building commodity volatility for asof " << asof_);
760 QuantLib::ext::shared_ptr<CommodityVolCurve> commodityVolCurve = QuantLib::ext::make_shared<CommodityVolCurve>(
763 itr = requiredCommodityVolCurves_.insert(make_pair(commodityVolSpec->name(), commodityVolCurve)).first;
764 calibrationInfo_->commVolCalibrationInfo[commodityVolSpec->name()] = commodityVolCurve->calibrationInfo();
765 }
766
767 string commodityName = node.name;
768 DLOG("Adding commodity volatility (" << commodityName << ") with spec " << *commodityVolSpec
769 << " to configuration " << configuration);
770
771 // Logic copied from Equity vol section of TodaysMarket for now
772 QuantLib::ext::shared_ptr<BlackVolTermStructure> bvts(itr->second->volatility());
773 Handle<YieldTermStructure> discount = discountCurve(commodityVolSpec->currency(), configuration);
774 Handle<PriceTermStructure> priceCurve = commodityPriceCurve(commodityName, configuration);
775 Handle<YieldTermStructure> yield =
776 Handle<YieldTermStructure>(QuantLib::ext::make_shared<PriceTermStructureAdapter>(*priceCurve, *discount));
777 Handle<Quote> spot(QuantLib::ext::make_shared<SimpleQuote>(priceCurve->price(0, true)));
778
779 bvts = QuantLib::ext::make_shared<QuantExt::BlackVolatilityWithATM>(bvts, spot, discount, yield);
780 commodityVols_[make_pair(configuration, node.name)] = Handle<BlackVolTermStructure>(bvts);
781 break;
782 }
783
784 // Correlation
786 QuantLib::ext::shared_ptr<CorrelationCurveSpec> corrspec = QuantLib::ext::dynamic_pointer_cast<CorrelationCurveSpec>(spec);
787 auto itr = requiredCorrelationCurves_.find(corrspec->name());
788 if (itr == requiredCorrelationCurves_.end()) {
789 DLOG("Building CorrelationCurve for asof " << asof_);
790 QuantLib::ext::shared_ptr<CorrelationCurve> corrCurve = QuantLib::ext::make_shared<CorrelationCurve>(
791 asof_, *corrspec, *loader_, *curveConfigs_, requiredSwapIndices_[configuration],
793 itr = requiredCorrelationCurves_.insert(make_pair(corrspec->name(), corrCurve)).first;
794 }
795
796 DLOG("Adding CorrelationCurve (" << node.name << ") with spec " << *corrspec << " to configuration "
797 << configuration);
798 auto tokens = getCorrelationTokens(node.name);
799 QL_REQUIRE(tokens.size() == 2, "Invalid correlation spec " << node.name);
800 correlationCurves_[make_tuple(configuration, tokens[0], tokens[1])] =
801 Handle<QuantExt::CorrelationTermStructure>(itr->second->corrTermStructure());
802 break;
803 }
804
805 default: {
806 QL_FAIL("Unhandled spec " << *spec);
807 }
808
809 } // switch(specName)
810 } // else-block (spec based node)
811
812 node.built = true;
813} // TodaysMarket::buildNode()
814
815void TodaysMarket::require(const MarketObject o, const string& name, const string& configuration,
816 const bool forceBuild) const {
817
818 // if the market is not lazily built, do nothing
819
820 if (!lazyBuild_ && !forceBuild)
821 return;
822
823 // search the node (o, name) in the dependency graph
824
825 DLOG("market object " << o << "(" << name << ") required for configuration '" << configuration << "'");
826
827 auto tmp = dependencies_.find(configuration);
828 if (tmp == dependencies_.end()) {
829 if (configuration != Market::defaultConfiguration) {
831 ore::data::to_string(o) + "(" + name + ")", "Unknown market configuration.",
832 "Configuration '" + configuration +
833 "' not known - check why this is used. Will retry with default configuration.")
834 .log();
836 return;
837 } else {
838 StructuredCurveErrorMessage(ore::data::to_string(o) + "(" + name + ")", "Failed to Build Curve",
839 "Configuration 'default' not known, this is unexpected. Do nothing.")
840 .log();
841 return;
842 }
843 }
844
845 Vertex node = nullptr;
846
847 Graph& g = tmp->second;
848 IndexMap index = QuantLib::ext::get(boost::vertex_index, g);
849
850 VertexIterator v, vend;
851 bool found = false;
852 for (std::tie(v, vend) = boost::vertices(g); v != vend; ++v) {
853 if (g[*v].obj == o) {
854 if (o == MarketObject::Correlation) {
855 // split the required name and the node name and compare the tokens
857 } else {
858 found = (g[*v].name == name);
859 }
860 if (found) {
861 node = *v;
862 break;
863 }
864 }
865 }
866
867 // if we did not find a node, we retry with the default configuration, as required by the interface
868
869 if (!found && configuration != Market::defaultConfiguration) {
870 DLOG("not found, retry with default configuration");
872 return;
873 }
874
875 // if we still have no node, we do nothing, the error handling is done in MarketImpl
876
877 if (!found) {
878 DLOG("not found, do nothing");
879 return;
880 }
881
882 // if the node is already built, we are done
883
884 if (g[node].built) {
885 DLOG("node already built, do nothing.");
886 return;
887 }
888
889 // run a DFS from the found node to identify the required nodes to be built and get a possible order to do this
890
891 map<string, string> buildErrors;
892 std::vector<Vertex> order;
893 bool foundCycle = false;
894
895 DfsVisitor<Vertex> dfs(order, foundCycle);
896 auto colorMap = boost::make_vector_property_map<boost::default_color_type>(index);
897 boost::depth_first_visit(g, node, dfs, colorMap);
898
899 if (foundCycle) {
900 order.clear();
901 buildErrors[g[node].curveSpec ? g[node].curveSpec->name() : g[node].name] = "found cycle";
902 }
903
904 // build the nodes
905
906 TLOG("Can build objects in the following order:");
907 for (auto const& m : order) {
908 TLOG("vertex #" << index[m] << ": " << g[m] << (g[m].built ? " (already built)" : " (not yet built)"));
909 }
910
911 Size countSuccess = 0, countError = 0;
912 for (auto const& m : order) {
913 if (g[m].built)
914 continue;
915 try {
916 buildNode(configuration, g[m]);
917 ++countSuccess;
918 DLOG("built node " << g[m] << " in configuration " << configuration);
919 } catch (const std::exception& e) {
920 if (g[m].curveSpec)
921 buildErrors[g[m].curveSpec->name()] = e.what();
922 else
923 buildErrors[g[m].name] = e.what();
924 ++countError;
925 ALOG("error while building node " << g[m] << " in configuration " << configuration << ": " << e.what());
926 }
927 }
928
929 if (countSuccess + countError > 0) {
930 DLOG("Loaded CurvesSpecs: success: " << countSuccess << ", error: " << countError);
931 }
932
933 // output errors
934
935 if (!buildErrors.empty()) {
936 for (auto const& error : buildErrors) {
937 StructuredCurveErrorMessage(error.first, "Failed to Build Curve", error.second).log();
938 }
939 if (!continueOnError_) {
940 string errStr;
941 for (auto const& error : buildErrors) {
942 errStr += "(" + error.first + ": " + error.second + "); ";
943 }
944 QL_FAIL("Cannot build all required curves! Building failed for: " << errStr);
945 }
946 }
947} // TodaysMarket::require()
948
949std::ostream& operator<<(std::ostream& o, const DependencyGraph::Node& n) {
950 return o << n.obj << "(" << n.name << "," << n.mapping << ")";
951}
952
953} // namespace data
954} // namespace ore
Wrapper class for building base correlation structures.
Build optionlet volatility structures from cap floor configurations.
Class for building cds volatility structures.
std::map< std::string, Graph > dependencies()
void buildDependencyGraph(const std::string &configuration, std::map< std::string, std::string > &buildErrors)
const FallbackData & fallbackData(const string &iborIndex) const
bool isIndexReplaced(const string &iborIndex, const QuantLib::Date &asof=QuantLib::Date::maxDate()) const
void log() const
generate Boost log record to pass to corresponding sinks
Definition: log.cpp:491
static const string defaultConfiguration
Default configuration label.
Definition: market.hpp:296
Handle< YieldTermStructure > discountCurve(const string &ccy, const string &configuration=Market::defaultConfiguration) const
Definition: market.cpp:351
Market Implementation.
Definition: marketimpl.hpp:53
map< pair< string, string >, Handle< OptionletVolatilityStructure > > capFloorCurves_
Definition: marketimpl.hpp:219
Handle< QuantExt::EquityIndex2 > equityCurve(const string &eqName, const string &configuration=Market::defaultConfiguration) const override
Definition: marketimpl.cpp:364
map< tuple< string, string, string >, Handle< QuantExt::CorrelationTermStructure > > correlationCurves_
Definition: marketimpl.hpp:229
map< pair< string, string >, QuantLib::Handle< QuantExt::EquityIndex2 > > equityCurves_
Definition: marketimpl.hpp:232
map< pair< string, string >, Handle< CPIVolatilitySurface > > cpiInflationCapFloorVolatilitySurfaces_
Definition: marketimpl.hpp:224
map< pair< string, string >, Handle< BlackVolTermStructure > > fxVols_
Definition: marketimpl.hpp:214
QuantLib::ext::shared_ptr< FXTriangulation > fx_
Definition: marketimpl.hpp:206
map< tuple< string, YieldCurveType, string >, Handle< YieldTermStructure > > yieldCurves_
Definition: marketimpl.hpp:208
map< pair< string, string >, QuantLib::Handle< QuantExt::CommodityIndex > > commodityIndices_
Definition: marketimpl.hpp:230
map< pair< string, string >, Handle< QuantExt::CreditCurve > > defaultCurves_
Definition: marketimpl.hpp:215
Handle< YieldTermStructure > equityDividendCurve(const string &eqName, const string &configuration=Market::defaultConfiguration) const override
Definition: marketimpl.cpp:369
map< pair< string, string >, Handle< IborIndex > > iborIndices_
Definition: marketimpl.hpp:209
map< pair< string, string >, Handle< YoYOptionletVolatilitySurface > > yoyCapFloorVolSurfaces_
Definition: marketimpl.hpp:221
Handle< QuantExt::CreditCurve > defaultCurve(const string &, const string &configuration=Market::defaultConfiguration) const override
Default Curves and Recovery Rates.
Definition: marketimpl.cpp:245
map< pair< string, string >, Handle< YoYInflationIndex > > yoyInflationIndices_
Definition: marketimpl.hpp:223
map< pair< string, string >, Handle< QuantExt::CreditVolCurve > > cdsVols_
Definition: marketimpl.hpp:216
map< pair< string, string >, Handle< Quote > > equitySpots_
Definition: marketimpl.hpp:225
map< pair< string, string >, Handle< QuantLib::SwaptionVolatilityStructure > > swaptionCurves_
Definition: marketimpl.hpp:211
map< pair< string, string >, Handle< QuantExt::BaseCorrelationTermStructure > > baseCorrelations_
Definition: marketimpl.hpp:217
map< pair< string, string >, Handle< Quote > > cprs_
Definition: marketimpl.hpp:233
map< pair< string, string >, Handle< Quote > > recoveryRates_
Definition: marketimpl.hpp:218
QuantLib::Handle< QuantExt::PriceTermStructure > commodityPriceCurve(const string &commodityName, const string &configuration=Market::defaultConfiguration) const override
Commodity curves.
Definition: marketimpl.cpp:395
Handle< Quote > equitySpot(const string &eqName, const string &configuration=Market::defaultConfiguration) const override
Equity curves.
Definition: marketimpl.cpp:359
map< pair< string, string >, Handle< ZeroInflationIndex > > zeroInflationIndices_
Definition: marketimpl.hpp:222
map< pair< string, string >, pair< string, string > > swaptionIndexBases_
Definition: marketimpl.hpp:212
map< pair< string, string >, Handle< BlackVolTermStructure > > equityVols_
Definition: marketimpl.hpp:226
map< pair< string, string >, Handle< QuantLib::SwaptionVolatilityStructure > > yieldVolCurves_
Definition: marketimpl.hpp:213
map< pair< string, string >, Handle< SwapIndex > > swapIndices_
Definition: marketimpl.hpp:210
map< pair< string, string >, Handle< Quote > > securitySpreads_
Definition: marketimpl.hpp:227
Handle< YieldTermStructure > yieldCurve(const YieldCurveType &type, const string &ccy, const string &configuration=Market::defaultConfiguration) const override
Yield Curves.
Definition: marketimpl.cpp:74
Handle< IborIndex > iborIndex(const string &indexName, const string &configuration=Market::defaultConfiguration) const override
Definition: marketimpl.cpp:107
map< pair< string, string >, QuantLib::Handle< QuantLib::BlackVolTermStructure > > commodityVols_
Definition: marketimpl.hpp:231
void addSwapIndex(const string &swapindex, const string &discountIndex, const string &configuration=Market::defaultConfiguration) const
add a swap index to the market
Definition: marketimpl.cpp:473
map< pair< string, string >, std::pair< string, QuantLib::Period > > capFloorIndexBase_
Definition: marketimpl.hpp:220
Utility class for Structured Curve errors, contains the curve ID.
map< string, QuantLib::ext::shared_ptr< GenericYieldVolCurve > > requiredGenericYieldVolCurves_
void initialise(const Date &asof)
map< string, std::pair< QuantLib::ext::shared_ptr< CapFloorVolCurve >, std::pair< std::string, QuantLib::Period > > > requiredCapFloorVolCurves_
const bool preserveQuoteLinkage_
const bool buildCalibrationInfo_
void require(const MarketObject o, const string &name, const string &configuration, const bool forceBuild=false) const override
map< string, QuantLib::ext::shared_ptr< DefaultCurve > > requiredDefaultCurves_
boost::graph_traits< Graph >::vertex_iterator VertexIterator
const QuantLib::ext::shared_ptr< const CurveConfigurations > curveConfigs_
boost::property_map< Graph, boost::vertex_index_t >::type IndexMap
map< string, QuantLib::ext::shared_ptr< FXVolCurve > > requiredFxVolCurves_
const QuantLib::ext::shared_ptr< TodaysMarketParameters > params_
map< string, QuantLib::ext::shared_ptr< CommodityCurve > > requiredCommodityCurves_
const QuantLib::ext::shared_ptr< ReferenceDataManager > referenceData_
map< string, map< string, QuantLib::ext::shared_ptr< SwapIndex > > > requiredSwapIndices_
map< string, QuantLib::ext::shared_ptr< CommodityVolCurve > > requiredCommodityVolCurves_
const QuantLib::ext::shared_ptr< Loader > loader_
map< string, QuantLib::ext::shared_ptr< InflationCurve > > requiredInflationCurves_
map< string, QuantLib::ext::shared_ptr< BaseCorrelationCurve > > requiredBaseCorrelationCurves_
map< string, QuantLib::ext::shared_ptr< CorrelationCurve > > requiredCorrelationCurves_
map< string, QuantLib::ext::shared_ptr< EquityCurve > > requiredEquityCurves_
boost::directed_graph< Node > Graph
std::map< std::string, Graph > dependencies_
map< string, QuantLib::ext::shared_ptr< YieldCurve > > requiredYieldCurves_
map< string, QuantLib::ext::shared_ptr< CDSVolCurve > > requiredCDSVolCurves_
boost::graph_traits< Graph >::vertex_descriptor Vertex
TodaysMarket(const Date &asof, const QuantLib::ext::shared_ptr< TodaysMarketParameters > &params, const QuantLib::ext::shared_ptr< Loader > &loader, const QuantLib::ext::shared_ptr< CurveConfigurations > &curveConfigs, const bool continueOnError=false, const bool loadFixings=true, const bool lazyBuild=false, const QuantLib::ext::shared_ptr< ReferenceDataManager > &referenceData=nullptr, const bool preserveQuoteLinkage=false, const IborFallbackConfig &iborFallbackConfig=IborFallbackConfig::defaultConfig(), const bool buildCalibrationInfo=true, const bool handlePseudoCurrencies=true)
Constructor taking pointers and allowing for a lazy build of the market objects.
map< string, QuantLib::ext::shared_ptr< Security > > requiredSecurities_
const IborFallbackConfig iborFallbackConfig_
map< string, QuantLib::ext::shared_ptr< InflationCapFloorVolCurve > > requiredInflationCapFloorVolCurves_
QuantLib::ext::shared_ptr< TodaysMarketCalibrationInfo > calibrationInfo_
void buildNode(const std::string &configuration, Node &node) const
map< string, QuantLib::ext::shared_ptr< EquityVolCurve > > requiredEquityVolCurves_
Class for building a commodity price curve.
Wrapper class for building commodity volatility structures.
CurveSpec parser.
Wrapper class for building Default curves.
Wrapper class for building Equity curves.
Wrapper class for building Equity volatility structures.
Wrapper class for building FX volatility structures.
QuantLib::ext::shared_ptr< ZeroInflationIndex > parseZeroInflationIndex(const string &s, const Handle< ZeroInflationTermStructure > &h)
Convert std::string to QuantLib::ZeroInflationIndex.
QuantLib::ext::shared_ptr< IborIndex > parseIborIndex(const string &s, const Handle< YieldTermStructure > &h)
Convert std::string to QuantLib::IborIndex.
translates between QuantLib::Index::name() and ORE names
Map text representations to QuantLib/QuantExt types.
Wrapper class for building YoY Inflation CapFloor volatility structures.
inflation curve class
Classes and functions for log message handling.
@ data
Definition: log.hpp:77
#define LOG(text)
Logging Macro (Level = Notice)
Definition: log.hpp:552
#define DLOG(text)
Logging Macro (Level = Debug)
Definition: log.hpp:554
#define ALOG(text)
Logging Macro (Level = Alert)
Definition: log.hpp:544
#define WLOG(text)
Logging Macro (Level = Warning)
Definition: log.hpp:550
#define TLOG(text)
Logging Macro (Level = Data)
Definition: log.hpp:556
Real error
Definition: utilities.cpp:65
std::ostream & operator<<(std::ostream &out, EquityReturnType t)
void applyDividends(const std::set< Dividend > &dividends)
Real sum(const Cash &c, const Cash &d)
std::vector< std::string > getCorrelationTokens(const std::string &name)
Helper function to get the two tokens in a correlation name Index2:Index1.
Definition: parsers.cpp:1281
MarketObject
Definition: market.hpp:65
std::string to_string(const LocationInfo &l)
Definition: ast.cpp:28
void applyFixings(const set< Fixing > &fixings)
Utility to write a vector of fixings in the QuantLib index manager's fixing history.
Definition: fixings.cpp:41
Serializable Credit Default Swap.
Definition: namespaces.docs:23
std::size_t count
A wrapper class for holding Bond Spread quotes.
QuantLib::ext::shared_ptr< CurveSpec > curveSpec
Error for market data or curve.
Wrapper class for building Swaption volatility structures.
vector< string > curveConfigs
string conversion utilities
An concrete implementation of the Market class that loads todays market and builds the required curve...
string name
MarketObject obj
Wrapper class for QuantLib term structures.
Wrapper class for building yield volatility structures.