27#include <boost/algorithm/string/find.hpp>
64 : returnType_(returnType) {}
67 const QuantLib::Date& d2)
const {
82 ALOG(
"Cannot calculate the relative return for key " << key <<
" so just returning 0: (" << d1 <<
"," << v1
83 <<
") to (" << d2 <<
"," << v2 <<
")");
88 if (!
close(v1, 0) && v2 / v1 > 0) {
89 return std::log(v2 / v1);
91 ALOG(
"Cannot calculate the relative return for key " << key <<
" so just returning 0: (" << d1 <<
"," << v1
92 <<
") to (" << d2 <<
"," << v2 <<
")");
97 QL_FAIL(
"ReturnConfiguration: return type not covered for key " << key <<
".");
120 QL_FAIL(
"ReturnConfiguration: return type for key " << key <<
" not covered");
126 DLOG(
"Base correlation value, " <<
value <<
", is not in range [-1.0, 1.0]");
128 DLOG(
"Base correlation value amended to " <<
value);
133 DLOG(
"Value of risk factor " << key <<
", " <<
value <<
", is not in range [0.0, 1.0]");
135 DLOG(
"Value of risk factor " << key <<
" amended to " <<
value);
148 return out <<
"Absolute";
150 return out <<
"Relative";
154 return out <<
"Unknown ReturnType (" <<
static_cast<int>(t) <<
")";
163 "ReturnConfiguration: key type " << keyType <<
" for key " << key <<
" not found");
167 const QuantLib::ext::shared_ptr<HistoricalScenarioLoader>& historicalScenarioLoader,
168 const QuantLib::ext::shared_ptr<ScenarioFactory>& scenarioFactory,
const QuantLib::Calendar& cal,
169 const QuantLib::ext::shared_ptr<ore::data::AdjustmentFactors>& adjFactors,
const Size mporDays,
171 const std::string& labelPrefix)
172 : i_(0), historicalScenarioLoader_(historicalScenarioLoader), scenarioFactory_(scenarioFactory),
173 cal_(cal), mporDays_(mporDays), adjFactors_(adjFactors), overlapping_(overlapping),
174 returnConfiguration_(returnConfiguration), labelPrefix_(labelPrefix) {
176 QL_REQUIRE(
mporDays > 0,
"Invalid mpor days of 0");
178 "HistoricalScenarioGenerator: require more than 1 scenario from historicalScenarioLoader_");
184 "historical scenarios are not ordered");
215 const boost::shared_ptr<HistoricalScenarioLoader>& historicalScenarioLoader,
216 const boost::shared_ptr<ScenarioFactory>& scenarioFactory,
217 const QuantLib::ext::shared_ptr<ore::data::AdjustmentFactors>& adjFactors,
219 : i_(0), historicalScenarioLoader_(historicalScenarioLoader), scenarioFactory_(scenarioFactory),
220 adjFactors_(adjFactors), returnConfiguration_(returnConfiguration), labelPrefix_(labelPrefix) {
223 "HistoricalScenarioGenerator: require more than 1 scenario from historicalScenarioLoader_");
228 "historical scenarios are not ordered");
237 "Cannot generate any more scenarios (i=" <<
i_ <<
" numScenarios=" <<
numScenarios() <<
")");
240 return std::pair<QuantLib::ext::shared_ptr<Scenario>, QuantLib::ext::shared_ptr<Scenario>>(s1, s2);
255 QL_REQUIRE(
baseScenario_ !=
nullptr,
"HistoricalScenarioGenerator: base scenario not set");
257 std::pair<QuantLib::ext::shared_ptr<Scenario>, QuantLib::ext::shared_ptr<Scenario>> scens =
scenarioPair();
258 QuantLib::ext::shared_ptr<Scenario> s1 = scens.first;
259 QuantLib::ext::shared_ptr<Scenario> s2 = scens.second;
262 QL_REQUIRE(d >=
baseScenario_->asof(),
"Cannot generate a scenario in the past");
263 QuantLib::ext::shared_ptr<Scenario> scen =
scenarioFactory_->buildScenario(d,
true, std::string(), 1.0);
267 Size calcDetailsCounter = 0;
270 Real v1 = 1.0, v2 = 1.0;
271 if (!s1->has(key) || !s2->has(key)) {
272 DLOG(
"Missing key in historical scenario (" << io::iso_date(s1->asof()) <<
"," << io::iso_date(s2->asof())
273 <<
"): " << key <<
" => no move in this factor");
284 returnVal = returnVal *
scaling;
287 if (std::isinf(
value)) {
288 ALOG(
"Value is inf for " << key <<
" from date " << s1->asof() <<
" to " << s2->asof());
291 scen->add(key,
value);
307 ++calcDetailsCounter;
320const std::vector<HistoricalScenarioGenerator::HistoricalScenarioCalculationDetails>&
331 std::vector<std::pair<Date, Date>> result;
342 QL_REQUIRE(
baseScenario() !=
nullptr,
"HistoricalScenarioGeneratorRandom: base scenario not set");
346 "HistoricalScenarioGeneratorRandom: Cannot generate a scenario in the past");
347 QuantLib::ext::shared_ptr<Scenario> scen =
scenarioFactory_->buildScenario(d,
true, std::string(), 1.0);
353 switch (key.keytype) {
381 value = std::max(std::min(
value, 0.9999), -0.9999);
384 QL_FAIL(
"HistoricalScenarioGeneratorRandom: unexpected key type in key " << key);
386 scen->add(key,
value);
396 normalrng_ = QuantLib::ext::make_shared<QuantLib::PseudoRandom::rng_type>(MersenneTwisterUniformRng(42));
401 const vector<RiskFactorKey>& keys =
baseScenario()->keys();
403 vector<Period> tenors;
407 for (Size k = 0; k < keys.size(); ++k) {
418 dc =
simMarket_->defaultCurve(keys[k].
name)->curve()->dayCounter();
422 endDate =
asof + tenors[keys[k].index];
424 auto toZero = [&dc, &
asof, &endDate](
double compound) {
425 return InterestRate::impliedRate(compound, dc, QuantLib::Compounding::Continuous,
426 QuantLib::Frequency::Annual,
asof, endDate)
430 Real zero = toZero(1.0 / scenario->get(keys[k]));
431 scenario->add(keys[k], zero);
447 const std::vector<TimePeriod>& filter,
const QuantLib::ext::shared_ptr<HistoricalScenarioGenerator>& gen)
449 gen_(gen), i_orig_(0) {
455 for (
auto const& f :
filter) {
457 Date minDate = *std::min_element(f.startDates().begin(), f.startDates().end());
458 Date maxDate = *std::max_element(f.endDates().begin(), f.endDates().end());
461 "The backtesting period " << f <<
" is not covered by the historical scenario generator: Required dates = ["
470 std::vector<Date> newStartDates, newEndDates;
474 for (
auto const& f :
filter) {
500 "HistoricalScenarioGeneratorWithFilteredDates:next(): no more scenarios available");
502 return gen_->next(d);
506 const QuantLib::ext::shared_ptr<HistoricalScenarioReader>& hsr,
507 const QuantLib::ext::shared_ptr<ore::data::AdjustmentFactors>& adjFactors,
const TimePeriod& period,
508 Calendar calendar, Size mporDays,
509 const QuantLib::ext::shared_ptr<ScenarioSimMarketParameters>& simParams,
510 const QuantLib::ext::shared_ptr<TodaysMarketParameters>& marketParams,
const bool overlapping) {
512 hsr->load(simParams, marketParams);
514 auto scenarioFactory = QuantLib::ext::make_shared<SimpleScenarioFactory>(
true);
516 QuantLib::ext::shared_ptr<HistoricalScenarioLoader> scenarioLoader = QuantLib::ext::make_shared<HistoricalScenarioLoader>(
520 return QuantLib::ext::make_shared<HistoricalScenarioGenerator>(scenarioLoader, scenarioFactory,
calendar, adjFactors,
525 const QuantLib::ext::shared_ptr<HistoricalScenarioReader>& hsr,
526 const QuantLib::ext::shared_ptr<ore::data::AdjustmentFactors>& adjFactors,
const std::set<QuantLib::Date>& dates,
527 const QuantLib::ext::shared_ptr<ScenarioSimMarketParameters>& simParams,
528 const QuantLib::ext::shared_ptr<TodaysMarketParameters>& marketParams) {
530 hsr->load(simParams, marketParams);
532 auto scenarioFactory = QuantLib::ext::make_shared<SimpleScenarioFactory>();
534 QuantLib::ext::shared_ptr<HistoricalScenarioLoader> scenarioLoader =
535 QuantLib::ext::make_shared<HistoricalScenarioLoader>(
539 return QuantLib::ext::make_shared<HistoricalScenarioGenerator>(scenarioLoader, scenarioFactory,
Historical Scenario Generator.
virtual void setDates()
set the start and end dates, can be overwritten in derived class
std::vector< QuantLib::Date > startDates_
std::vector< HistoricalScenarioCalculationDetails > calculationDetails_
QuantLib::ext::shared_ptr< Scenario > baseScenario_
QuantLib::Size mporDays() const
Get mpor days.
QuantLib::ext::shared_ptr< HistoricalScenarioLoader > historicalScenarioLoader_
QuantLib::ext::shared_ptr< Scenario > next(const QuantLib::Date &d) override
Return the next scenario for the given date.
QuantLib::ext::shared_ptr< ore::data::AdjustmentFactors > adjFactors_
const std::vector< HistoricalScenarioCalculationDetails > & lastHistoricalScenarioCalculationDetails() const
Return the calculation details of the last generated scenario */.
virtual QuantLib::Real scaling(const RiskFactorKey &key, const QuantLib::Real &keyReturn)
Scaling.
ReturnConfiguration returnConfiguration_
QuantLib::ext::shared_ptr< Scenario > & baseScenario()
Set base scenario, this also defines the asof date.
HistoricalScenarioGenerator(const QuantLib::ext::shared_ptr< HistoricalScenarioLoader > &historicalScenarioLoader, const QuantLib::ext::shared_ptr< ScenarioFactory > &scenarioFactory, const QuantLib::Calendar &cal, const QuantLib::ext::shared_ptr< ore::data::AdjustmentFactors > &adjFactors=nullptr, const Size mporDays=10, const bool overlapping=true, const ReturnConfiguration &returnConfiguration=ReturnConfiguration(), const std::string &labelPrefix="")
Default constructor.
virtual QuantLib::Size numScenarios() const
Number of scenarios this generator can generate.
std::vector< std::pair< QuantLib::Date, QuantLib::Date > > filteredScenarioDates(const ore::data::TimePeriod &period) const
Get (start, end) scenario date pairs filtered on the given period.
QuantLib::ext::shared_ptr< ScenarioFactory > scenarioFactory_
QuantLib::Real adjustedPrice(RiskFactorKey key, QuantLib::Date d, QuantLib::Real price)
Returns the adjusted price.
std::vector< QuantLib::Date > endDates_
std::pair< QuantLib::ext::shared_ptr< Scenario >, QuantLib::ext::shared_ptr< Scenario > > scenarioPair()
The Scenario Pairs for a given index.
void reset() override
Reset the generator so calls to next() return the first scenario.
QuantLib::ext::shared_ptr< Scenario > next(const QuantLib::Date &d) override
void reset() override
Reset the generator so calls to next() return the first scenario.
QuantLib::ext::shared_ptr< QuantLib::PseudoRandom::rng_type > normalrng_
HistoricalScenarioGeneratorWithFilteredDates(const std::vector< ore::data::TimePeriod > &filter, const QuantLib::ext::shared_ptr< HistoricalScenarioGenerator > &gen)
std::vector< bool > isRelevantScenario_
QuantLib::ext::shared_ptr< Scenario > next(const QuantLib::Date &d) override
QuantLib::ext::shared_ptr< HistoricalScenarioGenerator > gen_
void reset() override
Reset the generator so calls to next() return the first scenario.
Return type for historical scenario generation (absolute, relative, log)
const std::map< RiskFactorKey::KeyType, ReturnType > returnType_
QuantLib::Real applyReturn(const RiskFactorKey &key, const QuantLib::Real baseValue, const QuantLib::Real returnValue) const
apply return from v1, v2 to base value
ReturnConfiguration()
default return types per risk factor
const std::map< RiskFactorKey::KeyType, ReturnType > returnTypes() const
get return types
void check(const RiskFactorKey &key) const
Perform checks on key.
QuantLib::Real returnValue(const RiskFactorKey &key, const QuantLib::Real v1, const QuantLib::Real v2, const QuantLib::Date &d1, const QuantLib::Date &d2) const
Data types stored in the scenario class.
std::string name
Key name.
@ YoYInflationCapFloorVolatility
@ ZeroInflationCapFloorVolatility
const std::vector< Date > & endDates() const
const std::vector< Date > & startDates() const
bool contains(const Date &d) const
SafeStack< ValueType > value
SafeStack< Filter > filter
scenario generator that builds from historical shifts
Filter close_enough(const RandomVariable &x, const RandomVariable &y)
std::ostream & operator<<(std::ostream &out, EquityReturnType t)
bool close(const Real &t_1, const Real &t_2)
QuantLib::ext::shared_ptr< HistoricalScenarioGenerator > buildHistoricalScenarioGenerator(const QuantLib::ext::shared_ptr< HistoricalScenarioReader > &hsr, const QuantLib::ext::shared_ptr< ore::data::AdjustmentFactors > &adjFactors, const TimePeriod &period, Calendar calendar, Size mporDays, const QuantLib::ext::shared_ptr< ScenarioSimMarketParameters > &simParams, const QuantLib::ext::shared_ptr< TodaysMarketParameters > &marketParams, const bool overlapping)
std::string to_string(const LocationInfo &l)
factory classes for simple scenarios