Skip to content

Commit 3d920f0

Browse files
mgronckijenkins
authored andcommitted
QPR-9859 clean up
1 parent 588e189 commit 3d920f0

4 files changed

Lines changed: 63 additions & 53 deletions

File tree

OREAnalytics/orea/engine/amcvaluationengine.cpp

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,14 @@
2727
#include <ored/model/crossassetmodelbuilder.hpp>
2828
#include <ored/portfolio/enginefactory.hpp>
2929
#include <ored/portfolio/structuredtradeerror.hpp>
30+
#include <ored/utilities/to_string.hpp>
3031

3132
#include <qle/indexes/fallbackiborindex.hpp>
3233
#include <qle/instruments/payment.hpp>
3334
#include <qle/methods/multipathgeneratorbase.hpp>
3435
#include <qle/methods/multipathvariategenerator.hpp>
35-
#include <qle/pricingengines/mcmultilegbaseengine.hpp>
3636
#include <qle/models/lgmimpliedyieldtermstructure.hpp>
37+
#include <qle/pricingengines/mcmultilegbaseengine.hpp>
3738

3839
#include <ql/instruments/compositeinstrument.hpp>
3940

@@ -222,7 +223,6 @@ void runCoreEngine(const boost::shared_ptr<ore::data::Portfolio>& portfolio,
222223
McEngineStats::instance().calc_timer.start();
223224
McEngineStats::instance().calc_timer.stop();
224225

225-
226226
auto extractAmcCalculator = [&amcCalculators, &tradeId, &tradeLabel, &tradeType, &effectiveMultiplier,
227227
&currencyIndex, &tradeFees, &model,
228228
&outputCube](const std::pair<std::string, boost::shared_ptr<Trade>>& trade,
@@ -235,7 +235,7 @@ void runCoreEngine(const boost::shared_ptr<ore::data::Portfolio>& portfolio,
235235
tradeId.push_back(id->second);
236236
} else {
237237
QL_FAIL("AMCValuationEngine: trade id '" << trade.first
238-
<< "' is not present in output cube - internal error.");
238+
<< "' is not present in output cube - internal error.");
239239
}
240240
tradeLabel.push_back(trade.first);
241241
tradeType.push_back(trade.second->tradeType());
@@ -261,8 +261,7 @@ void runCoreEngine(const boost::shared_ptr<ore::data::Portfolio>& portfolio,
261261
auto inst = trade.second->instrument()->qlInstrument(true);
262262
QL_REQUIRE(inst != nullptr,
263263
"instrument has no ql instrument, this is not supported by the amc valuation engine.");
264-
Real multiplier = trade.second->instrument()->multiplier() *
265-
trade.second->instrument()->multiplier2();
264+
Real multiplier = trade.second->instrument()->multiplier() * trade.second->instrument()->multiplier2();
266265

267266
// handle composite trades
268267
if (auto cInst = boost::dynamic_pointer_cast<CompositeInstrument>(inst)) {
@@ -428,7 +427,8 @@ void runCoreEngine(const boost::shared_ptr<ore::data::Portfolio>& portfolio,
428427
auto res = simulatePathInterface2(amcCalculators[j], pathTimes, paths, allTimes, false, tradeLabel[j],
429428
tradeType[j]);
430429
Real v = outputCube->getT0(tradeId[j], 0);
431-
outputCube->setT0(v + res[0].at(0) * fx(fxBuffer, currencyIndex[j], 0, 0) *
430+
outputCube->setT0(v +
431+
res[0].at(0) * fx(fxBuffer, currencyIndex[j], 0, 0) *
432432
numRatio(model, irStateBuffer, currencyIndex[j], 0, 0.0, 0) *
433433
effectiveMultiplier[j] +
434434
resFee[0][0],
@@ -437,7 +437,8 @@ void runCoreEngine(const boost::shared_ptr<ore::data::Portfolio>& portfolio,
437437
Real t = sgd->getGrid()->timeGrid()[k];
438438
for (Size i = 0; i < outputCube->samples(); ++i) {
439439
Real v = outputCube->get(tradeId[j], k - 1, i, 0);
440-
outputCube->set(v + res[k][i] * fx(fxBuffer, currencyIndex[j], k, i) *
440+
outputCube->set(v +
441+
res[k][i] * fx(fxBuffer, currencyIndex[j], k, i) *
441442
numRatio(model, irStateBuffer, currencyIndex[j], k, t, i) *
442443
effectiveMultiplier[j] +
443444
resFee[k][i],
@@ -454,39 +455,44 @@ void runCoreEngine(const boost::shared_ptr<ore::data::Portfolio>& portfolio,
454455
auto resLag = simulatePathInterface2(amcCalculators[j], pathTimes, paths, closeOutTimes, true,
455456
tradeLabel[j], tradeType[j]);
456457
Real v = outputCube->getT0(tradeId[j], 0);
457-
outputCube->setT0(v + res[0].at(0) * fx(fxBuffer, currencyIndex[j], 0, 0) *
458+
outputCube->setT0(v +
459+
res[0].at(0) * fx(fxBuffer, currencyIndex[j], 0, 0) *
458460
numRatio(model, irStateBuffer, currencyIndex[j], 0, 0.0, 0) *
459461
effectiveMultiplier[j] +
460462
resFee[0][0],
461463
tradeId[j], 0);
462464
int dateIndex = -1;
463-
std::map<QuantLib::Date, size_t> dateIndexCache;
464-
std::map<QuantLib::Date, double> dateTimeCache;
465+
std::map<QuantLib::Date, std::pair<double, size_t>> dateIndexCache;
465466
for (Size k = 0; k < sgd->getGrid()->dates().size(); ++k) {
466467
Real t = sgd->getGrid()->timeGrid()[k + 1];
467-
468+
468469
if (sgd->getGrid()->isCloseOutDate()[k]) {
469470
Date closeOutDate = sgd->getGrid()->dates()[k];
470471
Date valuationDate = sgd->getGrid()->valuationDateFromCloseOutDate(closeOutDate);
471472
auto dateIndexIt = dateIndexCache.find(valuationDate);
472-
QL_REQUIRE(dateIndexIt != dateIndexCache.end(), "first date in grid must be a valuation date");
473-
Real tm = dateTimeCache[valuationDate];
473+
QL_REQUIRE(dateIndexIt != dateIndexCache.end(),
474+
"The valuation date (" << ore::data::to_string(valuationDate)
475+
<< ") needs to before the corresponding close out date ("
476+
<< ore::data::to_string(closeOutDate) << ")");
477+
auto [timeValueDate, timeIndexValueDate] = dateIndexIt->second;
474478
for (Size i = 0; i < outputCube->samples(); ++i) {
475479
Real v = outputCube->get(tradeId[j], dateIndex, i, 1);
476-
outputCube->set(v + resLag[dateIndex + 1][i] * fx(fxBuffer, currencyIndex[j], k + 1, i) *
477-
num(model, irStateBuffer, currencyIndex[j], k + 1, tm, i) *
478-
effectiveMultiplier[j] +
479-
resFee[dateIndex + 1][i],
480-
tradeId[j], dateIndexIt->second, i, 1);
480+
outputCube->set(
481+
v +
482+
resLag[dateIndex + 1][i] * fx(fxBuffer, currencyIndex[j], k + 1, i) *
483+
num(model, irStateBuffer, currencyIndex[j], k + 1, timeValueDate, i) *
484+
effectiveMultiplier[j] +
485+
resFee[dateIndex + 1][i],
486+
tradeId[j], timeIndexValueDate, i, 1);
481487
}
482488
}
483489
if (sgd->getGrid()->isValuationDate()[k]) {
484490
Date valuationDate = sgd->getGrid()->dates()[k];
485-
dateIndexCache[valuationDate] = ++dateIndex;
486-
dateTimeCache[valuationDate] = t;
491+
dateIndexCache[valuationDate] = std::make_pair(t, ++dateIndex);
487492
for (Size i = 0; i < outputCube->samples(); ++i) {
488493
Real v = outputCube->get(tradeId[j], dateIndex, i, 0);
489-
outputCube->set(v + res[dateIndex + 1][i] * fx(fxBuffer, currencyIndex[j], k + 1, i) *
494+
outputCube->set(v +
495+
res[dateIndex + 1][i] * fx(fxBuffer, currencyIndex[j], k + 1, i) *
490496
numRatio(model, irStateBuffer, currencyIndex[j], k + 1, t, i) *
491497
effectiveMultiplier[j] +
492498
resFee[dateIndex + 1][i],
@@ -500,33 +506,39 @@ void runCoreEngine(const boost::shared_ptr<ore::data::Portfolio>& portfolio,
500506
tradeType[j]);
501507
Real v = outputCube->getT0(tradeId[j], 0);
502508
outputCube->setT0(v + res[0].at(0) * fx(fxBuffer, currencyIndex[j], 0, 0) *
503-
numRatio(model, irStateBuffer, currencyIndex[j], 0, 0.0, 0) *
504-
effectiveMultiplier[j],
509+
numRatio(model, irStateBuffer, currencyIndex[j], 0, 0.0, 0) *
510+
effectiveMultiplier[j],
505511
tradeId[j], 0);
506-
std::map<QuantLib::Date, size_t> dateIndexCache;
512+
std::map<QuantLib::Date, std::pair<double, size_t>> dateIndexCache;
507513
int dateIndex = -1;
508514
for (Size k = 1; k < res.size(); ++k) {
509515
Real t = sgd->getGrid()->timeGrid()[k];
510516
if (sgd->getGrid()->isCloseOutDate()[k - 1]) {
511-
Date closeOutDate = sgd->getGrid()->dates()[k-1];
517+
Date closeOutDate = sgd->getGrid()->dates()[k - 1];
512518
Date valuationDate = sgd->getGrid()->valuationDateFromCloseOutDate(closeOutDate);
513519
auto dateIndexIt = dateIndexCache.find(valuationDate);
514-
QL_REQUIRE(dateIndexIt != dateIndexCache.end(), "first date in grid must be a valuation date");
520+
QL_REQUIRE(dateIndexIt != dateIndexCache.end(),
521+
"The valuation date (" << ore::data::to_string(valuationDate)
522+
<< ") needs to before the corresponding close out date ("
523+
<< ore::data::to_string(closeOutDate) << ")");
524+
auto [_, timeIndexValueDate] = dateIndexIt->second;
515525
for (Size i = 0; i < outputCube->samples(); ++i) {
516526
Real v = outputCube->get(tradeId[j], dateIndex, i, 1);
517-
outputCube->set(v + res[k][i] * fx(fxBuffer, currencyIndex[j], k, i) *
527+
outputCube->set(v +
528+
res[k][i] * fx(fxBuffer, currencyIndex[j], k, i) *
518529
num(model, irStateBuffer, currencyIndex[j], k, t, i) *
519530
effectiveMultiplier[j] +
520531
resFee[k][i],
521-
tradeId[j], dateIndexIt->second, i, 1);
532+
tradeId[j], timeIndexValueDate, i, 1);
522533
}
523534
}
524535
if (sgd->getGrid()->isValuationDate()[k - 1]) {
525-
Date valuationDate = sgd->getGrid()->dates()[k-1];
536+
Date valuationDate = sgd->getGrid()->dates()[k - 1];
526537
dateIndexCache[valuationDate] = ++dateIndex;
527538
for (Size i = 0; i < outputCube->samples(); ++i) {
528539
Real v = outputCube->get(tradeId[j], dateIndex, i, 0);
529-
outputCube->set(v + res[k][i] * fx(fxBuffer, currencyIndex[j], k, i) *
540+
outputCube->set(v +
541+
res[k][i] * fx(fxBuffer, currencyIndex[j], k, i) *
530542
numRatio(model, irStateBuffer, currencyIndex[j], k, t, i) *
531543
effectiveMultiplier[j] +
532544
resFee[k][i],

OREAnalytics/orea/engine/valuationengine.cpp

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@
2626
#include <ored/portfolio/optionwrapper.hpp>
2727
#include <ored/portfolio/portfolio.hpp>
2828
#include <ored/portfolio/structuredtradeerror.hpp>
29+
#include <ored/utilities/dategrid.hpp>
2930
#include <ored/utilities/log.hpp>
3031
#include <ored/utilities/parsers.hpp>
3132
#include <ored/utilities/progressbar.hpp>
3233
#include <ored/utilities/to_string.hpp>
33-
#include <ored/utilities/dategrid.hpp>
3434

3535
#include <ql/errors.hpp>
3636

@@ -194,14 +194,13 @@ void ValuationEngine::buildCube(const boost::shared_ptr<data::Portfolio>& portfo
194194
Date valueDate = dg_->valuationDates()[i];
195195
Date closeOutDate = dg_->closeOutDates()[i];
196196
std::tie(priceTime, upTime) = populateCube(
197-
valueDate, cubeDateIndex, sample, true, false, scenarioUpdated, trades, tradeHasError,
198-
calculators, outputCube, outputCubeNettingSet, counterparties, cptyCalculators, outputCptyCube);
197+
valueDate, cubeDateIndex, sample, true, false, scenarioUpdated, trades, tradeHasError, calculators,
198+
outputCube, outputCubeNettingSet, counterparties, cptyCalculators, outputCptyCube);
199199
pricingTime += priceTime;
200200
updateTime += upTime;
201-
std::tie(priceTime, upTime) =
202-
populateCube(closeOutDate, cubeDateIndex, sample, false, mporStickyDate, scenarioUpdated,
203-
trades, tradeHasError, calculators, outputCube, outputCubeNettingSet, counterparties,
204-
cptyCalculators, outputCptyCube);
201+
std::tie(priceTime, upTime) = populateCube(
202+
closeOutDate, cubeDateIndex, sample, false, mporStickyDate, scenarioUpdated, trades, tradeHasError,
203+
calculators, outputCube, outputCubeNettingSet, counterparties, cptyCalculators, outputCptyCube);
205204
pricingTime += priceTime;
206205
updateTime += upTime;
207206
}
@@ -210,8 +209,8 @@ void ValuationEngine::buildCube(const boost::shared_ptr<data::Portfolio>& portfo
210209
for (Size i = 0; i < dates.size(); ++i) {
211210
Date d = dates[i];
212211
// Process auxiliary close-out dates first (may coincide with a valuation date, see below)
213-
// Store result at same cubeDateIndex as the corresponding valuation date's result, but at different cube
214-
// depth Differences to valuation date processing above: Update valuation date and fixings, trades
212+
// Store result at same cubeDateIndex as the corresponding valuation date's result, but at different
213+
// cube depth Differences to valuation date processing above: Update valuation date and fixings, trades
215214
// exercisable depending on stickiness
216215
bool scenarioUpdated = false;
217216
if (dg_->isCloseOutDate()[i]) {
@@ -220,8 +219,8 @@ void ValuationEngine::buildCube(const boost::shared_ptr<data::Portfolio>& portfo
220219
Date valueDate = dg_->valuationDateFromCloseOutDate(d);
221220
size_t valueDateIndex = valueDateIndexCache[valueDate];
222221
std::tie(priceTime, upTime) = populateCube(
223-
d, valueDateIndex, sample, false, false, scenarioUpdated, trades, tradeHasError,
224-
calculators, outputCube, outputCubeNettingSet, counterparties, cptyCalculators, outputCptyCube);
222+
d, valueDateIndex, sample, false, false, scenarioUpdated, trades, tradeHasError, calculators,
223+
outputCube, outputCubeNettingSet, counterparties, cptyCalculators, outputCptyCube);
225224
pricingTime += priceTime;
226225
updateTime += upTime;
227226
scenarioUpdated = true;
@@ -232,8 +231,8 @@ void ValuationEngine::buildCube(const boost::shared_ptr<data::Portfolio>& portfo
232231
++cubeDateIndex;
233232
valueDateIndexCache[d] = cubeDateIndex;
234233
std::tie(priceTime, upTime) = populateCube(
235-
d, cubeDateIndex, sample, true, false, scenarioUpdated, trades, tradeHasError,
236-
calculators, outputCube, outputCubeNettingSet, counterparties, cptyCalculators, outputCptyCube);
234+
d, cubeDateIndex, sample, true, false, scenarioUpdated, trades, tradeHasError, calculators,
235+
outputCube, outputCubeNettingSet, counterparties, cptyCalculators, outputCptyCube);
237236
pricingTime += priceTime;
238237
updateTime += upTime;
239238
scenarioUpdated = true;
@@ -287,7 +286,7 @@ void ValuationEngine::runCalculators(bool isCloseOutDate, const std::map<std::st
287286
boost::shared_ptr<analytics::NPVCube>& outputCubeNettingSet, const Date& d,
288287
const Size cubeDateIndex, const Size sample, const string& label) {
289288
ObservationMode::Mode om = ObservationMode::instance().mode();
290-
for(auto& calc: calculators)
289+
for (auto& calc : calculators)
291290
calc->initScenario();
292291
// loop over trades
293292
size_t j = 0;
@@ -350,14 +349,12 @@ std::pair<double, double> ValuationEngine::populateCube(
350349
QL_REQUIRE(cubeDateIndex >= 0, "first date should be a valuation date");
351350
cpu_timer timer;
352351
timer.start();
353-
// All the steps below from preUpdate() to updateAsd(d) are combined in update(d), but we decompose as
354-
// follows simMarket_->update(d);
355352
simMarket_->preUpdate();
356353
if (isValueDate || !isStickyDate) {
357354
simMarket_->updateDate(d);
358355
}
359356
// We can skip this step, if we have done that above in the close-out date section
360-
if (!scenarioUpdated){
357+
if (!scenarioUpdated) {
361358
simMarket_->updateScenario(d);
362359
}
363360
// Always with fixing update here, in contrast to the close-out date section

OREData/ored/utilities/dategrid.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,12 @@ QuantLib::TimeGrid DateGrid::closeOutTimeGrid() const {
296296
return TimeGrid(times.begin(), times.end());
297297
}
298298

299+
QuantLib::Date DateGrid::valuationDateFromCloseOutDate(const QuantLib::Date& closeOutDate) const {
300+
auto it = closeOutToValuation_.find(closeOutDate);
301+
QL_REQUIRE(it != closeOutToValuation_.end(), "close out date " << closeOutDate << " not found in dategrid");
302+
return it->second;
303+
}
304+
299305
boost::shared_ptr<DateGrid> generateShiftedDateGrid(const boost::shared_ptr<DateGrid>& dg,
300306
const QuantLib::Period& shift) {
301307
DLOG("Building shifted date grid with shift of " << shift);

OREData/ored/utilities/dategrid.hpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,9 @@ class DateGrid {
102102
//@}
103103

104104
//! Given a close out date it returns the corresponding value date
105-
QuantLib::Date valuationDateFromCloseOutDate(const QuantLib::Date& closeOutDate) const {
106-
auto it = closeOutToValuation_.find(closeOutDate);
107-
QL_REQUIRE(it != closeOutToValuation_.end(), "close out date " << closeOutDate << " not found in dategrid");
108-
return it->second;
109-
}
105+
QuantLib::Date valuationDateFromCloseOutDate(const QuantLib::Date& closeOutDate) const;
110106
//@}
111107

112-
113108
//! Accessor methods
114109
const QuantLib::Date& operator[](QuantLib::Size i) const { return dates_[i]; };
115110

0 commit comments

Comments
 (0)