22#include <boost/test/unit_test.hpp>
27#include <ql/indexes/swap/euriborswap.hpp>
29#include <boost/assign/list_of.hpp>
33using namespace boost::unit_test_framework;
34using namespace boost::assign;
40 CommonVars(Size expiryIndex = 0, Size termIndex = 0, Real atmVolShift = 0) : referenceDate(5, Feb, 2016) {
43 Settings::instance().evaluationDate() = referenceDate;
46 QuantLib::ext::shared_ptr<IborIndex> iborIndex = conventions.floatIndex->clone(yieldCurves.forward6M);
47 QuantLib::ext::shared_ptr<SwapIndex> swapIndex =
48 conventions.swapIndex->clone(yieldCurves.forward6M, yieldCurves.forward6M);
49 QuantLib::ext::shared_ptr<SwapIndex> shortSwapIndex =
50 conventions.shortSwapIndex->clone(yieldCurves.forward6M, yieldCurves.forward6M);
53 swapConventions = QuantLib::ext::make_shared<SwapConventions>(conventions.settlementDays, conventions.fixedTenor,
54 conventions.fixedCalendar, conventions.fixedConvention,
55 conventions.fixedDayCounter, iborIndex);
58 Matrix shiftedAtmVols = atmVols.nVols;
59 QL_REQUIRE(expiryIndex < atmVols.optionTenors.size(),
"expiryIndex out of range");
60 QL_REQUIRE(termIndex < atmVols.swapTenors.size(),
"termIndex out of range");
61 shiftedAtmVols[expiryIndex][termIndex] += atmVolShift;
62 atmNormalVolMatrix = QuantLib::ext::make_shared<SwaptionVolatilityMatrix>(
63 referenceDate, conventions.fixedCalendar, conventions.fixedConvention, atmVols.optionTenors,
64 atmVols.swapTenors, shiftedAtmVols, Actual365Fixed(),
true, Normal);
66 atmLogNormalVolMatrix = QuantLib::ext::make_shared<SwaptionVolatilityMatrix>(
67 referenceDate, conventions.fixedCalendar, conventions.fixedConvention, atmVols.optionTenors,
68 atmVols.swapTenors, shiftedAtmVols, Actual365Fixed(),
true, ShiftedLognormal);
71 atmShiftedLogNormalVolMatrix_1 = QuantLib::ext::shared_ptr<SwaptionVolatilityMatrix>(
new SwaptionVolatilityMatrix(
72 referenceDate, conventions.fixedCalendar, conventions.fixedConvention, atmVols.optionTenors,
73 atmVols.swapTenors, shiftedAtmVols, Actual365Fixed(),
true, ShiftedLognormal, atmVols.shifts_1));
75 atmShiftedLogNormalVolMatrix_2 = QuantLib::ext::shared_ptr<SwaptionVolatilityMatrix>(
new SwaptionVolatilityMatrix(
76 referenceDate, conventions.fixedCalendar, conventions.fixedConvention, atmVols.optionTenors,
77 atmVols.swapTenors, atmVols.slnVols_2, Actual365Fixed(),
true, ShiftedLognormal, atmVols.shifts_2));
79 normalVolCube = QuantLib::ext::shared_ptr<SwaptionVolCube2>(
new SwaptionVolCube2(
80 Handle<QuantLib::SwaptionVolatilityStructure>(atmNormalVolMatrix), atmVols.optionTenors, atmVols.swapTenors,
81 atmVols.strikeSpreads, atmVols.nVolSpreads, swapIndex, shortSwapIndex,
false,
true));
82 logNormalVolCube = QuantLib::ext::shared_ptr<SwaptionVolCube2>(
new SwaptionVolCube2(
83 Handle<QuantLib::SwaptionVolatilityStructure>(atmLogNormalVolMatrix), atmVols.optionTenors,
84 atmVols.swapTenors, atmVols.strikeSpreads, atmVols.lnVolSpreads, swapIndex, shortSwapIndex,
false,
true));
85 shiftedLogNormalVolCube = QuantLib::ext::shared_ptr<SwaptionVolCube2>(
new SwaptionVolCube2(
86 Handle<QuantLib::SwaptionVolatilityStructure>(atmShiftedLogNormalVolMatrix_1), atmVols.optionTenors,
87 atmVols.swapTenors, atmVols.strikeSpreads, atmVols.slnVolSpreads, swapIndex, shortSwapIndex,
false,
true));
89 normalVolCubeConstantSpread = QuantLib::ext::shared_ptr<SwaptionVolatilityConstantSpread>(
91 Handle<QuantLib::SwaptionVolatilityStructure>(normalVolCube)));
93 logNormalVolCubeConstantSpread = QuantLib::ext::shared_ptr<SwaptionVolatilityConstantSpread>(
95 Handle<QuantLib::SwaptionVolatilityStructure>(logNormalVolCube)));
97 shiftedLogNormalVolCubeConstantSpread =
99 Handle<QuantLib::SwaptionVolatilityStructure>(atmShiftedLogNormalVolMatrix_1),
100 Handle<QuantLib::SwaptionVolatilityStructure>(shiftedLogNormalVolCube)));
108 QuantLib::ext::shared_ptr<SwapConventions> swapConventions;
109 QuantLib::ext::shared_ptr<SwaptionVolatilityStructure> atmNormalVolMatrix;
110 QuantLib::ext::shared_ptr<SwaptionVolatilityStructure> atmLogNormalVolMatrix;
111 QuantLib::ext::shared_ptr<SwaptionVolatilityStructure> atmShiftedLogNormalVolMatrix_1;
112 QuantLib::ext::shared_ptr<SwaptionVolatilityStructure> atmShiftedLogNormalVolMatrix_2;
113 QuantLib::ext::shared_ptr<SwaptionVolatilityStructure> normalVolCube, normalVolCubeConstantSpread;
114 QuantLib::ext::shared_ptr<SwaptionVolatilityStructure> logNormalVolCube, logNormalVolCubeConstantSpread;
115 QuantLib::ext::shared_ptr<SwaptionVolatilityStructure> shiftedLogNormalVolCube, shiftedLogNormalVolCubeConstantSpread;
117 SavedSettings backup;
123BOOST_AUTO_TEST_SUITE(SwaptionVolConstantSpreadTest)
125 BOOST_TEST_MESSAGE(
"Testing ATM normal vol shift propagation...");
128 Real tolerance = 0.000001;
130 for (Size i = 0; i < vars1.atmVols.optionTenors.size(); ++i) {
131 for (Size j = 0; j < vars1.atmVols.swapTenors.size(); ++j) {
132 CommonVars vars2(i, j, shift);
133 Period expiry = vars1.atmVols.optionTenors[i];
134 Period term = vars1.atmVols.swapTenors[j];
136 Real atmVol = vars1.atmNormalVolMatrix->volatility(expiry, term, 0.0);
137 Real shiftedAtmVol = vars2.atmNormalVolMatrix->volatility(expiry, term, 0.0);
138 BOOST_CHECK_SMALL(shiftedAtmVol - atmVol - shift, tolerance);
141 for (Real strike = 0.01; strike <= 0.08; strike += 0.005) {
142 Real otmVol = vars1.normalVolCubeConstantSpread->volatility(expiry, term, strike);
143 Real shiftedOtmVol = vars2.normalVolCubeConstantSpread->volatility(expiry, term, strike);
147 BOOST_CHECK_SMALL(shiftedOtmVol - otmVol - shift, tolerance);
151 for (Size ii = 0; ii < vars1.atmVols.optionTenors.size(); ++ii) {
154 for (Size jj = 0; jj < vars1.atmVols.swapTenors.size(); ++jj) {
157 Period expiry = vars1.atmVols.optionTenors[ii];
158 Period term = vars1.atmVols.swapTenors[jj];
159 Real atmVol = vars1.atmNormalVolMatrix->volatility(expiry, term, 0.0);
160 Real shiftedAtmVol = vars2.atmNormalVolMatrix->volatility(expiry, term, 0.0);
161 BOOST_CHECK_SMALL(shiftedAtmVol - atmVol, tolerance);
162 for (Real strike = 0.01; strike <= 0.08; strike += 0.005) {
163 Real otmVol = vars1.normalVolCubeConstantSpread->volatility(expiry, term, strike);
164 Real shiftedOtmVol = vars2.normalVolCubeConstantSpread->volatility(expiry, term, strike);
165 BOOST_CHECK_SMALL(shiftedOtmVol - otmVol, tolerance);
174 BOOST_TEST_MESSAGE(
"Testing ATM log-normal vol shift propagation...");
177 Real tolerance = 0.000001;
179 for (Size i = 0; i < vars1.atmVols.optionTenors.size(); ++i) {
180 for (Size j = 0; j < vars1.atmVols.swapTenors.size(); ++j) {
181 CommonVars vars2(i, j, shift);
182 Period expiry = vars1.atmVols.optionTenors[i];
183 Period term = vars1.atmVols.swapTenors[j];
185 Real atmVol = vars1.atmLogNormalVolMatrix->volatility(expiry, term, 0.0);
186 Real shiftedAtmVol = vars2.atmLogNormalVolMatrix->volatility(expiry, term, 0.0);
187 BOOST_CHECK_SMALL(shiftedAtmVol - atmVol - shift, tolerance);
190 for (Real strike = 0.01; strike <= 0.08; strike += 0.005) {
191 Real otmVol = vars1.normalVolCubeConstantSpread->volatility(expiry, term, strike);
192 Real shiftedOtmVol = vars2.normalVolCubeConstantSpread->volatility(expiry, term, strike);
196 BOOST_CHECK_SMALL(shiftedOtmVol - otmVol - shift, tolerance);
200 for (Size ii = 0; ii < vars1.atmVols.optionTenors.size(); ++ii) {
203 for (Size jj = 0; jj < vars1.atmVols.swapTenors.size(); ++jj) {
206 Period expiry = vars1.atmVols.optionTenors[ii];
207 Period term = vars1.atmVols.swapTenors[jj];
208 Real atmVol = vars1.atmLogNormalVolMatrix->volatility(expiry, term, 0.0);
209 Real shiftedAtmVol = vars2.atmLogNormalVolMatrix->volatility(expiry, term, 0.0);
210 BOOST_CHECK_SMALL(shiftedAtmVol - atmVol, tolerance);
211 for (Real strike = 0.01; strike <= 0.08; strike += 0.005) {
212 Real otmVol = vars1.logNormalVolCubeConstantSpread->volatility(expiry, term, strike);
213 Real shiftedOtmVol = vars2.logNormalVolCubeConstantSpread->volatility(expiry, term, strike);
214 BOOST_CHECK_SMALL(shiftedOtmVol - otmVol, tolerance);
222BOOST_AUTO_TEST_SUITE_END()
224BOOST_AUTO_TEST_SUITE_END()
Swaption cube that combines an ATM matrix and vol spreads from a cube.
structs containing swaption market data that can be used in tests
Convert swaption volatilities from one type to another.
swaption cube that combines an ATM matrix and vol spreads from a cube
Swaption volatility cube, fit-later-interpolate-early approach.
BOOST_AUTO_TEST_CASE(testAtmNormalVolShiftPropagation)
Fixture that can be used at top level.
structs containing yield curve market data that can be used in tests