24#include <boost/range/adaptor/indexed.hpp>
37template <
class KeyType,
class ValueType>
ValueType index(
const KeyType& k,
const map<KeyType, ValueType>& m) {
40 QL_REQUIRE(it != m.end(),
"Key, " << k <<
", was not found in the sensitivity cube.");
46 const std::map<ore::analytics::RiskFactorKey, SensitivityCube::FactorData>& m) {
49 QL_REQUIRE(it != m.end(),
"Key, " << k <<
", was not found in the sensitivity cube.");
56 return out << cp.first <<
"-" << cp.second;
60 const vector<ShiftScenarioDescription>& scenarioDescriptions,
61 const map<RiskFactorKey, QuantLib::Real>& targetShiftSizes,
62 const map<RiskFactorKey, QuantLib::Real>& actualShiftSizes,
63 const std::map<RiskFactorKey, ShiftScheme>& shiftSchemes)
64 : cube_(cube), scenarioDescriptions_(scenarioDescriptions), targetShiftSizes_(targetShiftSizes),
65 actualShiftSizes_(actualShiftSizes), shiftSchemes_(shiftSchemes) {
70 const vector<string>& scenarioDescriptions,
71 const map<RiskFactorKey, QuantLib::Real>& targetShiftSizes,
72 const map<RiskFactorKey, QuantLib::Real>& actualShiftSizes,
73 const std::map<RiskFactorKey, ShiftScheme>& shiftSchemes)
74 : cube_(cube), targetShiftSizes_(targetShiftSizes), actualShiftSizes_(actualShiftSizes),
75 shiftSchemes_(shiftSchemes) {
89 "Expected the first scenario in the sensitivity cube to be of type 'Base'");
102 fd.
rfkey = des.key1();
108 switch (des.type()) {
110 QL_REQUIRE(
upFactors_.count(des.key1()) == 0,
"Cannot have multiple up factors with "
111 "the same risk factor key["
112 << des.key1() <<
"]");
118 QL_REQUIRE(
downFactors_.count(des.key1()) == 0,
"Cannot have multiple down factors with "
119 "the same risk factor key ["
120 << des.key1() <<
"]");
126 factorPair = make_pair(des.key1(), des.key2());
127 QL_REQUIRE(
crossFactors.count(factorPair) == 0,
"Cannot have multiple cross factors with "
128 "the same risk factor key pair ["
129 << des.key1() <<
", " << des.key2() <<
"]");
172 Size scenarioIdx = index(riskFactorKey,
upFactors_).index;
178const std::map<SensitivityCube::crossPair, tuple<SensitivityCube::FactorData, SensitivityCube::FactorData, Size>>&
186 "Risk factor, " << riskFactorKey <<
", was not found in the target shift sizes.");
193 "Risk factor, " << riskFactorKey <<
", was not found in the actual shift sizes.");
199 QL_REQUIRE(it !=
shiftSchemes_.end(),
"Risk factor, " << riskFactorKey <<
", was not found in the shift schemes.");
208Real scaling(
const SensitivityCube::FactorData& fd) {
209 if (fd.targetShiftSize == 0.0 || fd.actualShiftSize == 0) {
210 WLOG(
"Sensitivity Calculation: Scaling from different shift size is not possible, if that is configured. No "
211 "shift sizes available for '"
212 << fd.rfkey <<
"', check consistency of simulation and sensitivity config.");
215 return fd.targetShiftSize / fd.actualShiftSize;
222 "SensitivityCube::delta(" <<
tradeIdx <<
", " << riskFactorKey <<
"): no shift scheme stored.");
234 QL_FAIL(
"SensitivityCube::delta(" <<
tradeIdx <<
", " << riskFactorKey <<
"): unknown shift scheme '"
235 << s->second <<
"'");
240 return delta(
cube_->getTradeIndex(tradeId), riskFactorKey);
249 return (upNpv - 2.0 * baseNpv + downNpv) * std::pow(scaling(fdup), 2);
253 return gamma(
cube_->getTradeIndex(tradeId), riskFactorKey);
257 QuantLib::Size crossIdx, QuantLib::Real scaling1,
258 QuantLib::Real scaling2)
const {
262 Real baseNpv =
cube_->getT0(
id, 0);
263 Real upNpv_1 =
cube_->get(
id, upIdx_1);
264 Real upNpv_2 =
cube_->get(
id, upIdx_2);
265 Real crossNpv =
cube_->get(
id, crossIdx);
266 return (crossNpv - upNpv_1 - upNpv_2 + baseNpv) * scaling1 * scaling2;
272 std::tie(upFd_1, upFd_2, crossIdx) = index(riskFactorKeyPair,
crossFactors_);
281 std::set<RiskFactorKey> result;
282 for (
auto const i :
cube_->relevantScenarios()) {
Data types stored in the scenario class.
std::map< RiskFactorKey, ShiftScheme > shiftSchemes_
std::string factorDescription(const RiskFactorKey &riskFactorKey) const
void initialise()
Initialise method used by the constructors.
std::vector< ShiftScenarioDescription > scenarioDescriptions_
std::map< std::string, QuantLib::Size > tradeIdx_
std::map< QuantLib::Size, RiskFactorKey > downIndexToKey_
bool hasTrade(const std::string &tradeId) const
Check if the cube has scenario NPVs for trade with ID tradeId.
std::map< RiskFactorKey, QuantLib::Real > targetShiftSizes_
SensitivityCube(const QuantLib::ext::shared_ptr< NPVSensiCube > &cube, const std::vector< ShiftScenarioDescription > &scenarioDescriptions, const std::map< RiskFactorKey, QuantLib::Real > &targetShiftSizes, const std::map< RiskFactorKey, QuantLib::Real > &actualShiftSizes, const std::map< RiskFactorKey, ShiftScheme > &shiftSchemes)
Constructor using a vector of scenario descriptions.
QuantLib::Real actualShiftSize(const RiskFactorKey &riskFactorKey) const
Returns the absolute actual shift size for given risk factor key.
const std::map< std::string, QuantLib::Size > & tradeIdx() const
Return the map of up trade id's to index in cube.
std::map< ShiftScenarioDescription, QuantLib::Size > scenarioIdx_
QuantLib::Real targetShiftSize(const RiskFactorKey &riskFactorKey) const
Returns the absolute target shift size for given risk factor key.
std::map< RiskFactorKey, FactorData > upFactors_
std::map< crossPair, std::tuple< FactorData, FactorData, QuantLib::Size > > crossFactors_
QuantLib::ext::shared_ptr< NPVSensiCube > cube_
QuantLib::Real gamma(const Size tradeIdx, const RiskFactorKey &riskFactorKey) const
Get the trade gamma for trade with index tradeIdx and for the given risk factor key riskFactorKey.
bool hasScenario(const ShiftScenarioDescription &scenarioDescription) const
Check if the cube has scenario NPVs for scenario with description scenarioDescription.
std::map< QuantLib::Size, crossPair > crossIndexToKey_
std::map< QuantLib::Size, RiskFactorKey > upIndexToKey_
QuantLib::Real delta(const Size tradeIdx, const RiskFactorKey &riskFactorKey) const
Get the trade delta for trade with index tradeIdx and for the given risk factor key riskFactorKey.
std::set< RiskFactorKey > factors_
RiskFactorKey upDownFactor(const Size index) const
const std::vector< ShiftScenarioDescription > & scenarioDescriptions() const
QuantLib::Real crossGamma(const Size tradeIdx, const crossPair &riskFactorKeyPair) const
std::map< RiskFactorKey, QuantLib::Real > actualShiftSizes_
const std::set< RiskFactorKey > & factors() const
Returns the set of risk factor keys for which a delta and gamma can be calculated.
const std::map< crossPair, std::tuple< SensitivityCube::FactorData, SensitivityCube::FactorData, QuantLib::Size > > & crossFactors() const
Returns the set of pairs of risk factor keys for which a cross gamma is available.
ShiftScheme shiftScheme(const RiskFactorKey &riskFactorKey) const
Returns the shift scheme for given risk factor key.
crossPair crossFactor(const Size crossIndex) const
QuantLib::Real npv(const std::string &tradeId) const
Get the base NPV for trade with ID tradeId.
std::map< RiskFactorKey, FactorData > downFactors_
std::pair< RiskFactorKey, RiskFactorKey > crossPair
std::set< RiskFactorKey > relevantRiskFactors() const
Get the relevant risk factors.
ShiftScenarioGenerator::ScenarioDescription ShiftScenarioDescription
std::ostream & operator<<(std::ostream &out, EquityReturnType t)
pair< RiskFactorKey, string > deconstructFactor(const string &factor)
boost::variant< RandomVariable, EventVec, CurrencyVec, IndexVec, DaycounterVec, Filter > ValueType
holds a grid of NPVs for a list of trades under various scenarios
QuantLib::Real targetShiftSize
QuantLib::Real actualShiftSize