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

Simulation Market updated with discrete scenarios. More...

#include <orea/scenario/scenariosimmarket.hpp>

+ Inheritance diagram for ScenarioSimMarket:
+ Collaboration diagram for ScenarioSimMarket:

Public Member Functions

 ScenarioSimMarket (const bool handlePseudoCurrencies)
 Constructor. More...
 
 ScenarioSimMarket (const QuantLib::ext::shared_ptr< Market > &initMarket, const QuantLib::ext::shared_ptr< ScenarioSimMarketParameters > &parameters, const std::string &configuration=Market::defaultConfiguration, const ore::data::CurveConfigurations &curveConfigs=ore::data::CurveConfigurations(), const ore::data::TodaysMarketParameters &todaysMarketParams=ore::data::TodaysMarketParameters(), const bool continueOnError=false, const bool useSpreadedTermStructures=false, const bool cacheSimData=false, const bool allowPartialScenarios=false, const IborFallbackConfig &iborFallbackConfig=IborFallbackConfig::defaultConfig(), const bool handlePseudoCurrencies=true, const QuantLib::ext::shared_ptr< Scenario > &offSetScenario=nullptr)
 
 ScenarioSimMarket (const QuantLib::ext::shared_ptr< Market > &initMarket, const QuantLib::ext::shared_ptr< ScenarioSimMarketParameters > &parameters, const QuantLib::ext::shared_ptr< FixingManager > &fixingManager, const std::string &configuration=Market::defaultConfiguration, const ore::data::CurveConfigurations &curveConfigs=ore::data::CurveConfigurations(), const ore::data::TodaysMarketParameters &todaysMarketParams=ore::data::TodaysMarketParameters(), const bool continueOnError=false, const bool useSpreadedTermStructures=false, const bool cacheSimData=false, const bool allowPartialScenarios=false, const IborFallbackConfig &iborFallbackConfig=IborFallbackConfig::defaultConfig(), const bool handlePseudoCurrencies=true, const QuantLib::ext::shared_ptr< Scenario > &offSetScenario=nullptr)
 
virtual QuantLib::ext::shared_ptr< ScenarioGenerator > & scenarioGenerator ()
 Set scenario generator. More...
 
virtual const QuantLib::ext::shared_ptr< ScenarioGenerator > & scenarioGenerator () const
 Get scenario generator. More...
 
virtual QuantLib::ext::shared_ptr< AggregationScenarioData > & aggregationScenarioData ()
 Set aggregation data. More...
 
virtual const QuantLib::ext::shared_ptr< AggregationScenarioData > & aggregationScenarioData () const
 Get aggregation data. More...
 
virtual QuantLib::ext::shared_ptr< ScenarioFilter > & filter ()
 Set scenarioFilter. More...
 
virtual const QuantLib::ext::shared_ptr< ScenarioFilter > & filter () const
 Get scenarioFilter. More...
 
virtual void preUpdate () override
 Update. More...
 
virtual void updateScenario (const Date &) override
 Retrieve next market scenario and apply this, but don't update date. More...
 
virtual void updateDate (const Date &) override
 Update to the given date. More...
 
virtual void postUpdate (const Date &d, bool withFixings) override
 Observable reset depending on selected mode, instrument updates. More...
 
virtual void updateAsd (const Date &) override
 Update aggregation scenario data. More...
 
virtual void reset () override
 Reset sim market to initial state. More...
 
virtual QuantLib::ext::shared_ptr< ScenariobaseScenario () const
 
virtual QuantLib::ext::shared_ptr< ScenariobaseScenarioAbsolute () const
 
bool useSpreadedTermStructures () const
 
const QuantLib::ext::shared_ptr< FixingManager > & fixingManager () const override
 Return the fixing manager. More...
 
virtual bool isSimulated (const RiskFactorKey::KeyType &factor) const
 is risk factor key simulated by this sim market instance? More...
 
void applyScenario (const QuantLib::ext::shared_ptr< Scenario > &scenario)
 
- Public Member Functions inherited from SimMarket
 SimMarket (const bool handlePseudoCurrencies)
 
virtual void update (const Date &d)
 Generate or retrieve market scenario, update market, notify termstructures and update fixings. More...
 
virtual void preUpdate ()=0
 Observable settings depending on selected mode, before we update the market. More...
 
virtual void updateDate (const Date &)=0
 Update to the given date. More...
 
virtual void updateScenario (const Date &)=0
 Retrieve next market scenario and apply this, but don't update date. More...
 
virtual void postUpdate (const Date &d, bool withFixings)=0
 Observable reset depending on selected mode, instrument updates. More...
 
virtual void updateAsd (const Date &)=0
 Update aggregation scenario data. More...
 
Real numeraire ()
 Return current numeraire value. More...
 
const std::string & label ()
 Return current scenario label, if any. More...
 
virtual void reset ()=0
 Reset sim market to initial state. More...
 
virtual const QuantLib::ext::shared_ptr< FixingManager > & fixingManager () const =0
 Get the fixing manager. More...
 
- Public Member Functions inherited from MarketImpl
 MarketImpl (const bool handlePseudoCurrencies)
 
Date asofDate () const override
 
Handle< YieldTermStructure > yieldCurve (const YieldCurveType &type, const string &ccy, const string &configuration=Market::defaultConfiguration) const override
 
Handle< YieldTermStructure > discountCurveImpl (const string &ccy, const string &configuration=Market::defaultConfiguration) const override
 
Handle< YieldTermStructure > yieldCurve (const string &name, const string &configuration=Market::defaultConfiguration) const override
 
Handle< IborIndexiborIndex (const string &indexName, const string &configuration=Market::defaultConfiguration) const override
 
Handle< SwapIndex > swapIndex (const string &indexName, const string &configuration=Market::defaultConfiguration) const override
 
Handle< QuantLib::SwaptionVolatilityStructure > swaptionVol (const string &key, const string &configuration=Market::defaultConfiguration) const override
 
string shortSwapIndexBase (const string &key, const string &configuration=Market::defaultConfiguration) const override
 
string swapIndexBase (const string &key, const string &configuration=Market::defaultConfiguration) const override
 
Handle< QuantLib::SwaptionVolatilityStructure > yieldVol (const string &securityID, const string &configuration=Market::defaultConfiguration) const override
 
QuantLib::Handle< QuantExt::FxIndexfxIndexImpl (const string &fxIndex, const string &configuration=Market::defaultConfiguration) const override
 
Handle< Quote > fxRateImpl (const string &ccypair, const string &configuration=Market::defaultConfiguration) const override
 
Handle< Quote > fxSpotImpl (const string &ccypair, const string &configuration=Market::defaultConfiguration) const override
 
Handle< BlackVolTermStructurefxVolImpl (const string &ccypair, const string &configuration=Market::defaultConfiguration) const override
 
Handle< QuantExt::CreditCurvedefaultCurve (const string &, const string &configuration=Market::defaultConfiguration) const override
 
Handle< Quote > recoveryRate (const string &, const string &configuration=Market::defaultConfiguration) const override
 
Handle< QuantExt::CreditVolCurvecdsVol (const string &name, const string &configuration=Market::defaultConfiguration) const override
 
Handle< QuantExt::BaseCorrelationTermStructurebaseCorrelation (const string &name, const string &configuration=Market::defaultConfiguration) const override
 
Handle< OptionletVolatilityStructure > capFloorVol (const string &key, const string &configuration=Market::defaultConfiguration) const override
 
std::pair< string, QuantLib::Period > capFloorVolIndexBase (const string &key, const string &configuration=Market::defaultConfiguration) const override
 
Handle< QuantExt::YoYOptionletVolatilitySurface > yoyCapFloorVol (const string &name, const string &configuration=Market::defaultConfiguration) const override
 
virtual Handle< ZeroInflationIndex > zeroInflationIndex (const string &indexName, const string &configuration=Market::defaultConfiguration) const override
 
virtual Handle< YoYInflationIndex > yoyInflationIndex (const string &indexName, const string &configuration=Market::defaultConfiguration) const override
 
virtual Handle< CPIVolatilitySurface > cpiInflationCapFloorVolatilitySurface (const string &indexName, const string &configuration=Market::defaultConfiguration) const override
 
Handle< Quote > equitySpot (const string &eqName, const string &configuration=Market::defaultConfiguration) const override
 
Handle< QuantExt::EquityIndex2equityCurve (const string &eqName, const string &configuration=Market::defaultConfiguration) const override
 
Handle< YieldTermStructure > equityDividendCurve (const string &eqName, const string &configuration=Market::defaultConfiguration) const override
 
Handle< BlackVolTermStructureequityVol (const string &eqName, const string &configuration=Market::defaultConfiguration) const override
 
Handle< YieldTermStructure > equityForecastCurve (const string &eqName, const string &configuration=Market::defaultConfiguration) const override
 
Handle< Quote > securitySpread (const string &securityID, const string &configuration=Market::defaultConfiguration) const override
 
Handle< QuantExt::InflationIndexObserverbaseCpis (const string &index, const string &configuration=Market::defaultConfiguration) const
 
QuantLib::Handle< QuantExt::PriceTermStructurecommodityPriceCurve (const string &commodityName, const string &configuration=Market::defaultConfiguration) const override
 
QuantLib::Handle< QuantExt::CommodityIndexcommodityIndex (const std::string &commodityName, const std::string &configuration=Market::defaultConfiguration) const override
 
QuantLib::Handle< QuantLib::BlackVolTermStructure > commodityVolatility (const string &commodityName, const string &configuration=Market::defaultConfiguration) const override
 
Handle< QuantExt::CorrelationTermStructurecorrelationCurve (const string &index1, const string &index2, const string &configuration=Market::defaultConfiguration) const override
 
QuantLib::Handle< Quote > cpr (const string &securityID, const string &configuration=Market::defaultConfiguration) const override
 
 MarketImpl (const MarketImpl &)=delete
 
MarketImploperator= (const MarketImpl &)=delete
 
void refresh (const string &configuration=Market::defaultConfiguration) override
 
Date asofDate () const override
 
Handle< YieldTermStructure > yieldCurve (const YieldCurveType &type, const string &ccy, const string &configuration=Market::defaultConfiguration) const override
 
Handle< YieldTermStructure > discountCurveImpl (const string &ccy, const string &configuration=Market::defaultConfiguration) const override
 
Handle< YieldTermStructure > yieldCurve (const string &name, const string &configuration=Market::defaultConfiguration) const override
 
Handle< IborIndexiborIndex (const string &indexName, const string &configuration=Market::defaultConfiguration) const override
 
Handle< SwapIndex > swapIndex (const string &indexName, const string &configuration=Market::defaultConfiguration) const override
 
Handle< QuantLib::SwaptionVolatilityStructure > swaptionVol (const string &key, const string &configuration=Market::defaultConfiguration) const override
 
string shortSwapIndexBase (const string &key, const string &configuration=Market::defaultConfiguration) const override
 
string swapIndexBase (const string &key, const string &configuration=Market::defaultConfiguration) const override
 
Handle< QuantLib::SwaptionVolatilityStructure > yieldVol (const string &securityID, const string &configuration=Market::defaultConfiguration) const override
 
QuantLib::Handle< QuantExt::FxIndexfxIndexImpl (const string &fxIndex, const string &configuration=Market::defaultConfiguration) const override
 
Handle< Quote > fxRateImpl (const string &ccypair, const string &configuration=Market::defaultConfiguration) const override
 
Handle< Quote > fxSpotImpl (const string &ccypair, const string &configuration=Market::defaultConfiguration) const override
 
Handle< BlackVolTermStructurefxVolImpl (const string &ccypair, const string &configuration=Market::defaultConfiguration) const override
 
Handle< QuantExt::CreditCurvedefaultCurve (const string &, const string &configuration=Market::defaultConfiguration) const override
 
Handle< Quote > recoveryRate (const string &, const string &configuration=Market::defaultConfiguration) const override
 
Handle< QuantExt::CreditVolCurvecdsVol (const string &name, const string &configuration=Market::defaultConfiguration) const override
 
Handle< QuantExt::BaseCorrelationTermStructurebaseCorrelation (const string &name, const string &configuration=Market::defaultConfiguration) const override
 
Handle< OptionletVolatilityStructure > capFloorVol (const string &key, const string &configuration=Market::defaultConfiguration) const override
 
std::pair< string, QuantLib::Period > capFloorVolIndexBase (const string &key, const string &configuration=Market::defaultConfiguration) const override
 
Handle< QuantExt::YoYOptionletVolatilitySurface > yoyCapFloorVol (const string &name, const string &configuration=Market::defaultConfiguration) const override
 
virtual Handle< ZeroInflationIndex > zeroInflationIndex (const string &indexName, const string &configuration=Market::defaultConfiguration) const override
 
virtual Handle< YoYInflationIndex > yoyInflationIndex (const string &indexName, const string &configuration=Market::defaultConfiguration) const override
 
virtual Handle< CPIVolatilitySurface > cpiInflationCapFloorVolatilitySurface (const string &indexName, const string &configuration=Market::defaultConfiguration) const override
 
Handle< Quote > equitySpot (const string &eqName, const string &configuration=Market::defaultConfiguration) const override
 
Handle< QuantExt::EquityIndex2equityCurve (const string &eqName, const string &configuration=Market::defaultConfiguration) const override
 
Handle< YieldTermStructure > equityDividendCurve (const string &eqName, const string &configuration=Market::defaultConfiguration) const override
 
Handle< BlackVolTermStructureequityVol (const string &eqName, const string &configuration=Market::defaultConfiguration) const override
 
Handle< YieldTermStructure > equityForecastCurve (const string &eqName, const string &configuration=Market::defaultConfiguration) const override
 
Handle< Quote > securitySpread (const string &securityID, const string &configuration=Market::defaultConfiguration) const override
 
Handle< QuantExt::InflationIndexObserverbaseCpis (const string &index, const string &configuration=Market::defaultConfiguration) const
 
QuantLib::Handle< QuantExt::PriceTermStructurecommodityPriceCurve (const string &commodityName, const string &configuration=Market::defaultConfiguration) const override
 
QuantLib::Handle< QuantExt::CommodityIndexcommodityIndex (const std::string &commodityName, const std::string &configuration=Market::defaultConfiguration) const override
 
QuantLib::Handle< QuantLib::BlackVolTermStructure > commodityVolatility (const string &commodityName, const string &configuration=Market::defaultConfiguration) const override
 
Handle< QuantExt::CorrelationTermStructurecorrelationCurve (const string &index1, const string &index2, const string &configuration=Market::defaultConfiguration) const override
 
QuantLib::Handle< Quote > cpr (const string &securityID, const string &configuration=Market::defaultConfiguration) const override
 
- Public Member Functions inherited from Market
 Market (const bool handlePseudoCurrencies)
 
virtual ~Market ()
 
virtual Date asofDate () const=0
 
virtual Handle< YieldTermStructure > yieldCurve (const YieldCurveType &type, const string &name, const string &configuration=Market::defaultConfiguration) const=0
 
Handle< YieldTermStructure > discountCurve (const string &ccy, const string &configuration=Market::defaultConfiguration) const
 
virtual Handle< YieldTermStructure > discountCurveImpl (const string &ccy, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< YieldTermStructure > yieldCurve (const string &name, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< IborIndexiborIndex (const string &indexName, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< SwapIndex > swapIndex (const string &indexName, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< SwaptionVolatilityStructureswaptionVol (const string &key, const string &configuration=Market::defaultConfiguration) const=0
 
virtual string shortSwapIndexBase (const string &key, const string &configuration=Market::defaultConfiguration) const=0
 
virtual string swapIndexBase (const string &key, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< SwaptionVolatilityStructureyieldVol (const string &securityID, const string &configuration=Market::defaultConfiguration) const=0
 
QuantLib::Handle< QuantExt::FxIndexfxIndex (const string &fxIndex, const string &configuration=Market::defaultConfiguration) const
 
virtual QuantLib::Handle< QuantExt::FxIndexfxIndexImpl (const string &fxIndex, const string &configuration=Market::defaultConfiguration) const=0
 
Handle< Quote > fxRate (const string &ccypair, const string &configuration=Market::defaultConfiguration) const
 
virtual Handle< Quote > fxRateImpl (const string &ccypair, const string &configuration=Market::defaultConfiguration) const=0
 
Handle< Quote > fxSpot (const string &ccypair, const string &configuration=Market::defaultConfiguration) const
 
virtual Handle< Quote > fxSpotImpl (const string &ccypair, const string &configuration=Market::defaultConfiguration) const=0
 
Handle< BlackVolTermStructurefxVol (const string &ccypair, const string &configuration=Market::defaultConfiguration) const
 
virtual Handle< BlackVolTermStructurefxVolImpl (const string &ccypair, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< QuantExt::CreditCurvedefaultCurve (const string &, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< Quote > recoveryRate (const string &, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< QuantExt::CreditVolCurvecdsVol (const string &, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< QuantExt::BaseCorrelationTermStructurebaseCorrelation (const string &, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< OptionletVolatilityStructure > capFloorVol (const string &key, const string &configuration=Market::defaultConfiguration) const=0
 
virtual std::pair< std::string, QuantLib::Period > capFloorVolIndexBase (const string &key, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< QuantExt::YoYOptionletVolatilitySurface > yoyCapFloorVol (const string &indexName, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< ZeroInflationIndex > zeroInflationIndex (const string &indexName, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< YoYInflationIndex > yoyInflationIndex (const string &indexName, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< CPIVolatilitySurface > cpiInflationCapFloorVolatilitySurface (const string &indexName, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< Quote > equitySpot (const string &eqName, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< YieldTermStructure > equityDividendCurve (const string &eqName, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< YieldTermStructure > equityForecastCurve (const string &eqName, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< QuantExt::EquityIndex2equityCurve (const string &eqName, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< Quote > securitySpread (const string &securityID, const string &configuration=Market::defaultConfiguration) const=0
 
virtual QuantLib::Handle< QuantExt::PriceTermStructurecommodityPriceCurve (const std::string &commodityName, const std::string &configuration=Market::defaultConfiguration) const=0
 
virtual QuantLib::Handle< QuantExt::CommodityIndexcommodityIndex (const std::string &commodityName, const std::string &configuration=Market::defaultConfiguration) const=0
 
virtual QuantLib::Handle< QuantLib::BlackVolTermStructure > commodityVolatility (const std::string &commodityName, const std::string &configuration=Market::defaultConfiguration) const=0
 
virtual QuantLib::Handle< QuantExt::CorrelationTermStructurecorrelationCurve (const std::string &index1, const std::string &index2, const std::string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< BlackVolTermStructureequityVol (const string &eqName, const string &configuration=Market::defaultConfiguration) const=0
 
virtual void refresh (const string &)
 
virtual Handle< Quote > cpr (const string &securityID, const string &configuration=Market::defaultConfiguration) const=0
 
string commodityCurveLookup (const string &pm) const
 
bool handlePseudoCurrencies () const
 
virtual Handle< YieldTermStructure > yieldCurve (const YieldCurveType &type, const string &name, const string &configuration=Market::defaultConfiguration) const=0
 
Handle< YieldTermStructure > discountCurve (const string &ccy, const string &configuration=Market::defaultConfiguration) const
 
virtual Handle< YieldTermStructure > discountCurveImpl (const string &ccy, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< YieldTermStructure > yieldCurve (const string &name, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< IborIndexiborIndex (const string &indexName, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< SwapIndex > swapIndex (const string &indexName, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< SwaptionVolatilityStructureswaptionVol (const string &key, const string &configuration=Market::defaultConfiguration) const=0
 
virtual string shortSwapIndexBase (const string &key, const string &configuration=Market::defaultConfiguration) const=0
 
virtual string swapIndexBase (const string &key, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< SwaptionVolatilityStructureyieldVol (const string &securityID, const string &configuration=Market::defaultConfiguration) const=0
 
QuantLib::Handle< QuantExt::FxIndexfxIndex (const string &fxIndex, const string &configuration=Market::defaultConfiguration) const
 
virtual QuantLib::Handle< QuantExt::FxIndexfxIndexImpl (const string &fxIndex, const string &configuration=Market::defaultConfiguration) const=0
 
Handle< Quote > fxRate (const string &ccypair, const string &configuration=Market::defaultConfiguration) const
 
virtual Handle< Quote > fxRateImpl (const string &ccypair, const string &configuration=Market::defaultConfiguration) const=0
 
Handle< Quote > fxSpot (const string &ccypair, const string &configuration=Market::defaultConfiguration) const
 
virtual Handle< Quote > fxSpotImpl (const string &ccypair, const string &configuration=Market::defaultConfiguration) const=0
 
Handle< BlackVolTermStructurefxVol (const string &ccypair, const string &configuration=Market::defaultConfiguration) const
 
virtual Handle< BlackVolTermStructurefxVolImpl (const string &ccypair, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< QuantExt::CreditCurvedefaultCurve (const string &, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< Quote > recoveryRate (const string &, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< QuantExt::CreditVolCurvecdsVol (const string &, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< QuantExt::BaseCorrelationTermStructurebaseCorrelation (const string &, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< OptionletVolatilityStructure > capFloorVol (const string &key, const string &configuration=Market::defaultConfiguration) const=0
 
virtual std::pair< std::string, QuantLib::Period > capFloorVolIndexBase (const string &key, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< QuantExt::YoYOptionletVolatilitySurface > yoyCapFloorVol (const string &indexName, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< ZeroInflationIndex > zeroInflationIndex (const string &indexName, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< YoYInflationIndex > yoyInflationIndex (const string &indexName, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< CPIVolatilitySurface > cpiInflationCapFloorVolatilitySurface (const string &indexName, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< Quote > equitySpot (const string &eqName, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< YieldTermStructure > equityDividendCurve (const string &eqName, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< YieldTermStructure > equityForecastCurve (const string &eqName, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< QuantExt::EquityIndex2equityCurve (const string &eqName, const string &configuration=Market::defaultConfiguration) const=0
 
virtual Handle< Quote > securitySpread (const string &securityID, const string &configuration=Market::defaultConfiguration) const=0
 
virtual QuantLib::Handle< QuantExt::PriceTermStructurecommodityPriceCurve (const std::string &commodityName, const std::string &configuration=Market::defaultConfiguration) const=0
 
virtual QuantLib::Handle< QuantExt::CommodityIndexcommodityIndex (const std::string &commodityName, const std::string &configuration=Market::defaultConfiguration) const=0
 
virtual QuantLib::Handle< QuantLib::BlackVolTermStructure > commodityVolatility (const std::string &commodityName, const std::string &configuration=Market::defaultConfiguration) const=0
 
virtual QuantLib::Handle< QuantExt::CorrelationTermStructurecorrelationCurve (const std::string &index1, const std::string &index2, const std::string &configuration=Market::defaultConfiguration) const=0
 

Protected Member Functions

void writeSimData (std::map< RiskFactorKey, QuantLib::ext::shared_ptr< SimpleQuote > > &simDataTmp, std::map< RiskFactorKey, Real > &absoluteSimDataTmp, const RiskFactorKey::KeyType keyType, const std::string &name, const std::vector< std::vector< Real > > &coordinates)
 
void addYieldCurve (const QuantLib::ext::shared_ptr< Market > &initMarket, const std::string &configuration, const RiskFactorKey::KeyType rf, const string &key, const vector< Period > &tenors, bool &simDataWritten, bool simulate=true, bool spreaded=false)
 
QuantLib::Handle< QuantLib::YieldTermStructure > getYieldCurve (const std::string &yieldSpecId, const ore::data::TodaysMarketParameters &todaysMarketParams, const std::string &configuration, const QuantLib::ext::shared_ptr< ore::data::Market > &market=nullptr) const
 
bool addSwapIndexToSsm (const std::string &indexName, const bool continueOnError)
 
- Protected Member Functions inherited from MarketImpl
virtual void require (const MarketObject o, const string &name, const string &configuration, const bool forceBuild=false) const
 
void addSwapIndex (const string &swapindex, const string &discountIndex, const string &configuration=Market::defaultConfiguration) const
 

Protected Attributes

const QuantLib::ext::shared_ptr< ScenarioSimMarketParametersparameters_
 
QuantLib::ext::shared_ptr< ScenarioGeneratorscenarioGenerator_
 
QuantLib::ext::shared_ptr< AggregationScenarioDataasd_
 
QuantLib::ext::shared_ptr< FixingManagerfixingManager_
 
QuantLib::ext::shared_ptr< ScenarioFilterfilter_
 
std::map< RiskFactorKey, QuantLib::ext::shared_ptr< SimpleQuote > > simData_
 
QuantLib::ext::shared_ptr< ScenariobaseScenario_
 
QuantLib::ext::shared_ptr< ScenariobaseScenarioAbsolute_
 
std::vector< QuantLib::ext::shared_ptr< SimpleQuote > > cachedSimData_
 
std::vector< boolcachedSimDataActive_
 
std::size_t cachedSimDataKeysHash_ = 0
 
std::set< RiskFactorKey::KeyTypenonSimulatedFactors_
 
bool useSpreadedTermStructures_
 
std::map< RiskFactorKey, Real > absoluteSimData_
 
std::set< std::tuple< RiskFactorKey::KeyType, std::string, std::vector< std::vector< Real > > > > coordinatesData_
 
bool cacheSimData_
 
bool allowPartialScenarios_
 
IborFallbackConfig iborFallbackConfig_
 
std::set< ore::analytics::RiskFactorKeydiffToBaseKeys_
 
QuantLib::ext::shared_ptr< ScenariocurrentScenario_
 
QuantLib::ext::shared_ptr< ScenariooffsetScenario_
 
- Protected Attributes inherited from SimMarket
Real numeraire_
 
std::string label_
 
- Protected Attributes inherited from MarketImpl
Date asof_
 
QuantLib::ext::shared_ptr< FXTriangulationfx_
 
map< tuple< string, YieldCurveType, string >, Handle< YieldTermStructure > > yieldCurves_
 
map< pair< string, string >, Handle< IborIndex > > iborIndices_
 
map< pair< string, string >, Handle< SwapIndex > > swapIndices_
 
map< pair< string, string >, Handle< QuantLib::SwaptionVolatilityStructure > > swaptionCurves_
 
map< pair< string, string >, pair< string, string > > swaptionIndexBases_
 
map< pair< string, string >, Handle< QuantLib::SwaptionVolatilityStructure > > yieldVolCurves_
 
map< pair< string, string >, Handle< BlackVolTermStructure > > fxVols_
 
map< pair< string, string >, Handle< QuantExt::CreditCurve > > defaultCurves_
 
map< pair< string, string >, Handle< QuantExt::CreditVolCurve > > cdsVols_
 
map< pair< string, string >, Handle< QuantExt::BaseCorrelationTermStructure > > baseCorrelations_
 
map< pair< string, string >, Handle< Quote > > recoveryRates_
 
map< pair< string, string >, Handle< OptionletVolatilityStructure > > capFloorCurves_
 
map< pair< string, string >, std::pair< string, QuantLib::Period > > capFloorIndexBase_
 
map< pair< string, string >, Handle< YoYOptionletVolatilitySurface > > yoyCapFloorVolSurfaces_
 
map< pair< string, string >, Handle< ZeroInflationIndex > > zeroInflationIndices_
 
map< pair< string, string >, Handle< YoYInflationIndex > > yoyInflationIndices_
 
map< pair< string, string >, Handle< CPIVolatilitySurface > > cpiInflationCapFloorVolatilitySurfaces_
 
map< pair< string, string >, Handle< Quote > > equitySpots_
 
map< pair< string, string >, Handle< BlackVolTermStructure > > equityVols_
 
map< pair< string, string >, Handle< Quote > > securitySpreads_
 
map< pair< string, string >, Handle< QuantExt::InflationIndexObserver > > baseCpis_
 
map< tuple< string, string, string >, Handle< QuantExt::CorrelationTermStructure > > correlationCurves_
 
map< pair< string, string >, QuantLib::Handle< QuantExt::CommodityIndex > > commodityIndices_
 
map< pair< string, string >, QuantLib::Handle< QuantLib::BlackVolTermStructure > > commodityVols_
 
map< pair< string, string >, QuantLib::Handle< QuantExt::EquityIndex2 > > equityCurves_
 
map< pair< string, string >, Handle< Quote > > cprs_
 
map< string, std::set< QuantLib::ext::shared_ptr< TermStructure > > > refreshTs_
 
- Protected Attributes inherited from Market
bool handlePseudoCurrencies_
 

Additional Inherited Members

- Static Public Attributes inherited from Market
static const string defaultConfiguration
 
static const string inCcyConfiguration
 

Detailed Description

Simulation Market updated with discrete scenarios.

If useSpreadedTermStructures is true, spreaded term structures over the initMarket for supported risk factors will be generated. This is used by the SensitivityScenarioGenerator.

If cacheSimData is true, the scenario application is optimised. This requires that all scenarios are SimpleScenario instances with identical key structure in their data.

If allowPartialScenarios is true, the check that all simData_ is touched by a scenario is disabled.

Definition at line 68 of file scenariosimmarket.hpp.

Constructor & Destructor Documentation

◆ ScenarioSimMarket() [1/3]

ScenarioSimMarket ( const bool  handlePseudoCurrencies)
explicit

Constructor.

Definition at line 71 of file scenariosimmarket.hpp.

SimMarket(const bool handlePseudoCurrencies)
Definition: simmarket.hpp:46
bool handlePseudoCurrencies() const

◆ ScenarioSimMarket() [2/3]

ScenarioSimMarket ( const QuantLib::ext::shared_ptr< Market > &  initMarket,
const QuantLib::ext::shared_ptr< ScenarioSimMarketParameters > &  parameters,
const std::string &  configuration = Market::defaultConfiguration,
const ore::data::CurveConfigurations curveConfigs = ore::data::CurveConfigurations(),
const ore::data::TodaysMarketParameters todaysMarketParams = ore::data::TodaysMarketParameters(),
const bool  continueOnError = false,
const bool  useSpreadedTermStructures = false,
const bool  cacheSimData = false,
const bool  allowPartialScenarios = false,
const IborFallbackConfig iborFallbackConfig = IborFallbackConfig::defaultConfig(),
const bool  handlePseudoCurrencies = true,
const QuantLib::ext::shared_ptr< Scenario > &  offSetScenario = nullptr 
)

Definition at line 306 of file scenariosimmarket.cpp.

314 : ScenarioSimMarket(initMarket, parameters, QuantLib::ext::make_shared<FixingManager>(initMarket->asofDate()),
315 configuration, curveConfigs, todaysMarketParams, continueOnError, useSpreadedTermStructures,
316 cacheSimData, allowPartialScenarios, iborFallbackConfig, handlePseudoCurrencies,
317 offSetScenario) {}
ScenarioSimMarket(const bool handlePseudoCurrencies)
Constructor.

◆ ScenarioSimMarket() [3/3]

ScenarioSimMarket ( const QuantLib::ext::shared_ptr< Market > &  initMarket,
const QuantLib::ext::shared_ptr< ScenarioSimMarketParameters > &  parameters,
const QuantLib::ext::shared_ptr< FixingManager > &  fixingManager,
const std::string &  configuration = Market::defaultConfiguration,
const ore::data::CurveConfigurations curveConfigs = ore::data::CurveConfigurations(),
const ore::data::TodaysMarketParameters todaysMarketParams = ore::data::TodaysMarketParameters(),
const bool  continueOnError = false,
const bool  useSpreadedTermStructures = false,
const bool  cacheSimData = false,
const bool  allowPartialScenarios = false,
const IborFallbackConfig iborFallbackConfig = IborFallbackConfig::defaultConfig(),
const bool  handlePseudoCurrencies = true,
const QuantLib::ext::shared_ptr< Scenario > &  offSetScenario = nullptr 
)

Definition at line 319 of file scenariosimmarket.cpp.

326 filter_(QuantLib::ext::make_shared<ScenarioFilter>()), useSpreadedTermStructures_(useSpreadedTermStructures),
327 cacheSimData_(cacheSimData), allowPartialScenarios_(allowPartialScenarios),
328 iborFallbackConfig_(iborFallbackConfig), offsetScenario_(offSetScenario) {
329
330 LOG("building ScenarioSimMarket...");
331 asof_ = initMarket->asofDate();
332 DLOG("AsOf " << QuantLib::io::iso_date(asof_));
333
334 // check ssm parameters
335 QL_REQUIRE(parameters_->interpolation() == "LogLinear" || parameters_->interpolation() == "LinearZero",
336 "ScenarioSimMarket: Interpolation (" << parameters_->interpolation()
337 << ") must be set to 'LogLinear' or 'LinearZero'");
338 QL_REQUIRE(parameters_->extrapolation() == "FlatZero" || parameters_->extrapolation() == "FlatFwd",
339 "ScenarioSimMarket: YieldCurves / Extrapolation ('" << parameters_->extrapolation()
340 << "') must be set to 'FlatZero' or 'FlatFwd'");
341 QL_REQUIRE(parameters_->defaultCurveExtrapolation() == "FlatZero" ||
342 parameters_->defaultCurveExtrapolation() == "FlatFwd",
343 "ScenarioSimMarket: DefaultCurves / Extrapolation ('" << parameters_->extrapolation()
344 << "') must be set to 'FlatZero' or 'FlatFwd'");
345
346 for (const auto& param : parameters->parameters()) {
347 try {
348 // we populate the temp containers for each curve and write the result to the global
349 // containers only if the set of data points is complete for this curve
350 std::map<RiskFactorKey, QuantLib::ext::shared_ptr<SimpleQuote>> simDataTmp;
351 std::map<RiskFactorKey, Real> absoluteSimDataTmp;
352
353 boost::timer::cpu_timer timer;
354
355 switch (param.first) {
357 std::map<std::string, Handle<Quote>> fxQuotes;
358 for (const auto& name : param.second.second) {
359 bool simDataWritten = false;
360 try {
361 // constructing fxSpots_
362 DLOG("adding " << name << " FX rates");
363 Real v = initMarket->fxSpot(name, configuration)->value();
364 auto q = QuantLib::ext::make_shared<SimpleQuote>(useSpreadedTermStructures_ ? 1.0 : v);
366 auto m = [v](Real x) { return x * v; };
367 fxQuotes[name] = Handle<Quote>(
368 QuantLib::ext::make_shared<DerivedQuote<decltype(m)>>(Handle<Quote>(q), m));
369 } else {
370 fxQuotes[name] = Handle<Quote>(q);
371 }
372 // Check if the risk factor is simulated before adding it
373 if (param.second.first) {
374 simDataTmp.emplace(std::piecewise_construct, std::forward_as_tuple(param.first, name),
375 std::forward_as_tuple(q));
377 absoluteSimDataTmp.emplace(std::piecewise_construct,
378 std::forward_as_tuple(param.first, name),
379 std::forward_as_tuple(v));
380 }
381 }
382 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name, {});
383 simDataWritten = true;
384 } catch (const std::exception& e) {
385 processException(continueOnError, e, name, param.first, simDataWritten);
386 }
387 }
388 fx_ = QuantLib::ext::make_shared<FXTriangulation>(fxQuotes);
389 break;
390 }
391
394 for (const auto& name : param.second.second) {
395 bool simDataWritten = false;
396 try {
397 DLOG("building " << name << " yield curve..");
398 vector<Period> tenors = parameters->yieldCurveTenors(name);
399 addYieldCurve(initMarket, configuration, param.first, name, tenors, simDataWritten,
400 param.second.first, useSpreadedTermStructures_);
401 DLOG("building " << name << " yield curve done");
402 } catch (const std::exception& e) {
403 processException(continueOnError, e, name, param.first, simDataWritten);
404 }
405 }
406 break;
407
409 // make sure we built overnight indices first, so that we can build ibor fallback indices
410 // that depend on them
411 std::vector<std::string> indices;
412 for (auto const& i : param.second.second) {
413 bool isOn = false;
414 try {
415 isOn = QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(*initMarket->iborIndex(i, configuration)) !=
416 nullptr;
417 } catch (...) {
418 }
419 if (isOn)
420 indices.insert(indices.begin(), i);
421 else
422 indices.push_back(i);
423 }
424 // loop over sorted indices and build them
425 for (const auto& name : indices) {
426 bool simDataWritten = false;
427 try {
428 DLOG("building " << name << " index curve");
429 std::vector<string> indexTokens;
430 split(indexTokens, name, boost::is_any_of("-"));
431 Handle<IborIndex> index;
432 if (indexTokens[1] == "GENERIC") {
433 // If we have a generic curve build the index using the index currency's discount curve
434 // no need to check for a convention based ibor index in this case
435 index = Handle<IborIndex>(
436 parseIborIndex(name, initMarket->discountCurve(indexTokens[0], configuration)));
437 } else {
438 index = initMarket->iborIndex(name, configuration);
439 }
440 QL_REQUIRE(!index.empty(), "index object for " << name << " not provided");
441 Handle<YieldTermStructure> wrapperIndex = index->forwardingTermStructure();
442 QL_REQUIRE(!wrapperIndex.empty(), "no termstructure for index " << name);
443 vector<string> keys(parameters->yieldCurveTenors(name).size());
444
445 DayCounter dc = wrapperIndex->dayCounter();
446 vector<Time> yieldCurveTimes(1, 0.0); // include today
447 vector<Date> yieldCurveDates(1, asof_);
448 QL_REQUIRE(parameters->yieldCurveTenors(name).front() > 0 * Days,
449 "yield curve tenors must not include t=0");
450 for (auto& tenor : parameters->yieldCurveTenors(name)) {
451 yieldCurveTimes.push_back(dc.yearFraction(asof_, asof_ + tenor));
452 yieldCurveDates.push_back(asof_ + tenor);
453 }
454
455 // include today
456 vector<Handle<Quote>> quotes;
457 QuantLib::ext::shared_ptr<SimpleQuote> q(new SimpleQuote(1.0));
458 quotes.push_back(Handle<Quote>(q));
459
460 for (Size i = 0; i < yieldCurveTimes.size() - 1; i++) {
461 Real val = wrapperIndex->discount(yieldCurveDates[i + 1]);
462 QuantLib::ext::shared_ptr<SimpleQuote> q(new SimpleQuote(useSpreadedTermStructures_ ? 1.0 : val));
463 Handle<Quote> qh(q);
464 quotes.push_back(qh);
465
466 simDataTmp.emplace(std::piecewise_construct, std::forward_as_tuple(param.first, name, i),
467 std::forward_as_tuple(q));
469 absoluteSimDataTmp.emplace(std::piecewise_construct,
470 std::forward_as_tuple(param.first, name, i),
471 std::forward_as_tuple(val));
472 }
473 // FIXME where do we check whether the risk factor is simulated?
474 DLOG("ScenarioSimMarket index curve " << name << " discount[" << i << "]=" << val);
475 }
476
477 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name,
478 {std::vector<Real>(std::next(yieldCurveTimes.begin(), 1), yieldCurveTimes.end())});
479 simDataWritten = true;
480
481 QuantLib::ext::shared_ptr<YieldTermStructure> indexCurve = makeYieldCurve(
482 name, useSpreadedTermStructures_, wrapperIndex, yieldCurveTimes, quotes, dc,
483 index->fixingCalendar(), parameters_->interpolation(), parameters_->extrapolation());
484
485 Handle<YieldTermStructure> ich(indexCurve);
486 if (wrapperIndex->allowsExtrapolation())
487 ich->enableExtrapolation();
488
489 QuantLib::ext::shared_ptr<IborIndex> i = index->clone(ich);
491 // handle ibor fallback indices
492 auto fallbackData = iborFallbackConfig_.fallbackData(name);
493 auto f = iborIndices_.find(make_pair(Market::defaultConfiguration, fallbackData.rfrIndex));
494 QL_REQUIRE(f != iborIndices_.end(),
495 "Could not build ibor fallback index '"
496 << name << "', because rfr index '" << fallbackData.rfrIndex
497 << "' is not present in scenario sim market, is the rfr index in the "
498 "scenario sim market parameters?");
499 auto rfrInd = QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(*f->second);
500 QL_REQUIRE(rfrInd != nullptr,
501 "Could not cast '"
502 << fallbackData.rfrIndex
503 << "' to overnight index when building the ibor fallback index '" << name
504 << "'");
505 if (auto original = QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(i))
506 i = QuantLib::ext::make_shared<QuantExt::FallbackOvernightIndex>(
507 original, rfrInd, fallbackData.spread, fallbackData.switchDate,
509 else
510 i = QuantLib::ext::make_shared<QuantExt::FallbackIborIndex>(
511 i, rfrInd, fallbackData.spread, fallbackData.switchDate,
513 DLOG("built ibor fall back index '"
514 << name << "' with rfr index '" << fallbackData.rfrIndex << "', spread "
515 << fallbackData.spread << ", use rfr curve in scen sim market: " << std::boolalpha
517 }
518 iborIndices_.insert(
519 make_pair(make_pair(Market::defaultConfiguration, name), Handle<IborIndex>(i)));
520 DLOG("building " << name << " index curve done");
521 } catch (const std::exception& e) {
522 processException(continueOnError, e, name, param.first, simDataWritten);
523 }
524 }
525 break;
526 }
527
529 for (const auto& name : param.second.second) {
530 bool simDataWritten = false;
531 try {
532 // building equity spots
533 DLOG("adding " << name << " equity spot...");
534 Real spotVal = initMarket->equitySpot(name, configuration)->value();
535 auto q = QuantLib::ext::make_shared<SimpleQuote>(useSpreadedTermStructures_ ? 1.0 : spotVal);
537 auto m = [spotVal](Real x) { return x * spotVal; };
538 equitySpots_.insert(
539 make_pair(make_pair(Market::defaultConfiguration, name),
540 Handle<Quote>(QuantLib::ext::make_shared<DerivedQuote<decltype(m)>>(
541 Handle<Quote>(q), m))));
542 } else {
543 equitySpots_.insert(
544 make_pair(make_pair(Market::defaultConfiguration, name), Handle<Quote>(q)));
545 }
546 simDataTmp.emplace(std::piecewise_construct, std::forward_as_tuple(param.first, name),
547 std::forward_as_tuple(q));
549 absoluteSimDataTmp.emplace(std::piecewise_construct,
550 std::forward_as_tuple(param.first, name),
551 std::forward_as_tuple(spotVal));
552 }
553 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name, {});
554 simDataWritten = true;
555 DLOG("adding " << name << " equity spot done");
556 } catch (const std::exception& e) {
557 processException(continueOnError, e, name, param.first, simDataWritten);
558 }
559 }
560 break;
561
563 for (const auto& name : param.second.second) {
564 bool simDataWritten = false;
565 try {
566 DLOG("building " << name << " equity dividend yield curve..");
567 vector<Period> tenors = parameters->equityDividendTenors(name);
568 addYieldCurve(initMarket, configuration, param.first, name, tenors, simDataWritten,
569 param.second.first, useSpreadedTermStructures_);
570 DLOG("building " << name << " equity dividend yield curve done");
571
572 // Equity spots and Yield/Index curves added first so we can now build equity index
573 // First get Forecast Curve
574 string forecastCurve;
575 if (curveConfigs.hasEquityCurveConfig(name)) {
576 // From the equity config, get the currency and forecast curve of the equity
577 auto eqVolConfig = curveConfigs.equityCurveConfig(name);
578 string forecastName = eqVolConfig->forecastingCurve();
579 string eqCcy = eqVolConfig->currency();
580 // Build a YieldCurveSpec and extract the yieldCurveSpec name
581 YieldCurveSpec ycspec(eqCcy, forecastName);
582 forecastCurve = ycspec.name();
583 TLOG("Got forecast curve '" << forecastCurve << "' from equity curve config for " << name);
584 }
585
586 // Get the nominal term structure from this scenario simulation market
587 Handle<YieldTermStructure> forecastTs =
588 getYieldCurve(forecastCurve, todaysMarketParams, Market::defaultConfiguration);
589 Handle<EquityIndex2> curve = initMarket->equityCurve(name, configuration);
590
591 // If forecast term structure is empty, fall back on this scenario simulation market's discount
592 // curve
593 if (forecastTs.empty()) {
594 string ccy = curve->currency().code();
595 TLOG("Falling back on the discount curve for currency '"
596 << ccy << "' for equity forecast curve '" << name << "'");
597 forecastTs = discountCurve(ccy);
598 }
599 QuantLib::ext::shared_ptr<EquityIndex2> ei(
600 curve->clone(equitySpot(name, configuration), forecastTs,
601 yieldCurve(YieldCurveType::EquityDividend, name, configuration)));
602 Handle<EquityIndex2> eh(ei);
603 equityCurves_.insert(make_pair(make_pair(Market::defaultConfiguration, name), eh));
604 } catch (const std::exception& e) {
605 processException(continueOnError, e, name, param.first, simDataWritten);
606 }
607 }
608 break;
609
611 for (const auto& name : param.second.second) {
612 // security spreads and recovery rates are optional
613 try {
614 DLOG("Adding security spread " << name << " from configuration " << configuration);
615 Real v = initMarket->securitySpread(name, configuration)->value();
616 auto q = QuantLib::ext::make_shared<SimpleQuote>(useSpreadedTermStructures_ ? 0.0 : v);
618 auto m = [v](Real x) { return x + v; };
619 securitySpreads_.insert(
620 make_pair(make_pair(Market::defaultConfiguration, name),
621 Handle<Quote>(QuantLib::ext::make_shared<DerivedQuote<decltype(m)>>(
622 Handle<Quote>(q), m))));
623 } else {
624 securitySpreads_.insert(
625 make_pair(make_pair(Market::defaultConfiguration, name), Handle<Quote>(q)));
626 }
627 if (param.second.first) {
628 simDataTmp.emplace(std::piecewise_construct, std::forward_as_tuple(param.first, name),
629 std::forward_as_tuple(q));
631 absoluteSimDataTmp.emplace(std::piecewise_construct,
632 std::forward_as_tuple(param.first, name),
633 std::forward_as_tuple(v));
634 }
635 }
636 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name, {});
637
638 } catch (const std::exception& e) {
639 DLOG("skipping this object: " << e.what());
640 }
641
642 try {
643 DLOG("Adding security recovery rate " << name << " from configuration " << configuration);
644 Real v = initMarket->recoveryRate(name, configuration)->value();
645 auto q = QuantLib::ext::make_shared<SimpleQuote>(useSpreadedTermStructures_ ? 1.0 : v);
647 auto m = [v](Real x) { return x * v; };
648 recoveryRates_.insert(
649 make_pair(make_pair(Market::defaultConfiguration, name),
650 Handle<Quote>(QuantLib::ext::make_shared<DerivedQuote<decltype(m)>>(
651 Handle<Quote>(q), m))));
652 } else {
653 recoveryRates_.insert(
654 make_pair(make_pair(Market::defaultConfiguration, name), Handle<Quote>(q)));
655 }
656
657 // TODO this comes from the default curves section in the parameters,
658 // do we want to specify the simulation of security recovery rates separately?
659 if (parameters->simulateRecoveryRates()) {
660 simDataTmp.emplace(std::piecewise_construct,
661 std::forward_as_tuple(RiskFactorKey::KeyType::RecoveryRate, name),
662 std::forward_as_tuple(q));
664 absoluteSimDataTmp.emplace(std::piecewise_construct,
665 std::forward_as_tuple(param.first, name),
666 std::forward_as_tuple(v));
667 }
668 }
669 writeSimData(simDataTmp, absoluteSimDataTmp, RiskFactorKey::KeyType::RecoveryRate, name, {});
670 } catch (const std::exception& e) {
671 DLOG("skipping this object: " << e.what());
672 }
673 }
674 break;
675
678 for (const auto& name : param.second.second) {
679 bool simDataWritten = false;
680 try {
681 // set parameters for swaption resp. yield vols
682 RelinkableHandle<SwaptionVolatilityStructure> wrapper;
683 vector<Period> optionTenors, underlyingTenors;
684 vector<Real> strikeSpreads;
685 string shortSwapIndexBase = "", swapIndexBase = "";
686 bool isCube, isAtm, simulateAtmOnly;
688 DLOG("building " << name << " swaption volatility curve...");
689 wrapper.linkTo(*initMarket->swaptionVol(name, configuration));
690 shortSwapIndexBase = initMarket->shortSwapIndexBase(name, configuration);
691 swapIndexBase = initMarket->swapIndexBase(name, configuration);
692 isCube = parameters->swapVolIsCube(name);
693 optionTenors = parameters->swapVolExpiries(name);
694 underlyingTenors = parameters->swapVolTerms(name);
695 strikeSpreads = parameters->swapVolStrikeSpreads(name);
696 simulateAtmOnly = parameters->simulateSwapVolATMOnly();
697 } else {
698 DLOG("building " << name << " yield volatility curve...");
699 wrapper.linkTo(*initMarket->yieldVol(name, configuration));
700 isCube = false;
701 optionTenors = parameters->yieldVolExpiries();
702 underlyingTenors = parameters->yieldVolTerms();
703 strikeSpreads = {0.0};
704 simulateAtmOnly = true;
705 }
706 DLOG("Initial market " << name << " yield volatility type = " << wrapper->volatilityType());
707
708 // Check if underlying market surface is atm or smile
709 isAtm = QuantLib::ext::dynamic_pointer_cast<SwaptionVolatilityMatrix>(*wrapper) != nullptr ||
710 QuantLib::ext::dynamic_pointer_cast<ConstantSwaptionVolatility>(*wrapper) != nullptr;
711
712 Handle<SwaptionVolatilityStructure> svp;
713 if (param.second.first) {
714 LOG("Simulating yield vols for ccy " << name);
715 DLOG("YieldVol T0 source is atm : " << (isAtm ? "True" : "False"));
716 DLOG("YieldVol ssm target is cube : " << (isCube ? "True" : "False"));
717 DLOG("YieldVol simulate atm only : " << (simulateAtmOnly ? "True" : "False"));
718 if (simulateAtmOnly) {
719 QL_REQUIRE(strikeSpreads.size() == 1 && close_enough(strikeSpreads[0], 0),
720 "for atmOnly strikeSpreads must be {0.0}");
721 }
722 QuantLib::ext::shared_ptr<QuantLib::SwaptionVolatilityCube> cube;
723 if (isCube && !isAtm) {
724 QuantLib::ext::shared_ptr<SwaptionVolCubeWithATM> tmp =
725 QuantLib::ext::dynamic_pointer_cast<SwaptionVolCubeWithATM>(*wrapper);
726 QL_REQUIRE(tmp, "swaption cube missing");
727 cube = tmp->cube();
728 }
729 vector<vector<Handle<Quote>>> quotes, atmQuotes;
730 quotes.resize(optionTenors.size() * underlyingTenors.size(),
731 vector<Handle<Quote>>(strikeSpreads.size(), Handle<Quote>()));
732 atmQuotes.resize(optionTenors.size(),
733 std::vector<Handle<Quote>>(underlyingTenors.size(), Handle<Quote>()));
734 vector<vector<Real>> shift(optionTenors.size(), vector<Real>(underlyingTenors.size(), 0.0));
735 Size atmSlice = std::find_if(strikeSpreads.begin(), strikeSpreads.end(),
736 [](const Real s) { return close_enough(s, 0.0); }) -
737 strikeSpreads.begin();
738 QL_REQUIRE(atmSlice < strikeSpreads.size(),
739 "could not find atm slice (strikeSpreads do not contain 0.0)");
740
741 // convert to normal if
742 // a) we have a swaption (i.e. not a yield) volatility and
743 // b) the T0 term structure is not normal
744 // c) we are not in the situation of simulating ATM only and having a non-normal cube in T0,
745 // since in this case the T0 structure is dynamically used to determine the sim market
746 // vols
747 // d) we do not use spreaded term structures, in which case we keep the original T0
748 // term structure in any case
749 bool convertToNormal = wrapper->volatilityType() != Normal &&
751 (!simulateAtmOnly || isAtm) && !useSpreadedTermStructures_;
752 DLOG("T0 ts is normal : " << (wrapper->volatilityType() == Normal ? "True"
753 : "False"));
754 DLOG("Have swaption vol : "
755 << (param.first == RiskFactorKey::KeyType::SwaptionVolatility ? "True" : "False"));
756 DLOG("Will convert to normal vol : " << (convertToNormal ? "True" : "False"));
757
758 // Set up a vol converter, and create if vol type is not normal
759 SwaptionVolatilityConverter* converter = nullptr;
760 if (convertToNormal) {
761 Handle<SwapIndex> swapIndex = initMarket->swapIndex(swapIndexBase, configuration);
762 Handle<SwapIndex> shortSwapIndex =
763 initMarket->swapIndex(shortSwapIndexBase, configuration);
764 converter = new SwaptionVolatilityConverter(asof_, *wrapper, *swapIndex,
765 *shortSwapIndex, Normal);
766 }
767
768 for (Size k = 0; k < strikeSpreads.size(); ++k) {
769 for (Size i = 0; i < optionTenors.size(); ++i) {
770 for (Size j = 0; j < underlyingTenors.size(); ++j) {
771 Real strike = Null<Real>();
772 if (!simulateAtmOnly && cube)
773 strike = cube->atmStrike(optionTenors[i], underlyingTenors[j]) +
774 strikeSpreads[k];
775 Real vol;
776 if (convertToNormal) {
777 // if not a normal volatility use the converted to convert to normal at
778 // given point
779 vol = converter->convert(wrapper->optionDateFromTenor(optionTenors[i]),
780 underlyingTenors[j], strikeSpreads[k],
781 wrapper->dayCounter(), Normal);
782 } else {
783 vol =
784 wrapper->volatility(optionTenors[i], underlyingTenors[j], strike, true);
785 }
786 QuantLib::ext::shared_ptr<SimpleQuote> q(
787 new SimpleQuote(useSpreadedTermStructures_ ? 0.0 : vol));
788
789 Size index = i * underlyingTenors.size() * strikeSpreads.size() +
790 j * strikeSpreads.size() + k;
791
792 simDataTmp.emplace(std::piecewise_construct,
793 std::forward_as_tuple(param.first, name, index),
794 std::forward_as_tuple(q));
796 absoluteSimDataTmp.emplace(std::piecewise_construct,
797 std::forward_as_tuple(param.first, name, index),
798 std::forward_as_tuple(vol));
799 }
800 auto tmp = Handle<Quote>(q);
801 quotes[i * underlyingTenors.size() + j][k] = tmp;
802 if (k == atmSlice) {
803 atmQuotes[i][j] = tmp;
804 shift[i][j] =
805 !convertToNormal && wrapper->volatilityType() == ShiftedLognormal
806 ? wrapper->shift(optionTenors[i], underlyingTenors[j])
807 : 0.0;
808 DLOG("AtmVol at " << optionTenors.at(i) << "/" << underlyingTenors.at(j)
809 << " is " << vol << ", shift is " << shift[i][j]
810 << ", (name,index) = (" << name << "," << index << ")");
811 } else {
812 DLOG("SmileVol at " << optionTenors.at(i) << "/" << underlyingTenors.at(j)
813 << "/" << strikeSpreads.at(k) << " is " << vol
814 << ", (name,index) = (" << name << "," << index << ")");
815 }
816 }
817 }
818 }
819
820 std::vector<std::vector<Real>> coordinates(3);
821 for (Size i = 0; i < optionTenors.size(); ++i) {
822 coordinates[0].push_back(
823 wrapper->timeFromReference(wrapper->optionDateFromTenor(optionTenors[i])));
824 }
825 for (Size j = 0; j < underlyingTenors.size(); ++j) {
826 coordinates[1].push_back(wrapper->swapLength(underlyingTenors[j]));
827 }
828 for (Size k = 0; k < strikeSpreads.size(); ++k) {
829 coordinates[2].push_back(strikeSpreads[k]);
830 }
831
832 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name, coordinates);
833 simDataWritten = true;
834 bool flatExtrapolation = true; // FIXME: get this from curve configuration
835 VolatilityType volType = convertToNormal ? Normal : wrapper->volatilityType();
836 DayCounter dc = wrapper->dayCounter();
837
839 bool stickyStrike = parameters_->swapVolSmileDynamics(name) == "StickyStrike";
840 QuantLib::ext::shared_ptr<SwapIndex> swapIndex, shortSwapIndex;
841 QuantLib::ext::shared_ptr<SwapIndex> simSwapIndex, simShortSwapIndex;
842 if (!stickyStrike) {
843 if (addSwapIndexToSsm(swapIndexBase, continueOnError)) {
844 simSwapIndex = *this->swapIndex(swapIndexBase, configuration);
845 }
846 if (addSwapIndexToSsm(shortSwapIndexBase, continueOnError)) {
847 simShortSwapIndex = *this->swapIndex(shortSwapIndexBase, configuration);
848 }
849 if (simSwapIndex == nullptr || simShortSwapIndex == nullptr)
850 stickyStrike = true;
851 }
852 if(!swapIndexBase.empty())
853 swapIndex = *initMarket->swapIndex(swapIndexBase, configuration);
854 if(!shortSwapIndexBase.empty())
855 shortSwapIndex = *initMarket->swapIndex(shortSwapIndexBase, configuration);
856 svp =
857 Handle<SwaptionVolatilityStructure>(QuantLib::ext::make_shared<SpreadedSwaptionVolatility>(
858 wrapper, optionTenors, underlyingTenors, strikeSpreads, quotes, swapIndex,
859 shortSwapIndex, simSwapIndex, simShortSwapIndex, !stickyStrike));
860 } else {
861 Handle<SwaptionVolatilityStructure> atm;
862 atm = Handle<SwaptionVolatilityStructure>(QuantLib::ext::make_shared<SwaptionVolatilityMatrix>(
863 wrapper->calendar(), wrapper->businessDayConvention(), optionTenors,
864 underlyingTenors, atmQuotes, dc, flatExtrapolation, volType, shift));
865 atm->enableExtrapolation(); // see below for svp, take this from T0 config?
866 if (simulateAtmOnly) {
867 if (isAtm) {
868 svp = atm;
869 } else {
870 // floating reference date matrix in sim market
871 // if we have a cube, we keep the vol spreads constant under scenarios
872 // notice that cube is from todaysmarket, so it has a fixed reference date,
873 // which means that we keep the smiles constant in terms of vol spreads when
874 // moving forward in time; notice also that the volatility will be "sticky
875 // strike", i.e. it will not react to changes in the ATM level
876 svp = Handle<SwaptionVolatilityStructure>(
877 QuantLib::ext::make_shared<SwaptionVolatilityConstantSpread>(atm, wrapper));
878 }
879 } else {
880 if (isCube) {
881 QuantLib::ext::shared_ptr<SwaptionVolatilityCube> tmp(new QuantExt::SwaptionVolCube2(
882 atm, optionTenors, underlyingTenors, strikeSpreads, quotes,
883 *initMarket->swapIndex(swapIndexBase, configuration),
884 *initMarket->swapIndex(shortSwapIndexBase, configuration), false,
885 flatExtrapolation, false));
886 tmp->setAdjustReferenceDate(false);
887 svp = Handle<SwaptionVolatilityStructure>(
888 QuantLib::ext::make_shared<SwaptionVolCubeWithATM>(tmp));
889 } else {
890 svp = atm;
891 }
892 }
893 }
894 } else {
895 string decayModeString = parameters->swapVolDecayMode();
896 ReactionToTimeDecay decayMode = parseDecayMode(decayModeString);
897 DLOG("Dynamic (" << wrapper->volatilityType() << ") yield vols (" << decayModeString
898 << ") for qualifier " << name);
899
900 QL_REQUIRE(!QuantLib::ext::dynamic_pointer_cast<ProxySwaptionVolatility>(*wrapper),
901 "DynamicSwaptionVolatilityMatrix does not support ProxySwaptionVolatility surface");
902
903 QuantLib::ext::shared_ptr<SwaptionVolatilityStructure> atmSlice;
904 if (isAtm)
905 atmSlice = *wrapper;
906 else {
907 auto c = QuantLib::ext::dynamic_pointer_cast<SwaptionVolCubeWithATM>(*wrapper);
908 QL_REQUIRE(c, "internal error - expected swaption cube to be SwaptionVolCubeWithATM.");
909 atmSlice = *c->cube()->atmVol();
910 }
911
912 if (isCube)
913 WLOG("Only ATM slice is considered from init market's cube");
914 QuantLib::ext::shared_ptr<QuantLib::SwaptionVolatilityStructure> svolp =
915 QuantLib::ext::make_shared<QuantExt::DynamicSwaptionVolatilityMatrix>(
916 atmSlice, 0, NullCalendar(), decayMode);
917 svp = Handle<SwaptionVolatilityStructure>(svolp);
918 }
919 svp->setAdjustReferenceDate(false);
920 svp->enableExtrapolation(); // FIXME
921
922 DLOG("Simulation market " << name << " yield volatility type = " << svp->volatilityType());
923
925 swaptionCurves_.insert(make_pair(make_pair(Market::defaultConfiguration, name), svp));
926 swaptionIndexBases_.insert(make_pair(make_pair(Market::defaultConfiguration, name),
927 make_pair(shortSwapIndexBase, swapIndexBase)));
928 swaptionIndexBases_.insert(make_pair(make_pair(Market::defaultConfiguration, name),
929 make_pair(swapIndexBase, swapIndexBase)));
930 } else {
931 yieldVolCurves_.insert(make_pair(make_pair(Market::defaultConfiguration, name), svp));
932 }
933 } catch (const std::exception& e) {
934 processException(continueOnError, e, name, param.first, simDataWritten);
935 }
936 }
937 break;
938
940 for (const auto& name : param.second.second) {
941 bool simDataWritten = false;
942 try {
943 LOG("building " << name << " cap/floor volatility curve...");
944 Handle<OptionletVolatilityStructure> wrapper = initMarket->capFloorVol(name, configuration);
945 auto [iborIndexName, rateComputationPeriod] =
946 initMarket->capFloorVolIndexBase(name, configuration);
947 QuantLib::ext::shared_ptr<IborIndex> iborIndex =
948 iborIndexName.empty() ? nullptr : parseIborIndex(iborIndexName);
949
950 LOG("Initial market cap/floor volatility type = " << wrapper->volatilityType());
951
952 Handle<OptionletVolatilityStructure> hCapletVol;
953
954 // Check if the risk factor is simulated before adding it
955 if (param.second.first) {
956 LOG("Simulating Cap/Floor Optionlet vols for key " << name);
957
958 // Try to get the ibor index that the cap floor structure relates to
959 // We use this to convert Period to Date below to sample from `wrapper`
960 Natural settleDays = 0;
961 bool isOis = false;
962 Calendar iborCalendar;
963 Size onSettlementDays = 0;
964
965 // get the curve config for the index, or if not available for its ccy
966 QuantLib::ext::shared_ptr<CapFloorVolatilityCurveConfig> config;
967 if (curveConfigs.hasCapFloorVolCurveConfig(name)) {
968 config = curveConfigs.capFloorVolCurveConfig(name);
969 } else {
970 if (iborIndex && curveConfigs.hasCapFloorVolCurveConfig(iborIndex->currency().code())) {
971 config = curveConfigs.capFloorVolCurveConfig(iborIndex->currency().code());
972 }
973 }
974
975 // get info from the config if we have one
976 if (config) {
977 settleDays = config->settleDays();
978 onSettlementDays = config->onCapSettlementDays();
979 }
980
981 // derive info from the ibor index
982 if (iborIndex) {
983 iborCalendar = iborIndex->fixingCalendar();
984 isOis = QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(iborIndex) != nullptr;
985 }
986
987 vector<Period> optionTenors = parameters->capFloorVolExpiries(name);
988 vector<Date> optionDates(optionTenors.size());
989
990 vector<Real> strikes = parameters->capFloorVolStrikes(name);
991 bool isAtm = false;
992 // Strikes may be empty here which means that an ATM curve has been configured
993 if (strikes.empty()) {
994 QL_REQUIRE(
995 parameters->capFloorVolIsAtm(name),
996 "Strikes for "
997 << name
998 << " is empty in simulation parameters so expected its ATM flag to be true");
999 strikes = {0.0};
1000 isAtm = true;
1001 }
1002
1003 vector<vector<Handle<Quote>>> quotes(
1004 optionTenors.size(), vector<Handle<Quote>>(strikes.size(), Handle<Quote>()));
1005
1006 DLOG("cap floor use adjusted option pillars = " << std::boolalpha << parameters_->capFloorVolAdjustOptionletPillars());
1007 DLOG("have ibor index = " << std::boolalpha << (iborIndex != nullptr));
1008
1009 Rate atmStrike = Null<Rate>();
1010 for (Size i = 0; i < optionTenors.size(); ++i) {
1011
1012 if (parameters_->capFloorVolAdjustOptionletPillars() && iborIndex) {
1013 // If we ask for cap pillars at tenors t_i for i = 1,...,N, we should attempt to
1014 // place the optionlet pillars at the fixing date of the last optionlet in the cap
1015 // with tenor t_i, if capFloorVolAdjustOptionletPillars is true.
1016 if(isOis) {
1017 Leg capFloor =
1019 CapFloor::Cap, optionTenors[i],
1020 QuantLib::ext::dynamic_pointer_cast<QuantLib::OvernightIndex>(iborIndex),
1021 rateComputationPeriod, 0.0)
1023 .withSettlementDays(onSettlementDays);
1024 if (capFloor.empty()) {
1025 optionDates[i] = asof_ + 1;
1026 } else {
1027 auto lastCoupon = QuantLib::ext::dynamic_pointer_cast<
1029 QL_REQUIRE(lastCoupon, "SSM internal error, could not cast to "
1030 "CappedFlooredOvernightIndexedCoupon "
1031 "when building optionlet vol for '"
1032 << name << "' (index=" << iborIndex->name()
1033 << ")");
1034 optionDates[i] =
1035 std::max(asof_ + 1, lastCoupon->underlying()->fixingDates().front());
1036 }
1037 } else {
1038 QuantLib::ext::shared_ptr<CapFloor> capFloor =
1039 MakeCapFloor(CapFloor::Cap, optionTenors[i], iborIndex, 0.0, 0 * Days);
1040 if (capFloor->floatingLeg().empty()) {
1041 optionDates[i] = asof_ + 1;
1042 } else {
1043 optionDates[i] =
1044 std::max(asof_ + 1, capFloor->lastFloatingRateCoupon()->fixingDate());
1045 }
1046 }
1047 QL_REQUIRE(i == 0 || optionDates[i] > optionDates[i - 1],
1048 "SSM: got non-increasing option dates "
1049 << optionDates[i - 1] << ", " << optionDates[i] << " for tenors "
1050 << optionTenors[i - 1] << ", " << optionTenors[i] << " for index "
1051 << iborIndex->name());
1052 } else {
1053 // Otherwise, just place the optionlet pillars at the configured tenors.
1054 optionDates[i] = wrapper->optionDateFromTenor(optionTenors[i]);
1055 if (iborCalendar != Calendar()) {
1056 // In case the original cap floor surface has the incorrect calendar configured.
1057 optionDates[i] = iborCalendar.adjust(optionDates[i]);
1058 }
1059 }
1060
1061 DLOG("Option [tenor, date] pair is [" << optionTenors[i] << ", "
1062 << io::iso_date(optionDates[i]) << "]");
1063
1064 // If ATM, use initial market's discount curve and ibor index to calculate ATM rate
1065 if (isAtm) {
1066 QL_REQUIRE(iborIndex != nullptr,
1067 "SSM: Expected ibor index for key "
1068 << name << " from the key or a curve config for a ccy");
1069 auto t0_iborIndex = *initMarket->iborIndex(
1070 IndexNameTranslator::instance().oreName(iborIndex->name()), configuration);
1071 if (parameters_->capFloorVolUseCapAtm()) {
1072 QL_REQUIRE(!isOis, "SSM: capFloorVolUseCapATM not supported for OIS indices ("
1073 << t0_iborIndex->name() << ")");
1074 QuantLib::ext::shared_ptr<CapFloor> cap =
1075 MakeCapFloor(CapFloor::Cap, optionTenors[i], t0_iborIndex, 0.0, 0 * Days);
1076 atmStrike = cap->atmRate(**initMarket->discountCurve(name, configuration));
1077 } else {
1078 if (isOis) {
1079 Leg capFloor =
1080 MakeOISCapFloor(CapFloor::Cap, optionTenors[i],
1081 QuantLib::ext::dynamic_pointer_cast<OvernightIndex>(t0_iborIndex),
1082 rateComputationPeriod, 0.0)
1084 .withSettlementDays(onSettlementDays);
1085 if (capFloor.empty()) {
1086 atmStrike = t0_iborIndex->fixing(optionDates[i]);
1087 } else {
1088 auto lastCoupon =
1089 QuantLib::ext::dynamic_pointer_cast<CappedFlooredOvernightIndexedCoupon>(
1090 capFloor.back());
1091 QL_REQUIRE(lastCoupon, "SSM internal error, could not cast to "
1092 "CappedFlooredOvernightIndexedCoupon "
1093 "when building optionlet vol for '"
1094 << name << "', index=" << t0_iborIndex->name());
1095 atmStrike = lastCoupon->underlying()->rate();
1096 }
1097 } else {
1098 atmStrike = t0_iborIndex->fixing(optionDates[i]);
1099 }
1100 }
1101 }
1102
1103 for (Size j = 0; j < strikes.size(); ++j) {
1104 Real strike = isAtm ? atmStrike : strikes[j];
1105 Real vol =
1106 wrapper->volatility(optionDates[i], strike, true);
1107 DLOG("Vol at [date, strike] pair [" << optionDates[i] << ", " << std::fixed
1108 << std::setprecision(4) << strike << "] is "
1109 << std::setprecision(12) << vol);
1110 QuantLib::ext::shared_ptr<SimpleQuote> q =
1111 QuantLib::ext::make_shared<SimpleQuote>(useSpreadedTermStructures_ ? 0.0 : vol);
1112 Size index = i * strikes.size() + j;
1113 simDataTmp.emplace(std::piecewise_construct,
1114 std::forward_as_tuple(param.first, name, index),
1115 std::forward_as_tuple(q));
1117 absoluteSimDataTmp.emplace(std::piecewise_construct,
1118 std::forward_as_tuple(param.first, name, index),
1119 std::forward_as_tuple(vol));
1120 }
1121 quotes[i][j] = Handle<Quote>(q);
1122 }
1123 }
1124
1125 std::vector<std::vector<Real>> coordinates(2);
1126 for(Size i=0;i<optionTenors.size();++i) {
1127 coordinates[0].push_back(
1128 wrapper->timeFromReference(wrapper->optionDateFromTenor(optionTenors[i])));
1129 }
1130 for(Size j=0;j<strikes.size();++j) {
1131 coordinates[1].push_back(isAtm ? atmStrike : strikes[j]);
1132 }
1133
1134 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name, coordinates);
1135 simDataWritten = true;
1136
1137 DayCounter dc = wrapper->dayCounter();
1138
1140 hCapletVol = Handle<OptionletVolatilityStructure>(
1141 QuantLib::ext::make_shared<QuantExt::SpreadedOptionletVolatility2>(wrapper, optionDates,
1142 strikes, quotes));
1143 } else {
1144 // FIXME: Works as of today only, i.e. for sensitivity/scenario analysis.
1145 // TODO: Build floating reference date StrippedOptionlet class for MC path generators
1146 QuantLib::ext::shared_ptr<StrippedOptionlet> optionlet = QuantLib::ext::make_shared<StrippedOptionlet>(
1147 settleDays, wrapper->calendar(), wrapper->businessDayConvention(), iborIndex,
1148 optionDates, strikes, quotes, dc, wrapper->volatilityType(),
1149 wrapper->displacement());
1150
1151 hCapletVol = Handle<OptionletVolatilityStructure>(
1153 optionlet));
1154 }
1155 } else {
1156 string decayModeString = parameters->capFloorVolDecayMode();
1157 ReactionToTimeDecay decayMode = parseDecayMode(decayModeString);
1158
1159 QL_REQUIRE(!QuantLib::ext::dynamic_pointer_cast<ProxyOptionletVolatility>(*wrapper),
1160 "DynamicOptionletVolatilityStructure does not support ProxyOptionletVolatility surface.");
1161
1162 QuantLib::ext::shared_ptr<OptionletVolatilityStructure> capletVol =
1163 QuantLib::ext::make_shared<DynamicOptionletVolatilityStructure>(*wrapper, 0, NullCalendar(),
1164 decayMode);
1165 hCapletVol = Handle<OptionletVolatilityStructure>(capletVol);
1166 }
1167 hCapletVol->setAdjustReferenceDate(false);
1168 hCapletVol->enableExtrapolation();
1169 capFloorCurves_.emplace(std::piecewise_construct,
1170 std::forward_as_tuple(Market::defaultConfiguration, name),
1171 std::forward_as_tuple(hCapletVol));
1172 capFloorIndexBase_.emplace(
1173 std::piecewise_construct, std::forward_as_tuple(Market::defaultConfiguration, name),
1174 std::forward_as_tuple(std::make_pair(iborIndexName, rateComputationPeriod)));
1175
1176 LOG("Simulation market cap/floor volatility type = " << hCapletVol->volatilityType());
1177 } catch (const std::exception& e) {
1178 processException(continueOnError, e, name, param.first, simDataWritten);
1179 }
1180 }
1181 break;
1182
1184 for (const auto& name : param.second.second) {
1185 bool simDataWritten = false;
1186 try {
1187 LOG("building " << name << " default curve..");
1188 auto wrapper = initMarket->defaultCurve(name, configuration);
1189 vector<Handle<Quote>> quotes;
1190
1191 QL_REQUIRE(parameters->defaultTenors(name).front() > 0 * Days,
1192 "default curve tenors must not include t=0");
1193
1194 vector<Date> dates(1, asof_);
1195 vector<Real> times(1, 0.0);
1196
1197 DayCounter dc = wrapper->curve()->dayCounter();
1198
1199 for (Size i = 0; i < parameters->defaultTenors(name).size(); i++) {
1200 dates.push_back(asof_ + parameters->defaultTenors(name)[i]);
1201 times.push_back(dc.yearFraction(asof_, dates.back()));
1202 }
1203
1204 QuantLib::ext::shared_ptr<SimpleQuote> q(new SimpleQuote(1.0));
1205 quotes.push_back(Handle<Quote>(q));
1206 for (Size i = 0; i < dates.size() - 1; i++) {
1207 Probability prob = wrapper->curve()->survivalProbability(dates[i + 1], true);
1208 QuantLib::ext::shared_ptr<SimpleQuote> q =
1209 QuantLib::ext::make_shared<SimpleQuote>(useSpreadedTermStructures_ ? 1.0 : prob);
1210 // Check if the risk factor is simulated before adding it
1211 if (param.second.first) {
1212 simDataTmp.emplace(std::piecewise_construct,
1213 std::forward_as_tuple(param.first, name, i),
1214 std::forward_as_tuple(q));
1215 DLOG("ScenarioSimMarket default curve " << name << " survival[" << i << "]=" << prob);
1217 absoluteSimDataTmp.emplace(std::piecewise_construct,
1218 std::forward_as_tuple(param.first, name, i),
1219 std::forward_as_tuple(prob));
1220 }
1221 }
1222 Handle<Quote> qh(q);
1223 quotes.push_back(qh);
1224 }
1225 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name,
1226 {std::vector<Real>(std::next(times.begin(), 1), times.end())});
1227 simDataWritten = true;
1228 Calendar cal = ore::data::parseCalendar(parameters->defaultCurveCalendar(name));
1229 Handle<DefaultProbabilityTermStructure> defaultCurve;
1231 defaultCurve = Handle<DefaultProbabilityTermStructure>(
1232 QuantLib::ext::make_shared<QuantExt::SpreadedSurvivalProbabilityTermStructure>(
1233 wrapper->curve(), times, quotes,
1234 parameters->defaultCurveExtrapolation() == "FlatZero"
1235 ? QuantExt::SpreadedSurvivalProbabilityTermStructure::Extrapolation::flatZero
1236 : QuantExt::SpreadedSurvivalProbabilityTermStructure::Extrapolation::flatFwd));
1237 } else {
1238 defaultCurve = Handle<DefaultProbabilityTermStructure>(
1239 QuantLib::ext::make_shared<QuantExt::SurvivalProbabilityCurve<LogLinear>>(
1240 dates, quotes, dc, cal, std::vector<Handle<Quote>>(), std::vector<Date>(),
1241 LogLinear(),
1242 parameters->defaultCurveExtrapolation() == "FlatZero"
1245 }
1246 defaultCurve->setAdjustReferenceDate(false);
1247 defaultCurve->enableExtrapolation();
1248 defaultCurves_.insert(make_pair(
1249 make_pair(Market::defaultConfiguration, name),
1250 Handle<CreditCurve>(QuantLib::ext::make_shared<CreditCurve>(
1251 defaultCurve, wrapper->rateCurve(), wrapper->recovery(), wrapper->refData()))));
1252 } catch (const std::exception& e) {
1253 processException(continueOnError, e, name, param.first, simDataWritten);
1254 }
1255 }
1256 break;
1257
1259 for (const auto& name : param.second.second) {
1260 bool simDataWritten = false;
1261 try {
1262 DLOG("Adding security recovery rate " << name << " from configuration " << configuration);
1263 Real v = initMarket->recoveryRate(name, configuration)->value();
1264 auto q = QuantLib::ext::make_shared<SimpleQuote>(useSpreadedTermStructures_ ? 1.0 : v);
1266 auto m = [v](Real x) { return x * v; };
1267 recoveryRates_.insert(
1268 make_pair(make_pair(Market::defaultConfiguration, name),
1269 Handle<Quote>(QuantLib::ext::make_shared<DerivedQuote<decltype(m)>>(
1270 Handle<Quote>(q), m))));
1271 } else {
1272 recoveryRates_.insert(
1273 make_pair(make_pair(Market::defaultConfiguration, name), Handle<Quote>(q)));
1274 }
1275 // Check if the risk factor is simulated before adding it
1276 if (param.second.first) {
1277 simDataTmp.emplace(std::piecewise_construct,
1278 std::forward_as_tuple(RiskFactorKey::KeyType::RecoveryRate, name),
1279 std::forward_as_tuple(q));
1281 absoluteSimDataTmp.emplace(
1282 std::piecewise_construct,
1283 std::forward_as_tuple(RiskFactorKey::KeyType::RecoveryRate, name),
1284 std::forward_as_tuple(v));
1285 }
1286 }
1287 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name, {});
1288 simDataWritten = true;
1289 recoveryRates_.insert(
1290 make_pair(make_pair(Market::defaultConfiguration, name), Handle<Quote>(q)));
1291 } catch (const std::exception& e) {
1292 processException(continueOnError, e, name, param.first, simDataWritten);
1293 }
1294 }
1295 break;
1296
1298 for (const auto& name : param.second.second) {
1299 bool simDataWritten = false;
1300 try {
1301 LOG("building " << name << " cds vols..");
1302 Handle<QuantExt::CreditVolCurve> wrapper = initMarket->cdsVol(name, configuration);
1303 Handle<QuantExt::CreditVolCurve> cvh;
1304 bool stickyStrike = parameters_->cdsVolSmileDynamics(name) == "StickyStrike";
1305 if (param.second.first) {
1306 LOG("Simulating CDS Vols for " << name);
1307 vector<Handle<Quote>> quotes;
1308 vector<Volatility> vols;
1309 vector<Time> times;
1310 vector<Date> expiryDates;
1311 DayCounter dc = wrapper->dayCounter();
1312 for (Size i = 0; i < parameters->cdsVolExpiries().size(); i++) {
1313 Date date = asof_ + parameters->cdsVolExpiries()[i];
1314 expiryDates.push_back(date);
1315 // hardcoded, single term 5y
1316 Volatility vol = wrapper->volatility(date, 5.0, Null<Real>(), wrapper->type());
1317 vols.push_back(vol);
1318 times.push_back(dc.yearFraction(asof_, date));
1319 QuantLib::ext::shared_ptr<SimpleQuote> q =
1320 QuantLib::ext::make_shared<SimpleQuote>(useSpreadedTermStructures_ ? 0.0 : vol);
1321 if (parameters->simulateCdsVols()) {
1322 simDataTmp.emplace(std::piecewise_construct,
1323 std::forward_as_tuple(param.first, name, i),
1324 std::forward_as_tuple(q));
1326 absoluteSimDataTmp.emplace(std::piecewise_construct,
1327 std::forward_as_tuple(param.first, name, i),
1328 std::forward_as_tuple(vol));
1329 }
1330 }
1331 quotes.emplace_back(q);
1332 }
1333 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name, {times});
1334 simDataWritten = true;
1336 (!useSpreadedTermStructures_ && parameters->simulateCdsVolATMOnly())) {
1337 std::vector<Handle<Quote>> spreads;
1338 if (parameters_->simulateCdsVolATMOnly()) {
1339 for (size_t i = 0; i < quotes.size(); i++) {
1340 Handle<Quote> atmVol(QuantLib::ext::make_shared<SimpleQuote>(quotes[i]->value()));
1341 Handle<Quote> quote(QuantLib::ext::make_shared <
1342 CompositeQuote<std::minus<double>>>(quotes[i], atmVol,
1343 std::minus<double>()));
1344 spreads.push_back(quote);
1345 }
1346 } else {
1347 spreads = quotes;
1348 }
1349 std::vector<QuantLib::Period> simTerms;
1350 std::vector<Handle<CreditCurve>> simTermCurves;
1351 if (curveConfigs.hasCdsVolCurveConfig(name)) {
1352 // get the term curves from the curve config if possible
1353 auto cc = curveConfigs.cdsVolCurveConfig(name);
1354 simTerms = cc->terms();
1355 for (auto const& c : cc->termCurves())
1356 simTermCurves.push_back(defaultCurve(parseCurveSpec(c)->curveConfigID()));
1357 } else {
1358 // assume the default curve names follow the naming convention volName_5Y
1359 simTerms = wrapper->terms();
1360 for (auto const& t : simTerms) {
1361 simTermCurves.push_back(defaultCurve(name + "_" + ore::data::to_string(t)));
1362 }
1363 }
1364 cvh = Handle<CreditVolCurve>(QuantLib::ext::make_shared<SpreadedCreditVolCurve>(
1365 wrapper, expiryDates, spreads, !stickyStrike, simTerms, simTermCurves));
1366 } else {
1367 // TODO support strike and term dependence
1368 cvh = Handle<CreditVolCurve>(QuantLib::ext::make_shared<CreditVolCurveWrapper>(
1369 Handle<BlackVolTermStructure>(QuantLib::ext::make_shared<BlackVarianceCurve3>(
1370 0, NullCalendar(), wrapper->businessDayConvention(), dc, times, quotes,
1371 false))));
1372 }
1373 } else {
1374 string decayModeString = parameters->cdsVolDecayMode();
1375 LOG("Deterministic CDS Vols with decay mode " << decayModeString << " for " << name);
1376 ReactionToTimeDecay decayMode = parseDecayMode(decayModeString);
1377
1378 // TODO support strike and term dependence, hardcoded term 5y
1379 cvh = Handle<CreditVolCurve>(
1380 QuantLib::ext::make_shared<CreditVolCurveWrapper>(Handle<BlackVolTermStructure>(
1381 QuantLib::ext::make_shared<QuantExt::DynamicBlackVolTermStructure<tag::curve>>(
1382 Handle<BlackVolTermStructure>(
1383 QuantLib::ext::make_shared<BlackVolFromCreditVolWrapper>(wrapper, 5.0)),
1384 0, NullCalendar(), decayMode,
1385 stickyStrike ? StickyStrike : StickyLogMoneyness))));
1386 }
1387 cvh->setAdjustReferenceDate(false);
1388 if (wrapper->allowsExtrapolation())
1389 cvh->enableExtrapolation();
1390 cdsVols_.insert(make_pair(make_pair(Market::defaultConfiguration, name), cvh));
1391 } catch (const std::exception& e) {
1392 processException(continueOnError, e, name, param.first, simDataWritten);
1393 }
1394 }
1395 break;
1396
1398 for (const auto& name : param.second.second) {
1399 bool simDataWritten = false;
1400 try {
1401 Handle<BlackVolTermStructure> wrapper = initMarket->fxVol(name, configuration);
1402 Handle<Quote> spot = fxSpot(name);
1403 QL_REQUIRE(name.length() == 6, "invalid ccy pair length");
1404 string forCcy = name.substr(0, 3);
1405 string domCcy = name.substr(3, 3);
1406
1407 // Get the yield curve IDs from the FX volatility configuration
1408 // They may still be empty
1409 string foreignTsId;
1410 string domesticTsId;
1411 if (curveConfigs.hasFxVolCurveConfig(name)) {
1412 auto fxVolConfig = curveConfigs.fxVolCurveConfig(name);
1413 foreignTsId = fxVolConfig->fxForeignYieldCurveID();
1414 TLOG("Got foreign term structure '" << foreignTsId
1415 << "' from FX volatility curve config for " << name);
1416 domesticTsId = fxVolConfig->fxDomesticYieldCurveID();
1417 TLOG("Got domestic term structure '" << domesticTsId
1418 << "' from FX volatility curve config for " << name);
1419 }
1420 Handle<BlackVolTermStructure> fvh;
1421
1422 bool stickyStrike = parameters_->fxVolSmileDynamics(name) == "StickyStrike";
1423
1424 if (param.second.first) {
1425 LOG("Simulating FX Vols for " << name);
1426 auto& expiries = parameters->fxVolExpiries(name);
1427 Size m = expiries.size();
1428 Calendar cal = wrapper->calendar();
1429 if (cal.empty()) {
1430 cal = NullCalendar();
1431 }
1432 DayCounter dc = wrapper->dayCounter();
1433 vector<vector<Handle<Quote>>> quotes;
1434 vector<Time> times(m);
1435 vector<Date> dates(m);
1436
1437 // Attempt to get the relevant yield curves from the initial market
1438 Handle<YieldTermStructure> initForTS =
1439 getYieldCurve(foreignTsId, todaysMarketParams, configuration, initMarket);
1440 TLOG("Foreign term structure '" << foreignTsId << "' from t_0 market is "
1441 << (initForTS.empty() ? "empty" : "not empty"));
1442 Handle<YieldTermStructure> initDomTS =
1443 getYieldCurve(domesticTsId, todaysMarketParams, configuration, initMarket);
1444 TLOG("Domestic term structure '" << domesticTsId << "' from t_0 market is "
1445 << (initDomTS.empty() ? "empty" : "not empty"));
1446
1447 // fall back on discount curves
1448 if (initForTS.empty() || initDomTS.empty()) {
1449 TLOG("Falling back on the discount curves for " << forCcy << " and " << domCcy
1450 << " from t_0 market");
1451 initForTS = initMarket->discountCurve(forCcy, configuration);
1452 initDomTS = initMarket->discountCurve(domCcy, configuration);
1453 }
1454
1455 // Attempt to get the relevant yield curves from this scenario simulation market
1456 Handle<YieldTermStructure> forTS =
1457 getYieldCurve(foreignTsId, todaysMarketParams, Market::defaultConfiguration);
1458 TLOG("Foreign term structure '" << foreignTsId << "' from sim market is "
1459 << (forTS.empty() ? "empty" : "not empty"));
1460 Handle<YieldTermStructure> domTS =
1461 getYieldCurve(domesticTsId, todaysMarketParams, Market::defaultConfiguration);
1462 TLOG("Domestic term structure '" << domesticTsId << "' from sim market is "
1463 << (domTS.empty() ? "empty" : "not empty"));
1464
1465 // fall back on discount curves
1466 if (forTS.empty() || domTS.empty()) {
1467 TLOG("Falling back on the discount curves for " << forCcy << " and " << domCcy
1468 << " from sim market");
1469 forTS = discountCurve(forCcy);
1470 domTS = discountCurve(domCcy);
1471 }
1472
1473 for (Size k = 0; k < m; k++) {
1474 dates[k] = asof_ + expiries[k];
1475 times[k] = wrapper->timeFromReference(dates[k]);
1476 }
1477
1478 QuantLib::ext::shared_ptr<BlackVolTermStructure> fxVolCurve;
1479 if (parameters->fxVolIsSurface(name)) {
1480 vector<Real> strikes;
1481 strikes = parameters->fxUseMoneyness(name) ? parameters->fxVolMoneyness(name)
1482 : parameters->fxVolStdDevs(name);
1483 Size n = strikes.size();
1484 quotes.resize(n, vector<Handle<Quote>>(m, Handle<Quote>()));
1485
1486 // hardcode this for now
1487 bool flatExtrapolation = true;
1488
1489 // get vol matrix to feed to surface
1490 if (parameters->fxUseMoneyness(name)) { // if moneyness
1491 for (Size j = 0; j < m; j++) {
1492 for (Size i = 0; i < n; i++) {
1493 Real mon = strikes[i];
1494 // strike (assuming forward prices)
1495 Real k = spot->value() * mon * initForTS->discount(dates[j]) /
1496 initDomTS->discount(dates[j]);
1497 Size idx = i * m + j;
1498
1499 Volatility vol = wrapper->blackVol(dates[j], k, true);
1500 QuantLib::ext::shared_ptr<SimpleQuote> q(
1501 new SimpleQuote(useSpreadedTermStructures_ ? 0.0 : vol));
1502 simDataTmp.emplace(std::piecewise_construct,
1503 std::forward_as_tuple(param.first, name, idx),
1504 std::forward_as_tuple(q));
1506 absoluteSimDataTmp.emplace(
1507 std::piecewise_construct,
1508 std::forward_as_tuple(param.first, name, idx),
1509 std::forward_as_tuple(q->value()));
1510 }
1511 quotes[i][j] = Handle<Quote>(q);
1512 }
1513 }
1514 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name, {strikes, times});
1515 simDataWritten = true;
1516 // build the surface
1518 fxVolCurve = QuantLib::ext::make_shared<SpreadedBlackVolatilitySurfaceMoneynessForward>(
1519 Handle<BlackVolTermStructure>(wrapper), spot, times,
1520 parameters->fxVolMoneyness(name), quotes,
1521 Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(spot->value())), initForTS,
1522 initDomTS, forTS, domTS, stickyStrike);
1523 } else {
1524 fxVolCurve = QuantLib::ext::make_shared<BlackVarianceSurfaceMoneynessForward>(
1525 cal, spot, times, parameters->fxVolMoneyness(name), quotes, dc, forTS,
1526 domTS, stickyStrike, flatExtrapolation);
1527 }
1528 } else { // if stdDevPoints
1529 // forwards
1530 vector<Real> fwds;
1531 vector<Real> atmVols;
1532 for (Size i = 0; i < m; i++) {
1533 Real k = spot->value() * initForTS->discount(dates[i]) / initDomTS->discount(dates[i]);
1534 fwds.push_back(k);
1535 atmVols.push_back(wrapper->blackVol(dates[i], k));
1536 DLOG("on date " << dates[i] << ": fwd = " << fwds.back()
1537 << ", atmVol = " << atmVols.back());
1538 }
1539
1540 // interpolations
1541 Interpolation forwardCurve =
1542 Linear().interpolate(times.begin(), times.end(), fwds.begin());
1543 Interpolation atmVolCurve =
1544 Linear().interpolate(times.begin(), times.end(), atmVols.begin());
1545
1546 // populate quotes
1547 vector<vector<Handle<Quote>>> absQuotes(n,
1548 vector<Handle<Quote>>(m, Handle<Quote>()));
1549 BlackVarianceSurfaceStdDevs::populateVolMatrix(wrapper, absQuotes, times,
1550 parameters->fxVolStdDevs(name),
1551 forwardCurve, atmVolCurve);
1553 for (Size i = 0; i < n; ++i)
1554 for (Size j = 0; j < m; ++j)
1555 quotes[i][j] = Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(0.0));
1556 } else {
1557 quotes = absQuotes;
1558 }
1559
1560 // sort out simDataTemp
1561 for (Size i = 0; i < m; i++) {
1562 for (Size j = 0; j < n; j++) {
1563 Size idx = j * m + i;
1564 QuantLib::ext::shared_ptr<Quote> q = quotes[j][i].currentLink();
1565 QuantLib::ext::shared_ptr<SimpleQuote> sq =
1566 QuantLib::ext::dynamic_pointer_cast<SimpleQuote>(q);
1567 simDataTmp.emplace(std::piecewise_construct,
1568 std::forward_as_tuple(param.first, name, idx),
1569 std::forward_as_tuple(sq));
1571 absoluteSimDataTmp.emplace(
1572 std::piecewise_construct,
1573 std::forward_as_tuple(param.first, name, idx),
1574 std::forward_as_tuple(absQuotes[j][i]->value()));
1575 }
1576 }
1577 }
1578 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name, {strikes, times});
1579 simDataWritten = true;
1580
1581 // set up a FX Index
1582 Handle<FxIndex> fxInd = fxIndex(name);
1583
1584 if (parameters->fxUseMoneyness(name)) { // moneyness
1585 } else { // standard deviations
1587 fxVolCurve = QuantLib::ext::make_shared<SpreadedBlackVolatilitySurfaceStdDevs>(
1588 Handle<BlackVolTermStructure>(wrapper), spot, times,
1589 parameters->fxVolStdDevs(name), quotes,
1590 Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(spot->value())),
1591 initForTS, initDomTS, forTS, domTS, stickyStrike);
1592 } else {
1593 fxVolCurve = QuantLib::ext::make_shared<BlackVarianceSurfaceStdDevs>(
1594 cal, spot, times, parameters->fxVolStdDevs(name), quotes, dc,
1595 fxInd.currentLink(), stickyStrike, flatExtrapolation);
1596 }
1597 }
1598 }
1599 } else { // not a surface - case for ATM or simulateATMOnly
1600 quotes.resize(1, vector<Handle<Quote>>(m, Handle<Quote>()));
1601 // Only need ATM quotes in this case
1602 for (Size j = 0; j < m; j++) {
1603 // Index is expires then moneyness.
1604 Size idx = j;
1605 Real f =
1606 spot->value() * initForTS->discount(dates[j]) / initDomTS->discount(dates[j]);
1607 Volatility vol = wrapper->blackVol(dates[j], f);
1608 QuantLib::ext::shared_ptr<SimpleQuote> q(
1609 new SimpleQuote(useSpreadedTermStructures_ ? 0.0 : vol));
1610 simDataTmp.emplace(std::piecewise_construct,
1611 std::forward_as_tuple(param.first, name, idx),
1612 std::forward_as_tuple(q));
1614 absoluteSimDataTmp.emplace(std::piecewise_construct,
1615 std::forward_as_tuple(param.first, name, idx),
1616 std::forward_as_tuple(vol));
1617 }
1618 quotes[0][j] = Handle<Quote>(q);
1619 }
1620
1621 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name, {times});
1622 simDataWritten = true;
1623
1625 // if simulate atm only is false, we use the ATM slice from the wrapper only
1626 // the smile dynamics is sticky strike here always (if t0 is a surface)
1627 fxVolCurve = QuantLib::ext::make_shared<SpreadedBlackVolatilityCurve>(
1628 Handle<BlackVolTermStructure>(wrapper), times, quotes[0],
1629 !parameters->simulateFxVolATMOnly());
1630 } else {
1631 LOG("ATM FX Vols (BlackVarianceCurve3) for " << name);
1632 QuantLib::ext::shared_ptr<BlackVolTermStructure> atmCurve;
1633 atmCurve = QuantLib::ext::make_shared<BlackVarianceCurve3>(
1634 0, NullCalendar(), wrapper->businessDayConvention(), dc, times, quotes[0], false);
1635 // if we have a surface but are only simulating atm vols we wrap the atm curve and
1636 // the full t0 surface
1637 if (parameters->simulateFxVolATMOnly()) {
1638 LOG("Simulating FX Vols (FXVolatilityConstantSpread) for " << name);
1639 fxVolCurve = QuantLib::ext::make_shared<BlackVolatilityConstantSpread>(
1640 Handle<BlackVolTermStructure>(atmCurve), wrapper);
1641 } else {
1642 fxVolCurve = atmCurve;
1643 }
1644 }
1645 }
1646 fvh = Handle<BlackVolTermStructure>(fxVolCurve);
1647
1648 } else {
1649 string decayModeString = parameters->fxVolDecayMode();
1650 LOG("Deterministic FX Vols with decay mode " << decayModeString << " for " << name);
1651 ReactionToTimeDecay decayMode = parseDecayMode(decayModeString);
1652
1653 // currently only curves (i.e. strike independent) FX volatility structures are
1654 // supported, so we use a) the more efficient curve tag and b) a hard coded sticky
1655 // strike stickiness, since then no yield term structures and no fx spot are required
1656 // that define the ATM level - to be revisited when FX surfaces are supported
1657 fvh = Handle<BlackVolTermStructure>(
1658 QuantLib::ext::make_shared<QuantExt::DynamicBlackVolTermStructure<tag::curve>>(
1659 wrapper, 0, NullCalendar(), decayMode,
1660 stickyStrike ? StickyStrike : StickyLogMoneyness));
1661 }
1662
1663 fvh->setAdjustReferenceDate(false);
1664 fvh->enableExtrapolation();
1665 fxVols_.insert(make_pair(make_pair(Market::defaultConfiguration, name), fvh));
1666
1667 // build inverted surface
1668 QL_REQUIRE(name.size() == 6, "Invalid Ccy pair " << name);
1669 string reverse = name.substr(3) + name.substr(0, 3);
1670 Handle<QuantLib::BlackVolTermStructure> ifvh(
1671 QuantLib::ext::make_shared<BlackInvertedVolTermStructure>(fvh));
1672 ifvh->enableExtrapolation();
1673 fxVols_.insert(make_pair(make_pair(Market::defaultConfiguration, reverse), ifvh));
1674 } catch (const std::exception& e) {
1675 processException(continueOnError, e, name, param.first, simDataWritten);
1676 }
1677 }
1678 break;
1679
1681 for (const auto& name : param.second.second) {
1682 bool simDataWritten = false;
1683 try {
1684 Handle<BlackVolTermStructure> wrapper = initMarket->equityVol(name, configuration);
1685 Handle<BlackVolTermStructure> evh;
1686
1687 bool stickyStrike = parameters_->equityVolSmileDynamics(name) == "StickyStrike";
1688 if (param.second.first) {
1689 auto eqCurve = equityCurve(name, Market::defaultConfiguration);
1690 Handle<Quote> spot = eqCurve->equitySpot();
1691 auto expiries = parameters->equityVolExpiries(name);
1692
1693 Size m = expiries.size();
1694 vector<vector<Handle<Quote>>> quotes;
1695 vector<Time> times(m);
1696 vector<Date> dates(m);
1697 Calendar cal;
1698 if (curveConfigs.hasEquityVolCurveConfig(name)) {
1699 auto cfg = curveConfigs.equityVolCurveConfig(name);
1700 if (cfg->calendar().empty())
1701 cal = parseCalendar(cfg->ccy());
1702 else
1703 cal = parseCalendar(cfg->calendar());
1704 }
1705 if (cal.empty() || cal == NullCalendar()) {
1706 // take the equity curves calendar - this at least ensures fixings align
1707 cal = eqCurve->fixingCalendar();
1708 }
1709 DayCounter dc = wrapper->dayCounter();
1710
1711 for (Size k = 0; k < m; k++) {
1712 dates[k] = cal.advance(asof_, expiries[k]);
1713 times[k] = dc.yearFraction(asof_, dates[k]);
1714 }
1715
1716 QuantLib::ext::shared_ptr<BlackVolTermStructure> eqVolCurve;
1717
1718 if (parameters->equityVolIsSurface(name)) {
1719 vector<Real> strikes;
1720 strikes = parameters->equityUseMoneyness(name)
1721 ? parameters->equityVolMoneyness(name)
1722 : parameters->equityVolStandardDevs(name);
1723 Size n = strikes.size();
1724 quotes.resize(n, vector<Handle<Quote>>(m, Handle<Quote>()));
1725
1726 if (parameters->equityUseMoneyness(name)) { // moneyness surface
1727 for (Size j = 0; j < m; j++) {
1728 for (Size i = 0; i < n; i++) {
1729 Real mon = strikes[i];
1730 // strike (assuming forward prices)
1731 Real k = eqCurve->forecastFixing(dates[j]) * mon;
1732 Size idx = i * m + j;
1733 Volatility vol = wrapper->blackVol(dates[j], k);
1734 QuantLib::ext::shared_ptr<SimpleQuote> q(
1735 new SimpleQuote(useSpreadedTermStructures_ ? 0.0 : vol));
1736 simDataTmp.emplace(std::piecewise_construct,
1737 std::forward_as_tuple(param.first, name, idx),
1738 std::forward_as_tuple(q));
1740 absoluteSimDataTmp.emplace(
1741 std::piecewise_construct,
1742 std::forward_as_tuple(param.first, name, idx),
1743 std::forward_as_tuple(vol));
1744 }
1745 quotes[i][j] = Handle<Quote>(q);
1746 }
1747 }
1748 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name, {strikes, times});
1749 simDataWritten = true;
1750 LOG("Simulating EQ Vols (BlackVarianceSurfaceMoneyness) for " << name);
1751
1753 eqVolCurve = QuantLib::ext::make_shared<SpreadedBlackVolatilitySurfaceMoneynessForward>(
1754 Handle<BlackVolTermStructure>(wrapper), spot, times,
1755 parameters->equityVolMoneyness(name), quotes,
1756 Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(spot->value())),
1757 initMarket->equityCurve(name, configuration)->equityDividendCurve(),
1758 initMarket->equityCurve(name, configuration)->equityForecastCurve(),
1759 eqCurve->equityDividendCurve(), eqCurve->equityForecastCurve(),
1760 stickyStrike);
1761 } else {
1762 // FIXME should that be Forward, since we read the vols at fwd moneyness above?
1763 eqVolCurve = QuantLib::ext::make_shared<BlackVarianceSurfaceMoneynessSpot>(
1764 cal, spot, times, parameters->equityVolMoneyness(name), quotes, dc,
1765 stickyStrike);
1766 }
1767 eqVolCurve->enableExtrapolation();
1768
1769 } else { // standard deviations surface
1770 // forwards
1771 vector<Real> fwds;
1772 vector<Real> atmVols;
1773 for (Size i = 0; i < expiries.size(); i++) {
1774 auto eqForward = eqCurve->forecastFixing(dates[i]);
1775 fwds.push_back(eqForward);
1776 atmVols.push_back(wrapper->blackVol(dates[i], eqForward));
1777 DLOG("on date " << dates[i] << ": fwd = " << fwds.back()
1778 << ", atmVol = " << atmVols.back());
1779 }
1780
1781 // interpolations
1782 Interpolation forwardCurve =
1783 Linear().interpolate(times.begin(), times.end(), fwds.begin());
1784 Interpolation atmVolCurve =
1785 Linear().interpolate(times.begin(), times.end(), atmVols.begin());
1786
1787 // populate quotes
1788 vector<vector<Handle<Quote>>> absQuotes(n,
1789 vector<Handle<Quote>>(m, Handle<Quote>()));
1790 BlackVarianceSurfaceStdDevs::populateVolMatrix(wrapper, absQuotes, times, strikes,
1791 forwardCurve, atmVolCurve);
1793 for (Size i = 0; i < n; ++i)
1794 for (Size j = 0; j < m; ++j)
1795 quotes[i][j] = Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(0.0));
1796 } else {
1797 quotes = absQuotes;
1798 }
1799
1800 // add to simDataTemp
1801 for (Size i = 0; i < m; i++) {
1802 for (Size j = 0; j < n; j++) {
1803 Size idx = j * m + i;
1804 QuantLib::ext::shared_ptr<Quote> q = quotes[j][i].currentLink();
1805 QuantLib::ext::shared_ptr<SimpleQuote> sq =
1806 QuantLib::ext::dynamic_pointer_cast<SimpleQuote>(q);
1807 QL_REQUIRE(sq, "Quote is not a SimpleQuote"); // why do we need this?
1808 simDataTmp.emplace(std::piecewise_construct,
1809 std::forward_as_tuple(param.first, name, idx),
1810 std::forward_as_tuple(sq));
1812 absoluteSimDataTmp.emplace(
1813 std::piecewise_construct,
1814 std::forward_as_tuple(param.first, name, idx),
1815 std::forward_as_tuple(absQuotes[j][i]->value()));
1816 }
1817 }
1818 }
1819 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name, {strikes, times});
1820 simDataWritten = true;
1821 bool flatExtrapolation = true; // flat extrapolation of strikes at far ends.
1823 eqVolCurve = QuantLib::ext::make_shared<SpreadedBlackVolatilitySurfaceStdDevs>(
1824 Handle<BlackVolTermStructure>(wrapper), spot, times,
1825 parameters->equityVolStandardDevs(name), quotes,
1826 Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(spot->value())),
1827 initMarket->equityCurve(name, configuration)->equityDividendCurve(),
1828 initMarket->equityCurve(name, configuration)->equityForecastCurve(),
1829 eqCurve->equityDividendCurve(), eqCurve->equityForecastCurve(),
1830 stickyStrike);
1831 } else {
1832 eqVolCurve = QuantLib::ext::make_shared<BlackVarianceSurfaceStdDevs>(
1833 cal, spot, times, parameters->equityVolStandardDevs(name), quotes, dc,
1834 eqCurve.currentLink(), stickyStrike, flatExtrapolation);
1835 }
1836 }
1837 } else { // not a surface - case for ATM or simulateATMOnly
1838 quotes.resize(1, vector<Handle<Quote>>(m, Handle<Quote>()));
1839 // Only need ATM quotes in this case
1840 for (Size j = 0; j < m; j++) {
1841 // Index is expires then moneyness. TODO: is this the best?
1842 Size idx = j;
1843 auto eqForward = eqCurve->fixing(dates[j]);
1844 Volatility vol = wrapper->blackVol(dates[j], eqForward);
1845 QuantLib::ext::shared_ptr<SimpleQuote> q(
1846 new SimpleQuote(useSpreadedTermStructures_ ? 0.0 : vol));
1847 simDataTmp.emplace(std::piecewise_construct,
1848 std::forward_as_tuple(param.first, name, idx),
1849 std::forward_as_tuple(q));
1851 absoluteSimDataTmp.emplace(std::piecewise_construct,
1852 std::forward_as_tuple(param.first, name, idx),
1853 std::forward_as_tuple(vol));
1854 }
1855 quotes[0][j] = Handle<Quote>(q);
1856 }
1857
1858 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name, {times});
1859 simDataWritten = true;
1860
1862 // if simulate atm only is false, we use the ATM slice from the wrapper only
1863 // the smile dynamics is sticky strike here always (if t0 is a surface)
1864 eqVolCurve = QuantLib::ext::make_shared<SpreadedBlackVolatilityCurve>(
1865 Handle<BlackVolTermStructure>(wrapper), times, quotes[0],
1866 !parameters->simulateEquityVolATMOnly());
1867 } else {
1868 LOG("ATM EQ Vols (BlackVarianceCurve3) for " << name);
1869 QuantLib::ext::shared_ptr<BlackVolTermStructure> atmCurve;
1870 atmCurve = QuantLib::ext::make_shared<BlackVarianceCurve3>(0, NullCalendar(),
1871 wrapper->businessDayConvention(),
1872 dc, times, quotes[0], false);
1873 // if we have a surface but are only simulating atm vols we wrap the atm curve and
1874 // the full t0 surface
1875 if (parameters->simulateEquityVolATMOnly()) {
1876 LOG("Simulating EQ Vols (EquityVolatilityConstantSpread) for " << name);
1877 eqVolCurve = QuantLib::ext::make_shared<BlackVolatilityConstantSpread>(
1878 Handle<BlackVolTermStructure>(atmCurve), wrapper);
1879 } else {
1880 eqVolCurve = atmCurve;
1881 }
1882 }
1883 }
1884 evh = Handle<BlackVolTermStructure>(eqVolCurve);
1885
1886 } else {
1887 string decayModeString = parameters->equityVolDecayMode();
1888 DLOG("Deterministic EQ Vols with decay mode " << decayModeString << " for " << name);
1889 ReactionToTimeDecay decayMode = parseDecayMode(decayModeString);
1890
1891 // currently only curves (i.e. strike independent) EQ volatility structures are
1892 // supported, so we use a) the more efficient curve tag and b) a hard coded sticky
1893 // strike stickiness, since then no yield term structures and no EQ spot are required
1894 // that define the ATM level - to be revisited when EQ surfaces are supported
1895 evh = Handle<BlackVolTermStructure>(
1896 QuantLib::ext::make_shared<QuantExt::DynamicBlackVolTermStructure<tag::curve>>(
1897 wrapper, 0, NullCalendar(), decayMode,
1898 stickyStrike ? StickyStrike : StickyLogMoneyness));
1899 }
1900
1901 evh->setAdjustReferenceDate(false);
1902 if (wrapper->allowsExtrapolation())
1903 evh->enableExtrapolation();
1904 equityVols_.insert(make_pair(make_pair(Market::defaultConfiguration, name), evh));
1905 DLOG("EQ volatility curve built for " << name);
1906 } catch (const std::exception& e) {
1907 processException(continueOnError, e, name, param.first, simDataWritten);
1908 }
1909 }
1910 break;
1911
1913 for (const auto& name : param.second.second) {
1914 bool simDataWritten = false;
1915 try {
1916 Handle<QuantExt::BaseCorrelationTermStructure> wrapper =
1917 initMarket->baseCorrelation(name, configuration);
1918 if (!param.second.first)
1919 baseCorrelations_.insert(make_pair(make_pair(Market::defaultConfiguration, name), wrapper));
1920 else {
1921 std::vector<Real> times;
1922 Size nd = parameters->baseCorrelationDetachmentPoints().size();
1923 Size nt = parameters->baseCorrelationTerms().size();
1924 vector<vector<Handle<Quote>>> quotes(nd, vector<Handle<Quote>>(nt));
1925 vector<Period> terms(nt);
1926 vector<double> detachmentPoints(nd);
1927 for (Size i = 0; i < nd; ++i) {
1928 Real lossLevel = parameters->baseCorrelationDetachmentPoints()[i];
1929 detachmentPoints[i] = lossLevel;
1930 for (Size j = 0; j < nt; ++j) {
1931 Period term = parameters->baseCorrelationTerms()[j];
1932 if (i == 0)
1933 terms[j] = term;
1934 times.push_back(wrapper->timeFromReference(asof_ + term));
1935 Real bc = wrapper->correlation(asof_ + term, lossLevel, true); // extrapolate
1936 QuantLib::ext::shared_ptr<SimpleQuote> q =
1937 QuantLib::ext::make_shared<SimpleQuote>(useSpreadedTermStructures_ ? 0.0 : bc);
1938 simDataTmp.emplace(std::piecewise_construct,
1939 std::forward_as_tuple(param.first, name, i * nt + j),
1940 std::forward_as_tuple(q));
1942 absoluteSimDataTmp.emplace(std::piecewise_construct,
1943 std::forward_as_tuple(param.first, name, i * nt + j),
1944 std::forward_as_tuple(bc));
1945 }
1946 quotes[i][j] = Handle<Quote>(q);
1947 }
1948 }
1949
1951 simDataTmp, absoluteSimDataTmp, param.first, name,
1952 {parameters->baseCorrelationDetachmentPoints(), times});
1953 simDataWritten = true;
1954
1955 //
1956 if (nt == 1) {
1957 terms.push_back(terms[0] + 1 * terms[0].units()); // arbitrary, but larger than the first term
1958 for (Size i = 0; i < nd; ++i)
1959 quotes[i].push_back(quotes[i][0]);
1960 }
1961
1962 if (nd == 1) {
1963 quotes.push_back(vector<Handle<Quote>>(terms.size()));
1964 for (Size j = 0; j < terms.size(); ++j)
1965 quotes[1][j] = quotes[0][j];
1966
1967 if (detachmentPoints[0] < 1.0 && !QuantLib::close_enough(detachmentPoints[0], 1.0)) {
1968 detachmentPoints.push_back(1.0);
1969 } else {
1970 detachmentPoints.insert(detachmentPoints.begin(), 0.01); // arbitrary, but larger than then 0 and less than 1.0
1971 }
1972 }
1973
1974 QuantLib::ext::shared_ptr<QuantExt::BaseCorrelationTermStructure> bcp;
1976 bcp = QuantLib::ext::make_shared<QuantExt::SpreadedBaseCorrelationCurve>(
1977 wrapper, terms, detachmentPoints, quotes);
1978 bcp->enableExtrapolation(wrapper->allowsExtrapolation());
1979 } else {
1980 DayCounter dc = wrapper->dayCounter();
1981 bcp = QuantLib::ext::make_shared<InterpolatedBaseCorrelationTermStructure<Bilinear>>(
1982 wrapper->settlementDays(), wrapper->calendar(), wrapper->businessDayConvention(),
1983 terms, detachmentPoints, quotes, dc);
1984
1985 bcp->enableExtrapolation(wrapper->allowsExtrapolation());
1986 }
1987 bcp->setAdjustReferenceDate(false);
1988 Handle<QuantExt::BaseCorrelationTermStructure> bch(bcp);
1989 baseCorrelations_.insert(make_pair(make_pair(Market::defaultConfiguration, name), bch));
1990 }
1991 DLOG("Base correlations built for " << name);
1992 } catch (const std::exception& e) {
1993 processException(continueOnError, e, name, param.first, simDataWritten);
1994 }
1995 }
1996 break;
1997
1999 for (const auto& name : param.second.second) {
2000 bool simDataWritten = false;
2001 try {
2002 DLOG("adding " << name << " base CPI price");
2003 Handle<ZeroInflationIndex> zeroInflationIndex =
2004 initMarket->zeroInflationIndex(name, configuration);
2005 Period obsLag = zeroInflationIndex->zeroInflationTermStructure()->observationLag();
2006 Date fixingDate = zeroInflationIndex->zeroInflationTermStructure()->baseDate();
2007 Real baseCPI = zeroInflationIndex->fixing(fixingDate);
2008
2009 QuantLib::ext::shared_ptr<InflationIndex> inflationIndex =
2010 QuantLib::ext::dynamic_pointer_cast<InflationIndex>(*zeroInflationIndex);
2011
2012 auto q = QuantLib::ext::make_shared<SimpleQuote>(baseCPI);
2014 auto m = [baseCPI](Real x) { return x * baseCPI; };
2015 Handle<InflationIndexObserver> inflObserver(
2016 QuantLib::ext::make_shared<InflationIndexObserver>(
2017 inflationIndex,
2018 Handle<Quote>(
2019 QuantLib::ext::make_shared<DerivedQuote<decltype(m)>>(Handle<Quote>(q), m)),
2020 obsLag));
2021 baseCpis_.insert(make_pair(make_pair(Market::defaultConfiguration, name), inflObserver));
2022 } else {
2023 Handle<InflationIndexObserver> inflObserver(
2024 QuantLib::ext::make_shared<InflationIndexObserver>(inflationIndex, Handle<Quote>(q),
2025 obsLag));
2026 baseCpis_.insert(make_pair(make_pair(Market::defaultConfiguration, name), inflObserver));
2027 }
2028 simDataTmp.emplace(std::piecewise_construct, std::forward_as_tuple(param.first, name),
2029 std::forward_as_tuple(q));
2031 absoluteSimDataTmp.emplace(std::piecewise_construct,
2032 std::forward_as_tuple(param.first, name),
2033 std::forward_as_tuple(baseCPI));
2034 }
2035 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name, {});
2036 simDataWritten = true;
2037 } catch (const std::exception& e) {
2038 processException(continueOnError, e, name, param.first, simDataWritten);
2039 }
2040 }
2041 break;
2042
2044 for (const auto& name : param.second.second) {
2045 bool simDataWritten = false;
2046 try {
2047 LOG("building " << name << " zero inflation curve");
2048
2049 Handle<ZeroInflationIndex> inflationIndex = initMarket->zeroInflationIndex(name, configuration);
2050 Handle<ZeroInflationTermStructure> inflationTs = inflationIndex->zeroInflationTermStructure();
2051 vector<string> keys(parameters->zeroInflationTenors(name).size());
2052
2053 Date date0 = asof_ - inflationTs->observationLag();
2054 DayCounter dc = inflationTs->dayCounter();
2055 vector<Date> quoteDates;
2056 vector<Time> zeroCurveTimes(
2057 1, -dc.yearFraction(inflationPeriod(date0, inflationTs->frequency()).first, asof_));
2058 vector<Handle<Quote>> quotes;
2059 QL_REQUIRE(parameters->zeroInflationTenors(name).front() > 0 * Days,
2060 "zero inflation tenors must not include t=0");
2061
2062 for (auto& tenor : parameters->zeroInflationTenors(name)) {
2063 Date inflDate = inflationPeriod(date0 + tenor, inflationTs->frequency()).first;
2064 zeroCurveTimes.push_back(dc.yearFraction(asof_, inflDate));
2065 quoteDates.push_back(asof_ + tenor);
2066 }
2067
2068 for (Size i = 1; i < zeroCurveTimes.size(); i++) {
2069 Real rate = inflationTs->zeroRate(quoteDates[i - 1]);
2070 if (inflationTs->hasSeasonality()) {
2071 Date fixingDate = quoteDates[i - 1] - inflationTs->observationLag();
2072 rate = inflationTs->seasonality()->deseasonalisedZeroRate(fixingDate,
2073 rate, *inflationTs.currentLink());
2074 }
2075 auto q = QuantLib::ext::make_shared<SimpleQuote>(useSpreadedTermStructures_ ? 0.0 : rate);
2076 if (i == 1) {
2077 // add the zero rate at first tenor to the T0 time, to ensure flat interpolation of T1
2078 // rate for time t T0 < t < T1
2079 quotes.push_back(Handle<Quote>(q));
2080 }
2081 quotes.push_back(Handle<Quote>(q));
2082 simDataTmp.emplace(std::piecewise_construct,
2083 std::forward_as_tuple(param.first, name, i - 1),
2084 std::forward_as_tuple(q));
2086 absoluteSimDataTmp.emplace(std::piecewise_construct,
2087 std::forward_as_tuple(param.first, name, i - 1),
2088 std::forward_as_tuple(rate));
2089 DLOG("ScenarioSimMarket zero inflation curve " << name << " zeroRate[" << i
2090 << "]=" << rate);
2091 }
2092
2093 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name,
2094 {std::vector<Real>(std::next(zeroCurveTimes.begin(), 1), zeroCurveTimes.end())});
2095 simDataWritten = true;
2096
2097 // FIXME: Settlement days set to zero - needed for floating term structure implementation
2098 QuantLib::ext::shared_ptr<ZeroInflationTermStructure> zeroCurve;
2100 zeroCurve =
2101 QuantLib::ext::make_shared<SpreadedZeroInflationCurve>(inflationTs, zeroCurveTimes, quotes);
2102 } else {
2103 zeroCurve = QuantLib::ext::make_shared<ZeroInflationCurveObserverMoving<Linear>>(
2104 0, inflationIndex->fixingCalendar(), dc, inflationTs->observationLag(),
2105 inflationTs->frequency(), false, zeroCurveTimes, quotes,
2106 inflationTs->seasonality());
2107 }
2108
2109 Handle<ZeroInflationTermStructure> its(zeroCurve);
2110 its->setAdjustReferenceDate(false);
2111 its->enableExtrapolation();
2112 QuantLib::ext::shared_ptr<ZeroInflationIndex> i =
2113 parseZeroInflationIndex(name, Handle<ZeroInflationTermStructure>(its));
2114 Handle<ZeroInflationIndex> zh(i);
2115 zeroInflationIndices_.insert(make_pair(make_pair(Market::defaultConfiguration, name), zh));
2116
2117 LOG("building " << name << " zero inflation curve done");
2118 } catch (const std::exception& e) {
2119 processException(continueOnError, e, name, param.first, simDataWritten);
2120 }
2121 }
2122 break;
2123
2125 for (const auto& name : param.second.second) {
2126 bool simDataWritten = false;
2127 try {
2128 LOG("building " << name << " zero inflation cap/floor volatility curve...");
2129 Handle<QuantLib::CPIVolatilitySurface> wrapper =
2130 initMarket->cpiInflationCapFloorVolatilitySurface(name, configuration);
2131 Handle<ZeroInflationIndex> zeroInflationIndex =
2132 initMarket->zeroInflationIndex(name, configuration);
2133 // LOG("Initial market zero inflation cap/floor volatility type = " <<
2134 // wrapper->volatilityType());
2135
2136 Handle<QuantLib::CPIVolatilitySurface> hCpiVol;
2137
2138 // Check if the risk factor is simulated before adding it
2139 if (param.second.first) {
2140 LOG("Simulating zero inflation cap/floor vols for index name " << name);
2141
2142 DayCounter dc = wrapper->dayCounter();
2143 vector<Period> optionTenors = parameters->zeroInflationCapFloorVolExpiries(name);
2144 vector<Date> optionDates(optionTenors.size());
2145 vector<Real> strikes = parameters->zeroInflationCapFloorVolStrikes(name);
2146 vector<vector<Handle<Quote>>> quotes(
2147 optionTenors.size(), vector<Handle<Quote>>(strikes.size(), Handle<Quote>()));
2148 for (Size i = 0; i < optionTenors.size(); ++i) {
2149 optionDates[i] = wrapper->optionDateFromTenor(optionTenors[i]);
2150 for (Size j = 0; j < strikes.size(); ++j) {
2151 Real vol =
2152 wrapper->volatility(optionTenors[i], strikes[j], wrapper->observationLag(),
2153 wrapper->allowsExtrapolation());
2154 auto q = QuantLib::ext::make_shared<SimpleQuote>(useSpreadedTermStructures_ ? 0.0 : vol);
2155 Size index = i * strikes.size() + j;
2156 simDataTmp.emplace(std::piecewise_construct,
2157 std::forward_as_tuple(param.first, name, index),
2158 std::forward_as_tuple(q));
2160 absoluteSimDataTmp.emplace(std::piecewise_construct,
2161 std::forward_as_tuple(param.first, name, index),
2162 std::forward_as_tuple(vol));
2163 }
2164 quotes[i][j] = Handle<Quote>(q);
2165 }
2166 }
2167
2168 std::vector<std::vector<Real>> coordinates(2);
2169 for (Size i = 0; i < optionTenors.size(); ++i) {
2170 coordinates[0].push_back(
2171 wrapper->timeFromReference(wrapper->optionDateFromTenor(optionTenors[i])));
2172 }
2173 for (Size j = 0; j < strikes.size(); ++j) {
2174 coordinates[1].push_back(strikes[j]);
2175 }
2176
2177 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name, coordinates);
2178 simDataWritten = true;
2179
2180
2181
2183 auto surface = QuantLib::ext::dynamic_pointer_cast<QuantExt::CPIVolatilitySurface>(wrapper.currentLink());
2184 QL_REQUIRE(surface,
2185 "Internal error, todays market should build QuantExt::CPIVolatiltiySurface "
2186 "instead of QuantLib::CPIVolatilitySurface");
2187 hCpiVol = Handle<QuantLib::CPIVolatilitySurface>(
2188 QuantLib::ext::make_shared<SpreadedCPIVolatilitySurface>(
2189 Handle<QuantExt::CPIVolatilitySurface>(surface), optionDates, strikes, quotes));
2190 } else {
2191 auto surface =
2192 QuantLib::ext::dynamic_pointer_cast<QuantExt::CPIVolatilitySurface>(wrapper.currentLink());
2193 QL_REQUIRE(surface,
2194 "Internal error, todays market should build QuantExt::CPIVolatiltiySurface "
2195 "instead of QuantLib::CPIVolatilitySurface");
2196 hCpiVol = Handle<QuantLib::CPIVolatilitySurface>(
2197 QuantLib::ext::make_shared<InterpolatedCPIVolatilitySurface<Bilinear>>(
2198 optionTenors, strikes, quotes, zeroInflationIndex.currentLink(),
2199 wrapper->settlementDays(), wrapper->calendar(),
2200 wrapper->businessDayConvention(), wrapper->dayCounter(),
2201 wrapper->observationLag(), surface->capFloorStartDate(), Bilinear(),
2202 surface->volatilityType(), surface->displacement()));
2203 }
2204 } else {
2205 // string decayModeString = parameters->zeroInflationCapFloorVolDecayMode();
2206 // ReactionToTimeDecay decayMode = parseDecayMode(decayModeString);
2207 // QuantLib::ext::shared_ptr<CPIVolatilitySurface> cpiVol =
2208 // QuantLib::ext::make_shared<QuantExt::DynamicCPIVolatilitySurface>(*wrapper, decayMode);
2209 // hCpiVol = Handle<CPIVolatilitySurface>(cpiVol);#
2210 // FIXME
2211 hCpiVol = wrapper;
2212 }
2213
2214 hCpiVol->setAdjustReferenceDate(false);
2215 if (wrapper->allowsExtrapolation())
2216 hCpiVol->enableExtrapolation();
2218 std::piecewise_construct, std::forward_as_tuple(Market::defaultConfiguration, name),
2219 std::forward_as_tuple(hCpiVol));
2220
2221 } catch (const std::exception& e) {
2222 processException(continueOnError, e, name, param.first, simDataWritten);
2223 }
2224 }
2225 break;
2226
2228 for (const auto& name : param.second.second) {
2229 bool simDataWritten = false;
2230 try {
2231 Handle<YoYInflationIndex> yoyInflationIndex =
2232 initMarket->yoyInflationIndex(name, configuration);
2233 Handle<YoYInflationTermStructure> yoyInflationTs =
2234 yoyInflationIndex->yoyInflationTermStructure();
2235 vector<string> keys(parameters->yoyInflationTenors(name).size());
2236
2237 Date date0 = asof_ - yoyInflationTs->observationLag();
2238 DayCounter dc = yoyInflationTs->dayCounter();
2239 vector<Date> quoteDates;
2240 vector<Time> yoyCurveTimes(
2241 1, -dc.yearFraction(inflationPeriod(date0, yoyInflationTs->frequency()).first, asof_));
2242 vector<Handle<Quote>> quotes;
2243 QL_REQUIRE(parameters->yoyInflationTenors(name).front() > 0 * Days,
2244 "zero inflation tenors must not include t=0");
2245
2246 for (auto& tenor : parameters->yoyInflationTenors(name)) {
2247 Date inflDate = inflationPeriod(date0 + tenor, yoyInflationTs->frequency()).first;
2248 yoyCurveTimes.push_back(dc.yearFraction(asof_, inflDate));
2249 quoteDates.push_back(asof_ + tenor);
2250 }
2251
2252 for (Size i = 1; i < yoyCurveTimes.size(); i++) {
2253 Real rate = yoyInflationTs->yoyRate(quoteDates[i - 1]);
2254 auto q = QuantLib::ext::make_shared<SimpleQuote>(useSpreadedTermStructures_ ? 0.0 : rate);
2255 if (i == 1) {
2256 // add the zero rate at first tenor to the T0 time, to ensure flat interpolation of T1
2257 // rate for time t T0 < t < T1
2258 quotes.push_back(Handle<Quote>(q));
2259 }
2260 quotes.push_back(Handle<Quote>(q));
2261 simDataTmp.emplace(std::piecewise_construct,
2262 std::forward_as_tuple(param.first, name, i - 1),
2263 std::forward_as_tuple(q));
2265 absoluteSimDataTmp.emplace(std::piecewise_construct,
2266 std::forward_as_tuple(param.first, name, i - 1),
2267 std::forward_as_tuple(rate));
2268 DLOG("ScenarioSimMarket yoy inflation curve " << name << " yoyRate[" << i << "]=" << rate);
2269 }
2270
2271 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name,
2272 {std::vector<Real>(std::next(yoyCurveTimes.begin(), 1), yoyCurveTimes.end())});
2273 simDataWritten = true;
2274
2275 QuantLib::ext::shared_ptr<YoYInflationTermStructure> yoyCurve;
2276 // Note this is *not* a floating term structure, it is only suitable for sensi runs
2277 // TODO: floating
2279 yoyCurve =
2280 QuantLib::ext::make_shared<SpreadedYoYInflationCurve>(yoyInflationTs, yoyCurveTimes, quotes);
2281 } else {
2282 yoyCurve = QuantLib::ext::make_shared<YoYInflationCurveObserverMoving<Linear>>(
2283 0, yoyInflationIndex->fixingCalendar(), dc, yoyInflationTs->observationLag(),
2284 yoyInflationTs->frequency(), yoyInflationIndex->interpolated(), yoyCurveTimes,
2285 quotes, yoyInflationTs->seasonality());
2286 }
2287 yoyCurve->setAdjustReferenceDate(false);
2288 Handle<YoYInflationTermStructure> its(yoyCurve);
2289 its->enableExtrapolation();
2290 QuantLib::ext::shared_ptr<YoYInflationIndex> i(yoyInflationIndex->clone(its));
2291 Handle<YoYInflationIndex> zh(i);
2292 yoyInflationIndices_.insert(make_pair(make_pair(Market::defaultConfiguration, name), zh));
2293 } catch (const std::exception& e) {
2294 processException(continueOnError, e, name, param.first, simDataWritten);
2295 }
2296 }
2297 break;
2298
2300 for (const auto& name : param.second.second) {
2301 bool simDataWritten = false;
2302 try {
2303 LOG("building " << name << " yoy inflation cap/floor volatility curve...");
2304 Handle<QuantExt::YoYOptionletVolatilitySurface> wrapper =
2305 initMarket->yoyCapFloorVol(name, configuration);
2306 LOG("Initial market "
2307 << name << " yoy inflation cap/floor volatility type = " << wrapper->volatilityType());
2308 Handle<QuantExt::YoYOptionletVolatilitySurface> hYoYCapletVol;
2309
2310 // Check if the risk factor is simulated before adding it
2311 if (param.second.first) {
2312 LOG("Simulating yoy inflation optionlet vols for index name " << name);
2313 vector<Period> optionTenors = parameters->yoyInflationCapFloorVolExpiries(name);
2314 vector<Date> optionDates(optionTenors.size());
2315 vector<Real> strikes = parameters->yoyInflationCapFloorVolStrikes(name);
2316 vector<vector<Handle<Quote>>> quotes(
2317 optionTenors.size(), vector<Handle<Quote>>(strikes.size(), Handle<Quote>()));
2318 for (Size i = 0; i < optionTenors.size(); ++i) {
2319 optionDates[i] = wrapper->optionDateFromTenor(optionTenors[i]);
2320 for (Size j = 0; j < strikes.size(); ++j) {
2321 Real vol =
2322 wrapper->volatility(optionTenors[i], strikes[j], wrapper->observationLag(),
2323 wrapper->allowsExtrapolation());
2324 QuantLib::ext::shared_ptr<SimpleQuote> q(
2325 new SimpleQuote(useSpreadedTermStructures_ ? 0.0 : vol));
2326 Size index = i * strikes.size() + j;
2327 simDataTmp.emplace(std::piecewise_construct,
2328 std::forward_as_tuple(param.first, name, index),
2329 std::forward_as_tuple(q));
2331 absoluteSimDataTmp.emplace(std::piecewise_construct,
2332 std::forward_as_tuple(param.first, name, index),
2333 std::forward_as_tuple(vol));
2334 }
2335 quotes[i][j] = Handle<Quote>(q);
2336 TLOG("ScenarioSimMarket yoy cf vol " << name << " tenor #" << i << " strike #" << j
2337 << " " << vol);
2338 }
2339 }
2340
2341 std::vector<std::vector<Real>> coordinates(2);
2342 for (Size i = 0; i < optionTenors.size(); ++i) {
2343 coordinates[0].push_back(
2344 wrapper->timeFromReference(wrapper->optionDateFromTenor(optionTenors[i])));
2345 }
2346 for (Size j = 0; j < strikes.size(); ++j) {
2347 coordinates[1].push_back(strikes[j]);
2348 }
2349
2350 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name, coordinates);
2351 simDataWritten = true;
2352
2353 DayCounter dc = wrapper->dayCounter();
2354
2355 QuantLib::ext::shared_ptr<QuantExt::YoYOptionletVolatilitySurface> yoyoptionletvolsurface;
2357 yoyoptionletvolsurface = QuantLib::ext::make_shared<QuantExt::SpreadedYoYVolatilitySurface>(
2358 wrapper, optionDates, strikes, quotes);
2359 } else {
2360 yoyoptionletvolsurface = QuantLib::ext::make_shared<StrippedYoYInflationOptionletVol>(
2361 0, wrapper->calendar(), wrapper->businessDayConvention(), dc,
2362 wrapper->observationLag(), wrapper->frequency(), wrapper->indexIsInterpolated(),
2363 optionDates, strikes, quotes, wrapper->volatilityType(), wrapper->displacement());
2364 }
2365 hYoYCapletVol = Handle<QuantExt::YoYOptionletVolatilitySurface>(yoyoptionletvolsurface);
2366 } else {
2367 string decayModeString = parameters->yoyInflationCapFloorVolDecayMode();
2368 ReactionToTimeDecay decayMode = parseDecayMode(decayModeString);
2369 QuantLib::ext::shared_ptr<QuantExt::DynamicYoYOptionletVolatilitySurface> yoyCapletVol =
2370 QuantLib::ext::make_shared<QuantExt::DynamicYoYOptionletVolatilitySurface>(*wrapper, decayMode);
2371 hYoYCapletVol = Handle<QuantExt::YoYOptionletVolatilitySurface>(yoyCapletVol);
2372 }
2373 hYoYCapletVol->setAdjustReferenceDate(false);
2374 if (wrapper->allowsExtrapolation())
2375 hYoYCapletVol->enableExtrapolation();
2376 yoyCapFloorVolSurfaces_.emplace(std::piecewise_construct,
2377 std::forward_as_tuple(Market::defaultConfiguration, name),
2378 std::forward_as_tuple(hYoYCapletVol));
2379 LOG("Simulation market yoy inflation cap/floor volatility type = "
2380 << hYoYCapletVol->volatilityType());
2381 } catch (const std::exception& e) {
2382 processException(continueOnError, e, name, param.first, simDataWritten);
2383 }
2384 }
2385 break;
2386
2388
2389 std::vector<std::string> curveNames;
2390 std::vector<std::string> basisCurves;
2391 for (const auto& name : param.second.second) {
2392 try {
2393 Handle<PriceTermStructure> initialCommodityCurve =
2394 initMarket->commodityPriceCurve(name, configuration);
2395 QuantLib::ext::shared_ptr<CommodityBasisPriceTermStructure> basisCurve =
2396 QuantLib::ext::dynamic_pointer_cast<QuantExt::CommodityBasisPriceTermStructure>(
2397 initialCommodityCurve.currentLink());
2398 if (basisCurve != nullptr) {
2399 basisCurves.push_back(name);
2400 } else {
2401 curveNames.push_back(name);
2402 }
2403 } catch (...) {
2404 curveNames.push_back(name);
2405 }
2406 }
2407 curveNames.insert(curveNames.end(), basisCurves.begin(), basisCurves.end());
2408
2409 for (const auto& name : curveNames) {
2410
2411 bool simDataWritten = false;
2412 try {
2413 LOG("building commodity curve for " << name);
2414
2415 // Time zero initial market commodity curve
2416 Handle<PriceTermStructure> initialCommodityCurve =
2417 initMarket->commodityPriceCurve(name, configuration);
2418
2419 bool allowsExtrapolation = initialCommodityCurve->allowsExtrapolation();
2420
2421 // Get the configured simulation tenors. Simulation tenors being empty at this point means
2422 // that we wish to use the pillar date points from the t_0 market PriceTermStructure.
2423 vector<Period> simulationTenors = parameters->commodityCurveTenors(name);
2424 DayCounter commodityCurveDayCounter = initialCommodityCurve->dayCounter();
2425 if (simulationTenors.empty()) {
2426 DLOG("simulation tenors are empty, use "
2427 << initialCommodityCurve->pillarDates().size()
2428 << " pillar dates from T0 curve to build ssm curve.");
2429 simulationTenors.reserve(initialCommodityCurve->pillarDates().size());
2430 for (const Date& d : initialCommodityCurve->pillarDates()) {
2431 QL_REQUIRE(d >= asof_, "Commodity curve pillar date (" << io::iso_date(d)
2432 << ") must be after as of ("
2433 << io::iso_date(asof_) << ").");
2434 simulationTenors.push_back(Period(d - asof_, Days));
2435 }
2436
2437 // It isn't great to be updating parameters here. However, actual tenors are requested
2438 // downstream from parameters and they need to be populated.
2439 parameters->setCommodityCurveTenors(name, simulationTenors);
2440 } else {
2441 DLOG("using " << simulationTenors.size() << " simulation tenors.");
2442 }
2443
2444 // Get prices at specified simulation times from time 0 market curve and place in quotes
2445 vector<Handle<Quote>> quotes(simulationTenors.size());
2446 vector<Real> times;
2447 for (Size i = 0; i < simulationTenors.size(); i++) {
2448 Date d = asof_ + simulationTenors[i];
2449 Real price = initialCommodityCurve->price(d, allowsExtrapolation);
2450 times.push_back(initialCommodityCurve->timeFromReference(d));
2451 TLOG("Commodity curve: price at " << io::iso_date(d) << " is " << price);
2452 // if we simulate the factors and use spreaded ts, the quote should be zero
2453 QuantLib::ext::shared_ptr<SimpleQuote> quote = QuantLib::ext::make_shared<SimpleQuote>(
2454 param.second.first && useSpreadedTermStructures_ ? 0.0 : price);
2455 quotes[i] = Handle<Quote>(quote);
2456
2457 // If we are simulating commodities, add the quote to simData_
2458 if (param.second.first) {
2459 simDataTmp.emplace(piecewise_construct, forward_as_tuple(param.first, name, i),
2460 forward_as_tuple(quote));
2462 absoluteSimDataTmp.emplace(piecewise_construct,
2463 forward_as_tuple(param.first, name, i),
2464 forward_as_tuple(price));
2465 }
2466 }
2467
2468 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name, {times});
2469 simDataWritten = true;
2470 QuantLib::ext::shared_ptr<PriceTermStructure> priceCurve;
2471
2472 if (param.second.first && useSpreadedTermStructures_) {
2473 vector<Real> simulationTimes;
2474 for (auto const& t : simulationTenors) {
2475 simulationTimes.push_back(commodityCurveDayCounter.yearFraction(asof_, asof_ + t));
2476 }
2477 if (simulationTimes.front() != 0.0) {
2478 simulationTimes.insert(simulationTimes.begin(), 0.0);
2479 quotes.insert(quotes.begin(), quotes.front());
2480 }
2481 // Created spreaded commodity price curve if we simulate commodities and spreads should be
2482 // used
2483 priceCurve = QuantLib::ext::make_shared<SpreadedPriceTermStructure>(initialCommodityCurve,
2484 simulationTimes, quotes);
2485 } else {
2486 priceCurve= QuantLib::ext::make_shared<InterpolatedPriceCurve<LinearFlat>>(
2487 simulationTenors, quotes, commodityCurveDayCounter, initialCommodityCurve->currency());
2488 }
2489
2490 auto orgBasisCurve =
2491 QuantLib::ext::dynamic_pointer_cast<QuantExt::CommodityBasisPriceTermStructure>(
2492 initialCommodityCurve.currentLink());
2493
2494 Handle<PriceTermStructure> pts;
2495 if (orgBasisCurve == nullptr) {
2496 pts = Handle<PriceTermStructure>(priceCurve);
2497 } else {
2498 auto baseIndex = commodityIndices_.find(
2499 {Market::defaultConfiguration, orgBasisCurve->baseIndex()->underlyingName()});
2500 QL_REQUIRE(baseIndex != commodityIndices_.end(),
2501 "Internal error in scenariosimmarket: couldn't find underlying base curve '"
2502 << orgBasisCurve->baseIndex()->underlyingName()
2503 << "' while building commodity basis curve '" << name << "'");
2504 pts = Handle<PriceTermStructure>(QuantLib::ext::make_shared<CommodityBasisPriceCurveWrapper>(
2505 orgBasisCurve, baseIndex->second.currentLink(), priceCurve));
2506 }
2507
2508 pts->setAdjustReferenceDate(false);
2509 pts->enableExtrapolation(allowsExtrapolation);
2510
2511 Handle<CommodityIndex> commIdx(parseCommodityIndex(name, false, pts));
2512 commodityIndices_.emplace(piecewise_construct,
2513 forward_as_tuple(Market::defaultConfiguration, name),
2514 forward_as_tuple(commIdx));
2515 } catch (const std::exception& e) {
2516 processException(continueOnError, e, name, param.first, simDataWritten);
2517 }
2518 }
2519 break;
2520 }
2522 for (const auto& name : param.second.second) {
2523 bool simDataWritten = false;
2524 try {
2525 LOG("building commodity volatility for " << name);
2526
2527 // Get initial base volatility structure
2528 Handle<BlackVolTermStructure> baseVol = initMarket->commodityVolatility(name, configuration);
2529
2530 Handle<BlackVolTermStructure> newVol;
2531 bool stickyStrike = parameters_->commodityVolSmileDynamics(name) == "StickyStrike";
2532 if (param.second.first) {
2533
2534 // Check and reorg moneyness and/or expiries to simplify subsequent code.
2535 vector<Real> moneyness = parameters->commodityVolMoneyness(name);
2536 QL_REQUIRE(!moneyness.empty(), "Commodity volatility moneyness for "
2537 << name << " should have at least one element.");
2538 sort(moneyness.begin(), moneyness.end());
2539 auto mIt = unique(moneyness.begin(), moneyness.end(),
2540 [](const Real& x, const Real& y) { return close(x, y); });
2541 QL_REQUIRE(mIt == moneyness.end(),
2542 "Commodity volatility moneyness values for " << name << " should be unique.");
2543
2544 vector<Period> expiries = parameters->commodityVolExpiries(name);
2545 QL_REQUIRE(!expiries.empty(), "Commodity volatility expiries for "
2546 << name << " should have at least one element.");
2547 sort(expiries.begin(), expiries.end());
2548 auto eIt = unique(expiries.begin(), expiries.end());
2549 QL_REQUIRE(eIt == expiries.end(),
2550 "Commodity volatility expiries for " << name << " should be unique.");
2551
2552 // Get this scenario simulation market's commodity price curve. An exception is expected
2553 // if there is no commodity curve but there is a commodity volatility.
2554 const auto& priceCurve = *commodityPriceCurve(name, configuration);
2555
2556 // More than one moneyness implies a surface. If we have a surface, we will build a
2557 // forward surface below which requires two yield term structures, one for the commodity
2558 // price currency and another that recovers the commodity forward prices. We don't want
2559 // the commodity prices changing with changes in the commodity price currency yield curve
2560 // so we take a copy here - it will work for sticky strike false also.
2561 bool isSurface = moneyness.size() > 1;
2562 Handle<YieldTermStructure> yts;
2563 Handle<YieldTermStructure> priceYts;
2564
2565 if (isSurface) {
2566
2567 vector<Date> dates{asof_};
2568 vector<Real> dfs{1.0};
2569
2570 auto discCurve = discountCurve(priceCurve->currency().code(), configuration);
2571 for (const auto& expiry : expiries) {
2572 auto d = asof_ + expiry;
2573 if (d == asof_)
2574 continue;
2575 dates.push_back(d);
2576 dfs.push_back(discCurve->discount(d, true));
2577 }
2578
2579 auto ytsPtr = QuantLib::ext::make_shared<DiscountCurve>(dates, dfs, discCurve->dayCounter());
2580 ytsPtr->enableExtrapolation();
2581 yts = Handle<YieldTermStructure>(ytsPtr);
2582 priceYts = Handle<YieldTermStructure>(
2583 QuantLib::ext::make_shared<PriceTermStructureAdapter>(priceCurve, ytsPtr));
2584 priceYts->enableExtrapolation();
2585 }
2586
2587 // Create surface of quotes, rows are moneyness, columns are expiries.
2588 using QuoteRow = vector<Handle<Quote>>;
2589 using QuoteMatrix = vector<QuoteRow>;
2590 QuoteMatrix quotes(moneyness.size(), QuoteRow(expiries.size()));
2591
2592 // Calculate up front the expiry times, dates and forward prices.
2593 vector<Date> expiryDates(expiries.size());
2594 vector<Time> expiryTimes(expiries.size());
2595 vector<Real> forwards(expiries.size());
2596 // TODO: do we want to use the base vol dc or - as elsewhere - a dc specified in the ssm
2597 // parameters?
2598 DayCounter dayCounter = baseVol->dayCounter();
2599 for (Size j = 0; j < expiries.size(); ++j) {
2600 Date d = asof_ + expiries[j];
2601 expiryDates[j] = d;
2602 expiryTimes[j] = dayCounter.yearFraction(asof_, d);
2603 forwards[j] = priceCurve->price(d);
2604 }
2605
2606 // Store the quotes.
2607 Size index = 0;
2608 for (Size i = 0; i < moneyness.size(); ++i) {
2609 for (Size j = 0; j < expiries.size(); ++j) {
2610 Real strike = moneyness[i] * forwards[j];
2611 auto vol = baseVol->blackVol(expiryDates[j], strike);
2612 auto quote =
2613 QuantLib::ext::make_shared<SimpleQuote>(useSpreadedTermStructures_ ? 0.0 : vol);
2614 simDataTmp.emplace(piecewise_construct, forward_as_tuple(param.first, name, index),
2615 forward_as_tuple(quote));
2617 absoluteSimDataTmp.emplace(piecewise_construct,
2618 forward_as_tuple(param.first, name, index),
2619 forward_as_tuple(vol));
2620 }
2621 quotes[i][j] = Handle<Quote>(quote);
2622 ++index;
2623 }
2624 }
2625
2626 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name, {moneyness, expiryTimes});
2627 simDataWritten = true;
2628
2629 // Create volatility structure
2630 if (!isSurface) {
2631 DLOG("Ssm comm vol for " << name << " uses BlackVarianceCurve3.");
2633 newVol =
2634 Handle<BlackVolTermStructure>(QuantLib::ext::make_shared<SpreadedBlackVolatilityCurve>(
2635 Handle<BlackVolTermStructure>(baseVol), expiryTimes, quotes[0], true));
2636 } else {
2637 newVol = Handle<BlackVolTermStructure>(QuantLib::ext::make_shared<BlackVarianceCurve3>(
2638 0, NullCalendar(), baseVol->businessDayConvention(), dayCounter, expiryTimes,
2639 quotes[0], false));
2640 }
2641 } else {
2642 DLOG("Ssm comm vol for " << name << " uses BlackVarianceSurfaceMoneynessSpot.");
2643
2644 bool flatExtrapMoneyness = true;
2645 Handle<Quote> spot(QuantLib::ext::make_shared<SimpleQuote>(priceCurve->price(0)));
2647 // get init market curves to populate sticky ts in vol surface ctor
2648 Handle<YieldTermStructure> initMarketYts =
2649 initMarket->discountCurve(priceCurve->currency().code(), configuration);
2650 Handle<QuantExt::PriceTermStructure> priceCurve =
2651 initMarket->commodityPriceCurve(name, configuration);
2652 Handle<YieldTermStructure> initMarketPriceYts(
2653 QuantLib::ext::make_shared<PriceTermStructureAdapter>(*priceCurve, *initMarketYts));
2654 // create vol surface
2655 newVol = Handle<BlackVolTermStructure>(
2656 QuantLib::ext::make_shared<SpreadedBlackVolatilitySurfaceMoneynessForward>(
2657 Handle<BlackVolTermStructure>(baseVol), spot, expiryTimes, moneyness,
2658 quotes, Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(spot->value())),
2659 initMarketPriceYts, initMarketYts, priceYts, yts, stickyStrike));
2660 } else {
2661 newVol = Handle<BlackVolTermStructure>(
2662 QuantLib::ext::make_shared<BlackVarianceSurfaceMoneynessForward>(
2663 baseVol->calendar(), spot, expiryTimes, moneyness, quotes, dayCounter,
2664 priceYts, yts, stickyStrike, flatExtrapMoneyness));
2665 }
2666 }
2667
2668 } else {
2669 string decayModeString = parameters->commodityVolDecayMode();
2670 DLOG("Deterministic commodity volatilities with decay mode " << decayModeString << " for "
2671 << name);
2672 ReactionToTimeDecay decayMode = parseDecayMode(decayModeString);
2673 // Copy what was done for equity here
2674 // May need to revisit when looking at commodity RFE
2675 newVol = Handle<BlackVolTermStructure>(
2676 QuantLib::ext::make_shared<QuantExt::DynamicBlackVolTermStructure<tag::curve>>(
2677 baseVol, 0, NullCalendar(), decayMode,
2678 stickyStrike ? StickyStrike : StickyLogMoneyness));
2679 }
2680
2681 newVol->setAdjustReferenceDate(false);
2682 newVol->enableExtrapolation(baseVol->allowsExtrapolation());
2683 commodityVols_.emplace(piecewise_construct,
2684 forward_as_tuple(Market::defaultConfiguration, name),
2685 forward_as_tuple(newVol));
2686
2687 DLOG("Commodity volatility curve built for " << name);
2688 } catch (const std::exception& e) {
2689 processException(continueOnError, e, name, param.first, simDataWritten);
2690 }
2691 }
2692 break;
2693
2695 for (const auto& name : param.second.second) {
2696 bool simDataWritten = false;
2697 try {
2698 LOG("Adding correlations for " << name << " from configuration " << configuration);
2699
2700 vector<string> tokens = getCorrelationTokens(name);
2701 QL_REQUIRE(tokens.size() == 2, "not a valid correlation pair: " << name);
2702 pair<string, string> pair = std::make_pair(tokens[0], tokens[1]);
2703
2704 QuantLib::ext::shared_ptr<QuantExt::CorrelationTermStructure> corr;
2705 Handle<QuantExt::CorrelationTermStructure> baseCorr =
2706 initMarket->correlationCurve(pair.first, pair.second, configuration);
2707
2708 Handle<QuantExt::CorrelationTermStructure> ch;
2709 if (param.second.first) {
2710 Size n = parameters->correlationStrikes().size();
2711 Size m = parameters->correlationExpiries().size();
2712 vector<vector<Handle<Quote>>> quotes(n, vector<Handle<Quote>>(m, Handle<Quote>()));
2713 vector<Time> times(m);
2714 Calendar cal = baseCorr->calendar();
2715 DayCounter dc = baseCorr->dayCounter();
2716
2717 for (Size i = 0; i < n; i++) {
2718 Real strike = parameters->correlationStrikes()[i];
2719
2720 for (Size j = 0; j < m; j++) {
2721 // Index is expiries then strike TODO: is this the best?
2722 Size idx = i * m + j;
2723 times[j] = dc.yearFraction(asof_, asof_ + parameters->correlationExpiries()[j]);
2724 Real correlation =
2725 baseCorr->correlation(asof_ + parameters->correlationExpiries()[j], strike);
2726 QuantLib::ext::shared_ptr<SimpleQuote> q(
2727 new SimpleQuote(useSpreadedTermStructures_ ? 0.0 : correlation));
2728 simDataTmp.emplace(
2729 std::piecewise_construct,
2730 std::forward_as_tuple(RiskFactorKey::KeyType::Correlation, name, idx),
2731 std::forward_as_tuple(q));
2733 absoluteSimDataTmp.emplace(
2734 std::piecewise_construct,
2735 std::forward_as_tuple(RiskFactorKey::KeyType::Correlation, name, idx),
2736 std::forward_as_tuple(correlation));
2737 }
2738 quotes[i][j] = Handle<Quote>(q);
2739 }
2740 }
2741
2742 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name,
2743 {parameters->correlationStrikes(), times});
2744 simDataWritten = true;
2745
2746 if (n == 1 && m == 1) {
2748 ch = Handle<QuantExt::CorrelationTermStructure>(
2749 QuantLib::ext::make_shared<QuantExt::SpreadedCorrelationCurve>(baseCorr, times,
2750 quotes[0]));
2751 } else {
2752 ch = Handle<QuantExt::CorrelationTermStructure>(QuantLib::ext::make_shared<FlatCorrelation>(
2753 baseCorr->settlementDays(), cal, quotes[0][0], dc));
2754 }
2755 } else if (n == 1) {
2757 ch = Handle<QuantExt::CorrelationTermStructure>(
2758 QuantLib::ext::make_shared<QuantExt::SpreadedCorrelationCurve>(baseCorr, times,
2759 quotes[0]));
2760 } else {
2761 ch = Handle<QuantExt::CorrelationTermStructure>(
2762 QuantLib::ext::make_shared<InterpolatedCorrelationCurve<Linear>>(times, quotes[0], dc,
2763 cal));
2764 }
2765 } else {
2766 QL_FAIL("only atm or flat correlation termstructures currently supported");
2767 }
2768
2769 ch->enableExtrapolation(baseCorr->allowsExtrapolation());
2770 } else {
2771 ch = Handle<QuantExt::CorrelationTermStructure>(*baseCorr);
2772 }
2773
2774 ch->setAdjustReferenceDate(false);
2775 correlationCurves_[make_tuple(Market::defaultConfiguration, pair.first, pair.second)] = ch;
2776 } catch (const std::exception& e) {
2777 processException(continueOnError, e, name, param.first, simDataWritten);
2778 }
2779 }
2780 break;
2781
2783 for (const auto& name : param.second.second) {
2784 bool simDataWritten = false;
2785 try {
2786 DLOG("Adding cpr " << name << " from configuration " << configuration);
2787 Real v = initMarket->cpr(name, configuration)->value();
2788 auto q = QuantLib::ext::make_shared<SimpleQuote>(useSpreadedTermStructures_ ? 0.0 : v);
2790 auto m = [v](Real x) { return x + v; };
2791 cprs_.insert(make_pair(make_pair(Market::defaultConfiguration, name),
2792 Handle<Quote>(QuantLib::ext::make_shared<DerivedQuote<decltype(m)>>(
2793 Handle<Quote>(q), m))));
2794 } else {
2795 cprs_.insert(make_pair(make_pair(Market::defaultConfiguration, name), Handle<Quote>(q)));
2796 }
2797
2798 if (param.second.first) {
2799 simDataTmp.emplace(std::piecewise_construct, std::forward_as_tuple(param.first, name),
2800 std::forward_as_tuple(q));
2802 absoluteSimDataTmp.emplace(std::piecewise_construct,
2803 std::forward_as_tuple(param.first, name),
2804 std::forward_as_tuple(v));
2805 }
2806 }
2807 writeSimData(simDataTmp, absoluteSimDataTmp, param.first, name, {});
2808 simDataWritten = true;
2809 } catch (const std::exception& e) {
2810 processException(continueOnError, e, name, param.first, simDataWritten);
2811 }
2812 }
2813 break;
2814
2816 // nothing to do, these are written to asd
2817 break;
2818
2820 // nothing to do, these are written to asd
2821 break;
2822
2824 WLOG("RiskFactorKey None not yet implemented");
2825 break;
2826 }
2827
2828 if (!param.second.second.empty()) {
2829 LOG("built " << std::left << std::setw(25) << param.first << std::right << std::setw(10)
2830 << param.second.second.size() << std::setprecision(3) << std::setw(15)
2831 << static_cast<double>(timer.elapsed().wall) / 1E6 << " ms");
2832 }
2833
2834 } catch (const std::exception& e) {
2835 StructuredMessage(ore::data::StructuredMessage::Category::Error,
2836 ore::data::StructuredMessage::Group::Curve, e.what(),
2837 {{"exceptionType", "ScenarioSimMarket top level catch - this should never happen, "
2838 "contact dev. Results are likely wrong or incomplete."}})
2839 .log();
2840 processException(continueOnError, e);
2841 }
2842 }
2843
2844 // swap indices
2845 DLOG("building swap indices...");
2846 for (const auto& it : parameters->swapIndices()) {
2847 addSwapIndexToSsm(it.first, continueOnError);
2848 }
2849
2850 if (offsetScenario_ != nullptr && offsetScenario_->isAbsolute() && !useSpreadedTermStructures_) {
2851 auto recastedScenario = recastScenario(offsetScenario_, offsetScenario_->coordinates(), coordinatesData_);
2852 QL_REQUIRE(recastedScenario != nullptr, "ScenarioSimMarke: Offset Scenario couldn't applied");
2853 for (auto& [key, quote] : simData_) {
2854 if (recastedScenario->has(key)) {
2855 quote->setValue(recastedScenario->get(key));
2856 } else {
2857 QL_FAIL("ScenarioSimMarket: Offset Scenario doesnt contain key "
2858 << key
2859 << ". Internal error, possibly an internal error in the recastScenario method, contact dev.");
2860 }
2861 }
2862 } else if (offsetScenario_ != nullptr && offsetScenario_->isAbsolute() && useSpreadedTermStructures_) {
2863 auto recastedScenario = recastScenario(offsetScenario_, offsetScenario_->coordinates(), coordinatesData_);
2864 QL_REQUIRE(recastedScenario != nullptr, "ScenarioSimMarke: Offset Scenario couldn't applied");
2865 for (auto& [key, data] : simData_) {
2866 if (recastedScenario->has(key)) {
2867 auto shift = getDifferenceScenario(key.keytype, absoluteSimData_[key], recastedScenario->get(key));
2868 data->setValue(shift);
2869 absoluteSimData_[key] = recastedScenario->get(key);
2870 } else {
2871 QL_FAIL("ScenarioSimMarket: Offset Scenario doesnt contain key "
2872 << key
2873 << ". Internal error, possibly an internal error in the recastScenario method, contact dev.");
2874 }
2875 }
2876 } else if (offsetScenario_ != nullptr && !offsetScenario_->isAbsolute() && !useSpreadedTermStructures_) {
2877 auto recastedScenario = recastScenario(offsetScenario_, offsetScenario_->coordinates(), coordinatesData_);
2878 QL_REQUIRE(recastedScenario != nullptr, "ScenarioSimMarke: Offset Scenario couldn't applied");
2879 for (auto& [key, quote] : simData_) {
2880 if (recastedScenario->has(key)) {
2881 quote->setValue(addDifferenceToScenario(key.keytype, quote->value(), recastedScenario->get(key)));
2882 } else {
2883 QL_FAIL("ScenarioSimMarket: Offset Scenario doesnt contain key "
2884 << key
2885 << ". Internal error, possibly an internal error in the recastScenario method, contact dev.");
2886 }
2887 }
2888 } else if (offsetScenario_ != nullptr && !offsetScenario_->isAbsolute() && useSpreadedTermStructures_) {
2889 auto recastedScenario = recastScenario(offsetScenario_, offsetScenario_->coordinates(), coordinatesData_);
2890 QL_REQUIRE(recastedScenario != nullptr, "ScenarioSimMarke: Offset Scenario couldn't applied");
2891 for (auto& [key, quote] : simData_) {
2892 if (recastedScenario->has(key)) {
2893 quote->setValue(recastedScenario->get(key));
2894 absoluteSimData_[key] =
2895 addDifferenceToScenario(key.keytype, absoluteSimData_[key], recastedScenario->get(key));
2896 } else {
2897 QL_FAIL("ScenarioSimMarket: Offset Scenario doesnt contain key "
2898 << key
2899 << ". Internal error, possibly an internal error in the recastScenario method, contact dev.");
2900 }
2901 }
2902 }
2903
2904 LOG("building base scenario");
2905 auto tmp = QuantLib::ext::make_shared<SimpleScenario>(initMarket->asofDate(), "BASE", 1.0);
2907 for (auto const& data : simData_) {
2908 tmp->add(data.first, data.second->value());
2909 }
2910 tmp->setAbsolute(true);
2911 for (auto const& [type, name, coordinates] : coordinatesData_) {
2912 tmp->setCoordinates(type, name, coordinates);
2913 }
2915 } else {
2916 auto tmpAbs = QuantLib::ext::make_shared<SimpleScenario>(initMarket->asofDate(), "BASE", 1.0);
2917 for (auto const& data : simData_) {
2918 tmp->add(data.first, data.second->value());
2919 }
2920 for (auto const& data : absoluteSimData_) {
2921 tmpAbs->add(data.first, data.second);
2922 }
2923 tmp->setAbsolute(false);
2924 tmpAbs->setAbsolute(true);
2925 for (auto const& [type, name, coordinates] : coordinatesData_) {
2926 tmp->setCoordinates(type, name, coordinates);
2927 tmpAbs->setCoordinates(type, name, coordinates);
2928 }
2929 baseScenario_ = tmp;
2930 baseScenarioAbsolute_ = tmpAbs;
2931 }
2932 LOG("building base scenario done");
2933}
static void populateVolMatrix(const QuantLib::Handle< QuantLib::BlackVolTermStructure > &termStructre, std::vector< std::vector< Handle< QuantLib::Quote > > > &quotesToPopulate, const std::vector< Real > &times, const std::vector< Real > &stdDevPoints, const QuantLib::Interpolation &forwardCurve, const QuantLib::Interpolation atmVolCurve)
MakeOISCapFloor & withSettlementDays(Natural settlementDays)
MakeOISCapFloor & withTelescopicValueDates(bool telescopicValueDates)
boost::shared_ptr< SwaptionVolatilityStructure > convert() const
std::map< RiskFactorKey, QuantLib::ext::shared_ptr< SimpleQuote > > simData_
QuantLib::ext::shared_ptr< ScenarioFilter > filter_
bool addSwapIndexToSsm(const std::string &indexName, const bool continueOnError)
QuantLib::ext::shared_ptr< FixingManager > fixingManager_
QuantLib::Handle< QuantLib::YieldTermStructure > getYieldCurve(const std::string &yieldSpecId, const ore::data::TodaysMarketParameters &todaysMarketParams, const std::string &configuration, const QuantLib::ext::shared_ptr< ore::data::Market > &market=nullptr) const
QuantLib::ext::shared_ptr< Scenario > baseScenario_
const QuantLib::ext::shared_ptr< ScenarioSimMarketParameters > parameters_
QuantLib::ext::shared_ptr< Scenario > baseScenarioAbsolute_
void addYieldCurve(const QuantLib::ext::shared_ptr< Market > &initMarket, const std::string &configuration, const RiskFactorKey::KeyType rf, const string &key, const vector< Period > &tenors, bool &simDataWritten, bool simulate=true, bool spreaded=false)
QuantLib::ext::shared_ptr< Scenario > offsetScenario_
const QuantLib::ext::shared_ptr< FixingManager > & fixingManager() const override
Return the fixing manager.
std::set< std::tuple< RiskFactorKey::KeyType, std::string, std::vector< std::vector< Real > > > > coordinatesData_
std::map< RiskFactorKey, Real > absoluteSimData_
void writeSimData(std::map< RiskFactorKey, QuantLib::ext::shared_ptr< SimpleQuote > > &simDataTmp, std::map< RiskFactorKey, Real > &absoluteSimDataTmp, const RiskFactorKey::KeyType keyType, const std::string &name, const std::vector< std::vector< Real > > &coordinates)
const FallbackData & fallbackData(const string &iborIndex) const
bool useRfrCurveInSimulationMarket() const
bool isIndexReplaced(const string &iborIndex, const QuantLib::Date &asof=QuantLib::Date::maxDate()) const
Handle< Quote > fxSpot(const string &ccypair, const string &configuration=Market::defaultConfiguration) const
QuantLib::Handle< QuantExt::FxIndex > fxIndex(const string &fxIndex, const string &configuration=Market::defaultConfiguration) const
static const string defaultConfiguration
Handle< YieldTermStructure > discountCurve(const string &ccy, const string &configuration=Market::defaultConfiguration) const
map< pair< string, string >, Handle< OptionletVolatilityStructure > > capFloorCurves_
string shortSwapIndexBase(const string &key, const string &configuration=Market::defaultConfiguration) const override
string swapIndexBase(const string &key, const string &configuration=Market::defaultConfiguration) const override
virtual Handle< ZeroInflationIndex > zeroInflationIndex(const string &indexName, const string &configuration=Market::defaultConfiguration) const override
Handle< QuantExt::EquityIndex2 > equityCurve(const string &eqName, const string &configuration=Market::defaultConfiguration) const override
map< tuple< string, string, string >, Handle< QuantExt::CorrelationTermStructure > > correlationCurves_
map< pair< string, string >, QuantLib::Handle< QuantExt::EquityIndex2 > > equityCurves_
map< pair< string, string >, Handle< CPIVolatilitySurface > > cpiInflationCapFloorVolatilitySurfaces_
map< pair< string, string >, Handle< QuantExt::InflationIndexObserver > > baseCpis_
map< pair< string, string >, Handle< BlackVolTermStructure > > fxVols_
QuantLib::ext::shared_ptr< FXTriangulation > fx_
map< pair< string, string >, QuantLib::Handle< QuantExt::CommodityIndex > > commodityIndices_
map< pair< string, string >, Handle< QuantExt::CreditCurve > > defaultCurves_
map< pair< string, string >, Handle< IborIndex > > iborIndices_
map< pair< string, string >, Handle< YoYOptionletVolatilitySurface > > yoyCapFloorVolSurfaces_
Handle< QuantExt::CreditCurve > defaultCurve(const string &, const string &configuration=Market::defaultConfiguration) const override
map< pair< string, string >, Handle< YoYInflationIndex > > yoyInflationIndices_
map< pair< string, string >, Handle< QuantExt::CreditVolCurve > > cdsVols_
map< pair< string, string >, Handle< Quote > > equitySpots_
map< pair< string, string >, Handle< QuantLib::SwaptionVolatilityStructure > > swaptionCurves_
map< pair< string, string >, Handle< QuantExt::BaseCorrelationTermStructure > > baseCorrelations_
map< pair< string, string >, Handle< Quote > > cprs_
map< pair< string, string >, Handle< Quote > > recoveryRates_
QuantLib::Handle< QuantExt::PriceTermStructure > commodityPriceCurve(const string &commodityName, const string &configuration=Market::defaultConfiguration) const override
Handle< Quote > equitySpot(const string &eqName, const string &configuration=Market::defaultConfiguration) const override
map< pair< string, string >, Handle< ZeroInflationIndex > > zeroInflationIndices_
Handle< SwapIndex > swapIndex(const string &indexName, const string &configuration=Market::defaultConfiguration) const override
map< pair< string, string >, pair< string, string > > swaptionIndexBases_
map< pair< string, string >, Handle< BlackVolTermStructure > > equityVols_
virtual Handle< YoYInflationIndex > yoyInflationIndex(const string &indexName, const string &configuration=Market::defaultConfiguration) const override
map< pair< string, string >, Handle< QuantLib::SwaptionVolatilityStructure > > yieldVolCurves_
map< pair< string, string >, Handle< Quote > > securitySpreads_
Handle< YieldTermStructure > yieldCurve(const YieldCurveType &type, const string &ccy, const string &configuration=Market::defaultConfiguration) const override
Handle< IborIndex > iborIndex(const string &indexName, const string &configuration=Market::defaultConfiguration) const override
map< pair< string, string >, QuantLib::Handle< QuantLib::BlackVolTermStructure > > commodityVols_
map< pair< string, string >, std::pair< string, QuantLib::Period > > capFloorIndexBase_
SafeStack< ValueType > value
QuantLib::ext::shared_ptr< CurveSpec > parseCurveSpec(const string &s)
ReactionToTimeDecay
QuantLib::ext::shared_ptr< ZeroInflationIndex > parseZeroInflationIndex(const string &s, const Handle< ZeroInflationTermStructure > &h=Handle< ZeroInflationTermStructure >())
Calendar parseCalendar(const string &s)
QuantLib::ext::shared_ptr< IborIndex > parseIborIndex(const string &s, const Handle< YieldTermStructure > &h=Handle< YieldTermStructure >())
data
#define LOG(text)
#define DLOG(text)
#define WLOG(text)
#define TLOG(text)
QuantLib::Date fixingDate(const QuantLib::Date &d, const QuantLib::Period obsLag, const QuantLib::Frequency freq, bool interpolated)
Filter close_enough(const RandomVariable &x, const RandomVariable &y)
RandomVariable log(RandomVariable x)
Real getDifferenceScenario(const RiskFactorKey::KeyType keyType, const Real v1, const Real v2)
QuantLib::ext::shared_ptr< Scenario > recastScenario(const QuantLib::ext::shared_ptr< Scenario > &scenario, const std::map< std::pair< RiskFactorKey::KeyType, std::string >, std::vector< std::vector< Real > > > &oldCoordinates, const std::map< std::pair< RiskFactorKey::KeyType, std::string >, std::vector< std::vector< Real > > > &newCoordinates)
Real addDifferenceToScenario(const RiskFactorKey::KeyType keyType, const Real v, const Real d)
std::vector< std::string > getCorrelationTokens(const std::string &name)
Size size(const ValueType &v)
std::string to_string(const LocationInfo &l)
QuantLib::ext::shared_ptr< QuantExt::CommodityIndex > parseCommodityIndex(const string &name, bool hasPrefix, const Handle< PriceTermStructure > &ts, const Calendar &cal, const bool enforceFutureIndex)
vector< Real > strikes
vector< string > curveConfigs
string name
+ Here is the call graph for this function:

Member Function Documentation

◆ scenarioGenerator() [1/2]

virtual QuantLib::ext::shared_ptr< ScenarioGenerator > & scenarioGenerator ( )
virtual

Set scenario generator.

Definition at line 97 of file scenariosimmarket.hpp.

97{ return scenarioGenerator_; }
QuantLib::ext::shared_ptr< ScenarioGenerator > scenarioGenerator_

◆ scenarioGenerator() [2/2]

virtual const QuantLib::ext::shared_ptr< ScenarioGenerator > & scenarioGenerator ( ) const
virtual

Get scenario generator.

Definition at line 99 of file scenariosimmarket.hpp.

99{ return scenarioGenerator_; }

◆ aggregationScenarioData() [1/2]

virtual QuantLib::ext::shared_ptr< AggregationScenarioData > & aggregationScenarioData ( )
virtual

Set aggregation data.

Definition at line 102 of file scenariosimmarket.hpp.

102{ return asd_; }
QuantLib::ext::shared_ptr< AggregationScenarioData > asd_

◆ aggregationScenarioData() [2/2]

virtual const QuantLib::ext::shared_ptr< AggregationScenarioData > & aggregationScenarioData ( ) const
virtual

Get aggregation data.

Definition at line 104 of file scenariosimmarket.hpp.

104{ return asd_; }

◆ filter() [1/2]

virtual QuantLib::ext::shared_ptr< ScenarioFilter > & filter ( )
virtual

Set scenarioFilter.

Definition at line 107 of file scenariosimmarket.hpp.

107{ return filter_; }

◆ filter() [2/2]

virtual const QuantLib::ext::shared_ptr< ScenarioFilter > & filter ( ) const
virtual

Get scenarioFilter.

Definition at line 109 of file scenariosimmarket.hpp.

109{ return filter_; }

◆ preUpdate()

void preUpdate ( )
overridevirtual

Update.

Implements SimMarket.

Definition at line 3095 of file scenariosimmarket.cpp.

3095 {
3096 ObservationMode::Mode om = ObservationMode::instance().mode();
3098 ObservableSettings::instance().disableUpdates(false);
3099 else if (om == ObservationMode::Mode::Defer)
3100 ObservableSettings::instance().disableUpdates(true);
3101}

◆ updateScenario()

void updateScenario ( const Date &  )
overridevirtual

Retrieve next market scenario and apply this, but don't update date.

Implements SimMarket.

Definition at line 3119 of file scenariosimmarket.cpp.

3119 {
3120 QL_REQUIRE(scenarioGenerator_ != nullptr, "ScenarioSimMarket::update: no scenario generator set");
3121 auto scenario = scenarioGenerator_->next(d);
3122 QL_REQUIRE(scenario->asof() == d,
3123 "Invalid Scenario date " << scenario->asof() << ", expected " << d);
3124 numeraire_ = scenario->getNumeraire();
3125 label_ = scenario->label();
3126 applyScenario(scenario);
3127}
void applyScenario(const QuantLib::ext::shared_ptr< Scenario > &scenario)

◆ updateDate()

void updateDate ( const Date &  )
overridevirtual

Update to the given date.

Implements SimMarket.

Definition at line 3103 of file scenariosimmarket.cpp.

3103 {
3104 ObservationMode::Mode om = ObservationMode::instance().mode();
3105 if (d != Settings::instance().evaluationDate())
3106 Settings::instance().evaluationDate() = d;
3107 else if (om == ObservationMode::Mode::Unregister) {
3108 // Due to some of the notification chains having been unregistered,
3109 // it is possible that some lazy objects might be missed in the case
3110 // that the evaluation date has not been updated. Therefore, we
3111 // manually kick off an observer notification from this level.
3112 // We have unit regression tests in OREAnalyticsTestSuite to ensure
3113 // the various ObservationMode settings return the anticipated results.
3114 QuantLib::ext::shared_ptr<QuantLib::Observable> obs = QuantLib::Settings::instance().evaluationDate();
3115 obs->notifyObservers();
3116 }
3117}

◆ postUpdate()

void postUpdate ( const Date &  d,
bool  withFixings 
)
overridevirtual

Observable reset depending on selected mode, instrument updates.

Implements SimMarket.

Definition at line 3129 of file scenariosimmarket.cpp.

3129 {
3130 ObservationMode::Mode om = ObservationMode::instance().mode();
3131
3132 // Observation Mode - key to update these before fixings are set
3134 refresh();
3135 ObservableSettings::instance().enableUpdates();
3136 } else if (om == ObservationMode::Mode::Defer) {
3137 ObservableSettings::instance().enableUpdates();
3138 }
3139
3140 // Apply fixings as historical fixings. Must do this before we populate ASD
3141 if (withFixings)
3142 fixingManager_->update(d);
3143}
void refresh(const string &configuration=Market::defaultConfiguration) override

◆ updateAsd()

void updateAsd ( const Date &  )
overridevirtual

Update aggregation scenario data.

Implements SimMarket.

Definition at line 3145 of file scenariosimmarket.cpp.

3145 {
3146 if (asd_) {
3147 // add additional scenario data to the given container, if required
3148 for (auto i : parameters_->additionalScenarioDataIndices()) {
3149 QuantLib::ext::shared_ptr<QuantLib::Index> index;
3150 try {
3151 index = *iborIndex(i);
3152 } catch (...) {
3153 }
3154 try {
3155 index = *swapIndex(i);
3156 } catch (...) {
3157 }
3158 QL_REQUIRE(index != nullptr, "ScenarioSimMarket::update() index " << i << " not found in sim market");
3159 if (auto fb = QuantLib::ext::dynamic_pointer_cast<FallbackIborIndex>(index)) {
3160 // proxy fallback ibor index by its rfr index's fixing
3161 index = fb->rfrIndex();
3162 }
3163 asd_->set(index->fixing(index->fixingCalendar().adjust(d)), AggregationScenarioDataType::IndexFixing, i);
3164 }
3165
3166 for (auto c : parameters_->additionalScenarioDataCcys()) {
3167 if (c != parameters_->baseCcy())
3168 asd_->set(fxSpot(c + parameters_->baseCcy())->value(), AggregationScenarioDataType::FXSpot, c);
3169 }
3170
3171 for (Size i = 0; i < parameters_->additionalScenarioDataNumberOfCreditStates(); ++i) {
3172 RiskFactorKey key(RiskFactorKey::KeyType::CreditState, std::to_string(i));
3173 QL_REQUIRE(currentScenario_->has(key), "scenario does not have key " << key);
3174 asd_->set(currentScenario_->get(key), AggregationScenarioDataType::CreditState, std::to_string(i));
3175 }
3176
3177 for (const auto& n : parameters_->additionalScenarioDataSurvivalWeights()) {
3178 RiskFactorKey key(RiskFactorKey::KeyType::SurvivalWeight, n);
3179 QL_REQUIRE(currentScenario_->has(key), "scenario does not have key " << key);
3181 RiskFactorKey rrKey(RiskFactorKey::KeyType::RecoveryRate, n);
3182 QL_REQUIRE(currentScenario_->has(rrKey), "scenario does not have key " << key);
3184 }
3185
3187
3188 asd_->next();
3189 }
3190}
QuantLib::ext::shared_ptr< Scenario > currentScenario_

◆ reset()

void reset ( )
overridevirtual

Reset sim market to initial state.

Implements SimMarket.

Definition at line 2951 of file scenariosimmarket.cpp.

2951 {
2952 auto filterBackup = filter_;
2953 // no filter
2954 filter_ = QuantLib::ext::make_shared<ScenarioFilter>();
2955 // reset eval date
2956 Settings::instance().evaluationDate() = baseScenario_->asof();
2957 // reset numeraire and label
2958 numeraire_ = baseScenario_->getNumeraire();
2959 label_ = baseScenario_->label();
2960 // delete the sim data cache
2961 cachedSimData_.clear();
2962 cachedSimDataActive_.clear();
2963 // reset term structures
2965 // clear delta scenario keys
2966 diffToBaseKeys_.clear();
2967 // see the comment in update() for why this is necessary...
2968 if (ObservationMode::instance().mode() == ObservationMode::Mode::Unregister) {
2969 QuantLib::ext::shared_ptr<QuantLib::Observable> obs = QuantLib::Settings::instance().evaluationDate();
2970 obs->notifyObservers();
2971 }
2972 // reset fixing manager
2973 fixingManager_->reset();
2974 // restore the filter
2975 filter_ = filterBackup;
2976}
std::vector< QuantLib::ext::shared_ptr< SimpleQuote > > cachedSimData_
std::set< ore::analytics::RiskFactorKey > diffToBaseKeys_

◆ baseScenario()

virtual QuantLib::ext::shared_ptr< Scenario > baseScenario ( ) const
virtual

Scenario representing the initial state of the market. If useSpreadedTermStructures = false, this scenario contains absolute values for all risk factor keys. If useSpreadedTermStructures = true, this scenario contains spread values for all risk factor keys which support spreaded term structures and absolute values for the other risk factor keys. The spread values will typically be zero (e.g. for vol risk factors) or 1 (e.g. for rate curve risk factors, since we use discount factors there).

Definition at line 127 of file scenariosimmarket.hpp.

127{ return baseScenario_; }

◆ baseScenarioAbsolute()

virtual QuantLib::ext::shared_ptr< Scenario > baseScenarioAbsolute ( ) const
virtual

Scenario representing the initial state of the market. This scenario contains absolute values for all risk factor types, no matter whether useSpreadedTermStructures is true or false.

Definition at line 131 of file scenariosimmarket.hpp.

131{ return baseScenarioAbsolute_; }

◆ useSpreadedTermStructures()

bool useSpreadedTermStructures ( ) const

Return true if this instance uses spreaded term structures

Definition at line 134 of file scenariosimmarket.hpp.

◆ fixingManager()

const QuantLib::ext::shared_ptr< FixingManager > & fixingManager ( ) const
overridevirtual

Return the fixing manager.

Implements SimMarket.

Definition at line 137 of file scenariosimmarket.hpp.

137{ return fixingManager_; }

◆ isSimulated()

bool isSimulated ( const RiskFactorKey::KeyType factor) const
virtual

is risk factor key simulated by this sim market instance?

Definition at line 3192 of file scenariosimmarket.cpp.

3192 {
3193 return std::find(nonSimulatedFactors_.begin(), nonSimulatedFactors_.end(), factor) == nonSimulatedFactors_.end();
3194}
std::set< RiskFactorKey::KeyType > nonSimulatedFactors_

◆ applyScenario()

void applyScenario ( const QuantLib::ext::shared_ptr< Scenario > &  scenario)

Definition at line 2978 of file scenariosimmarket.cpp.

2978 {
2979
2980 currentScenario_ = scenario;
2981
2982 // 1 handle delta scenario
2983
2984 auto deltaScenario = QuantLib::ext::dynamic_pointer_cast<DeltaScenario>(scenario);
2985
2986 /*! our assumption is that either all or none of the scenarios we apply are
2987 delta scenarios or the base scenario */
2988
2989 if (deltaScenario != nullptr) {
2990 for (auto const& key : diffToBaseKeys_) {
2991 auto it = simData_.find(key);
2992 if (it != simData_.end()) {
2993 it->second->setValue(baseScenario_->get(key));
2994 }
2995 }
2996 diffToBaseKeys_.clear();
2997 auto delta = deltaScenario->delta();
2998 bool missingPoint = false;
2999 for (auto const& key : delta->keys()) {
3000 auto it = simData_.find(key);
3001 if (it == simData_.end()) {
3002 ALOG("simulation data point missing for key " << key);
3003 missingPoint = true;
3004 } else {
3005 if (filter_->allow(key)) {
3006 it->second->setValue(delta->get(key));
3007 diffToBaseKeys_.insert(key);
3008 }
3009 }
3010 }
3011 QL_REQUIRE(!missingPoint, "simulation data points missing from scenario, exit.");
3012
3013 return;
3014 }
3015
3016 // 2 apply scenario based on cached indices for simData_ for a SimpleScenario
3017 // the scenario's keysHash() is used to make sure consistent keys are used
3018 // if keysHash() is zero, this check is not effective (for backwards compatibility)
3019 if (cacheSimData_) {
3020 if (auto s = QuantLib::ext::dynamic_pointer_cast<SimpleScenario>(scenario)) {
3021
3022 // fill cache
3023
3024 if (cachedSimData_.empty() || s->keysHash() != cachedSimDataKeysHash_) {
3025 cachedSimData_.clear();
3026 cachedSimDataKeysHash_ = s->keysHash();
3027 Size count = 0;
3028 for (auto const& key : s->keys()) {
3029 auto it = simData_.find(key);
3030 if (it == simData_.end()) {
3031 WLOG("simulation data point missing for key " << key);
3032 cachedSimData_.push_back(QuantLib::ext::shared_ptr<SimpleQuote>());
3033 cachedSimDataActive_.push_back(false);
3034 } else {
3035 ++count;
3036 cachedSimData_.push_back(it->second);
3037 cachedSimDataActive_.push_back(filter_->allow(key));
3038 }
3039 }
3040 if (count != simData_.size() && !allowPartialScenarios_) {
3041 ALOG("mismatch between scenario and sim data size, " << count << " vs " << simData_.size());
3042 for (auto it : simData_) {
3043 if (!scenario->has(it.first))
3044 WLOG("Key " << it.first << " missing in scenario");
3045 }
3046 QL_FAIL("mismatch between scenario and sim data size, exit.");
3047 }
3048 }
3049
3050 // apply scenario data according to cached indices
3051
3052 Size i = 0;
3053 for (auto const& q : s->data()) {
3054 if (cachedSimDataActive_[i])
3055 cachedSimData_[i]->setValue(q);
3056 ++i;
3057 }
3058
3059 return;
3060 }
3061 }
3062
3063 // 3 all other cases
3064
3065 const vector<RiskFactorKey>& keys = scenario->keys();
3066
3067 Size count = 0;
3068 for (const auto& key : keys) {
3069 // Loop through the scenario keys and check which keys are present in simData_,
3070 // adding to the count when a match is identified
3071 // Then check that the count=simData_.size - this ensures that simData_ is a valid
3072 // subset of the scenario - fails is a member of simData is not present in the
3073 // scenario
3074 auto it = simData_.find(key);
3075 if (it == simData_.end()) {
3076 WLOG("simulation data point missing for key " << key);
3077 } else {
3078 if (filter_->allow(key)) {
3079 it->second->setValue(scenario->get(key));
3080 }
3081 count++;
3082 }
3083 }
3084
3085 if (count != simData_.size() && !allowPartialScenarios_) {
3086 ALOG("mismatch between scenario and sim data size, " << count << " vs " << simData_.size());
3087 for (auto it : simData_) {
3088 if (!scenario->has(it.first))
3089 ALOG("Key " << it.first << " missing in scenario");
3090 }
3091 QL_FAIL("mismatch between scenario and sim data size, exit.");
3092 }
3093}
#define ALOG(text)
std::size_t count

◆ writeSimData()

void writeSimData ( std::map< RiskFactorKey, QuantLib::ext::shared_ptr< SimpleQuote > > &  simDataTmp,
std::map< RiskFactorKey, Real > &  absoluteSimDataTmp,
const RiskFactorKey::KeyType  keyType,
const std::string &  name,
const std::vector< std::vector< Real > > &  coordinates 
)
protected

Definition at line 238 of file scenariosimmarket.cpp.

241 {
242 simData_.insert(simDataTmp.begin(), simDataTmp.end());
243 absoluteSimData_.insert(absoluteSimDataTmp.begin(), absoluteSimDataTmp.end());
244 coordinatesData_.insert(std::make_tuple(keyType, name, coordinates));
245 simDataTmp.clear();
246 absoluteSimDataTmp.clear();
247}
+ Here is the caller graph for this function:

◆ addYieldCurve()

void addYieldCurve ( const QuantLib::ext::shared_ptr< Market > &  initMarket,
const std::string &  configuration,
const RiskFactorKey::KeyType  rf,
const string &  key,
const vector< Period > &  tenors,
bool simDataWritten,
bool  simulate = true,
bool  spreaded = false 
)
protected

Definition at line 249 of file scenariosimmarket.cpp.

251 {
252 Handle<YieldTermStructure> wrapper = (riskFactorYieldCurve(rf) == ore::data::YieldCurveType::Discount)
253 ? initMarket->discountCurve(key, configuration)
254 : initMarket->yieldCurve(riskFactorYieldCurve(rf), key, configuration);
255 QL_REQUIRE(!wrapper.empty(), "yield curve not provided for " << key);
256 QL_REQUIRE(tenors.front() > 0 * Days, "yield curve tenors must not include t=0");
257 // include today
258
259 // constructing yield curves
260 DayCounter dc = wrapper->dayCounter();
261 vector<Time> yieldCurveTimes(1, 0.0); // include today
262 vector<Date> yieldCurveDates(1, asof_);
263 for (auto& tenor : tenors) {
264 yieldCurveTimes.push_back(dc.yearFraction(asof_, asof_ + tenor));
265 yieldCurveDates.push_back(asof_ + tenor);
266 }
267
268 vector<Handle<Quote>> quotes;
269 QuantLib::ext::shared_ptr<SimpleQuote> q(new SimpleQuote(1.0));
270 quotes.push_back(Handle<Quote>(q));
271 vector<Real> discounts(yieldCurveTimes.size());
272 std::map<RiskFactorKey, QuantLib::ext::shared_ptr<SimpleQuote>> simDataTmp;
273 std::map<RiskFactorKey, Real> absoluteSimDataTmp;
274 for (Size i = 0; i < yieldCurveTimes.size() - 1; i++) {
275 Real val = wrapper->discount(yieldCurveDates[i + 1]);
276 DLOG("ScenarioSimMarket yield curve " << rf << " " << key << " discount[" << i << "]=" << val);
277 QuantLib::ext::shared_ptr<SimpleQuote> q(new SimpleQuote(spreaded ? 1.0 : val));
278 Handle<Quote> qh(q);
279 quotes.push_back(qh);
280
281 // Check if the risk factor is simulated before adding it
282 if (simulate) {
283 simDataTmp.emplace(std::piecewise_construct, std::forward_as_tuple(rf, key, i), std::forward_as_tuple(q));
284 // if generating spreaded scenarios, add the absolute value as well
285 if (spreaded) {
286 absoluteSimDataTmp.emplace(std::piecewise_construct, std::forward_as_tuple(rf, key, i),
287 std::forward_as_tuple(val));
288 }
289 }
290 }
291
292 writeSimData(simDataTmp, absoluteSimDataTmp, rf, key,
293 {std::vector<Real>(std::next(yieldCurveTimes.begin(), 1), yieldCurveTimes.end())});
294 simDataWritten = true;
295
296 QuantLib::ext::shared_ptr<YieldTermStructure> yieldCurve =
297 makeYieldCurve(key, spreaded, wrapper, yieldCurveTimes, quotes, dc, TARGET(), parameters_->interpolation(),
298 parameters_->extrapolation());
299
300 Handle<YieldTermStructure> ych(yieldCurve);
301 if (wrapper->allowsExtrapolation())
302 ych->enableExtrapolation();
303 yieldCurves_.insert(make_pair(make_tuple(Market::defaultConfiguration, riskFactorYieldCurve(rf), key), ych));
304}
map< tuple< string, YieldCurveType, string >, Handle< YieldTermStructure > > yieldCurves_
ore::data::YieldCurveType riskFactorYieldCurve(const RiskFactorKey::KeyType rf)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getYieldCurve()

Handle< YieldTermStructure > getYieldCurve ( const std::string &  yieldSpecId,
const ore::data::TodaysMarketParameters todaysMarketParams,
const std::string &  configuration,
const QuantLib::ext::shared_ptr< ore::data::Market > &  market = nullptr 
) const
protected

Given a yield curve spec ID, yieldSpecId, return the corresponding yield term structure from the market. If market is nullptr, then the yield term structure is taken from this ScenarioSimMarket instance.

Definition at line 3196 of file scenariosimmarket.cpp.

3199 {
3200
3201 // If yield spec ID is "", return empty Handle
3202 if (yieldSpecId.empty())
3203 return Handle<YieldTermStructure>();
3204
3205 if (todaysMarketParams.hasConfiguration(configuration)) {
3206 // Look for yield spec ID in index curves of todays market
3207 if (todaysMarketParams.hasMarketObject(MarketObject::IndexCurve)) {
3208 for (const auto& indexMapping : todaysMarketParams.mapping(MarketObject::IndexCurve, configuration)) {
3209 if (indexMapping.second == yieldSpecId) {
3210 if (market) {
3211 return market->iborIndex(indexMapping.first, configuration)->forwardingTermStructure();
3212 } else {
3213 return iborIndex(indexMapping.first, configuration)->forwardingTermStructure();
3214 }
3215 }
3216 }
3217 }
3218
3219 // Look for yield spec ID in yield curves of todays market
3220 if (todaysMarketParams.hasMarketObject(MarketObject::YieldCurve)) {
3221 for (const auto& yieldMapping : todaysMarketParams.mapping(MarketObject::YieldCurve, configuration)) {
3222 if (yieldMapping.second == yieldSpecId) {
3223 if (market) {
3224 return market->yieldCurve(yieldMapping.first, configuration);
3225 } else {
3226 return yieldCurve(yieldMapping.first, configuration);
3227 }
3228 }
3229 }
3230 }
3231
3232 // Look for yield spec ID in discount curves of todays market
3233 if (todaysMarketParams.hasMarketObject(MarketObject::DiscountCurve)) {
3234 for (const auto& discountMapping : todaysMarketParams.mapping(MarketObject::DiscountCurve, configuration)) {
3235 if (discountMapping.second == yieldSpecId) {
3236 if (market) {
3237 return market->discountCurve(discountMapping.first, configuration);
3238 } else {
3239 return discountCurve(discountMapping.first, configuration);
3240 }
3241 }
3242 }
3243 }
3244 } else if (configuration != Market::defaultConfiguration) {
3245 // try to fall back on default configuration
3246 return getYieldCurve(yieldSpecId, todaysMarketParams, Market::defaultConfiguration);
3247 }
3248
3249 // If yield spec ID still has not been found, return empty Handle
3250 return Handle<YieldTermStructure>();
3251}
bool hasConfiguration(const string &configuration) const
const map< string, string > & mapping(const MarketObject o, const string &configuration) const
bool hasMarketObject(const MarketObject &o) const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ addSwapIndexToSsm()

bool addSwapIndexToSsm ( const std::string &  indexName,
const bool  continueOnError 
)
protected

add a single swap index to the market, return true if successful

Definition at line 2935 of file scenariosimmarket.cpp.

2935 {
2936 auto dsc = parameters_->swapIndices().find(indexName);
2937 if (dsc == parameters_->swapIndices().end()) {
2938 return false;
2939 }
2940 DLOG("Adding swap index " << indexName << " with discounting index " << dsc->second);
2941 try {
2942 addSwapIndex(indexName, dsc->second, Market::defaultConfiguration);
2943 DLOG("Adding swap index " << indexName << " done.");
2944 return true;
2945 } catch (const std::exception& e) {
2946 processException(continueOnError, e, indexName);
2947 return false;
2948 }
2949}
void addSwapIndex(const string &swapindex, const string &discountIndex, const string &configuration=Market::defaultConfiguration) const
+ Here is the caller graph for this function:

Member Data Documentation

◆ parameters_

const QuantLib::ext::shared_ptr<ScenarioSimMarketParameters> parameters_
protected

Definition at line 166 of file scenariosimmarket.hpp.

◆ scenarioGenerator_

QuantLib::ext::shared_ptr<ScenarioGenerator> scenarioGenerator_
protected

Definition at line 167 of file scenariosimmarket.hpp.

◆ asd_

QuantLib::ext::shared_ptr<AggregationScenarioData> asd_
protected

Definition at line 168 of file scenariosimmarket.hpp.

◆ fixingManager_

QuantLib::ext::shared_ptr<FixingManager> fixingManager_
protected

Definition at line 169 of file scenariosimmarket.hpp.

◆ filter_

QuantLib::ext::shared_ptr<ScenarioFilter> filter_
protected

Definition at line 170 of file scenariosimmarket.hpp.

◆ simData_

std::map<RiskFactorKey, QuantLib::ext::shared_ptr<SimpleQuote> > simData_
protected

Definition at line 172 of file scenariosimmarket.hpp.

◆ baseScenario_

QuantLib::ext::shared_ptr<Scenario> baseScenario_
protected

Definition at line 173 of file scenariosimmarket.hpp.

◆ baseScenarioAbsolute_

QuantLib::ext::shared_ptr<Scenario> baseScenarioAbsolute_
protected

Definition at line 174 of file scenariosimmarket.hpp.

◆ cachedSimData_

std::vector<QuantLib::ext::shared_ptr<SimpleQuote> > cachedSimData_
protected

Definition at line 176 of file scenariosimmarket.hpp.

◆ cachedSimDataActive_

std::vector<bool> cachedSimDataActive_
protected

Definition at line 177 of file scenariosimmarket.hpp.

◆ cachedSimDataKeysHash_

std::size_t cachedSimDataKeysHash_ = 0
protected

Definition at line 178 of file scenariosimmarket.hpp.

◆ nonSimulatedFactors_

std::set<RiskFactorKey::KeyType> nonSimulatedFactors_
protected

Definition at line 180 of file scenariosimmarket.hpp.

◆ useSpreadedTermStructures_

bool useSpreadedTermStructures_
protected

Definition at line 184 of file scenariosimmarket.hpp.

◆ absoluteSimData_

std::map<RiskFactorKey, Real> absoluteSimData_
protected

Definition at line 185 of file scenariosimmarket.hpp.

◆ coordinatesData_

std::set<std::tuple<RiskFactorKey::KeyType, std::string, std::vector<std::vector<Real> > > > coordinatesData_
protected

Definition at line 188 of file scenariosimmarket.hpp.

◆ cacheSimData_

bool cacheSimData_
protected

Definition at line 190 of file scenariosimmarket.hpp.

◆ allowPartialScenarios_

bool allowPartialScenarios_
protected

Definition at line 191 of file scenariosimmarket.hpp.

◆ iborFallbackConfig_

IborFallbackConfig iborFallbackConfig_
protected

Definition at line 192 of file scenariosimmarket.hpp.

◆ diffToBaseKeys_

std::set<ore::analytics::RiskFactorKey> diffToBaseKeys_
protected

Definition at line 195 of file scenariosimmarket.hpp.

◆ currentScenario_

QuantLib::ext::shared_ptr<Scenario> currentScenario_
mutableprotected

Definition at line 197 of file scenariosimmarket.hpp.

◆ offsetScenario_

QuantLib::ext::shared_ptr<Scenario> offsetScenario_
protected

Definition at line 198 of file scenariosimmarket.hpp.