Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
historicalscenariogenerator.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2017 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
19/*! \file orea/scenario/historicalscenariogenerator.hpp
20 \brief scenario generator that builds from historical shifts
21 \ingroup scenario
22 */
23
24#pragma once
25
26#include <boost/make_shared.hpp>
34
35#include <ql/math/randomnumbers/rngtraits.hpp>
36
37namespace ore {
38namespace analytics {
39
40//! Return type for historical scenario generation (absolute, relative, log)
42
43public:
44 enum class ReturnType { Absolute, Relative, Log };
45
46 //! default return types per risk factor
48
49 //! customised return types per risk factor
50 ReturnConfiguration(const std::map<RiskFactorKey::KeyType, ReturnType>& returnType);
51
52 /*! Compute return from v1, v2.
53 The date parameters are are used to improve the log messages
54 */
55 QuantLib::Real returnValue(const RiskFactorKey& key, const QuantLib::Real v1, const QuantLib::Real v2,
56 const QuantLib::Date& d1, const QuantLib::Date& d2) const;
57
58 //! apply return from v1, v2 to base value
59 QuantLib::Real applyReturn(const RiskFactorKey& key, const QuantLib::Real baseValue,
60 const QuantLib::Real returnValue) const;
61
62 //! get return types
63 const std::map<RiskFactorKey::KeyType, ReturnType> returnTypes() const;
64
65private:
66 const std::map<RiskFactorKey::KeyType, ReturnType> returnType_;
67
68 //! Perform checks on key
69 void check(const RiskFactorKey& key) const;
70};
71
72std::ostream& operator<<(std::ostream& out, const ReturnConfiguration::ReturnType t);
73
74//! Historical Scenario Generator
75/*! A Scenario Generator that takes historical scenarios and builds new scenarios by applying historical shifts to the
76 * base scenario (which typically comes from todays market).
77 *
78 * This generator can be used for historical VAR and backtesting calculations, unlike a PRNG based generator it is
79 * limited in the number of scenarios it can generate.
80 *
81 * The scenarios generated are based on the scenario differences between t and t+mpor, these differences are typically
82 * a relative change and this change is then applied to the baseScenario to give a new scenario which is asof Today or
83 * Today+mpor.
84 */
86public:
91 double baseValue;
97 double scaling;
100 };
101
102 //! Default constructor
104 //! Historical Scenario Loader containing all scenarios
105 const QuantLib::ext::shared_ptr<HistoricalScenarioLoader>& historicalScenarioLoader,
106 //! Scenario factory to use
107 const QuantLib::ext::shared_ptr<ScenarioFactory>& scenarioFactory,
108 //! Calendar to use
109 const QuantLib::Calendar& cal,
110 //! optional adjustment factors for stock splits etc
111 const QuantLib::ext::shared_ptr<ore::data::AdjustmentFactors>& adjFactors = nullptr,
112 //! Mpor days or step size
113 const Size mporDays = 10,
114 //! overlapping scenarios
115 const bool overlapping = true,
116 //! return configuration
118 //! string prepended to label of all scenarios generated
119 const std::string& labelPrefix = "");
120
121
122 //! Constructor with no mporDays/Calendar, construct historical shift scenario between each scneario
124 //! Historical Scenario Loader containing all scenarios
125 const boost::shared_ptr<HistoricalScenarioLoader>& historicalScenarioLoader,
126 //! Scenario factory to use
127 const boost::shared_ptr<ScenarioFactory>& scenarioFactory,
128 //! optional adjustment factors for stock splits etc
129 const boost::shared_ptr<ore::data::AdjustmentFactors>& adjFactors = nullptr,
130 //! return configuration
132 //! string prepended to label of all scenarios generated
133 const std::string& labelPrefix = "");
134
135 //! Set base scenario, this also defines the asof date
136 QuantLib::ext::shared_ptr<Scenario>& baseScenario() { return baseScenario_; }
137 //! Get base scenario
138 const QuantLib::ext::shared_ptr<Scenario>& baseScenario() const { return baseScenario_; }
139
140 //! Get calendar
141 const QuantLib::Calendar& cal() const { return cal_; }
142 //! Get mpor days
143 QuantLib::Size mporDays() const { return mporDays_; }
144 //! Are scenarios overlapping
145 bool overlapping() const { return overlapping_; }
146
147 //! Return configuration
149
150 //! Scaling
151 virtual QuantLib::Real scaling(const RiskFactorKey& key, const QuantLib::Real& keyReturn) { return 1; };
152
153 //! Return the next scenario for the given date.
154 /*! Date should be asof or asof+mporDays, this class only checks that date is >= the asof date.
155 Whatever you put in here will be in the returned scenario.
156
157 Generator returns scenarios in order of shifts and throws if we have run out of historicals
158
159 If Mpor > 1 than the scenarios will overlap.
160 */
161 QuantLib::ext::shared_ptr<Scenario> next(const QuantLib::Date& d) override;
162
163 //! Return the calculation details of the last generated scenario */
164 const std::vector<HistoricalScenarioCalculationDetails>& lastHistoricalScenarioCalculationDetails() const;
165
166 //! Reset the generator so calls to next() return the first scenario.
167 /*! This allows re-generation of scenarios if required. */
168 void reset() override { i_ = 0; }
169
170 //! Number of scenarios this generator can generate
171 virtual QuantLib::Size numScenarios() const;
172
173 //! set the start and end dates, can be overwritten in derived class
174 virtual void setDates();
175
176 //! start dates from which the scenarios were generated from
177 const std::vector<QuantLib::Date>& startDates() const { return startDates_; }
178 //! end dates from which the scenarios were generated from
179 const std::vector<QuantLib::Date>& endDates() const { return endDates_; }
180
181 //! Get the HistoricalScenarioLoader
182 const QuantLib::ext::shared_ptr<HistoricalScenarioLoader>& scenarioLoader() const { return historicalScenarioLoader_; }
183
184 //! Get the ScenarioFactory
185 const QuantLib::ext::shared_ptr<ScenarioFactory>& scenarioFactory() const { return scenarioFactory_; }
186
187 //! Get the adj factors
188 const QuantLib::ext::shared_ptr<ore::data::AdjustmentFactors>& adjFactors() const { return adjFactors_; }
189
190 //! Get (start, end) scenario date pairs filtered on the given period
191 std::vector<std::pair<QuantLib::Date, QuantLib::Date>> filteredScenarioDates(const ore::data::TimePeriod& period) const;
192
193 //! Get the scenario label prefix
194 const std::string& labelPrefix() const { return labelPrefix_; }
195
196protected:
197 // to be managed in derived classes, if next is overwritten
198 Size i_;
199
200 QuantLib::ext::shared_ptr<HistoricalScenarioLoader> historicalScenarioLoader_;
201 std::vector<QuantLib::Date> startDates_, endDates_;
202
203 QuantLib::ext::shared_ptr<ScenarioFactory> scenarioFactory_;
204 QuantLib::ext::shared_ptr<Scenario> baseScenario_;
205
206 //! The Scenario Pairs for a given index
207 std::pair<QuantLib::ext::shared_ptr<Scenario>, QuantLib::ext::shared_ptr<Scenario>> scenarioPair();
208
209 //! Returns the adjusted price
210 /*! Scenarios may contian unadjusted market prices e.g equity spot prices,
211 apply adjustment factors to ensure no jumps between 2 scenarios
212 Only handles equity spot adjustments at the moment */
213 QuantLib::Real adjustedPrice(RiskFactorKey key, QuantLib::Date d, QuantLib::Real price);
214
215 // details on the last generated scenario
216 std::vector<HistoricalScenarioCalculationDetails> calculationDetails_;
217
218protected:
220 QuantLib::Size mporDays_ = 10;
221
222private:
223 QuantLib::ext::shared_ptr<ore::data::AdjustmentFactors> adjFactors_;
224 bool overlapping_ = true;
226 std::string labelPrefix_;
227};
228
229//! Historical scenario generator generating random scenarios, for testing purposes
231public:
233 //! Historical Scenario Loader containing all scenarios
234 const QuantLib::ext::shared_ptr<HistoricalScenarioLoader>& historicalScenarioLoader,
235 /*! Scenario factory to use */
236 const QuantLib::ext::shared_ptr<ScenarioFactory>& scenarioFactory,
237 //! Calendar to use
238 const QuantLib::Calendar& cal,
239 //! optional adjustment factors for stock splits etc
240 const QuantLib::ext::shared_ptr<ore::data::AdjustmentFactors>& adjFactors = nullptr,
241 //! MPOR days
242 const QuantLib::Size mporDays = 10,
243 //! overlapping scenarios
244 const bool overlapping = true,
245 //! return configuration
247 : HistoricalScenarioGenerator(historicalScenarioLoader, scenarioFactory, cal, adjFactors,
249 normalrng_ = QuantLib::ext::make_shared<QuantLib::PseudoRandom::rng_type>(MersenneTwisterUniformRng(42));
250 };
251
252 QuantLib::ext::shared_ptr<Scenario> next(const QuantLib::Date& d) override;
253 void reset() override;
254
255private:
256 QuantLib::ext::shared_ptr<QuantLib::PseudoRandom::rng_type> normalrng_;
257};
258
259//! Historical scenario generator transform
260/*! This class allows scenarios within a historical scenario generator to be transformed from discount rates to
261 * zero rates and survival probabilities to hazard rates
262 * WARNING: This transform function should only be used for backtesting statistics reports requiring the transforms
263 * listed above.
264 */
266public:
267 HistoricalScenarioGeneratorTransform(QuantLib::ext::shared_ptr<HistoricalScenarioGenerator>& hsg,
268 const QuantLib::ext::shared_ptr<ScenarioSimMarket>& simMarket,
269 const QuantLib::ext::shared_ptr<ScenarioSimMarketParameters>& simMarketConfig)
271 hsg->mporDays(), hsg->overlapping(), hsg->returnConfiguration(),
272 hsg->labelPrefix()),
273 simMarket_(simMarket), simMarketConfig_(simMarketConfig) {
274 baseScenario_ = hsg->baseScenario();
275 }
276
277 QuantLib::ext::shared_ptr<Scenario> next(const QuantLib::Date& d) override;
278
279private:
280 QuantLib::ext::shared_ptr<ScenarioSimMarket> simMarket_;
281 QuantLib::ext::shared_ptr<ScenarioSimMarketParameters> simMarketConfig_;
282};
283
284// Historical scenario generator with filtered scenario dates
285/*! This class will only generate the subset of scenarios with start / end dates contained in one of the given time periods.
286 Warning: the base scenario in the passed historical scenario generator must be set on construction of this class, later
287 changes in the base scenario will not be reflected in an instance of this class. */
289public:
290 HistoricalScenarioGeneratorWithFilteredDates(const std::vector<ore::data::TimePeriod>& filter,
291 const QuantLib::ext::shared_ptr<HistoricalScenarioGenerator>& gen);
292 void reset() override;
293 QuantLib::ext::shared_ptr<Scenario> next(const QuantLib::Date& d) override;
294
295private:
296 QuantLib::ext::shared_ptr<HistoricalScenarioGenerator> gen_;
297 std::vector<bool> isRelevantScenario_;
298 QuantLib::Size i_orig_;
299};
300
301QuantLib::ext::shared_ptr<HistoricalScenarioGenerator> buildHistoricalScenarioGenerator(
302 const QuantLib::ext::shared_ptr<HistoricalScenarioReader>& hsr,
303 const QuantLib::ext::shared_ptr<ore::data::AdjustmentFactors>& adjFactors, const TimePeriod& period,
304 Calendar calendar, Size mporDays,
305 const QuantLib::ext::shared_ptr<ScenarioSimMarketParameters>& simParams,
306 const QuantLib::ext::shared_ptr<TodaysMarketParameters>& marketParam,
307 const bool overlapping = true);
308
309QuantLib::ext::shared_ptr<HistoricalScenarioGenerator> buildHistoricalScenarioGenerator(
310 const QuantLib::ext::shared_ptr<HistoricalScenarioReader>& hsr,
311 const QuantLib::ext::shared_ptr<ore::data::AdjustmentFactors>& adjFactors, const std::set<QuantLib::Date>& dates,
312 const QuantLib::ext::shared_ptr<ScenarioSimMarketParameters>& simParams,
313 const QuantLib::ext::shared_ptr<TodaysMarketParameters>& marketParam);
314
315} // namespace analytics
316} // namespace ore
const QuantLib::ext::shared_ptr< ore::data::AdjustmentFactors > & adjFactors() const
Get the adj factors.
virtual void setDates()
set the start and end dates, can be overwritten in derived class
const std::vector< QuantLib::Date > & startDates() const
start dates from which the scenarios were generated from
const QuantLib::ext::shared_ptr< Scenario > & baseScenario() const
Get base scenario.
bool overlapping() const
Are scenarios overlapping.
std::vector< HistoricalScenarioCalculationDetails > calculationDetails_
const QuantLib::ext::shared_ptr< ScenarioFactory > & scenarioFactory() const
Get the ScenarioFactory.
HistoricalScenarioGenerator(const boost::shared_ptr< HistoricalScenarioLoader > &historicalScenarioLoader, const boost::shared_ptr< ScenarioFactory > &scenarioFactory, const boost::shared_ptr< ore::data::AdjustmentFactors > &adjFactors=nullptr, const ReturnConfiguration &returnConfiguration=ReturnConfiguration(), const std::string &labelPrefix="")
Constructor with no mporDays/Calendar, construct historical shift scenario between each scneario.
QuantLib::ext::shared_ptr< Scenario > baseScenario_
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.
const QuantLib::ext::shared_ptr< HistoricalScenarioLoader > & scenarioLoader() const
Get the HistoricalScenarioLoader.
QuantLib::ext::shared_ptr< Scenario > & baseScenario()
Set base scenario, this also defines the asof date.
const std::vector< QuantLib::Date > & endDates() const
end dates from which the scenarios were generated from
virtual QuantLib::Size numScenarios() const
Number of scenarios this generator can generate.
const std::string & labelPrefix() const
Get the scenario label prefix.
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_
const QuantLib::Calendar & cal() const
Get calendar.
QuantLib::Real adjustedPrice(RiskFactorKey key, QuantLib::Date d, QuantLib::Real price)
Returns the adjusted price.
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.
const ReturnConfiguration & returnConfiguration() const
Return configuration.
Historical scenario generator generating random scenarios, for testing purposes.
QuantLib::ext::shared_ptr< Scenario > next(const QuantLib::Date &d) override
HistoricalScenarioGeneratorRandom(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 QuantLib::Size mporDays=10, const bool overlapping=true, const ReturnConfiguration &returnConfiguration=ReturnConfiguration())
void reset() override
Reset the generator so calls to next() return the first scenario.
QuantLib::ext::shared_ptr< QuantLib::PseudoRandom::rng_type > normalrng_
QuantLib::ext::shared_ptr< ScenarioSimMarketParameters > simMarketConfig_
QuantLib::ext::shared_ptr< ScenarioSimMarket > simMarket_
QuantLib::ext::shared_ptr< Scenario > next(const QuantLib::Date &d) override
HistoricalScenarioGeneratorTransform(QuantLib::ext::shared_ptr< HistoricalScenarioGenerator > &hsg, const QuantLib::ext::shared_ptr< ScenarioSimMarket > &simMarket, const QuantLib::ext::shared_ptr< ScenarioSimMarketParameters > &simMarketConfig)
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
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.
Definition: scenario.hpp:48
Scenario generator base class.
SafeStack< Filter > filter
historical scenario loader
historical scenario reader
std::ostream & operator<<(std::ostream &out, EquityReturnType t)
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)
factory classes for scenarios
Scenario generator base classes.
A Market class that can be updated by Scenarios.