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

Class that wraps a sensitivity stream and decompose default, equity and commodity risk records given weights. More...

#include <orea/engine/decomposedsensitivitystream.hpp>

+ Inheritance diagram for DecomposedSensitivityStream:
+ Collaboration diagram for DecomposedSensitivityStream:

Classes

struct  IndexDecompositionResult
 

Public Member Functions

 DecomposedSensitivityStream (const QuantLib::ext::shared_ptr< SensitivityStream > &ss, const std::string &baseCurrency, std::map< std::string, std::map< std::string, double > > defaultRiskDecompositionWeights={}, const std::set< std::string > &eqComDecompositionTradeIds={}, const std::map< std::string, std::map< std::string, double > > &currencyHedgedIndexQuantities={}, const QuantLib::ext::shared_ptr< ore::data::ReferenceDataManager > &refDataManager=nullptr, const QuantLib::ext::shared_ptr< ore::data::CurveConfigurations > &curveConfigs=nullptr, const QuantLib::ext::shared_ptr< SensitivityScenarioData > &scenarioData=nullptr, const QuantLib::ext::shared_ptr< ore::data::Market > &todaysMarket=nullptr)
 
SensitivityRecord next () override
 Returns the next SensitivityRecord in the stream after filtering. More...
 
void reset () override
 Resets the stream so that SensitivityRecord objects can be streamed again. More...
 
- Public Member Functions inherited from SensitivityStream
virtual ~SensitivityStream ()
 Destructor. More...
 
virtual SensitivityRecord next ()=0
 Returns the next SensitivityRecord in the stream. More...
 
virtual void reset ()=0
 Resets the stream so that SensitivityRecord objects can be streamed again. More...
 

Private Member Functions

std::map< std::string, double > constituentSpotRiskFromDecomposition (const double spotDelta, const std::map< std::string, double > &indexWeights) const
 Decompose a equity/commodity spot sensitivity into the constituent spot sensistivities. More...
 
std::map< std::string, double > fxRiskFromDecomposition (const std::map< std::string, double > &spotRisk, const std::map< std::string, std::vector< std::string > > &constituentCurrencies, const std::map< std::string, double > &fxSpotShiftSize, const double eqShiftSize) const
 Compute the resulting fx risks from a given equity/commodity decomposition. More...
 
double fxRiskShiftSize (const std::string ccy) const
 Return the sensi shift size for the shifting the ccy-baseCurrency spot quote. More...
 
std::map< std::string, double > fxRiskShiftSizes (const std::map< std::string, std::vector< std::string > > &constituentCurrencies) const
 Returns the shift sizes for all currencies in the map. More...
 
double assetSpotShiftSize (const std::string name, const ore::data::CurveSpec::CurveType curveType) const
 Return the asset spot shift size. More...
 
double equitySpotShiftSize (const std::string name) const
 
double commoditySpotShiftSize (const std::string name) const
 
std::map< std::string, std::vector< std::string > > getConstituentCurrencies (const std::map< std::string, double > &constituents, const std::string &indexCurrency, const ore::data::CurveSpec::CurveType curveType) const
 
std::vector< SensitivityRecorddecompose (const SensitivityRecord &record) const
 Decompose the record and add it to the internal storage;. More...
 
std::vector< SensitivityRecorddecomposeSurvivalProbability (const SensitivityRecord &record) const
 
std::vector< SensitivityRecorddecomposeCurrencyHedgedIndexRisk (const SensitivityRecord &record) const
 
IndexDecompositionResult indexDecomposition (double delta, const std::string &indexName, const ore::data::CurveSpec::CurveType curveType) const
 
std::vector< SensitivityRecordsensitivityRecords (const std::map< std::string, double > &eqDeltas, const std::map< std::string, double > &fxDeltas, const std::string indexCurrency, const SensitivityRecord &orginialRecord) const
 
std::string curveCurrency (const std::string &name, ore::data::CurveSpec::CurveType curveType) const
 

Private Attributes

std::vector< SensitivityRecorddecomposedRecords_
 
std::vector< SensitivityRecord >::iterator itCurrent_
 
QuantLib::ext::shared_ptr< SensitivityStreamss_
 The underlying sensitivity stream that has been wrapped. More...
 
std::string baseCurrency_
 
std::map< std::string, std::map< std::string, double > > defaultRiskDecompositionWeights_
 map of trade ids to the basket consituents with their resp. weights More...
 
std::set< std::string > eqComDecompositionTradeIds_
 list of trade id, for which a equity index decomposition should be applied More...
 
std::map< std::string, std::map< std::string, double > > currencyHedgedIndexQuantities_
 list of trade id, for which a commodity index decomposition should be applied More...
 
QuantLib::ext::shared_ptr< ore::data::ReferenceDataManagerrefDataManager_
 refDataManager holding the equity and commodity index decomposition weights More...
 
QuantLib::ext::shared_ptr< ore::data::CurveConfigurationscurveConfigs_
 
QuantLib::ext::shared_ptr< SensitivityScenarioDatassd_
 
QuantLib::ext::shared_ptr< ore::data::MarkettodaysMarket_
 
bool decompose_
 

Detailed Description

Class that wraps a sensitivity stream and decompose default, equity and commodity risk records given weights.

Definition at line 38 of file decomposedsensitivitystream.hpp.

Constructor & Destructor Documentation

◆ DecomposedSensitivityStream()

DecomposedSensitivityStream ( const QuantLib::ext::shared_ptr< SensitivityStream > &  ss,
const std::string &  baseCurrency,
std::map< std::string, std::map< std::string, double > >  defaultRiskDecompositionWeights = {},
const std::set< std::string > &  eqComDecompositionTradeIds = {},
const std::map< std::string, std::map< std::string, double > > &  currencyHedgedIndexQuantities = {},
const QuantLib::ext::shared_ptr< ore::data::ReferenceDataManager > &  refDataManager = nullptr,
const QuantLib::ext::shared_ptr< ore::data::CurveConfigurations > &  curveConfigs = nullptr,
const QuantLib::ext::shared_ptr< SensitivityScenarioData > &  scenarioData = nullptr,
const QuantLib::ext::shared_ptr< ore::data::Market > &  todaysMarket = nullptr 
)

Constructor providing the weights for the credit index decomposition and the ids and reference data used for

Definition at line 30 of file decomposedsensitivitystream.cpp.

39 : ss_(ss), baseCurrency_(baseCurrency), defaultRiskDecompositionWeights_(defaultRiskDecompositionWeights),
40 eqComDecompositionTradeIds_(eqComDecompositionTradeIds),
41 currencyHedgedIndexQuantities_(currencyHedgedIndexQuantities), refDataManager_(refDataManager),
42 curveConfigs_(curveConfigs), ssd_(scenarioData), todaysMarket_(todaysMarket) {
43 reset();
45}
QuantLib::ext::shared_ptr< ore::data::CurveConfigurations > curveConfigs_
QuantLib::ext::shared_ptr< ore::data::Market > todaysMarket_
QuantLib::ext::shared_ptr< SensitivityScenarioData > ssd_
QuantLib::ext::shared_ptr< SensitivityStream > ss_
The underlying sensitivity stream that has been wrapped.
QuantLib::ext::shared_ptr< ore::data::ReferenceDataManager > refDataManager_
refDataManager holding the equity and commodity index decomposition weights
std::map< std::string, std::map< std::string, double > > currencyHedgedIndexQuantities_
list of trade id, for which a commodity index decomposition should be applied
void reset() override
Resets the stream so that SensitivityRecord objects can be streamed again.
std::set< std::string > eqComDecompositionTradeIds_
list of trade id, for which a equity index decomposition should be applied
std::map< std::string, std::map< std::string, double > > defaultRiskDecompositionWeights_
map of trade ids to the basket consituents with their resp. weights
+ Here is the call graph for this function:

Member Function Documentation

◆ next()

SensitivityRecord next ( )
overridevirtual

Returns the next SensitivityRecord in the stream after filtering.

Implements SensitivityStream.

Definition at line 48 of file decomposedsensitivitystream.cpp.

48 {
49 if (!decompose_)
50 return ss_->next();
51 // No decomposed records left, so continue to the next record
52 if (itCurrent_ == decomposedRecords_.end()) {
55 }
56 return *(itCurrent_++);
57}
std::vector< SensitivityRecord > decompose(const SensitivityRecord &record) const
Decompose the record and add it to the internal storage;.
std::vector< SensitivityRecord >::iterator itCurrent_
+ Here is the call graph for this function:

◆ reset()

void reset ( )
overridevirtual

Resets the stream so that SensitivityRecord objects can be streamed again.

Implements SensitivityStream.

Definition at line 319 of file decomposedsensitivitystream.cpp.

319 {
320 ss_->reset();
321 decomposedRecords_.clear();
323}
+ Here is the caller graph for this function:

◆ constituentSpotRiskFromDecomposition()

std::map< std::string, double > constituentSpotRiskFromDecomposition ( const double  spotDelta,
const std::map< std::string, double > &  indexWeights 
) const
private

Decompose a equity/commodity spot sensitivity into the constituent spot sensistivities.

Decompose.

Definition at line 133 of file decomposedsensitivitystream.cpp.

134 {
135 std::map<std::string, double> results;
136 for (const auto& [constituent, weight] : indexWeights) {
137 results[constituent] = weight * spotDelta;
138 }
139 return results;
140}
+ Here is the caller graph for this function:

◆ fxRiskFromDecomposition()

std::map< std::string, double > fxRiskFromDecomposition ( const std::map< std::string, double > &  spotRisk,
const std::map< std::string, std::vector< std::string > > &  constituentCurrencies,
const std::map< std::string, double > &  fxSpotShiftSize,
const double  eqShiftSize 
) const
private

Compute the resulting fx risks from a given equity/commodity decomposition.

Definition at line 142 of file decomposedsensitivitystream.cpp.

145 {
146 std::map<std::string, double> results;
147 for (const auto& [currency, constituents] : constituentCurrencies) {
148 if (currency != baseCurrency_) {
149 QL_REQUIRE(fxSpotShiftSize.count(currency) == 1, "Can not find fxSpotShiftSize for currency " << currency);
150 for (const auto& constituent : constituents) {
151 QL_REQUIRE(spotRisk.count(constituent) == 1, "Can not find spotDelta for " << constituent);
152 results[currency] += spotRisk.at(constituent) * fxSpotShiftSize.at(currency) / eqShiftSize;
153 }
154 }
155 }
156 return results;
157}
+ Here is the caller graph for this function:

◆ fxRiskShiftSize()

double fxRiskShiftSize ( const std::string  ccy) const
private

Return the sensi shift size for the shifting the ccy-baseCurrency spot quote.

Definition at line 159 of file decomposedsensitivitystream.cpp.

159 {
160 auto fxpair = ccy + baseCurrency_;
161 auto fxShiftSizeIt = ssd_->fxShiftData().find(fxpair);
162 QL_REQUIRE(fxShiftSizeIt != ssd_->fxShiftData().end(), "Couldn't find shiftsize for " << fxpair);
163 QL_REQUIRE(fxShiftSizeIt->second.shiftType == ore::analytics::ShiftType::Relative,
164 "Requires a relative fxSpot shift for index decomposition");
165 return fxShiftSizeIt->second.shiftSize;
166}
+ Here is the caller graph for this function:

◆ fxRiskShiftSizes()

std::map< std::string, double > fxRiskShiftSizes ( const std::map< std::string, std::vector< std::string > > &  constituentCurrencies) const
private

Returns the shift sizes for all currencies in the map.

Definition at line 169 of file decomposedsensitivitystream.cpp.

169 {
170 std::map<std::string, double> results;
171 for (const auto& [ccy,_] : currencies) {
172 if (ccy != baseCurrency_) {
173 double shiftSize = fxRiskShiftSize(ccy);
174 results[ccy] = shiftSize;
175 }
176 }
177 return results;
178}
double fxRiskShiftSize(const std::string ccy) const
Return the sensi shift size for the shifting the ccy-baseCurrency spot quote.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ assetSpotShiftSize()

double assetSpotShiftSize ( const std::string  name,
const ore::data::CurveSpec::CurveType  curveType 
) const
private

Return the asset spot shift size.

Definition at line 188 of file decomposedsensitivitystream.cpp.

189 {
190 if (curveType == ore::data::CurveSpec::CurveType::Equity) {
191 return equitySpotShiftSize(indexName);
192 } else if (curveType == ore::data::CurveSpec::CurveType::Commodity) {
193 return commoditySpotShiftSize(indexName);
194 } else {
195 QL_FAIL("unsupported curveType, got "
196 << curveType << ". Only Equity and Commodity curves are supported for decomposition.");
197 }
198}
double commoditySpotShiftSize(const std::string name) const
double equitySpotShiftSize(const std::string name) const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ equitySpotShiftSize()

double equitySpotShiftSize ( const std::string  name) const
private

Definition at line 180 of file decomposedsensitivitystream.cpp.

180 {
181 auto eqShiftSizeIt = ssd_->equityShiftData().find(name);
182 QL_REQUIRE(eqShiftSizeIt != ssd_->equityShiftData().end(), "Couldn't find a equity shift size for " << name);
183 QL_REQUIRE(eqShiftSizeIt->second.shiftType == ore::analytics::ShiftType::Relative,
184 "Requires a relative eqSpot shift for index decomposition");
185 return eqShiftSizeIt->second.shiftSize;
186}
+ Here is the caller graph for this function:

◆ commoditySpotShiftSize()

double commoditySpotShiftSize ( const std::string  name) const
private

Definition at line 200 of file decomposedsensitivitystream.cpp.

200 {
201 auto commShiftSizeIt = ssd_->commodityCurveShiftData().find(name);
202 if (commShiftSizeIt != ssd_->commodityCurveShiftData().end()) {
203 QL_REQUIRE(commShiftSizeIt->second->shiftType == ore::analytics::ShiftType::Relative,
204 "Requires a relative eqSpot shift for index decomposition");
205 return commShiftSizeIt->second->shiftSize;
206 } else {
207 LOG("Could not find a commodity shift size for commodity index "
208 << name << ". Try to find a equity spot shift size as fallback")
209 return equitySpotShiftSize(name);
210 }
211}
#define LOG(text)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getConstituentCurrencies()

std::map< std::string, std::vector< std::string > > getConstituentCurrencies ( const std::map< std::string, double > &  constituents,
const std::string &  indexCurrency,
const ore::data::CurveSpec::CurveType  curveType 
) const
private

Definition at line 214 of file decomposedsensitivitystream.cpp.

216 {
217 std::map<std::string, std::vector<std::string>> results;
218 for (const auto& [constituent, _] : constituents) {
219 auto ccy = curveCurrency(constituent, curveType);
220 if (ccy.empty()) {
221 ccy = indexCurrency;
222 StructuredAnalyticsErrorMessage("CRIF Generation", "Equity index decomposition",
223 "Cannot find currency for equity " + constituent +
224 " from curve configs, fallback to use index currency (" +
225 indexCurrency + ")")
226 .log();
227 }
228 if (ccy != baseCurrency_) {
229 results[ccy].push_back(constituent);
230 }
231
232 }
233 return results;
234}
std::string curveCurrency(const std::string &name, ore::data::CurveSpec::CurveType curveType) const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ decompose()

std::vector< SensitivityRecord > decompose ( const SensitivityRecord record) const
private

Decompose the record and add it to the internal storage;.

Definition at line 59 of file decomposedsensitivitystream.cpp.

59 {
60 std::vector<SensitivityRecord> results;
61
62 bool tradeMarkedForDecompositionDefaultRisk =
64 bool tradeMarkedForDecomposition =
65 eqComDecompositionTradeIds_.find(record.tradeId) != eqComDecompositionTradeIds_.end();
66 bool isNotCrossGamma = record.isCrossGamma() == false;
67 bool isSurvivalProbSensi = record.key_1.keytype == RiskFactorKey::KeyType::SurvivalProbability;
68 bool isEquitySpotSensi = record.key_1.keytype == RiskFactorKey::KeyType::EquitySpot;
69 bool isCommoditySpotSensi = record.key_1.keytype == RiskFactorKey::KeyType::CommodityCurve;
70
71 bool decomposeEquitySpot = tradeMarkedForDecomposition && isEquitySpotSensi && refDataManager_ != nullptr &&
72 refDataManager_->hasData("EquityIndex", record.key_1.name);
73 bool decomposeCurrencyHedgedSpot = tradeMarkedForDecomposition && isEquitySpotSensi && refDataManager_ != nullptr &&
74 refDataManager_->hasData("CurrencyHedgedEquityIndex", record.key_1.name);
75 bool decomposeCommoditySpot = tradeMarkedForDecomposition && (isCommoditySpotSensi || isEquitySpotSensi) &&
76 refDataManager_ != nullptr &&
77 refDataManager_->hasData("CommodityIndex", record.key_1.name);
78
79 try {
80 if (tradeMarkedForDecompositionDefaultRisk && isSurvivalProbSensi && isNotCrossGamma) {
81 return decomposeSurvivalProbability(record);
82 } else if (decomposeEquitySpot && isNotCrossGamma) {
83 auto decompResults =
84 indexDecomposition(record.delta, record.key_1.name, ore::data::CurveSpec::CurveType::Equity);
85 return sensitivityRecords(decompResults.spotRisk, decompResults.fxRisk, decompResults.indexCurrency,
86 record);
87 } else if (decomposeCurrencyHedgedSpot && isNotCrossGamma) {
89 } else if (decomposeCommoditySpot && isNotCrossGamma) {
90 auto decompResults =
91 indexDecomposition(record.delta, record.key_1.name, ore::data::CurveSpec::CurveType::Commodity);
92 return sensitivityRecords(decompResults.spotRisk, decompResults.fxRisk, decompResults.indexCurrency,
93 record);
94 } else if (tradeMarkedForDecomposition && (isCommoditySpotSensi || isEquitySpotSensi) && isNotCrossGamma) {
95 auto subFields = std::map<std::string, std::string>({{"tradeId", record.tradeId}});
96 StructuredAnalyticsErrorMessage(
97 "Sensitivity Decomposition", "Index decomposition failed",
98 "Cannot decompose equity index delta (" + record.key_1.name +
99 ") for trade: no reference data found. Continuing without decomposition.",
100 subFields)
101 .log();
102 }
103 } catch (const std::exception& e) {
104 auto subFields = std::map<std::string, std::string>({{"tradeId", record.tradeId}});
105 StructuredAnalyticsErrorMessage(
106 "Sensitivity Decomposition", "Index decomposition failed",
107 "Cannot decompose equity index delta (" + record.key_1.name + ") for trade:" + e.what(), subFields)
108 .log();
109 } catch (...) {
110 auto subFields = std::map<std::string, std::string>({{"tradeId", record.tradeId}});
111 StructuredAnalyticsErrorMessage(
112 "Sensitivity Decomposition", "Index decomposition failed",
113 "Cannot decompose equity index delta (" + record.key_1.name + ") for trade: unkown error", subFields)
114 .log();
115 }
116 return {record};
117}
IndexDecompositionResult indexDecomposition(double delta, const std::string &indexName, const ore::data::CurveSpec::CurveType curveType) const
std::vector< SensitivityRecord > decomposeSurvivalProbability(const SensitivityRecord &record) const
std::vector< SensitivityRecord > decomposeCurrencyHedgedIndexRisk(const SensitivityRecord &record) const
std::vector< SensitivityRecord > sensitivityRecords(const std::map< std::string, double > &eqDeltas, const std::map< std::string, double > &fxDeltas, const std::string indexCurrency, const SensitivityRecord &orginialRecord) const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ decomposeSurvivalProbability()

std::vector< SensitivityRecord > decomposeSurvivalProbability ( const SensitivityRecord record) const
private

Definition at line 120 of file decomposedsensitivitystream.cpp.

120 {
121 std::vector<SensitivityRecord> results;
122 auto decompRecord = record;
123 for (const auto& [constituent, weight] : defaultRiskDecompositionWeights_.at(record.tradeId)) {
124 decompRecord.key_1 = RiskFactorKey(record.key_1.keytype, constituent, record.key_1.index);
125 decompRecord.delta = record.delta * weight;
126 decompRecord.gamma = record.gamma * weight;
127 results.push_back(decompRecord);
128 }
129 return results;
130}
+ Here is the caller graph for this function:

◆ decomposeCurrencyHedgedIndexRisk()

std::vector< SensitivityRecord > decomposeCurrencyHedgedIndexRisk ( const SensitivityRecord record) const
private

Definition at line 262 of file decomposedsensitivitystream.cpp.

262 {
263
264 auto indexName = sr.key_1.name;
265 auto indexCurrency = curveCurrency(indexName, ore::data::CurveSpec::CurveType::Equity);
266
267 QuantLib::ext::shared_ptr<ore::data::CurrencyHedgedEquityIndexDecomposition> decomposeCurrencyHedgedIndexHelper;
268 decomposeCurrencyHedgedIndexHelper =
270 if (decomposeCurrencyHedgedIndexHelper != nullptr) {
271 QL_REQUIRE(currencyHedgedIndexQuantities_.count(sr.tradeId) > 0,
272 "CurrencyHedgedIndexDecomposition failed, there is no index quantity for trade "
273 << sr.tradeId << " and equity index EQ-" << indexName);
274 QL_REQUIRE(currencyHedgedIndexQuantities_.at(sr.tradeId).count("EQ-" + indexName) > 0,
275 "CurrencyHedgedIndexDecomposition failed, there is no index quantity for trade "
276 << sr.tradeId << " and equity index EQ-" << indexName);
277 QL_REQUIRE(todaysMarket_ != nullptr,
278 "CurrencyHedgedIndexDecomposition failed, there is no market given quantity for trade "
279 << sr.tradeId);
280
281 Date today = QuantLib::Settings::instance().evaluationDate();
282
283 auto quantity = currencyHedgedIndexQuantities_.at(sr.tradeId).find("EQ-" + indexName)->second;
284
285 QL_REQUIRE(quantity != QuantLib::Null<double>(),
286 "CurrencyHedgedIndexDecomposition failed, index quantity cannot be NULL.");
287
288 double assetSensiShift = assetSpotShiftSize(indexName, ore::data::CurveSpec::CurveType::Equity);
289
290 double hedgedExposure = sr.delta / assetSensiShift;
291
292 double unhedgedExposure =
293 decomposeCurrencyHedgedIndexHelper->unhedgedSpotExposure(hedgedExposure, quantity, today, todaysMarket_);
294
295 double unhedgedDelta = unhedgedExposure * assetSensiShift;
296
297 auto decompResults =
298 indexDecomposition(unhedgedDelta, decomposeCurrencyHedgedIndexHelper->underlyingIndexName(),
299 ore::data::CurveSpec::CurveType::Equity);
300
301 // Correct FX Delta from FxForwards
302 for (const auto& [ccy, fxRisk] :
303 decomposeCurrencyHedgedIndexHelper->fxSpotRiskFromForwards(quantity, today, todaysMarket_, 1.0)) {
304 decompResults.fxRisk[ccy] = decompResults.fxRisk[ccy] - fxRisk * fxRiskShiftSize(ccy);
305 }
306
307 return sensitivityRecords(decompResults.spotRisk, decompResults.fxRisk, indexCurrency, sr);
308 } else {
309 auto subFields = std::map<std::string, std::string>({{"tradeId", sr.tradeId}});
310 StructuredAnalyticsErrorMessage("CRIF Generation", "Equity index decomposition failed",
311 "Cannot decompose equity index delta (" + indexName +
312 ") for trade: no reference data found. Continuing without decomposition.",
313 subFields)
314 .log();
315 return {sr};
316 }
317}
double assetSpotShiftSize(const std::string name, const ore::data::CurveSpec::CurveType curveType) const
Return the asset spot shift size.
QuantLib::ext::shared_ptr< CurrencyHedgedEquityIndexDecomposition > loadCurrencyHedgedIndexDecomposition(const std::string &name, const QuantLib::ext::shared_ptr< ReferenceDataManager > &refDataMgr, const QuantLib::ext::shared_ptr< CurveConfigurations > &curveConfigs)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ indexDecomposition()

DecomposedSensitivityStream::IndexDecompositionResult indexDecomposition ( double  delta,
const std::string &  indexName,
const ore::data::CurveSpec::CurveType  curveType 
) const
private

Definition at line 237 of file decomposedsensitivitystream.cpp.

238 {
239 IndexDecompositionResult result;
240 std::string refDataType = curveType == ore::data::CurveSpec::CurveType::Equity ? "EquityIndex" : "CommodityIndex";
241
242 QL_REQUIRE(refDataManager_->hasData(refDataType, indexName),
243 "Cannot decompose equity index delta ("
244 << indexName << ") for trade: no reference data found. Continuing without decomposition.");
245
246 auto refDatum = refDataManager_->getData(refDataType, indexName);
247 auto indexRefDatum = QuantLib::ext::dynamic_pointer_cast<ore::data::IndexReferenceDatum>(refDatum);
248 std::string indexCurrency = curveCurrency(indexName, curveType);
249 std::map<string, double> indexWeights = indexRefDatum->underlyings();
250 auto spotRisk = constituentSpotRiskFromDecomposition(delta, indexWeights);
251 auto currencies = getConstituentCurrencies(spotRisk, indexCurrency, curveType);
252 auto fxShifts = fxRiskShiftSizes(currencies);
253 double spotShift = assetSpotShiftSize(indexName, curveType);
254 auto fxRisk = fxRiskFromDecomposition(spotRisk, currencies, fxShifts, spotShift);
255 result.spotRisk = spotRisk;
256 result.fxRisk = fxRisk;
257 result.indexCurrency = indexCurrency;
258 return result;
259}
std::map< std::string, std::vector< std::string > > getConstituentCurrencies(const std::map< std::string, double > &constituents, const std::string &indexCurrency, const ore::data::CurveSpec::CurveType curveType) const
std::map< std::string, double > fxRiskFromDecomposition(const std::map< std::string, double > &spotRisk, const std::map< std::string, std::vector< std::string > > &constituentCurrencies, const std::map< std::string, double > &fxSpotShiftSize, const double eqShiftSize) const
Compute the resulting fx risks from a given equity/commodity decomposition.
std::map< std::string, double > constituentSpotRiskFromDecomposition(const double spotDelta, const std::map< std::string, double > &indexWeights) const
Decompose a equity/commodity spot sensitivity into the constituent spot sensistivities.
std::map< std::string, double > fxRiskShiftSizes(const std::map< std::string, std::vector< std::string > > &constituentCurrencies) const
Returns the shift sizes for all currencies in the map.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sensitivityRecords()

std::vector< SensitivityRecord > sensitivityRecords ( const std::map< std::string, double > &  eqDeltas,
const std::map< std::string, double > &  fxDeltas,
const std::string  indexCurrency,
const SensitivityRecord orginialRecord 
) const
private

Definition at line 326 of file decomposedsensitivitystream.cpp.

328 {
329 std::vector<SensitivityRecord> records;
330 for (auto [underlying, delta] : eqDeltas) {
331 RiskFactorKey underlyingKey(sr.key_1.keytype, underlying, sr.key_1.index);
332 records.push_back(SensitivityRecord(sr.tradeId, sr.isPar, underlyingKey, sr.desc_1, sr.shift_1, RiskFactorKey(),
333 "", sr.shift_2, sr.currency, sr.baseNpv, delta, 0.0));
334 }
335 // Add aggregated FX Deltas
336 for (auto [ccy, delta] : fxDeltas) {
337 if (ccy != indexCurrency && ccy != baseCurrency_) {
338 RiskFactorKey underlyingKey(RiskFactorKey::KeyType::FXSpot, ccy + baseCurrency_, 0);
339 records.push_back(SensitivityRecord(sr.tradeId, sr.isPar, underlyingKey, sr.desc_1, sr.shift_1,
340 RiskFactorKey(), "", sr.shift_2, sr.currency, sr.baseNpv, delta, 0.0));
341 }
342 }
343 return records;
344}
+ Here is the caller graph for this function:

◆ curveCurrency()

std::string curveCurrency ( const std::string &  name,
ore::data::CurveSpec::CurveType  curveType 
) const
private

Definition at line 346 of file decomposedsensitivitystream.cpp.

347 {
348 std::string curveCurrency;
349 if (curveConfigs_->has(curveType, name)) {
350 curveCurrency = curveType == ore::data::CurveSpec::CurveType::Equity
351 ? curveConfigs_->equityCurveConfig(name)->currency()
352 : curveConfigs_->commodityCurveConfig(name)->currency();
353 } else if (curveConfigs_->hasEquityCurveConfig(name)) {
354 // if we use a equity curve as proxy fall back to lookup the currency from the proxy config
355 curveCurrency = curveConfigs_->equityCurveConfig(name)->currency();
356 }
357 return curveCurrency;
358}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Data Documentation

◆ decomposedRecords_

std::vector<SensitivityRecord> decomposedRecords_
private

Definition at line 105 of file decomposedsensitivitystream.hpp.

◆ itCurrent_

std::vector<SensitivityRecord>::iterator itCurrent_
private

Definition at line 106 of file decomposedsensitivitystream.hpp.

◆ ss_

QuantLib::ext::shared_ptr<SensitivityStream> ss_
private

The underlying sensitivity stream that has been wrapped.

Definition at line 109 of file decomposedsensitivitystream.hpp.

◆ baseCurrency_

std::string baseCurrency_
private

Definition at line 110 of file decomposedsensitivitystream.hpp.

◆ defaultRiskDecompositionWeights_

std::map<std::string, std::map<std::string, double> > defaultRiskDecompositionWeights_
private

map of trade ids to the basket consituents with their resp. weights

Definition at line 112 of file decomposedsensitivitystream.hpp.

◆ eqComDecompositionTradeIds_

std::set<std::string> eqComDecompositionTradeIds_
private

list of trade id, for which a equity index decomposition should be applied

Definition at line 114 of file decomposedsensitivitystream.hpp.

◆ currencyHedgedIndexQuantities_

std::map<std::string, std::map<std::string, double> > currencyHedgedIndexQuantities_
private

list of trade id, for which a commodity index decomposition should be applied

Definition at line 116 of file decomposedsensitivitystream.hpp.

◆ refDataManager_

QuantLib::ext::shared_ptr<ore::data::ReferenceDataManager> refDataManager_
private

refDataManager holding the equity and commodity index decomposition weights

Definition at line 118 of file decomposedsensitivitystream.hpp.

◆ curveConfigs_

QuantLib::ext::shared_ptr<ore::data::CurveConfigurations> curveConfigs_
private

Definition at line 119 of file decomposedsensitivitystream.hpp.

◆ ssd_

QuantLib::ext::shared_ptr<SensitivityScenarioData> ssd_
private

Definition at line 120 of file decomposedsensitivitystream.hpp.

◆ todaysMarket_

QuantLib::ext::shared_ptr<ore::data::Market> todaysMarket_
private

Definition at line 122 of file decomposedsensitivitystream.hpp.

◆ decompose_

bool decompose_
private

Definition at line 124 of file decomposedsensitivitystream.hpp.