Skip to content

Commit 4736162

Browse files
committed
Merge branch 'update20230907' into 'master'
update 20230907 Closes QPR-11732 See merge request qs/ore-github!6
2 parents c17e941 + 12b6a99 commit 4736162

62 files changed

Lines changed: 1307 additions & 399 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Docker/.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
TAG=latest
22
DEBIAN_TAG=11.7
3-
QL_TAG=1.30_4274655e
3+
QL_TAG=1.30_00d2fced87
44
BOOST_TAG=1.78.0
55
BOOST_DIR=1_78_0
66
NUM_CORES=16

Docs/UserGuide/allowablevalues.tex

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,16 +251,19 @@ \subsection{Allowable Values}
251251
\emph{A364, Actual/364, Act/364, ACT/364}& Actual 364 \\ \hline
252252
\emph{Actual/365 (No Leap), Act/365 (NL), NL/365, Actual/365 (JGB)} & Actual 365 Fixed (No Leap Year)\\ \hline
253253
\emph{Act/365 (Canadian Bond)} & Actual 365 Fixed (Canadian Bond)\\ \hline
254-
\emph{T360, 30/360, 30/360 (Bond Basis), ACT/nACT, 30/360 US, 30U/360, 30US/360} & Thirty 360 (US) \\ \hline
254+
\emph{T360, 30/360, ACT/nACT, 30/360 US, 30/360 (US), 30U/360, 30US/360} & Thirty 360 (US) \\ \hline
255+
\emph{30/360 (Bond Basis)} & Thirty 360 (Bond Basis) \\ \hline
255256
\emph{30E/360 (Eurobond Basis), 30E/360, 30/360 AIBD (Euro), 30E/360.ICMA, 30E/360 ICMA} & Thirty 360 (European) \\ \hline
256257
\emph{30E/360E, 30E/360 ISDA, 30E/360.ISDA, 30/360 German, 30/360 (German)} & Thirty 360 (German) \\ \hline
257258
\emph{30/360 Italian, 30/360 (Italian)} & Thirty 360 (Italian) \\ \hline
258-
\emph{ActActISDA, ACT/ACT.ISDA, Actual/Actual (ISDA), ActualActual (ISDA), ACT/ACT, ACT} & Actual Actual (ISDA) \\ \hline
259+
\emph{ActActISDA, ACT/ACT.ISDA, Actual/Actual (ISDA), ActualActual (ISDA), ACT/ACT, Act/Act, ACT} & Actual Actual (ISDA) \\ \hline
259260
\emph{ActActISMA, Actual/Actual (ISMA), ActualActual (ISMA), ACT/ACT.ISMA} & Actual Actual (ISMA) \\ \hline
260261
\emph{ActActICMA, Actual/Actual (ICMA), ActualActual (ICMA), ACT/ACT.ICMA} & Actual Actual (ICMA) \\ \hline
261-
\emph{ActActAFB, ACT/ACT.AFB, Actual/Actual (AFB)} & Actual Actual (AFB) \\ \hline
262+
\emph{ActActAFB, ACT/ACT.AFB, Actual/Actual (AFB), ACT29} & Actual Actual (AFB) \\ \hline
262263
\emph{BUS/252, Business/252} & Brazilian Bus/252 \\ \hline
263264
\emph{1/1} & 1/1 \\ \hline
265+
\emph{Simple} & Simple Day Counter \\ \hline
266+
\emph{Year} & Year Counter \\ \hline
264267
\end{tabular}
265268
\caption{Allowable Values for DayCount Convention}
266269
\label{tab:daycount}

Docs/UserGuide/curve_configurations/commodity_volatilities.tex

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,9 +303,12 @@ \subsubsection{Commodity Volatilities}
303303
\item \lstinline!PutDeltas!:
304304
A comma separated list of one or more put deltas to use in the volatility surface. Note that the put deltas should be given without a sign e.g.\ \lstinline!<PutDeltas>0.10,0.20,0.30,0.40</PutDeltas>! would be an example.
305305

306-
\item \lstinline!PutDeltas!:
306+
\item \lstinline!CallDeltas!:
307307
A comma separated list of one or more call deltas to use in the volatility surface.
308308

309+
\item \lstinline!Expiries!:
310+
A comma separated list of one or more expiries (e.g. 1W, 1M) to load. Supports using the single wildcard value \lstinline!*!.
311+
309312
\item \lstinline!TimeInterpolation!:
310313
Only \lstinline!Linear! is currently supported here.
311314

Docs/UserGuide/curve_configurations/yieldcurves.tex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ \subsubsection{Yield Curves}
1313
<Segments> </Segments>
1414
<InterpolationVariable> </InterpolationVariable>
1515
<InterpolationMethod> </InterpolationMethod>
16-
<ZeroDayCounter> </ZeroDayCounter>
16+
<YieldCurveDayCounter> </YieldCurveDayCounter>
1717
<Tolerance> </Tolerance>
1818
<Extrapolation> </Extrapolation>
1919
<BootstrapConfig>
@@ -40,7 +40,7 @@ \subsubsection{Yield Curves}
4040
\emph{Discount}.
4141
\item InterpolationMethod [Optional]: The interpolation method to use. The allowable values are given in Table
4242
\ref{tab:allow_interp_methods}. If the element is omitted or left blank, then it defaults to \emph{LogLinear}.
43-
\item ZeroDayCounter [Optional]: The day count basis used internally by the yield curve to calculate the time between
43+
\item YieldCurveDayCounter [Optional]: The day count basis used internally by the yield curve to calculate the time between
4444
dates. In particular, if the curve is queried for a zero rate without specifying the day count basis, the zero rate that
4545
is returned has this basis. If the element is omitted or left blank, then it defaults to \emph{A365}.
4646

Docs/UserGuide/parameterisation/ore.tex

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,8 @@ \subsubsection{Analytics}\label{sec:analytics}
528528
<Parameter name="mcSamples">100000</Parameter>
529529
<Parameter name="mcSeed">42</Parameter>
530530
<Parameter name="outputFile">var.csv</Parameter>
531-
</Analytic> </Analytics>
531+
</Analytic>
532+
</Analytics>
532533
\end{minted}
533534
\caption{ORE analytic: VaR}
534535
\label{lst:ore_var}
@@ -547,4 +548,34 @@ \subsubsection{Analytics}\label{sec:analytics}
547548
\item {\tt mcSamples:} Number of Monte Carlo samples used when the {\em MonteCarlo} method is chosen
548549
\item {\tt mcSeed:} Random number generator seed when the {\em MonteCarlo} method is chosen
549550
\item {\tt outputFile:} Output file name
551+
\end{itemize}
552+
553+
\medskip The {\tt scenarioStatistics} 'analytics' provide the statistics and distribution of the scenarios generated through simulation. Listing \ref{lst:ore_scenarioStatistics}
554+
shows a typical configuration for sensitivity calculation.
555+
556+
\begin{listing}[H]
557+
%\hrule\medskip
558+
\begin{minted}[fontsize=\footnotesize]{xml}
559+
<Analytics>
560+
<Analytic type="scenarioStatistics">
561+
<Parameter name="active">Y</Parameter>
562+
<Parameter name="simulationConfigFile">simulation.xml</Parameter>
563+
<Parameter name="distributionBuckets">20</Parameter>
564+
<Parameter name="outputZeroRate">Y</Parameter>
565+
<Parameter name="scenariodump">scenariodump.csv</Parameter>
566+
</Analytic>
567+
</Analytics>
568+
\end{minted}
569+
\caption{ORE analytic: scenarioStatistics}
570+
\label{lst:ore_scenarioStatistics}
571+
\end{listing}
572+
573+
The parameters have the following interpretation:
574+
575+
\begin{itemize}
576+
\item {\tt simulationConfigFile:} Configuration file defining the simulation market under which sensitivities are computed,
577+
see \ref{sec:simulation}.
578+
\item {\tt distributionBuckets:} Number of buckets used for the distribution histogram.
579+
\item {\tt outputZeroRate:} Determine whether the statistics report and distribution report will use zero rate or discount factors. If set to Y, the reports will use zero rates. If set to N, they will use discount factors.
580+
\item {\tt scenariodump:} File containing all the scenarios generated through simulation market. If the node is not given, this file will not be outputted.
550581
\end{itemize}

Docs/UserGuide/tradedata/commodityapo.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ \subsubsection{Commodity Average Price Option}
2727

2828
Allowable values: See \lstinline!Name! for commodity trades in Table \ref{tab:commodity_data}.
2929

30-
\item \lstinline!Currency!: The currency of the payoff which must be consistent with either currency of the market data set up for the commodity or the other currency specified in !lstinline!FXIndex! (see below).
30+
\item \lstinline!Currency!: The currency of the payoff which must be consistent with either currency of the market data set up for the commodity or the other currency specified in \lstinline!FXIndex! (see below).
3131

3232
Allowable values: See \lstinline!Currency! in Table \ref{tab:allow_stand_data}.
3333

Examples/Example_40/ExpectedOutput/par_sensitivity.csv renamed to Examples/Example_40/ExpectedOutput/parsensitivity.csv

File renamed without changes.

News.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ INSTRUMENTS
1616
- support notional changes within calculation periods on fixed and floating legs
1717

1818
MARKETS
19-
- Add a new yield curve segment "Bond Yield Shifted", see Example 49
19+
- Add a new yield curve segment "Bond Yield Shifted", see Example 49, thanks to Oleg Kulkov
2020

2121
ANALYTICS
2222
- Add a proof-of-concept Credit Portfolio Model to construct portfolio loss distributions due to

OREAnalytics/orea/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ aggregation/xvacalculator.cpp
1818
app/analytic.cpp
1919
app/analytics/parconversionanalytic.cpp
2020
app/analytics/pricinganalytic.cpp
21+
app/analytics/scenariostatisticsanalytic.cpp
2122
app/analytics/simmanalytic.cpp
2223
app/analytics/varanalytic.cpp
2324
app/analytics/xvaanalytic.cpp
@@ -80,6 +81,7 @@ scenario/lgmscenariogenerator.cpp
8081
scenario/scenario.cpp
8182
scenario/scenariogeneratorbuilder.cpp
8283
scenario/scenariogeneratordata.cpp
84+
scenario/scenariogeneratortransform.cpp
8385
scenario/scenarioshiftcalculator.cpp
8486
scenario/scenariosimmarket.cpp
8587
scenario/scenariosimmarketparameters.cpp
@@ -145,6 +147,7 @@ aggregation/xvacalculator.hpp
145147
app/analytic.hpp
146148
app/analytics/parconversionanalytic.hpp
147149
app/analytics/pricinganalytic.hpp
150+
app/analytics/scenariostatisticsanalytic.hpp
148151
app/analytics/simmanalytic.hpp
149152
app/analytics/varanalytic.hpp
150153
app/analytics/xvaanalytic.hpp
@@ -223,6 +226,7 @@ scenario/scenariofilter.hpp
223226
scenario/scenariogenerator.hpp
224227
scenario/scenariogeneratorbuilder.hpp
225228
scenario/scenariogeneratordata.hpp
229+
scenario/scenariogeneratortransform.hpp
226230
scenario/scenarioshiftcalculator.hpp
227231
scenario/scenariosimmarket.hpp
228232
scenario/scenariosimmarketparameters.hpp
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/*
2+
Copyright (C) 2022 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+
#include <orea/app/analytics/scenariostatisticsanalytic.hpp>
20+
#include <orea/app/reportwriter.hpp>
21+
#include <orea/app/structuredanalyticserror.hpp>
22+
#include <orea/app/structuredanalyticswarning.hpp>
23+
#include <orea/scenario/scenariowriter.hpp>
24+
#include <orea/scenario/simplescenariofactory.hpp>
25+
#include <orea/scenario/crossassetmodelscenariogenerator.hpp>
26+
#include <orea/scenario/scenariogeneratortransform.hpp>
27+
28+
#include <ored/model/crossassetmodelbuilder.hpp>
29+
#include <ored/portfolio/structuredtradeerror.hpp>
30+
31+
using namespace ore::data;
32+
using namespace boost::filesystem;
33+
34+
namespace ore {
35+
namespace analytics {
36+
37+
/******************************************************************************
38+
* ScenarioStatistics Analytic: Scenario_Statistics
39+
******************************************************************************/
40+
41+
void ScenarioStatisticsAnalyticImpl::setUpConfigurations() {
42+
LOG("ScenarioStatisticsAnalytic::setUpConfigurations() called");
43+
analytic()->configurations().todaysMarketParams = inputs_->todaysMarketParams();
44+
analytic()->configurations().simMarketParams = inputs_->exposureSimMarketParams();
45+
analytic()->configurations().scenarioGeneratorData = inputs_->scenarioGeneratorData();
46+
analytic()->configurations().crossAssetModelData = inputs_->crossAssetModelData();
47+
}
48+
49+
void ScenarioStatisticsAnalyticImpl::buildScenarioSimMarket() {
50+
51+
std::string configuration = inputs_->marketConfig("simulation");
52+
simMarket_ = boost::make_shared<ScenarioSimMarket>(
53+
analytic()->market(),
54+
analytic()->configurations().simMarketParams,
55+
boost::make_shared<FixingManager>(inputs_->asof()),
56+
configuration,
57+
*inputs_->curveConfigs().get(),
58+
*analytic()->configurations().todaysMarketParams,
59+
inputs_->continueOnError(),
60+
false, true, false,
61+
*inputs_->iborFallbackConfig(),
62+
false);
63+
}
64+
65+
void ScenarioStatisticsAnalyticImpl::buildScenarioGenerator(const bool continueOnCalibrationError) {
66+
if (!model_)
67+
buildCrossAssetModel(continueOnCalibrationError);
68+
ScenarioGeneratorBuilder sgb(analytic()->configurations().scenarioGeneratorData);
69+
boost::shared_ptr<ScenarioFactory> sf = boost::make_shared<SimpleScenarioFactory>();
70+
string config = inputs_->marketConfig("simulation");
71+
scenarioGenerator_ = sgb.build(model_, sf, analytic()->configurations().simMarketParams, inputs_->asof(), analytic()->market(), config);
72+
QL_REQUIRE(scenarioGenerator_, "failed to build the scenario generator");
73+
samples_ = analytic()->configurations().scenarioGeneratorData->samples();
74+
LOG("simulation grid size " << grid_->size());
75+
LOG("simulation grid valuation dates " << grid_->valuationDates().size());
76+
LOG("simulation grid close-out dates " << grid_->closeOutDates().size());
77+
LOG("simulation grid front date " << io::iso_date(grid_->dates().front()));
78+
LOG("simulation grid back date " << io::iso_date(grid_->dates().back()));
79+
80+
if (inputs_->writeScenarios()) {
81+
auto report = boost::make_shared<InMemoryReport>();
82+
analytic()->reports()["SCENARIO_STATISTICS"]["scenario"] = report;
83+
scenarioGenerator_ = boost::make_shared<ScenarioWriter>(scenarioGenerator_, report);
84+
}
85+
}
86+
87+
void ScenarioStatisticsAnalyticImpl::buildCrossAssetModel(const bool continueOnCalibrationError) {
88+
LOG("SCENARIO_STATISTICS: Build Simulation Model (continueOnCalibrationError = "
89+
<< std::boolalpha << continueOnCalibrationError << ")");
90+
CrossAssetModelBuilder modelBuilder(
91+
analytic()->market(), analytic()->configurations().crossAssetModelData, inputs_->marketConfig("lgmcalibration"),
92+
inputs_->marketConfig("fxcalibration"), inputs_->marketConfig("eqcalibration"),
93+
inputs_->marketConfig("infcalibration"), inputs_->marketConfig("crcalibration"),
94+
inputs_->marketConfig("simulation"), false, continueOnCalibrationError, "",
95+
inputs_->salvageCorrelationMatrix() ? SalvagingAlgorithm::Spectral : SalvagingAlgorithm::None,
96+
"xva cam building");
97+
model_ = *modelBuilder.model();
98+
}
99+
100+
void ScenarioStatisticsAnalyticImpl::runAnalytic(const boost::shared_ptr<ore::data::InMemoryLoader>& loader,
101+
const std::set<std::string>& runTypes) {
102+
103+
LOG("Scenario analytic called with asof " << io::iso_date(inputs_->asof()));
104+
105+
Settings::instance().evaluationDate() = inputs_->asof();
106+
//ObservationMode::instance().setMode(inputs_->exposureObservationModel());
107+
108+
LOG("SCENARIO_STATISTICS: Build Today's Market");
109+
CONSOLEW("SCENARIO_STATISTICS: Build Market");
110+
analytic()->buildMarket(loader);
111+
CONSOLE("OK");
112+
113+
grid_ = analytic()->configurations().scenarioGeneratorData->getGrid();
114+
115+
LOG("SCENARIO_STATISTICS: Build simulation market");
116+
buildScenarioSimMarket();
117+
118+
LOG("SCENARIO_STATISTICS: Build Scenario Generator");
119+
auto globalParams = inputs_->simulationPricingEngine()->globalParameters();
120+
auto continueOnCalErr = globalParams.find("ContinueOnCalibrationError");
121+
bool continueOnErr = (continueOnCalErr != globalParams.end()) && parseBool(continueOnCalErr->second);
122+
buildScenarioGenerator(continueOnErr);
123+
124+
LOG("SCENARIO_STATISTICS: Attach Scenario Generator to ScenarioSimMarket");
125+
simMarket_->scenarioGenerator() = scenarioGenerator_;
126+
127+
MEM_LOG;
128+
129+
// Output scenario statistics and distribution reports
130+
const vector<RiskFactorKey>& keys = simMarket_->baseScenario()->keys();
131+
boost::shared_ptr<ScenarioGenerator> scenarioGenerator =
132+
inputs_->scenarioOutputZeroRate()
133+
? boost::make_shared<ScenarioGeneratorTransform>(scenarioGenerator_, simMarket_,
134+
analytic()->configurations().simMarketParams)
135+
: scenarioGenerator_;
136+
137+
auto statsReport = boost::make_shared<InMemoryReport>();
138+
scenarioGenerator->reset();
139+
ReportWriter().writeScenarioStatistics(scenarioGenerator, keys, samples_, grid_->valuationDates(),
140+
*statsReport);
141+
analytic()->reports()["SCENARIO_STATISTICS"]["scenario_statistics"] = statsReport;
142+
143+
auto distributionReport = boost::make_shared<InMemoryReport>();
144+
scenarioGenerator->reset();
145+
ReportWriter().writeScenarioDistributions(scenarioGenerator, keys, samples_, grid_->valuationDates(),
146+
inputs_->scenarioDistributionSteps(), *distributionReport);
147+
analytic()->reports()["SCENARIO_STATISTICS"]["scenario_distribution"] = distributionReport;
148+
}
149+
150+
} // namespace analytics
151+
} // namespace ore

0 commit comments

Comments
 (0)