Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
commodityvolcurveconfig.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2018 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 <boost/test/unit_test.hpp>
20#include <oret/toplevelfixture.hpp>
21
23
24using namespace std;
25using namespace boost::unit_test_framework;
26using namespace QuantLib;
27using namespace ore::data;
28
29BOOST_FIXTURE_TEST_SUITE(OREDataTestSuite, ore::test::TopLevelFixture)
30
31BOOST_AUTO_TEST_SUITE(CommodityVolatilityConfigTests)
32
33BOOST_AUTO_TEST_CASE(testParseConstantVolFromXml) {
34
35 BOOST_TEST_MESSAGE("Testing parsing of constant commodity vol curve configuration from XML");
36
37 // Create an XML string representation of the commodity volatility curve configuration
38 string configXml;
39 configXml.append("<CommodityVolatility>");
40 configXml.append(" <CurveId>GOLD_USD_VOLS</CurveId>");
41 configXml.append(" <CurveDescription/>");
42 configXml.append(" <Currency>USD</Currency>");
43 configXml.append(" <Constant>");
44 configXml.append(" <Quote>COMMODITY_OPTION/RATE_LNVOL/GOLD/USD/1Y/ATM/AtmFwd</Quote>");
45 configXml.append(" </Constant>");
46 configXml.append("</CommodityVolatility>");
47
48 // Create the XMLNode
49 XMLDocument doc;
50 doc.fromXMLString(configXml);
51 XMLNode* configNode = doc.getFirstNode("CommodityVolatility");
52
53 // Parse commodity volatility curve configuration from XML
55 config.fromXML(configNode);
56
57 // Check fields
58 BOOST_CHECK_EQUAL(config.curveID(), "GOLD_USD_VOLS");
59 BOOST_CHECK_EQUAL(config.currency(), "USD");
60 // Check that we have a constant volatility config.
61 QuantLib::ext::shared_ptr<ConstantVolatilityConfig> vc;
62 for (auto v : config.volatilityConfig()) {
63 if ((vc = QuantLib::ext::dynamic_pointer_cast<ConstantVolatilityConfig>(v)))
64 break;
65 }
66 BOOST_CHECK(vc);
67 BOOST_CHECK_EQUAL(config.quotes().size(), 1);
68 BOOST_CHECK_EQUAL(config.quotes()[0], "COMMODITY_OPTION/RATE_LNVOL/GOLD/USD/1Y/ATM/AtmFwd");
69
70 // Check defaults (don't matter for constant config in any case)
71 BOOST_CHECK_EQUAL(config.dayCounter(), "A365");
72 BOOST_CHECK_EQUAL(config.calendar(), "NullCalendar");
73 BOOST_CHECK_EQUAL(config.futureConventionsId(), "");
74 BOOST_CHECK_EQUAL(config.optionExpiryRollDays(), 0);
75}
76
77BOOST_AUTO_TEST_CASE(testParseVolCurveFromXml) {
78
79 BOOST_TEST_MESSAGE("Testing parsing of commodity vol curve configuration from XML");
80
81 // Create an XML string representation of the commodity volatility curve configuration
82 string configXml;
83 configXml.append("<CommodityVolatility>");
84 configXml.append(" <CurveId>GOLD_USD_VOLS</CurveId>");
85 configXml.append(" <CurveDescription/>");
86 configXml.append(" <Currency>USD</Currency>");
87 configXml.append(" <Curve>");
88 configXml.append(" <Quotes>");
89 configXml.append(" <Quote>COMMODITY_OPTION/RATE_LNVOL/GOLD/USD/1Y/ATM/AtmFwd</Quote>");
90 configXml.append(" <Quote>COMMODITY_OPTION/RATE_LNVOL/GOLD/USD/5Y/ATM/AtmFwd</Quote>");
91 configXml.append(" <Quote>COMMODITY_OPTION/RATE_LNVOL/GOLD/USD/10Y/ATM/AtmFwd</Quote>");
92 configXml.append(" </Quotes>");
93 configXml.append(" <Interpolation>Linear</Interpolation>");
94 configXml.append(" <Extrapolation>Flat</Extrapolation>");
95 configXml.append(" </Curve>");
96 configXml.append("</CommodityVolatility>");
97
98 // Create the XMLNode
99 XMLDocument doc;
100 doc.fromXMLString(configXml);
101 XMLNode* configNode = doc.getFirstNode("CommodityVolatility");
102
103 // Parse commodity volatility curve configuration from XML
105 config.fromXML(configNode);
106
107 // Expected vector of quotes
108 vector<string> quotes = {"COMMODITY_OPTION/RATE_LNVOL/GOLD/USD/1Y/ATM/AtmFwd",
109 "COMMODITY_OPTION/RATE_LNVOL/GOLD/USD/5Y/ATM/AtmFwd",
110 "COMMODITY_OPTION/RATE_LNVOL/GOLD/USD/10Y/ATM/AtmFwd"};
111
112 // Check fields
113 BOOST_CHECK_EQUAL(config.curveID(), "GOLD_USD_VOLS");
114 BOOST_CHECK_EQUAL(config.currency(), "USD");
115 // Check that we have a volatility curve config.
116 QuantLib::ext::shared_ptr<VolatilityCurveConfig> vc;
117 for (auto v : config.volatilityConfig()) {
118 if ((vc = QuantLib::ext::dynamic_pointer_cast<VolatilityCurveConfig>(v)))
119 break;
120 }
121
122 BOOST_REQUIRE(vc);
123 BOOST_CHECK_EQUAL(vc->interpolation(), "Linear");
124 BOOST_CHECK_EQUAL(vc->extrapolation(), "Flat");
125 BOOST_CHECK_EQUAL(config.quotes().size(), 3);
126 BOOST_CHECK_EQUAL_COLLECTIONS(quotes.begin(), quotes.end(), config.quotes().begin(), config.quotes().end());
127
128 // Check defaults
129 BOOST_CHECK_EQUAL(config.dayCounter(), "A365");
130 BOOST_CHECK_EQUAL(config.calendar(), "NullCalendar");
131 BOOST_CHECK_EQUAL(config.futureConventionsId(), "");
132 BOOST_CHECK_EQUAL(config.optionExpiryRollDays(), 0);
133
134 // Override defaults in turn and check
135
136 // Day counter
137 XMLUtils::addChild(doc, configNode, "DayCounter", "ACT");
138 config.fromXML(configNode);
139 BOOST_CHECK_EQUAL(config.dayCounter(), "ACT");
140
141 // Calendar
142 XMLUtils::addChild(doc, configNode, "Calendar", "TARGET");
143 config.fromXML(configNode);
144 BOOST_CHECK_EQUAL(config.calendar(), "TARGET");
145
146 // Future conventions Id
147 XMLUtils::addChild(doc, configNode, "FutureConventions", "NYMEX:CL");
148 config.fromXML(configNode);
149 BOOST_CHECK_EQUAL(config.futureConventionsId(), "NYMEX:CL");
150
151 // Option expiry roll days
152 XMLUtils::addChild(doc, configNode, "OptionExpiryRollDays", "2");
153 config.fromXML(configNode);
154 BOOST_CHECK_EQUAL(config.optionExpiryRollDays(), 2);
155}
156
157BOOST_AUTO_TEST_CASE(testParseVolSurfaceFromXml) {
158
159 BOOST_TEST_MESSAGE("Testing parsing of commodity vol surface configuration from XML");
160
161 // Create an XML string representation of the commodity volatility curve configuration
162 string configXml;
163 configXml.append("<CommodityVolatility>");
164 configXml.append(" <CurveId>WTI_USD_VOLS</CurveId>");
165 configXml.append(" <CurveDescription/>");
166 configXml.append(" <Currency>USD</Currency>");
167 configXml.append(" <StrikeSurface>");
168 configXml.append(" <Strikes>30.0,40.0,60.0</Strikes>");
169 configXml.append(" <Expiries>1Y,5Y,10Y</Expiries>");
170 configXml.append(" <TimeInterpolation>Linear</TimeInterpolation>");
171 configXml.append(" <StrikeInterpolation>Linear</StrikeInterpolation>");
172 configXml.append(" <Extrapolation>true</Extrapolation>");
173 configXml.append(" <TimeExtrapolation>Flat</TimeExtrapolation>");
174 configXml.append(" <StrikeExtrapolation>Flat</StrikeExtrapolation>");
175 configXml.append(" </StrikeSurface>");
176 configXml.append("</CommodityVolatility>");
177
178 // Create the XMLNode
179 XMLDocument doc;
180 doc.fromXMLString(configXml);
181 XMLNode* configNode = doc.getFirstNode("CommodityVolatility");
182
183 // Parse commodity volatility curve configuration from XML
185 config.fromXML(configNode);
186
187 // Expected vector of quotes
188 vector<string> quotes = {"COMMODITY_OPTION/RATE_LNVOL/WTI_USD_VOLS/USD/1Y/30.0",
189 "COMMODITY_OPTION/RATE_LNVOL/WTI_USD_VOLS/USD/1Y/40.0",
190 "COMMODITY_OPTION/RATE_LNVOL/WTI_USD_VOLS/USD/1Y/60.0",
191 "COMMODITY_OPTION/RATE_LNVOL/WTI_USD_VOLS/USD/5Y/30.0",
192 "COMMODITY_OPTION/RATE_LNVOL/WTI_USD_VOLS/USD/5Y/40.0",
193 "COMMODITY_OPTION/RATE_LNVOL/WTI_USD_VOLS/USD/5Y/60.0",
194 "COMMODITY_OPTION/RATE_LNVOL/WTI_USD_VOLS/USD/10Y/30.0",
195 "COMMODITY_OPTION/RATE_LNVOL/WTI_USD_VOLS/USD/10Y/40.0",
196 "COMMODITY_OPTION/RATE_LNVOL/WTI_USD_VOLS/USD/10Y/60.0"};
197
198 // Check fields
199 BOOST_CHECK_EQUAL(config.curveID(), "WTI_USD_VOLS");
200 BOOST_CHECK_EQUAL(config.currency(), "USD");
201 // Check that we have a volatility strike surface config.
202 QuantLib::ext::shared_ptr<VolatilityStrikeSurfaceConfig> vc;
203 for (auto v : config.volatilityConfig()) {
204 if ((vc = QuantLib::ext::dynamic_pointer_cast<VolatilityStrikeSurfaceConfig>(v)))
205 break;
206 }
207 BOOST_REQUIRE(vc);
208 BOOST_CHECK_EQUAL(vc->timeInterpolation(), "Linear");
209 BOOST_CHECK_EQUAL(vc->strikeInterpolation(), "Linear");
210 BOOST_CHECK(vc->extrapolation());
211 BOOST_CHECK_EQUAL(vc->timeExtrapolation(), "Flat");
212 BOOST_CHECK_EQUAL(vc->strikeExtrapolation(), "Flat");
213 BOOST_CHECK_EQUAL(config.quotes().size(), 9);
214 BOOST_CHECK_EQUAL_COLLECTIONS(quotes.begin(), quotes.end(), config.quotes().begin(), config.quotes().end());
215
216 // Check defaults
217 BOOST_CHECK_EQUAL(config.dayCounter(), "A365");
218 BOOST_CHECK_EQUAL(config.calendar(), "NullCalendar");
219 BOOST_CHECK_EQUAL(config.futureConventionsId(), "");
220 BOOST_CHECK_EQUAL(config.optionExpiryRollDays(), 0);
221}
222
223BOOST_AUTO_TEST_SUITE_END()
224
225BOOST_AUTO_TEST_SUITE_END()
Commodity volatility configuration.
const std::vector< QuantLib::ext::shared_ptr< VolatilityConfig > > & volatilityConfig() const
const std::string & futureConventionsId() const
const string & curveID() const
Definition: curveconfig.hpp:54
virtual const vector< string > & quotes()
Return all the market quotes required for this config.
Definition: curveconfig.hpp:69
Small XML Document wrapper class.
Definition: xmlutils.hpp:65
void fromXMLString(const string &xmlString)
load a document from a hard-coded string
Definition: xmlutils.cpp:103
XMLNode * getFirstNode(const string &name) const
Definition: xmlutils.cpp:116
static XMLNode * addChild(XMLDocument &doc, XMLNode *n, const string &name)
Definition: xmlutils.cpp:181
Commodity volatility curve configuration.
BOOST_AUTO_TEST_CASE(testParseConstantVolFromXml)