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

Valuation Engine. More...

#include <orea/engine/valuationengine.hpp>

+ Inheritance diagram for ValuationEngine:
+ Collaboration diagram for ValuationEngine:

Public Member Functions

 ValuationEngine (const QuantLib::Date &today, const QuantLib::ext::shared_ptr< ore::data::DateGrid > &dg, const QuantLib::ext::shared_ptr< analytics::SimMarket > &simMarket, const set< std::pair< std::string, QuantLib::ext::shared_ptr< QuantExt::ModelBuilder > > > &modelBuilders=set< std::pair< std::string, QuantLib::ext::shared_ptr< QuantExt::ModelBuilder > > >())
 Constructor. More...
 
void buildCube (const QuantLib::ext::shared_ptr< data::Portfolio > &portfolio, QuantLib::ext::shared_ptr< analytics::NPVCube > outputCube, std::vector< QuantLib::ext::shared_ptr< ValuationCalculator > > calculators, bool mporStickyDate=true, QuantLib::ext::shared_ptr< analytics::NPVCube > outputCubeNettingSet=nullptr, QuantLib::ext::shared_ptr< analytics::NPVCube > outputCptyCube=nullptr, std::vector< QuantLib::ext::shared_ptr< CounterpartyCalculator > > cptyCalculators={}, bool dryRun=false)
 Build NPV cube. More...
 
- Public Member Functions inherited from ProgressReporter
 ProgressReporter ()
 
void registerProgressIndicator (const QuantLib::ext::shared_ptr< ProgressIndicator > &indicator)
 
void unregisterProgressIndicator (const QuantLib::ext::shared_ptr< ProgressIndicator > &indicator)
 
void unregisterAllProgressIndicators ()
 
void updateProgress (const unsigned long progress, const unsigned long total, const std::string &detail="")
 
void resetProgress ()
 
const std::set< QuantLib::ext::shared_ptr< ProgressIndicator > > & progressIndicators () const
 

Private Member Functions

void recalibrateModels ()
 
std::pair< double, double > populateCube (const QuantLib::Date &d, size_t cubeDateIndex, size_t sample, bool isValueDate, bool isStickyDate, bool scenarioUpdated, const std::map< std::string, QuantLib::ext::shared_ptr< ore::data::Trade > > &trades, std::vector< bool > &tradeHasError, const std::vector< QuantLib::ext::shared_ptr< ValuationCalculator > > &calculators, QuantLib::ext::shared_ptr< analytics::NPVCube > &outputCube, QuantLib::ext::shared_ptr< analytics::NPVCube > &outputCubeNettingSet, const std::map< std::string, size_t > &counterparties, const std::vector< QuantLib::ext::shared_ptr< CounterpartyCalculator > > &cptyCalculators, QuantLib::ext::shared_ptr< analytics::NPVCube > &outputCptyCube)
 
void runCalculators (bool isCloseOutDate, const std::map< std::string, QuantLib::ext::shared_ptr< ore::data::Trade > > &trades, std::vector< bool > &tradeHasError, const std::vector< QuantLib::ext::shared_ptr< ValuationCalculator > > &calculators, QuantLib::ext::shared_ptr< analytics::NPVCube > &outputCube, QuantLib::ext::shared_ptr< analytics::NPVCube > &outputCubeSensis, const QuantLib::Date &d, const QuantLib::Size cubeDateIndex, const QuantLib::Size sample, const std::string &label="")
 
void runCalculators (bool isCloseOutDate, const std::map< std::string, QuantLib::Size > &counterparties, const std::vector< QuantLib::ext::shared_ptr< CounterpartyCalculator > > &calculators, QuantLib::ext::shared_ptr< analytics::NPVCube > &cptyCube, const QuantLib::Date &d, const QuantLib::Size cubeDateIndex, const QuantLib::Size sample)
 
void tradeExercisable (bool enable, const std::map< std::string, QuantLib::ext::shared_ptr< ore::data::Trade > > &trades)
 

Private Attributes

QuantLib::Date today_
 
QuantLib::ext::shared_ptr< ore::data::DateGriddg_
 
QuantLib::ext::shared_ptr< ore::analytics::SimMarketsimMarket_
 
set< std::pair< std::string, QuantLib::ext::shared_ptr< QuantExt::ModelBuilder > > > modelBuilders_
 

Detailed Description

Valuation Engine.

The valuation engine's purpose is to generate an NPV cube. Its buildCube loops over samples->dates->trades and prices the portfolio under all samples and dates.

The number of dates is defined by the DateGrid passed to the constructor. The number of trades is defined by the size of the portfolio passed to buildCube(). The number of samples is defined by the NPVCube that is passed to buildCube(), this can be dynamic.

In addition to storing the resulting NPVs it can be given any number of calculators that can store additional values in the cube.

Definition at line 69 of file valuationengine.hpp.

Constructor & Destructor Documentation

◆ ValuationEngine()

ValuationEngine ( const QuantLib::Date &  today,
const QuantLib::ext::shared_ptr< ore::data::DateGrid > &  dg,
const QuantLib::ext::shared_ptr< analytics::SimMarket > &  simMarket,
const set< std::pair< std::string, QuantLib::ext::shared_ptr< QuantExt::ModelBuilder > > > &  modelBuilders = set<std::pair<std::string, QuantLib::ext::shared_ptr<QuantExt::ModelBuilder>>>() 
)

Constructor.

Parameters
todayValuation date
dgSimulation date grid
simMarketSimulated market object
modelBuildersmodel builders to be updated

Definition at line 49 of file valuationengine.cpp.

52 : today_(today), dg_(dg), simMarket_(simMarket), modelBuilders_(modelBuilders) {
53
54 QL_REQUIRE(dg_->size() > 0, "Error, DateGrid size must be > 0");
55 QL_REQUIRE(today <= dg_->dates().front(), "ValuationEngine: Error today ("
56 << today << ") must not be later than first DateGrid date "
57 << dg_->dates().front());
58 QL_REQUIRE(simMarket_, "ValuationEngine: Error, Null SimMarket");
59}
QuantLib::ext::shared_ptr< ore::data::DateGrid > dg_
QuantLib::ext::shared_ptr< ore::analytics::SimMarket > simMarket_
set< std::pair< std::string, QuantLib::ext::shared_ptr< QuantExt::ModelBuilder > > > modelBuilders_

Member Function Documentation

◆ buildCube()

void buildCube ( const QuantLib::ext::shared_ptr< data::Portfolio > &  portfolio,
QuantLib::ext::shared_ptr< analytics::NPVCube outputCube,
std::vector< QuantLib::ext::shared_ptr< ValuationCalculator > >  calculators,
bool  mporStickyDate = true,
QuantLib::ext::shared_ptr< analytics::NPVCube outputCubeNettingSet = nullptr,
QuantLib::ext::shared_ptr< analytics::NPVCube outputCptyCube = nullptr,
std::vector< QuantLib::ext::shared_ptr< CounterpartyCalculator > >  cptyCalculators = {},
bool  dryRun = false 
)

Build NPV cube.

Parameters
portfolioPortfolio to be priced
outputCubeObject for storing the results at trade level (e.g. NPVs, close-out NPVs, flows)
calculatorsCalculators to use
mporStickyDateUse sticky date in MPOR evaluation?
outputCubeNettingSetOutput cube for netting set-level results
outputCptyCubeOutput cube for storing counterparty-level survival probabilities
cptyCalculatorsCalculators for filling counterparty-level results
dryRunLimit samples to one and fill the rest of the cube with random values

Definition at line 70 of file valuationengine.cpp.

75 {
76
77 struct SimMarketResetter {
78 SimMarketResetter(QuantLib::ext::shared_ptr<SimMarket> simMarket) : simMarket_(simMarket) {}
79 ~SimMarketResetter() { simMarket_->reset(); }
80 QuantLib::ext::shared_ptr<SimMarket> simMarket_;
81 } simMarketResetter(simMarket_);
82
83 LOG("Build cube with mporStickyDate=" << mporStickyDate << ", dryRun=" << std::boolalpha << dryRun);
84
85 QL_REQUIRE(portfolio->size() > 0, "ValuationEngine: Error portfolio is empty");
86
87 QL_REQUIRE(outputCube->numIds() == portfolio->trades().size(),
88 "cube x dimension (" << outputCube->numIds() << ") "
89 << "different from portfolio size (" << portfolio->trades().size() << ")");
90
91 QL_REQUIRE(outputCube->numDates() == dg_->valuationDates().size(),
92 "cube y dimension (" << outputCube->numDates() << ") "
93 << "different from number of valuation dates (" << dg_->valuationDates().size()
94 << ")");
95
96 if (outputCptyCube) {
97 QL_REQUIRE(outputCptyCube->numIds() == portfolio->counterparties().size() + 1,
98 "cptyCube x dimension (" << outputCptyCube->numIds() << "minus 1) "
99 << "different from portfolio counterparty size ("
100 << portfolio->counterparties().size() << ")");
101
102 QL_REQUIRE(outputCptyCube->numDates() == dg_->dates().size(), "outputCptyCube y dimension ("
103 << outputCptyCube->numDates() << ") "
104 << "different from number of time steps ("
105 << dg_->dates().size() << ")");
106 }
107
108 LOG("Starting ValuationEngine for " << portfolio->size() << " trades, " << outputCube->samples() << " samples and "
109 << dg_->size() << " dates.");
110
111 ObservationMode::Mode om = ObservationMode::instance().mode();
112 Real updateTime = 0.0;
113 Real pricingTime = 0.0;
114 Real fixingTime = 0.0;
115
116 LOG("Initialise " << calculators.size() << " valuation calculators");
117 for (auto const& c : calculators) {
118 c->init(portfolio, simMarket_);
119 c->initScenario();
120 }
121
122 // Loop is Samples, Dates, Trades
123 const auto& dates = dg_->dates();
124 const auto& trades = portfolio->trades();
125 auto& counterparties = outputCptyCube ? outputCptyCube->idsAndIndexes() : std::map<string, Size>();
126 std::vector<bool> tradeHasError(portfolio->size(), false);
127 LOG("Initialise state objects...");
128 // initialise state objects for each trade (required for path-dependent derivatives in particular)
129 size_t i = 0;
130 for (const auto& [tradeId, trade] : trades) {
131 QL_REQUIRE(!trade->npvCurrency().empty(), "NPV currency not set for trade " << trade->id());
132
133 DLOG("Initialise wrapper for trade " << trade->id());
134 trade->instrument()->initialise(dates);
135
137
138 // T0 values
139 try {
140 for (auto& calc : calculators)
141 calc->calculateT0(trade, i, simMarket_, outputCube, outputCubeNettingSet);
142 } catch (const std::exception& e) {
143 string expMsg = string("T0 valuation error: ") + e.what();
144 StructuredTradeErrorMessage(tradeId, trade->tradeType(), "ScenarioValuation", expMsg.c_str()).log();
145 tradeHasError[i] = true;
146 }
147
149 for (const Leg& leg : trade->legs()) {
150 for (Size n = 0; n < leg.size(); n++) {
151 QuantLib::ext::shared_ptr<FloatingRateCoupon> frc = QuantLib::ext::dynamic_pointer_cast<FloatingRateCoupon>(leg[n]);
152 if (frc) {
153 frc->unregisterWith(frc->index());
154 trade->instrument()->qlInstrument()->unregisterWith(frc);
155 // Unregister with eval dates
156 frc->unregisterWith(Settings::instance().evaluationDate());
157 frc->index()->unregisterWith(Settings::instance().evaluationDate());
158 trade->instrument()->qlInstrument()->unregisterWith(Settings::instance().evaluationDate());
159 }
160 }
161 }
162 }
163 ++i;
164 }
165 LOG("Total number of trades = " << portfolio->size());
166
167 if (!dates.empty() && dates.front() > simMarket_->asofDate()) {
168 // the fixing manager is only required if sim dates contain future dates
169 simMarket_->fixingManager()->initialise(portfolio, simMarket_);
170 }
171
172 cpu_timer timer;
173 cpu_timer loopTimer;
174 Size nTrades = trades.size();
175
176 // We call Cube::samples() each time here to allow for dynamic stopping times
177 // e.g. MC convergence tests
178 for (Size sample = 0; sample < (dryRun ? std::min<Size>(1, outputCube->samples()) : outputCube->samples());
179 ++sample) {
180 TLOG("ValuationEngine: apply scenario sample #" << sample);
181
182 for (auto& [tradeId, trade] : portfolio->trades())
183 trade->instrument()->reset();
184
185 // loop over Dates, increase cubeDateIndex for each valuation date we hit
186 int cubeDateIndex = -1;
187 if (!dg_->closeOutDates().empty() && mporStickyDate) {
188 // loop over dates and always do value date and close out date in one run
189 const bool scenarioUpdated = false;
190 for (size_t i = 0; i < dg_->valuationDates().size(); ++i) {
191 double priceTime = 0;
192 double upTime = 0;
193 ++cubeDateIndex;
194 Date valueDate = dg_->valuationDates()[i];
195 Date closeOutDate = dg_->closeOutDateFromValuationDate(valueDate);
196 std::tie(priceTime, upTime) = populateCube(
197 valueDate, cubeDateIndex, sample, true, false, scenarioUpdated, trades, tradeHasError, calculators,
198 outputCube, outputCubeNettingSet, counterparties, cptyCalculators, outputCptyCube);
199 pricingTime += priceTime;
200 updateTime += upTime;
201 if(closeOutDate != Date()){
202 std::tie(priceTime, upTime) = populateCube(
203 closeOutDate, cubeDateIndex, sample, false, mporStickyDate, scenarioUpdated, trades, tradeHasError,
204 calculators, outputCube, outputCubeNettingSet, counterparties, cptyCalculators, outputCptyCube);
205 pricingTime += priceTime;
206 updateTime += upTime;
207 }
208 }
209 } else {
210 std::map<Date, std::vector<size_t>> closeOutDateToValueDateIndex;
211 for (Size i = 0; i < dates.size(); ++i) {
212 Date d = dates[i];
213 // Process auxiliary close-out dates first (may coincide with a valuation date, see below)
214 // Store result at same cubeDateIndex as the corresponding valuation date's result, but at different
215 // cube depth Differences to valuation date processing above: Update valuation date and fixings, trades
216 // exercisable depending on stickiness
217 bool scenarioUpdated = false;
218 if (dg_->isCloseOutDate()[i]) {
219 double priceTime = 0;
220 double upTime = 0;
221 QL_REQUIRE(closeOutDateToValueDateIndex.count(d) == 1 && !closeOutDateToValueDateIndex[d].empty(),
222 "Need to calculate valuation date before close out date");
223 for (size_t& valueDateIndex : closeOutDateToValueDateIndex[d]) {
224 std::tie(priceTime, upTime) =
225 populateCube(d, valueDateIndex, sample, false, mporStickyDate, scenarioUpdated, trades,
226 tradeHasError, calculators, outputCube, outputCubeNettingSet, counterparties,
227 cptyCalculators, outputCptyCube);
228 pricingTime += priceTime;
229 updateTime += upTime;
230 scenarioUpdated = true;
231 }
232 }
233 if (dg_->isValuationDate()[i]) {
234 double priceTime = 0;
235 double upTime = 0;
236 ++cubeDateIndex;
237 Date closeOutDate = dg_->closeOutDateFromValuationDate(d);
238 if(closeOutDate != Date())
239 closeOutDateToValueDateIndex[closeOutDate].push_back(cubeDateIndex);
240 std::tie(priceTime, upTime) = populateCube(
241 d, cubeDateIndex, sample, true, false, scenarioUpdated, trades, tradeHasError, calculators,
242 outputCube, outputCubeNettingSet, counterparties, cptyCalculators, outputCptyCube);
243 pricingTime += priceTime;
244 updateTime += upTime;
245 scenarioUpdated = true;
246 }
247 }
248 }
249
250 std::ostringstream detail;
251 detail << nTrades << " trade" << (nTrades == 1 ? "" : "s") << ", " << outputCube->samples() << " sample"
252 << (outputCube->samples() == 1 ? "" : "s");
253 updateProgress(sample * nTrades, outputCube->samples() * nTrades, detail.str());
254
255 timer.start();
256 simMarket_->fixingManager()->reset();
257 fixingTime += timer.elapsed().wall * 1e-9;
258 }
259
260 if (dryRun) {
261 LOG("Doing a dry run - fill remaining cube with random values.");
262 for (Size sample = 1; sample < outputCube->samples(); ++sample) {
263 for (Size i = 0; i < dates.size(); ++i) {
264 for (Size j = 0; j < trades.size(); ++j) {
265 for (Size d = 0; d < outputCube->depth(); ++d) {
266 // add some noise, but only for the first few samples, so that e.g.
267 // a sensi run is not polluted with too many sensis for each trade
268 Real noise = sample < 10 ? static_cast<Real>(i + j + d + sample) : 0.0;
269 outputCube->set(outputCube->getT0(j, d) + noise, j, i, sample, d);
270 }
271 }
272 }
273 }
274 }
275
276 std::ostringstream detail;
277 detail << nTrades << " trade" << (nTrades == 1 ? "" : "s") << ", " << outputCube->samples() << " sample"
278 << (outputCube->samples() == 1 ? "" : "s");
279 updateProgress(outputCube->samples() * nTrades, outputCube->samples() * nTrades, detail.str());
280 loopTimer.stop();
281 LOG("ValuationEngine completed: loop " << setprecision(2) << loopTimer.format(2, "%w") << " sec, "
282 << "pricing " << pricingTime << " sec, "
283 << "update " << updateTime << " sec "
284 << "fixing " << fixingTime);
285
286 // for trades with errors set all output cube values to zero
287 i = 0;
288 for (auto& [tradeId, trade] : trades) {
289 if (tradeHasError[i]) {
290 ALOG("setting all results in output cube to zero for trade '"
291 << tradeId << "' since there was at least one error during simulation");
292 outputCube->remove(i);
293 }
294 i++;
295 }
296}
std::pair< double, double > populateCube(const QuantLib::Date &d, size_t cubeDateIndex, size_t sample, bool isValueDate, bool isStickyDate, bool scenarioUpdated, const std::map< std::string, QuantLib::ext::shared_ptr< ore::data::Trade > > &trades, std::vector< bool > &tradeHasError, const std::vector< QuantLib::ext::shared_ptr< ValuationCalculator > > &calculators, QuantLib::ext::shared_ptr< analytics::NPVCube > &outputCube, QuantLib::ext::shared_ptr< analytics::NPVCube > &outputCubeNettingSet, const std::map< std::string, size_t > &counterparties, const std::vector< QuantLib::ext::shared_ptr< CounterpartyCalculator > > &cptyCalculators, QuantLib::ext::shared_ptr< analytics::NPVCube > &outputCptyCube)
void updateProgress(const unsigned long progress, const unsigned long total, const std::string &detail="")
#define LOG(text)
#define DLOG(text)
#define ALOG(text)
#define TLOG(text)
Size size(const ValueType &v)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ recalibrateModels()

void recalibrateModels ( )
private

Definition at line 61 of file valuationengine.cpp.

61 {
62 ObservationMode::Mode om = ObservationMode::instance().mode();
63 for (auto const& b : modelBuilders_) {
65 b.second->forceRecalculate();
66 b.second->recalibrate();
67 }
68}
+ Here is the caller graph for this function:

◆ populateCube()

std::pair< double, double > populateCube ( const QuantLib::Date &  d,
size_t  cubeDateIndex,
size_t  sample,
bool  isValueDate,
bool  isStickyDate,
bool  scenarioUpdated,
const std::map< std::string, QuantLib::ext::shared_ptr< ore::data::Trade > > &  trades,
std::vector< bool > &  tradeHasError,
const std::vector< QuantLib::ext::shared_ptr< ValuationCalculator > > &  calculators,
QuantLib::ext::shared_ptr< analytics::NPVCube > &  outputCube,
QuantLib::ext::shared_ptr< analytics::NPVCube > &  outputCubeNettingSet,
const std::map< std::string, size_t > &  counterparties,
const std::vector< QuantLib::ext::shared_ptr< CounterpartyCalculator > > &  cptyCalculators,
QuantLib::ext::shared_ptr< analytics::NPVCube > &  outputCptyCube 
)
private

Definition at line 355 of file valuationengine.cpp.

362 {
363 double pricingTime = 0;
364 double updateTime = 0;
365 QL_REQUIRE(cubeDateIndex >= 0, "first date should be a valuation date");
366 cpu_timer timer;
367 timer.start();
368 simMarket_->preUpdate();
369 if (isValueDate || !isStickyDate) {
370 simMarket_->updateDate(d);
371 }
372 // We can skip this step, if we have done that above in the close-out date section
373 if (!scenarioUpdated) {
374 simMarket_->updateScenario(d);
375 }
376 // Always with fixing update here, in contrast to the close-out date section
377 simMarket_->postUpdate(d, !isStickyDate || isValueDate);
378 // Aggregation scenario data update on valuation dates only
379 if (isValueDate) {
380 simMarket_->updateAsd(d);
381 }
383
384 timer.stop();
385 updateTime += timer.elapsed().wall * 1e-9;
386
387 timer.start();
388 if (isStickyDate && !isValueDate) // switch on again, if sticky
389 tradeExercisable(false, trades);
390 // loop over trades
391 runCalculators(!isValueDate, trades, tradeHasError, calculators, outputCube, outputCubeNettingSet, d, cubeDateIndex,
392 sample, simMarket_->label());
393 if (isStickyDate && !isValueDate) // switch on again, if sticky
394 tradeExercisable(true, trades);
395 // loop over counterparty names
396 if (isValueDate) {
397 runCalculators(false, counterparties, cptyCalculators, outputCptyCube, d, cubeDateIndex, sample);
398 }
399 timer.stop();
400 pricingTime += timer.elapsed().wall * 1e-9;
401 return std::make_pair(pricingTime, updateTime);
402}
void runCalculators(bool isCloseOutDate, const std::map< std::string, QuantLib::ext::shared_ptr< ore::data::Trade > > &trades, std::vector< bool > &tradeHasError, const std::vector< QuantLib::ext::shared_ptr< ValuationCalculator > > &calculators, QuantLib::ext::shared_ptr< analytics::NPVCube > &outputCube, QuantLib::ext::shared_ptr< analytics::NPVCube > &outputCubeSensis, const QuantLib::Date &d, const QuantLib::Size cubeDateIndex, const QuantLib::Size sample, const std::string &label="")
void tradeExercisable(bool enable, const std::map< std::string, QuantLib::ext::shared_ptr< ore::data::Trade > > &trades)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ runCalculators() [1/2]

void runCalculators ( bool  isCloseOutDate,
const std::map< std::string, QuantLib::ext::shared_ptr< ore::data::Trade > > &  trades,
std::vector< bool > &  tradeHasError,
const std::vector< QuantLib::ext::shared_ptr< ValuationCalculator > > &  calculators,
QuantLib::ext::shared_ptr< analytics::NPVCube > &  outputCube,
QuantLib::ext::shared_ptr< analytics::NPVCube > &  outputCubeSensis,
const QuantLib::Date &  d,
const QuantLib::Size  cubeDateIndex,
const QuantLib::Size  sample,
const std::string &  label = "" 
)
private
+ Here is the caller graph for this function:

◆ runCalculators() [2/2]

void runCalculators ( bool  isCloseOutDate,
const std::map< std::string, QuantLib::Size > &  counterparties,
const std::vector< QuantLib::ext::shared_ptr< CounterpartyCalculator > > &  calculators,
QuantLib::ext::shared_ptr< analytics::NPVCube > &  cptyCube,
const QuantLib::Date &  d,
const QuantLib::Size  cubeDateIndex,
const QuantLib::Size  sample 
)
private

◆ tradeExercisable()

void tradeExercisable ( bool  enable,
const std::map< std::string, QuantLib::ext::shared_ptr< ore::data::Trade > > &  trades 
)
private

Definition at line 343 of file valuationengine.cpp.

343 {
344 for (const auto& [tradeId, trade] : trades) {
345 auto t = QuantLib::ext::dynamic_pointer_cast<OptionWrapper>(trade->instrument());
346 if (t != nullptr) {
347 if (enable)
348 t->enableExercise();
349 else
350 t->disableExercise();
351 }
352 }
353}
+ Here is the caller graph for this function:

Member Data Documentation

◆ today_

QuantLib::Date today_
private

Definition at line 125 of file valuationengine.hpp.

◆ dg_

QuantLib::ext::shared_ptr<ore::data::DateGrid> dg_
private

Definition at line 126 of file valuationengine.hpp.

◆ simMarket_

QuantLib::ext::shared_ptr<ore::analytics::SimMarket> simMarket_
private

Definition at line 127 of file valuationengine.hpp.

◆ modelBuilders_

set<std::pair<std::string, QuantLib::ext::shared_ptr<QuantExt::ModelBuilder> > > modelBuilders_
private

Definition at line 128 of file valuationengine.hpp.