Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Namespaces | Functions
capfloortermvolcurve.cpp File Reference
#include <boost/assign.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/test/data/test_case.hpp>
#include <boost/variant.hpp>
#include <test/capfloormarketdata.hpp>
#include <test/toplevelfixture.hpp>
#include <ql/math/interpolations/backwardflatinterpolation.hpp>
#include <ql/quotes/simplequote.hpp>
#include <qle/math/flatextrapolation.hpp>
#include <qle/termstructures/capfloortermvolcurve.hpp>

Go to the source code of this file.

Namespaces

namespace  boost
 
namespace  boost::test_tools
 
namespace  boost::test_tools::tt_detail
 

Functions

 BOOST_DATA_TEST_CASE_F (CommonVars, testCapFloorTermVolCurveInterpolation, bdata::make(interpolationTypes) *bdata::make(isMovingValues) *bdata::make(flatFirstPeriodValues), interpolationType, isMoving, flatFirstPeriod)
 

Function Documentation

◆ BOOST_DATA_TEST_CASE_F()

BOOST_DATA_TEST_CASE_F ( CommonVars  ,
testCapFloorTermVolCurveInterpolation  ,
bdata::make(interpolationTypes) *bdata::make(isMovingValues) *bdata::make(flatFirstPeriodValues)  ,
interpolationType  ,
isMoving  ,
flatFirstPeriod   
)

Definition at line 147 of file capfloortermvolcurve.cpp.

150 {
151
152 BOOST_TEST_MESSAGE("Testing cap floor term volatility curve with different interpolation methods");
153
154 BOOST_TEST_MESSAGE("Test inputs are:");
155 BOOST_TEST_MESSAGE(" Interpolation type: " << to_string(interpolationType));
156 BOOST_TEST_MESSAGE(" Floating reference date: " << boolalpha << isMoving);
157 BOOST_TEST_MESSAGE(" Flat first period: " << boolalpha << flatFirstPeriod);
158
159 // Create the CapFloorTermVolatilityStructure using the appropriate interpolation and reference date/settlement days
160 QuantLib::ext::shared_ptr<CapFloorTermVolatilityStructure> cftvs;
161 switch (interpolationType.which()) {
162 case 0:
163 if (isMoving) {
164 BOOST_TEST_MESSAGE("Using Linear interpolation with a moving reference date");
165 BOOST_REQUIRE_NO_THROW(cftvs = QuantLib::ext::make_shared<InterpolatedCapFloorTermVolCurve<Linear> >(
166 settlementDays, calendar, bdc, tenors, volHandles, dayCounter, flatFirstPeriod));
167 } else {
168 BOOST_TEST_MESSAGE("Using Linear interpolation with a fixed reference date");
169 BOOST_REQUIRE_NO_THROW(cftvs = QuantLib::ext::make_shared<InterpolatedCapFloorTermVolCurve<Linear> >(
170 referenceDate, calendar, bdc, tenors, volHandles, dayCounter, flatFirstPeriod));
171 }
172 break;
173 case 1:
174 if (isMoving) {
175 BOOST_TEST_MESSAGE("Using BackwardFlat interpolation with a moving reference date");
176 BOOST_REQUIRE_NO_THROW(cftvs = QuantLib::ext::make_shared<InterpolatedCapFloorTermVolCurve<BackwardFlat> >(
177 settlementDays, calendar, bdc, tenors, volHandles, dayCounter, flatFirstPeriod));
178 } else {
179 BOOST_TEST_MESSAGE("Using BackwardFlat interpolation with a fixed reference date");
180 BOOST_REQUIRE_NO_THROW(cftvs = QuantLib::ext::make_shared<InterpolatedCapFloorTermVolCurve<BackwardFlat> >(
181 referenceDate, calendar, bdc, tenors, volHandles, dayCounter, flatFirstPeriod));
182 }
183 break;
184 case 2:
185 if (isMoving) {
186 BOOST_TEST_MESSAGE("Using LinearFlat interpolation with a moving reference date");
187 BOOST_REQUIRE_NO_THROW(cftvs = QuantLib::ext::make_shared<InterpolatedCapFloorTermVolCurve<LinearFlat> >(
188 settlementDays, calendar, bdc, tenors, volHandles, dayCounter, flatFirstPeriod));
189 } else {
190 BOOST_TEST_MESSAGE("Using LinearFlat interpolation with a fixed reference date");
191 BOOST_REQUIRE_NO_THROW(cftvs = QuantLib::ext::make_shared<InterpolatedCapFloorTermVolCurve<LinearFlat> >(
192 referenceDate, calendar, bdc, tenors, volHandles, dayCounter, flatFirstPeriod));
193 }
194 break;
195 case 3:
196 if (isMoving) {
197 BOOST_TEST_MESSAGE("Using Cubic interpolation with a moving reference date");
198 BOOST_REQUIRE_NO_THROW(cftvs = QuantLib::ext::make_shared<InterpolatedCapFloorTermVolCurve<Cubic> >(
199 settlementDays, calendar, bdc, tenors, volHandles, dayCounter, flatFirstPeriod));
200 } else {
201 BOOST_TEST_MESSAGE("Using Cubic interpolation with a fixed reference date");
202 BOOST_REQUIRE_NO_THROW(cftvs = QuantLib::ext::make_shared<InterpolatedCapFloorTermVolCurve<Cubic> >(
203 referenceDate, calendar, bdc, tenors, volHandles, dayCounter, flatFirstPeriod));
204 }
205 break;
206 case 4:
207 if (isMoving) {
208 BOOST_TEST_MESSAGE("Using CubicFlat interpolation with a moving reference date");
209 BOOST_REQUIRE_NO_THROW(cftvs = QuantLib::ext::make_shared<InterpolatedCapFloorTermVolCurve<CubicFlat> >(
210 settlementDays, calendar, bdc, tenors, volHandles, dayCounter, flatFirstPeriod));
211 } else {
212 BOOST_TEST_MESSAGE("Using CubicFlat interpolation with a fixed reference date");
213 BOOST_REQUIRE_NO_THROW(cftvs = QuantLib::ext::make_shared<InterpolatedCapFloorTermVolCurve<CubicFlat> >(
214 referenceDate, calendar, bdc, tenors, volHandles, dayCounter, flatFirstPeriod));
215 }
216 break;
217 default:
218 BOOST_FAIL("Unexpected interpolation type");
219 }
220
221 BOOST_TEST_MESSAGE("Test the initial curve dates");
222 for (Size i = 0; i < tenors.size(); ++i) {
223 Date curveDate = cftvs->optionDateFromTenor(tenors[i]);
224 Date manualDate = calendar.advance(referenceDate, tenors[i], bdc);
225 BOOST_CHECK_EQUAL(curveDate, manualDate);
226 }
227
228 BOOST_TEST_MESSAGE("Test that curve returns input values on pillars");
229 for (Size i = 0; i < tenors.size(); ++i) {
230 Volatility vol = cftvs->volatility(tenors[i], 0.01);
231 BOOST_CHECK_SMALL(volQuotes[i]->value() - vol, tolerance);
232 }
233
234 // Bump the 5Y ATM volatility quote (3rd element in quote vector)
235 Size idx = 2;
236 Volatility bump = 0.0005;
237 Volatility baseValue = volQuotes[idx]->value();
238 volQuotes[idx]->setValue(baseValue + bump);
239
240 BOOST_TEST_MESSAGE("Test that curve returns input values on pillars after bump");
241 for (Size i = 0; i < tenors.size(); ++i) {
242 Volatility vol = cftvs->volatility(tenors[i], 0.01);
243 BOOST_CHECK_SMALL(volQuotes[i]->value() - vol, tolerance);
244 // Also check the point was bumped
245 if (i == idx) {
246 BOOST_CHECK_SMALL(vol - baseValue - bump, tolerance);
247 }
248 }
249
250 BOOST_TEST_MESSAGE("Test the curve dates after moving the evaluation date");
251 Date manualDate;
252 Date newDate = calendar.advance(referenceDate, 1 * Months);
253 Settings::instance().evaluationDate() = newDate;
254 for (Size i = 0; i < tenors.size(); ++i) {
255 Date curveDate = cftvs->optionDateFromTenor(tenors[i]);
256 manualDate =
257 isMoving ? calendar.advance(newDate, tenors[i], bdc) : calendar.advance(referenceDate, tenors[i], bdc);
258 BOOST_CHECK_EQUAL(curveDate, manualDate);
259 }
260
261 BOOST_TEST_MESSAGE("Test that curve returns input values after moving the evaluation date");
262 for (Size i = 0; i < tenors.size(); ++i) {
263 Volatility vol = cftvs->volatility(tenors[i], 0.01);
264 BOOST_CHECK_SMALL(volQuotes[i]->value() - vol, tolerance);
265 }
266
267 // Reset the evaluation date
268 Settings::instance().evaluationDate() = referenceDate;
269
270 BOOST_TEST_MESSAGE("Test extrapolation settings with out of range date");
271 Date oorDate = cftvs->maxDate() + 1 * Months;
272 BOOST_CHECK_NO_THROW(cftvs->volatility(oorDate, 0.01, true));
273 BOOST_CHECK_THROW(cftvs->volatility(oorDate, 0.01), Error);
274 cftvs->enableExtrapolation();
275 BOOST_CHECK_NO_THROW(cftvs->volatility(oorDate, 0.01));
276}
Interpolated cap floor term volatility curve.