19#include <boost/test/unit_test.hpp>
26#include <oret/toplevelfixture.hpp>
27#include <ql/termstructures/credit/flathazardrate.hpp>
28#include <ql/termstructures/volatility/capfloor/constantcapfloortermvol.hpp>
29#include <ql/termstructures/volatility/equityfx/blackconstantvol.hpp>
30#include <ql/termstructures/volatility/swaption/swaptionconstantvol.hpp>
31#include <ql/termstructures/yield/flatforward.hpp>
32#include <ql/time/daycounters/actualactual.hpp>
37#include <ql/indexes/ibor/all.hpp>
41using namespace boost::unit_test_framework;
50QuantLib::ext::shared_ptr<data::Conventions>
convs() {
51 QuantLib::ext::shared_ptr<Conventions> conventions = InstrumentConventions::instance().conventions();
54 QuantLib::ext::shared_ptr<data::Convention> swapIndexConv(
56 conventions->add(swapIndexConv);
58 QuantLib::ext::shared_ptr<data::Convention> swapConv(
59 new data::IRSwapConvention(
"EUR-6M-SWAP-CONVENTIONS",
"TARGET",
"Annual",
"MF",
"30/360",
"EUR-EURIBOR-6M"));
60 conventions->add(swapConv);
65QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters> scenarioParameters() {
67 parameters->baseCcy() =
"EUR";
68 parameters->setDiscountCurveNames({
"EUR",
"USD"});
69 parameters->setYieldCurveTenors(
"", {6 * Months, 1 * Years, 2 * Years});
70 parameters->setIndices({
"EUR-EURIBOR-6M",
"USD-LIBOR-6M"});
71 parameters->interpolation() =
"LogLinear";
72 parameters->extrapolation() =
"FlatFwd";
74 parameters->setSwapVolTerms(
"", {6 * Months, 1 * Years});
75 parameters->setSwapVolExpiries(
"", {1 * Years, 2 * Years});
76 parameters->setSwapVolKeys({
"EUR",
"USD"});
77 parameters->swapVolDecayMode() =
"ForwardVariance";
79 parameters->setDefaultNames({
"dc2"});
80 parameters->setDefaultTenors(
"", {6 * Months, 8 * Months, 1 * Years, 2 * Years});
82 parameters->setSimulateFXVols(
false);
83 parameters->setFxVolExpiries(
"", vector<Period>{2 * Years, 3 * Years, 4 * Years});
84 parameters->setFxVolDecayMode(
string(
"ConstantVariance"));
85 parameters->setSimulateEquityVols(
false);
87 parameters->setFxVolCcyPairs({
"USDEUR"});
89 parameters->setFxCcyPairs({
"USDEUR"});
91 parameters->setZeroInflationIndices({
"EUHICPXT"});
92 parameters->setZeroInflationTenors(
"", {6 * Months, 1 * Years, 2 * Years});
94 parameters->setSimulateCorrelations(
false);
95 parameters->correlationExpiries() = {1 * Years, 2 * Years};
96 parameters->setCorrelationPairs({
"EUR-CMS-10Y:EUR-CMS-1Y",
"USD-CMS-10Y:USD-CMS-1Y"});
101void testFxSpot(QuantLib::ext::shared_ptr<ore::data::Market>& initMarket,
102 QuantLib::ext::shared_ptr<ore::analytics::ScenarioSimMarket>& simMarket,
103 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters>& parameters) {
105 for (
const auto& ccy : parameters->ccys()) {
106 if (ccy != parameters->baseCcy()) {
107 string ccyPair(parameters->baseCcy() + ccy);
108 string ccyReverse(ccy + parameters->baseCcy());
110 Handle<Quote> fx_sim = simMarket->fxSpot(ccyPair);
111 Handle<Quote> fx_init = initMarket->fxSpot(ccyPair);
113 BOOST_FAIL(
"fx_sim handle is empty");
115 BOOST_FAIL(
"fx_init handle is empty");
117 BOOST_CHECK_CLOSE(fx_init->value(), fx_sim->value(), 1e-12);
119 fx_sim = simMarket->fxSpot(ccyReverse);
120 fx_init = initMarket->fxSpot(ccyReverse);
122 BOOST_FAIL(
"fx_sim handle is empty");
124 BOOST_FAIL(
"fx_init handle is empty");
126 BOOST_CHECK_CLOSE(fx_init->value(), fx_sim->value(), 1e-12);
132 QuantLib::ext::shared_ptr<ore::analytics::ScenarioSimMarket>& simMarket,
133 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters>& parameters) {
135 for (
const auto& ccy : parameters->ccys()) {
136 Handle<YieldTermStructure> simCurve = simMarket->discountCurve(ccy);
137 Handle<YieldTermStructure> initCurve = initMarket->discountCurve(ccy);
139 BOOST_CHECK_CLOSE(simCurve->discount(0.5), initCurve->discount(0.5), 1e-12);
144 QuantLib::ext::shared_ptr<ore::analytics::ScenarioSimMarket>& simMarket,
145 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters>& parameters) {
147 for (
const auto& ind : parameters->indices()) {
148 Handle<YieldTermStructure> simCurve = simMarket->iborIndex(ind)->forwardingTermStructure();
149 Handle<YieldTermStructure> initCurve = initMarket->iborIndex(ind)->forwardingTermStructure();
151 BOOST_CHECK_CLOSE(simCurve->discount(1), initCurve->discount(1), 1e-4);
156 QuantLib::ext::shared_ptr<ore::analytics::ScenarioSimMarket>& simMarket,
157 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters>& parameters) {
158 for (
const auto& ccy : parameters->ccys()) {
159 Handle<QuantLib::SwaptionVolatilityStructure> simCurve = simMarket->swaptionVol(ccy);
160 Handle<QuantLib::SwaptionVolatilityStructure> initCurve = initMarket->swaptionVol(ccy);
161 for (
const auto&
maturity : parameters->swapVolExpiries(
"")) {
162 for (
const auto& tenor : parameters->swapVolTerms(
"")) {
163 BOOST_CHECK_CLOSE(simCurve->volatility(
maturity, tenor, 0.0,
true),
164 initCurve->volatility(
maturity, tenor, 0.0,
true), 1e-12);
171 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarket>& simMarket,
172 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters>& parameters) {
173 for (
const auto& ccyPair : parameters->fxVolCcyPairs()) {
174 Handle<BlackVolTermStructure> simCurve = simMarket->fxVol(ccyPair);
175 Handle<BlackVolTermStructure> initCurve = initMarket->fxVol(ccyPair);
177 Date
asof = initMarket->asofDate();
178 for (Size i = 0; i < parameters->fxVolExpiries(ccyPair).
size(); i++) {
179 dates.push_back(
asof + parameters->fxVolExpiries(ccyPair)[i]);
182 for (
const auto& date : dates) {
183 BOOST_CHECK_CLOSE(simCurve->blackVol(date, 0.0,
true), initCurve->blackVol(date, 0.0,
true), 1e-12);
189 QuantLib::ext::shared_ptr<ore::analytics::ScenarioSimMarket>& simMarket,
190 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters>& parameters) {
191 for (
const auto& spec : parameters->defaultNames()) {
193 Handle<DefaultProbabilityTermStructure> simCurve = simMarket->defaultCurve(spec)->curve();
194 Handle<DefaultProbabilityTermStructure> initCurve = initMarket->defaultCurve(spec)->curve();
195 BOOST_CHECK_EQUAL(initCurve->referenceDate(), simCurve->referenceDate());
197 Date
asof = initMarket->asofDate();
198 for (Size i = 0; i < parameters->defaultTenors(
"").
size(); i++) {
199 dates.push_back(
asof + parameters->defaultTenors(
"")[i]);
202 for (
const auto& date : dates) {
203 BOOST_CHECK_CLOSE(simCurve->survivalProbability(date,
true), initCurve->survivalProbability(date,
true),
210 QuantLib::ext::shared_ptr<ore::analytics::ScenarioSimMarket>& simMarket,
211 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters>& parameters) {
212 for (
const auto& spec : parameters->zeroInflationIndices()) {
214 Handle<ZeroInflationTermStructure> simCurve = simMarket->zeroInflationIndex(spec)->zeroInflationTermStructure();
215 Handle<ZeroInflationTermStructure> initCurve =
216 initMarket->zeroInflationIndex(spec)->zeroInflationTermStructure();
217 BOOST_CHECK_EQUAL(initCurve->referenceDate(), simCurve->referenceDate());
219 Date
asof = initMarket->asofDate();
220 for (Size i = 0; i < parameters->zeroInflationTenors(
"").
size(); i++) {
221 dates.push_back(
asof + parameters->zeroInflationTenors(
"")[i]);
224 for (
const auto& date : dates) {
225 BOOST_CHECK_CLOSE(simCurve->zeroRate(date), initCurve->zeroRate(date), 1e-12);
231 QuantLib::ext::shared_ptr<ore::analytics::ScenarioSimMarket>& simMarket,
232 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters>& parameters) {
233 for (
const auto& spec : parameters->correlationPairs()) {
234 vector<string> tokens;
235 boost::split(tokens, spec, boost::is_any_of(
":&"));
236 QL_REQUIRE(tokens.size() == 2,
"not a valid correlation pair: " << spec);
237 pair<string, string> pair = std::make_pair(tokens[0], tokens[1]);
238 Handle<QuantExt::CorrelationTermStructure> simCurve = simMarket->correlationCurve(pair.first, pair.second);
239 Handle<QuantExt::CorrelationTermStructure> initCurve = initMarket->correlationCurve(pair.first, pair.second);
240 BOOST_CHECK_EQUAL(initCurve->referenceDate(), simCurve->referenceDate());
242 Date
asof = initMarket->asofDate();
243 for (Size i = 0; i < parameters->correlationExpiries().
size(); i++) {
244 dates.push_back(
asof + parameters->correlationExpiries()[i]);
247 for (
const auto& date : dates) {
248 BOOST_CHECK_CLOSE(simCurve->correlation(date), initCurve->correlation(date), 1e-12);
253void testToXML(QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters> params) {
255 BOOST_TEST_MESSAGE(
"Testing to XML...");
257 string testFile =
"simtest.xml";
258 XMLNode* simulationNode = params->toXML(outDoc);
264 newParams->fromFile(testFile);
265 BOOST_CHECK(*params == *newParams);
267 newParams->baseCcy() =
"JPY";
268 BOOST_CHECK(*params != *newParams);
270 remove(
"simtest.xml");
275BOOST_AUTO_TEST_SUITE(ScenarioSimMarketTest)
278 BOOST_TEST_MESSAGE(
"Testing OREAnalytics ScenarioSimMarket...");
280 SavedSettings backup;
282 Date today(20, Jan, 2015);
283 Settings::instance().evaluationDate() = today;
284 QuantLib::ext::shared_ptr<ore::data::Market> initMarket = QuantLib::ext::make_shared<TestMarket>(today);
287 QuantLib::ext::shared_ptr<ore::analytics::ScenarioGenerator> scenarioGenerator;
290 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarketParameters> parameters = scenarioParameters();
293 QuantLib::ext::shared_ptr<analytics::ScenarioSimMarket> simMarket(
295 simMarket->scenarioGenerator() = scenarioGenerator;
298 testFxSpot(initMarket, simMarket, parameters);
309BOOST_AUTO_TEST_SUITE_END()
311BOOST_AUTO_TEST_SUITE_END()
Simulation Market updated with discrete scenarios.
ScenarioSimMarket description.
void appendNode(XMLNode *)
void toFile(const string &filename) const
OREAnalytics Top level fixture.
Simple flat market setup to be used in the test suite.
Size size(const ValueType &v)
QuantLib::ext::shared_ptr< data::Conventions > convs()
Fixture that can be used at top level of OREAnalytics test suites.
A Market class that can be updated by Scenarios.
A class to hold Scenario parameters for scenarioSimMarket.
void testZeroInflationCurve(QuantLib::ext::shared_ptr< ore::data::Market > &initMarket, QuantLib::ext::shared_ptr< ore::analytics::ScenarioSimMarket > &simMarket, QuantLib::ext::shared_ptr< analytics::ScenarioSimMarketParameters > ¶meters)
void testDefaultCurve(QuantLib::ext::shared_ptr< ore::data::Market > &initMarket, QuantLib::ext::shared_ptr< ore::analytics::ScenarioSimMarket > &simMarket, QuantLib::ext::shared_ptr< analytics::ScenarioSimMarketParameters > ¶meters)
BOOST_AUTO_TEST_CASE(testScenarioSimMarket)
void testCorrelationCurve(QuantLib::ext::shared_ptr< ore::data::Market > &initMarket, QuantLib::ext::shared_ptr< ore::analytics::ScenarioSimMarket > &simMarket, QuantLib::ext::shared_ptr< analytics::ScenarioSimMarketParameters > ¶meters)
void testDiscountCurve(QuantLib::ext::shared_ptr< ore::data::Market > &initMarket, QuantLib::ext::shared_ptr< ore::analytics::ScenarioSimMarket > &simMarket, QuantLib::ext::shared_ptr< analytics::ScenarioSimMarketParameters > ¶meters)
void testIndexCurve(QuantLib::ext::shared_ptr< ore::data::Market > &initMarket, QuantLib::ext::shared_ptr< ore::analytics::ScenarioSimMarket > &simMarket, QuantLib::ext::shared_ptr< analytics::ScenarioSimMarketParameters > ¶meters)
void testSwaptionVolCurve(QuantLib::ext::shared_ptr< ore::data::Market > &initMarket, QuantLib::ext::shared_ptr< ore::analytics::ScenarioSimMarket > &simMarket, QuantLib::ext::shared_ptr< analytics::ScenarioSimMarketParameters > ¶meters)
void testToXML(QuantLib::ext::shared_ptr< analytics::ScenarioSimMarketParameters > params)
void testFxSpot(QuantLib::ext::shared_ptr< ore::data::Market > &initMarket, QuantLib::ext::shared_ptr< ore::analytics::ScenarioSimMarket > &simMarket, QuantLib::ext::shared_ptr< analytics::ScenarioSimMarketParameters > ¶meters)
void testFxVolCurve(QuantLib::ext::shared_ptr< data::Market > &initMarket, QuantLib::ext::shared_ptr< analytics::ScenarioSimMarket > &simMarket, QuantLib::ext::shared_ptr< analytics::ScenarioSimMarketParameters > ¶meters)