19#include <boost/algorithm/string/split.hpp>
40 std::vector<string> tokens;
41 boost::split(tokens, key.
name, boost::is_any_of(
"-"));
45 boost::replace_all(
keyName,
"/",
"\\/");
54 vector<string> tokens;
55 boost::split(tokens, description, boost::is_any_of(
":"));
57 if (tokens.size() == 1 && tokens[0] ==
"Base") {
66 }
else if (tokens.size() == 2 && (tokens[0] ==
"Up" || tokens[0] ==
"Down")) {
71 indexDesc1_ = temp.second;
76 }
else if (tokens.size() == 3 && tokens[0] ==
"Cross") {
81 indexDesc1_ = temp.second;
85 indexDesc2_ = temp.second;
88 QL_FAIL(
"Could not construct ScenarioDescription from string '" << description <<
"'");
102 QL_FAIL(
"ScenarioDescription::Type not covered");
108 o <<
"/" << indexDesc1_;
117 o <<
"/" << indexDesc2_;
124 string result = factor1();
126 result +=
":" + factor2();
131 const QuantLib::ext::shared_ptr<ScenarioSimMarketParameters>& simMarketData,
132 const QuantLib::ext::weak_ptr<ScenarioSimMarket>& simMarket)
134 QL_REQUIRE(
baseScenario_ != NULL,
"ShiftScenarioGenerator: baseScenario is null");
135 QL_REQUIRE(
simMarketData_ != NULL,
"ShiftScenarioGenerator: simMarketData is null");
147 if (scenarioDescription.
factor1() !=
"")
148 out <<
":" << scenarioDescription.
factor1();
149 if (scenarioDescription.
factor2() !=
"")
150 out <<
":" << scenarioDescription.
factor2();
157 if (factor.empty()) {
161 boost::escaped_list_separator<char> sep(
'\\',
'/',
'\"');
162 boost::tokenizer<boost::escaped_list_separator<char> > tokenSplit(factor, sep);
164 vector<string> tokens(tokenSplit.begin(), tokenSplit.end());
168 if (tokens.size() > 3) {
171 while (i < tokens.size()) {
172 o <<
"/" << tokens[i];
190QuantLib::ext::shared_ptr<RiskFactorKey>
parseRiskFactorKey(
const string& str, vector<string>& addTokens) {
195 boost::escaped_list_separator<char> sep(
'\\',
'/',
'\"');
196 boost::tokenizer<boost::escaped_list_separator<char> > tokenSplit(p.second, sep);
198 vector<string> tokens(tokenSplit.begin(), tokenSplit.end());
202 return QuantLib::ext::make_shared<RiskFactorKey>(p.first.keytype, p.first.name, p.first.index);
206 const vector<Time>& tenors,
const vector<Real>& values,
207 const vector<Real>& times, vector<Real>& shiftedValues,
bool initialise) {
209 QL_REQUIRE(j < tenors.size(),
"index j out of range");
210 QL_REQUIRE(times.size() == values.size(),
"vector size mismatch");
211 QL_REQUIRE(shiftedValues.size() == values.size(),
"shifted values vector size does not match input");
216 for (Size i = 0; i < values.size(); ++i)
217 shiftedValues[i] = values[i];
220 if (tenors.size() == 1) {
221 Real w = up ? 1.0 : -1.0;
222 for (Size k = 0; k < times.size(); k++) {
224 shiftedValues[k] += w * shiftSize;
226 shiftedValues[k] *= (1.0 + w * shiftSize);
229 Time t2 = tenors[j + 1];
230 for (Size k = 0; k < times.size(); k++) {
234 else if (times[k] <= t2)
235 w = (t2 - times[k]) / (t2 - t1);
239 shiftedValues[k] += w * shiftSize;
241 shiftedValues[k] *= (1.0 + w * shiftSize);
243 }
else if (j == tenors.size() - 1) {
244 Time t0 = tenors[j - 1];
245 for (Size k = 0; k < times.size(); k++) {
247 if (times[k] >= t0 && times[k] <= t1)
248 w = (times[k] - t0) / (t1 - t0);
249 else if (times[k] > t1)
254 shiftedValues[k] += w * shiftSize;
256 shiftedValues[k] *= (1.0 + w * shiftSize);
259 Time t0 = tenors[j - 1];
260 Time t2 = tenors[j + 1];
261 for (Size k = 0; k < times.size(); k++) {
263 if (times[k] >= t0 && times[k] <= t1)
264 w = (times[k] - t0) / (t1 - t0);
265 else if (times[k] > t1 && times[k] <= t2)
266 w = (t2 - times[k]) / (t2 - t1);
270 shiftedValues[k] += w * shiftSize;
272 shiftedValues[k] *= (1.0 + w * shiftSize);
278 const vector<Time>& shiftX,
const vector<Time>& shiftY,
279 const vector<Time>& dataX,
const vector<Time>& dataY,
280 const vector<vector<Real>>& data, vector<vector<Real>>& shiftedData,
282 QL_REQUIRE(shiftX.size() >= 1 && shiftY.size() >= 1,
"shift vector size >= 1 required");
283 QL_REQUIRE(i < shiftX.size(),
"index i out of range");
284 QL_REQUIRE(j < shiftY.size(),
"index j out of range");
288 for (Size k = 0; k < dataX.size(); ++k) {
289 for (Size l = 0; l < dataY.size(); ++l)
290 shiftedData[k][l] =
data[k][l];
295 if (shiftX.size() == 1 && shiftY.size() == 1) {
296 Real w = up ? 1.0 : -1.0;
297 for (Size k = 0; k < dataX.size(); ++k) {
298 for (Size l = 0; l < dataY.size(); ++l) {
300 shiftedData[k][l] += w * shiftSize;
302 shiftedData[k][l] *= (1.0 + w * shiftSize);
308 Size iMax = shiftX.size() - 1;
309 Size jMax = shiftY.size() - 1;
312 Real tx1 = i > 0 ? shiftX[i - 1] : QL_MAX_REAL;
313 Real ty1 = j > 0 ? shiftY[j - 1] : QL_MAX_REAL;
314 Real tx2 = i < iMax ? shiftX[i + 1] : -QL_MAX_REAL;
315 Real ty2 = j < jMax ? shiftY[j + 1] : -QL_MAX_REAL;
317 for (Size ix = 0; ix < dataX.size(); ++ix) {
319 for (Size iy = 0; iy < dataY.size(); ++iy) {
323 if (x >= tx && x <= tx2 && y >= ty && y <= ty2) {
324 wx = (tx2 - x) / (tx2 - tx);
325 wy = (ty2 - y) / (ty2 - ty);
326 }
else if (x >= tx && x <= tx2 && y >= ty1 && y <= ty) {
327 wx = (tx2 - x) / (tx2 - tx);
328 wy = (y - ty1) / (ty - ty1);
329 }
else if (x >= tx1 && x <= tx && y >= ty1 && y <= ty) {
330 wx = (x - tx1) / (tx - tx1);
331 wy = (y - ty1) / (ty - ty1);
332 }
else if (x >= tx1 && x <= tx && y >= ty && y <= ty2) {
333 wx = (x - tx1) / (tx - tx1);
334 wy = (ty2 - y) / (ty2 - ty);
335 }
else if ((x <= tx && i == 0 && y < ty && j == 0) || (x <= tx && i == 0 && y >= ty && j == jMax) ||
336 (x >= tx && i == iMax && y >= ty && j == jMax) || (x >= tx && i == iMax && y < ty && j == 0)) {
339 }
else if (((x <= tx && i == 0) || (x >= tx && i == iMax)) && y >= ty1 && y <= ty) {
341 wy = (y - ty1) / (ty - ty1);
342 }
else if (((x <= tx && i == 0) || (x >= tx && i == iMax)) && y >= ty && y <= ty2) {
344 wy = (ty2 - y) / (ty2 - ty);
345 }
else if (x >= tx1 && x <= tx && ((y < ty && j == 0) || (y >= ty && j == jMax))) {
346 wx = (x - tx1) / (tx - tx1);
348 }
else if (x >= tx && x <= tx2 && ((y < ty && j == 0) || (y >= ty && j == jMax))) {
349 wx = (tx2 - x) / (tx2 - tx);
352 QL_REQUIRE(wx >= 0.0 && wx <= 1.0,
"wx out of range");
353 QL_REQUIRE(wy >= 0.0 && wy <= 1.0,
"wy out of range");
355 Real w = up ? 1.0 : -1.0;
357 shiftedData[ix][iy] += w * wx * wy * shiftSize;
359 shiftedData[ix][iy] *= (1.0 + w * wx * wy * shiftSize);
Data types stored in the scenario class.
std::string name
Key name.
KeyType
Risk Factor types.
string typeString() const
Return type as string.
ScenarioDescription(Type type)
Constructor.
string factor2() const
Return key2 as string with text2 appended as key index description.
string factor1() const
Return key1 as string with text1 appended as key index description.
string factors() const
Return "factor1" and append ":factor2" if factor2 is not empty.
string keyName(RiskFactorKey key) const
std::vector< ScenarioDescription > scenarioDescriptions_
ShiftScenarioGenerator(const QuantLib::ext::shared_ptr< Scenario > &baseScenario, const QuantLib::ext::shared_ptr< ScenarioSimMarketParameters > &simMarketData, const QuantLib::ext::weak_ptr< ScenarioSimMarket > &simMarket)
Constructor.
const QuantLib::ext::shared_ptr< Scenario > & baseScenario()
Return the base scenario, i.e. cached initial values of all relevant market points.
std::vector< QuantLib::ext::shared_ptr< Scenario > > scenarios_
QuantLib::ext::shared_ptr< Scenario > next(const Date &d) override
Scenario Generator interface.
const QuantLib::ext::shared_ptr< Scenario > baseScenario_
void applyShift(Size j, Real shiftSize, bool up, ShiftType type, const vector< Time > &shiftTimes, const vector< Real > &values, const vector< Time > ×, vector< Real > &shiftedValues, bool initialise)
Apply 1d triangular shift to 1d data such as yield curves, public to allow test suite access.
const QuantLib::ext::weak_ptr< ScenarioSimMarket > simMarket_
const QuantLib::ext::shared_ptr< ScenarioSimMarketParameters > simMarketData_
Integer parseInteger(const string &s)
std::ostream & operator<<(std::ostream &out, EquityReturnType t)
RiskFactorKey::KeyType parseRiskFactorKeyType(const string &str)
string reconstructFactor(const RiskFactorKey &key, const string &desc)
Reconstruct the string description from a risk factor key and its index description desc.
RiskFactorKey parseRiskFactorKey(const string &str)
pair< RiskFactorKey, string > deconstructFactor(const string &factor)
std::string to_string(const LocationInfo &l)
Shift scenario generation.
factory classes for simple scenarios