Skip to content

Commit fce4a2a

Browse files
author
Damien Barker
committed
QPR-13711 PNL/PNL Explain issues
1 parent b3c608e commit fce4a2a

12 files changed

Lines changed: 60 additions & 32 deletions

OREAnalytics/orea/app/analytics/pnlexplainanalytic.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ void PnlExplainAnalyticImpl::runAnalytic(const QuantLib::ext::shared_ptr<ore::da
135135
t0SimMarket->scenarioGenerator() = sgen;
136136

137137
// use difference scenarios for par sensi pnl explain
138-
zeroScenarios->setGenerateDifferenceScenarios(t0SimMarket->useSpreadedTermStructures());
138+
zeroScenarios->setGenerateDifferenceScenarios(true);
139139

140140
QL_REQUIRE(parSensiAnalysis, "Par Sensi Analysis required");
141141
auto parScenarios = QuantLib::ext::make_shared<ZeroToParScenarioGenerator>(zeroScenarios, t0SimMarket,

OREAnalytics/orea/app/inputparameters.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ class InputParameters {
132132
void setBuildFailedTrades(bool b) { buildFailedTrades_ = b; }
133133
void setObservationModel(const std::string& s) { observationModel_ = s; }
134134
void setImplyTodaysFixings(bool b) { implyTodaysFixings_ = b; }
135+
void setFixingCutOffDate(Date d) { fixingCutOffDate_ = d; }
135136
void setUseAtParCouponsCurves(bool b) { useAtParCouponsCurves_ = b; }
136137
void setUseAtParCouponsTrades(bool b) { useAtParCouponsTrades_ = b; }
137138
void setEnrichIndexFixings(bool b) { enrichIndexFixings_ = b; }
@@ -151,6 +152,8 @@ class InputParameters {
151152
void setConventions(const std::string& xml);
152153
void setConventions(const QuantLib::ext::shared_ptr<Conventions>& convs);
153154
void setConventionsFromFile(const std::string& fileName);
155+
void setMporConventions(const std::string& xml);
156+
void setMporConventionsFromFile(const std::string& fileName);
154157
void setIborFallbackConfig(const std::string& xml);
155158
void setIborFallbackConfigFromFile(const std::string& fileName);
156159
void setBaselTrafficLightConfig(const std::string& xml);
@@ -611,6 +614,7 @@ class InputParameters {
611614
bool buildFailedTrades() const { return buildFailedTrades_; }
612615
const std::string& observationModel() const { return observationModel_; }
613616
bool implyTodaysFixings() const { return implyTodaysFixings_; }
617+
Date fixingCutOffDate() const { return fixingCutOffDate_; }
614618
bool useAtParCouponsCurves() const { return useAtParCouponsCurves_; }
615619
bool useAtParCouponsTrades() const { return useAtParCouponsTrades_; }
616620
bool enrichIndexFixings() const { return enrichIndexFixings_; }
@@ -620,6 +624,7 @@ class InputParameters {
620624
const std::string& marketConfig(const std::string& context);
621625
const QuantLib::ext::shared_ptr<ore::data::BasicReferenceDataManager>& refDataManager() const { return refDataManager_; }
622626
const QuantLib::ext::shared_ptr<ore::data::Conventions>& conventions() const { return conventions_; }
627+
const QuantLib::ext::shared_ptr<ore::data::Conventions>& mporConventions() const { return mporConventions_; }
623628
const QuantLib::ext::shared_ptr<ore::data::IborFallbackConfig>& iborFallbackConfig() const { return iborFallbackConfig_; }
624629
const QuantLib::ext::shared_ptr<ore::data::BaselTrafficLightData>& baselTrafficLightConfig() const { return baselTrafficLightConfig_; }
625630

@@ -1104,6 +1109,7 @@ class InputParameters {
11041109
bool buildFailedTrades_ = true;
11051110
std::string observationModel_ = "None";
11061111
bool implyTodaysFixings_ = false;
1112+
Date fixingCutOffDate_;
11071113
bool useAtParCouponsCurves_ = true;
11081114
bool useAtParCouponsTrades_ = true;
11091115
bool enrichIndexFixings_ = false;
@@ -1117,7 +1123,7 @@ class InputParameters {
11171123
std::map<std::string, std::string> marketConfigs_;
11181124
QuantLib::ext::shared_ptr<ore::data::BasicReferenceDataManager> refDataManager_;
11191125
QuantLib::ext::shared_ptr<ore::data::BaselTrafficLightData> baselTrafficLightConfig_;
1120-
QuantLib::ext::shared_ptr<ore::data::Conventions> conventions_;
1126+
QuantLib::ext::shared_ptr<ore::data::Conventions> conventions_, mporConventions_;
11211127
QuantLib::ext::shared_ptr<ore::data::IborFallbackConfig> iborFallbackConfig_;
11221128
CurveConfigurationsManager curveConfigs_;
11231129
QuantLib::ext::shared_ptr<ore::data::CalendarAdjustmentConfig> calendarAdjustment_;

OREAnalytics/orea/app/marketdatainmemoryloader.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ void MarketDataInMemoryLoaderImpl::retrieveMarketData(
3636
const Date& relabelDate) {
3737

3838
if (inputs_->entireMarket()) {
39-
loadDataFromBuffers(*loader, marketData_, std::vector<std::string>(), inputs_->implyTodaysFixings());
39+
loadDataFromBuffers(*loader, marketData_, std::vector<std::string>(), inputs_->implyTodaysFixings(), inputs_->fixingCutOffDate());
4040
} else {
4141
QL_FAIL("MarketDataInMemoryLoaderImpl::retrieveMarketData() requires inputs_->entireMarket()");
4242
}
@@ -47,7 +47,8 @@ void MarketDataInMemoryLoaderImpl::retrieveFixings(const QuantLib::ext::shared_p
4747
map<pair<string, Date>, set<Date>> lastAvailableFixingLookupMap) {
4848

4949
if (inputs_->allFixings()) {
50-
loadDataFromBuffers(*loader, std::vector<std::string>(), fixingData_, inputs_->implyTodaysFixings());
50+
loadDataFromBuffers(*loader, std::vector<std::string>(), fixingData_, inputs_->implyTodaysFixings(),
51+
inputs_->fixingCutOffDate());
5152
} else {
5253
QL_FAIL("MarketDataInMemoryLoaderImpl::retrieveFixings() requires inputs_->allFixings()");
5354
}

OREAnalytics/orea/app/oreapp.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,8 @@ void OREApp::initFromInputs() {
413413
// Initialise Singletons
414414
Settings::instance().evaluationDate() = inputs_->asof();
415415
InstrumentConventions::instance().setConventions(inputs_->conventions());
416+
if (inputs_->mporConventions() && inputs_->mporDate() != Date())
417+
InstrumentConventions::instance().setConventions(inputs_->mporConventions(), inputs_->mporDate());
416418

417419
if (inputs_->currencyConfigs() != nullptr)
418420
inputs_->currencyConfigs()->addCurrencies();
@@ -752,6 +754,10 @@ void OREAppInputParameters::loadParameters() {
752754
if (tmp != "")
753755
setImplyTodaysFixings(ore::data::parseBool(tmp));
754756

757+
tmp = params_->get("setup", "fixingCutOffDate", false);
758+
if (tmp != "")
759+
setFixingCutOffDate(ore::data::parseDate(tmp));
760+
755761
tmp = params_->get("setup", "useAtParCouponsCurves", false);
756762
if (tmp != "")
757763
setUseAtParCouponsCurves(ore::data::parseBool(tmp));

OREAnalytics/orea/engine/parsensitivityinstrumentbuilder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ void ParSensitivityInstrumentBuilder::createParInstruments(
175175
SensitivityScenarioData::CurveShiftParData data =
176176
*QuantLib::ext::dynamic_pointer_cast<SensitivityScenarioData::CurveShiftParData>(c.second);
177177
LOG("ParSensitivityAnalysis: Discount curve ccy=" << ccy);
178-
Size n_ten = data.shiftTenors.size();
178+
Size n_ten = data.shiftTenors.size();
179179
QL_REQUIRE(data.parInstruments.size() == n_ten,
180180
"ParSensitivityInstrumentBuilder::createParInstruments(): number of tenors does not match "
181181
"number of discount curve par instruments, "

OREAnalytics/orea/scenario/historicalscenariogenerator.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class HistoricalScenarioGenerator : public ScenarioGenerator {
100100
const QuantLib::ext::shared_ptr<ore::data::AdjustmentFactors>& adjFactors = nullptr,
101101
//! string prepended to label of all scenarios generated
102102
const std::string& labelPrefix = "",
103-
//! indicates if the generated sceanrios will be absolute or difference
103+
//! indicates if the generated scenarios will be absolute or difference
104104
const bool generateDifferenceScenarios = false);
105105

106106
//! Set base scenario, this also defines the asof date

OREAnalytics/orea/scenario/scenarioutilities.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,10 +188,11 @@ QuantLib::ext::shared_ptr<Scenario> getDifferenceScenario(const QuantLib::ext::s
188188
QuantLib::ext::shared_ptr<Scenario> addDifferenceToScenario(const QuantLib::ext::shared_ptr<Scenario>& s,
189189
const QuantLib::ext::shared_ptr<Scenario>& d,
190190
const QuantLib::Date& targetScenarioAsOf,
191-
const QuantLib::Real targetScenarioNumeraire) {
191+
const QuantLib::Real targetScenarioNumeraire,
192+
const bool allowAdditionalKeysInD) {
192193

193194
QL_REQUIRE(!d->isAbsolute(), "addDifferenceToScenario(): second argument must be difference scenario");
194-
QL_REQUIRE(checkKeyDifferences(s, d, false),
195+
QL_REQUIRE(checkKeyDifferences(s, d, allowAdditionalKeysInD),
195196
"addDifferenceToScenario(): scenario key sets are not compatible. Check log for details.");
196197

197198
QuantLib::Date asof = targetScenarioAsOf;

OREAnalytics/orea/scenario/scenarioutilities.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ QuantLib::Real addDifferenceToScenario(const RiskFactorKey::KeyType keyType, con
4646
QuantLib::ext::shared_ptr<Scenario> addDifferenceToScenario(const QuantLib::ext::shared_ptr<Scenario>& s,
4747
const QuantLib::ext::shared_ptr<Scenario>& d,
4848
const QuantLib::Date& targetScenarioAsOf = QuantLib::Date(),
49-
const QuantLib::Real targetScenarioNumeraire = 0.0);
49+
const QuantLib::Real targetScenarioNumeraire = 0.0,
50+
const bool allowAdditionalKeysInD = false);
5051

5152
QuantLib::ext::shared_ptr<Scenario>
5253
recastScenario(const QuantLib::ext::shared_ptr<Scenario>& scenario,

OREAnalytics/orea/scenario/zerotoparscenariogenerator.cpp

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,32 +33,41 @@ ZeroToParScenarioGenerator::ZeroToParScenarioGenerator(
3333
: HistoricalScenarioGenerator(hsg->scenarioLoader(), hsg->scenarioFactory(), hsg->returnConfiguration(),
3434
hsg->adjFactors(), hsg->labelPrefix(), hsg->generateDifferenceScenarios()) {
3535

36-
baseScenario_ = hsg->baseScenario();
36+
auto bs = hsg->baseScenario();
3737
shiftConverter_ = QuantLib::ext::make_shared<ZeroToParShiftConverter>(parInstruments, simMarket);
3838
auto baseValues = shiftConverter_->baseValues();
3939

40-
// build a base par scenario off the zero base scenario, and update with the calculated par rates
41-
baseParScenario_ = baseScenario_->clone();
40+
// build a base and base par scenario off the zero base scenario, and update with the calculated par rates
41+
// base scenario must be the minimum of the simulation (hsg baseScenario) and sensitivity configuration
42+
baseScenario_ = QuantLib::ext::make_shared<SimpleScenario>(bs->asof(), bs->label(), bs->getNumeraire());
43+
baseParScenario_ = QuantLib::ext::make_shared<SimpleScenario>(bs->asof(), bs->label(), bs->getNumeraire());
4244
baseParScenario_->setPar(true);
43-
for (const auto& kv : baseValues)
44-
baseParScenario_->add(kv.first, kv.second);
45+
for (const auto& kv : baseValues) {
46+
if (bs->has(kv.first)) {
47+
baseScenario_->add(kv.first, bs->get(kv.first));
48+
baseParScenario_->add(kv.first, kv.second);
49+
}
50+
}
4551
}
4652

4753
QuantLib::ext::shared_ptr<Scenario> ZeroToParScenarioGenerator::next(const Date& d) {
4854
auto zeroScenario = HistoricalScenarioGenerator::next(d);
4955

5056
// create a par scenario to hold the par shifts
51-
QuantLib::ext::shared_ptr<Scenario> parScenario =
52-
addDifferenceToScenario(baseScenario_, zeroScenario, d, baseScenario_->getNumeraire());
57+
QuantLib::ext::shared_ptr<Scenario> parScenario = QuantLib::ext::make_shared<SimpleScenario>(
58+
baseScenario_->asof(), baseScenario_->label(), baseScenario_->getNumeraire());
5359
parScenario->setPar(true);
60+
parScenario->label(zeroScenario->label());
5461

5562
// get the par shifts and update the par scenario
5663
auto parShifts = shiftConverter_->parShifts(zeroScenario);
5764
auto baseRates = shiftConverter_->baseValues();
5865

5966
for (const auto& kv : parShifts) {
60-
auto base = baseRates[kv.first];
61-
parScenario->add(kv.first, base + kv.second);
67+
if (baseScenario_->has(kv.first)) {
68+
auto base = baseRates[kv.first];
69+
parScenario->add(kv.first, base + kv.second);
70+
}
6271
}
6372

6473
return parScenario;

OREData/ored/marketdata/csvloader.hpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,17 @@ class CSVLoader : public Loader {
4949
const string& fixingFilename,
5050
//! Enable/disable implying today's fixings
5151
bool implyTodaysFixings = false,
52-
//! Load fixings up to this date
53-
Date fixingCutOffDate = Date());
52+
//! Load fixings up to this date
53+
Date fixingCutOffDate = Date());
5454

5555
CSVLoader( //! Quote file name
5656
const vector<string>& marketFiles,
5757
//! Fixing file name
5858
const vector<string>& fixingFiles,
5959
//! Enable/disable implying today's fixings
6060
bool implyTodaysFixings = false,
61-
//! Load fixings up to this date
62-
Date fixingCutOffDate = Date());
61+
//! Load fixings up to this date
62+
Date fixingCutOffDate = Date());
6363

6464
CSVLoader( //! Quote file name
6565
const string& marketFilename,
@@ -69,8 +69,8 @@ class CSVLoader : public Loader {
6969
const string& dividendFilename,
7070
//! Enable/disable implying today's fixings
7171
bool implyTodaysFixings = false,
72-
//! Load fixings up to this date
73-
Date fixingCutOffDate = Date());
72+
//! Load fixings up to this date
73+
Date fixingCutOffDate = Date());
7474

7575
CSVLoader( //! Quote file name
7676
const vector<string>& marketFiles,
@@ -80,8 +80,8 @@ class CSVLoader : public Loader {
8080
const vector<string>& dividendFiles,
8181
//! Enable/disable implying today's fixings
8282
bool implyTodaysFixings = false,
83-
//! Load fixings up to this date
84-
Date fixingCutOffDate = Date());
83+
//! Load fixings up to this date
84+
Date fixingCutOffDate = Date());
8585

8686
std::vector<QuantLib::ext::shared_ptr<MarketDatum>> loadQuotes(const QuantLib::Date&) const override;
8787

0 commit comments

Comments
 (0)