30using namespace boost::filesystem;
36 std::map<RiskFactorKey, std::string> descriptions;
37 auto sensiScenGen = QuantLib::ext::dynamic_pointer_cast<SensitivityScenarioGenerator>(scenGen);
39 for (
const auto& desc : sensiScenGen->scenarioDescriptions()) {
40 descriptions[desc.key1()] = desc.indexDesc1();
55 const std::set<std::string>& runTypes) {
59 LOG(
"ParConversionAnalytic::runAnalytic called");
65 QL_REQUIRE(parConversionAnalytic,
"ParConversionAnalyticImpl internal error, can not convert analytic() to ParConversionAnalytic");
67 auto zeroSensis = parConversionAnalytic->loadZeroSensitivities();
69 if (!zeroSensis.empty()) {
72 auto parAnalysis = QuantLib::ext::make_shared<ParSensitivityAnalysis>(
76 if (
inputs_->parConversionAlignPillars()) {
77 LOG(
"Sensi analysis - align pillars (for the par conversion or because alignPillars is enabled)");
78 parAnalysis->alignPillars();
80 LOG(
"Sensi analysis - skip aligning pillars");
85 auto simMarket = QuantLib::ext::make_shared<ScenarioSimMarket>(
86 analytic()->market(), configs.simMarketParams,
inputs_->marketConfig(
"pricing"),
89 configs.sensiScenarioData->useSpreadedTermStructures(),
false,
false, *
inputs_->iborFallbackConfig());
91 auto scenarioGenerator = QuantLib::ext::make_shared<SensitivityScenarioGenerator>(
92 configs.sensiScenarioData, simMarket->baseScenario(), configs.simMarketParams, simMarket,
93 QuantLib::ext::make_shared<DeltaScenarioFactory>(simMarket->baseScenario()),
true, std::string(),
true,
94 simMarket->baseScenarioAbsolute());
96 simMarket->scenarioGenerator() = scenarioGenerator;
98 parAnalysis->computeParInstrumentSensitivities(simMarket);
100 QuantLib::ext::shared_ptr<ParSensitivityConverter> parConverter =
101 QuantLib::ext::make_shared<ParSensitivityConverter>(parAnalysis->parSensitivities(), parAnalysis->shiftSizes());
103 map<RiskFactorKey, Size> factorToIndex;
105 auto shiftSizes = parAnalysis->shiftSizes();
108 for (
auto const& k : parConverter->rawKeys()) {
109 factorToIndex[k] = counter++;
112 std::vector<SensitivityRecord> results;
115 for (
const auto& [
id, sensis] : zeroSensis) {
116 boost::numeric::ublas::vector<Real> zeroDeltas(parConverter->rawKeys().size(), 0.0);
117 std::vector<SensitivityRecord> excludedDeltas;
119 for (
const auto& zero : sensis) {
120 if (zero.currency != configs.simMarketParams->baseCcy()) {
122 ALOG(
"Currency in the sensitivity input and config aren't consistent. Skip trade " <<
id);
127 auto it = factorToIndex.find(rf);
128 if (it == factorToIndex.end()) {
133 " not found in factorToIndex map")
141 sr.
delta = zero.delta;
145 sr.
gamma = QuantLib::Null<QuantLib::Real>();
146 excludedDeltas.push_back(sr);
149 auto shiftSize = shiftSizes.find(rf);
150 if (shiftSize == shiftSizes.end() || !
close_enough(shiftSize->second.first, zero.shiftSize)) {
152 ALOG(
"Shift sizes in the sensitivity input and config aren't consistent. Skip trade "
157 zeroDeltas[it->second] = zero.delta;
161 if (!sensis.empty() && valid) {
162 boost::numeric::ublas::vector<Real> parDeltas = parConverter->convertSensitivity(zeroDeltas);
164 for (
const auto& key : parConverter->parKeys()) {
165 if (!
close(parDeltas[counter], 0.0)) {
170 sr.
desc_1 = descriptions[key];
171 sr.
delta = parDeltas[counter];
172 sr.
baseNpv = sensis.begin()->baseNpv;
173 sr.
currency = sensis.begin()->currency;
174 sr.
shift_1 = shiftSizes[key].second;
175 sr.
gamma = QuantLib::Null<QuantLib::Real>();
176 results.push_back(sr);
180 results.insert(results.end(), excludedDeltas.begin(), excludedDeltas.end());
184 auto ss = QuantLib::ext::make_shared<SensitivityInMemoryStream>(results.begin(), results.end());
185 QuantLib::ext::shared_ptr<InMemoryReport> report = QuantLib::ext::make_shared<InMemoryReport>();
187 analytic()->
reports()[
"PARCONVERSION"][
"parConversionSensitivity"] = report;
189 if (
inputs_->parConversionOutputJacobi()) {
190 QuantLib::ext::shared_ptr<InMemoryReport> jacobiReport = QuantLib::ext::make_shared<InMemoryReport>();
192 analytic()->
reports()[
"PARCONVERSION"][
"parConversionJacobi"] = jacobiReport;
194 QuantLib::ext::shared_ptr<InMemoryReport> jacobiInverseReport = QuantLib::ext::make_shared<InMemoryReport>();
195 parConverter->writeConversionMatrix(*jacobiInverseReport);
196 analytic()->
reports()[
"PARCONVERSION"][
"parConversionJacobi_inverse"] = jacobiInverseReport;
199 LOG(
"Sensi Analysis - Completed");
Analytic * analytic() const
QuantLib::ext::shared_ptr< InputParameters > inputs_
analytic_reports & reports()
Result reports.
Configurations & configurations()
virtual void buildMarket(const QuantLib::ext::shared_ptr< ore::data::InMemoryLoader > &loader, const bool marketRequired=true)
void setUpConfigurations() override
void runAnalytic(const QuantLib::ext::shared_ptr< ore::data::InMemoryLoader > &loader, const std::set< std::string > &runTypes={}) override
static bool isParType(ore::analytics::RiskFactorKey::KeyType type)
Returns true if risk factor type is applicable for par conversion.
Write ORE outputs to reports.
virtual void writeSensitivityReport(ore::data::Report &report, const QuantLib::ext::shared_ptr< SensitivityStream > &ss, QuantLib::Real outputThreshold=0.0, QuantLib::Size outputPrecision=2)
static const string defaultConfiguration
factory class for cloning a cached scenario
Filter close_enough(const RandomVariable &x, const RandomVariable &y)
bool close(const Real &t_1, const Real &t_2)
void writeParConversionMatrix(const ParSensitivityAnalysis::ParContainer &parSensitivities, Report &report)
Write par instrument sensitivity report.
std::map< RiskFactorKey, std::string > getScenarioDescriptions(QuantLib::ext::shared_ptr< ScenarioGenerator > scenGen)
pair< RiskFactorKey, string > deconstructFactor(const string &factor)
std::string to_string(const LocationInfo &l)
Perfrom sensitivity analysis for a given portfolio.
A Class to write ORE outputs to reports.
Class for streaming SensitivityRecords from in-memory container.
Shift scenario generation.
QuantLib::ext::shared_ptr< ore::analytics::SensitivityScenarioData > sensiScenarioData
QuantLib::ext::shared_ptr< ore::data::EngineData > engineData
QuantLib::ext::shared_ptr< ore::data::TodaysMarketParameters > todaysMarketParams
QuantLib::ext::shared_ptr< ore::analytics::ScenarioSimMarketParameters > simMarketParams
Structured analytics error.