173 {
174 BOOST_TEST_MESSAGE("Testing ATM log-normal vol shift propagation...");
175
176 CommonVars vars1;
177 Real tolerance = 0.000001;
178 Real shift = 0.1;
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];
184
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);
188
189
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);
193
194
195
196 BOOST_CHECK_SMALL(shiftedOtmVol - otmVol - shift, tolerance);
197 }
198
199
200 for (Size ii = 0; ii < vars1.atmVols.optionTenors.size(); ++ii) {
201 if (i == ii)
202 continue;
203 for (Size jj = 0; jj < vars1.atmVols.swapTenors.size(); ++jj) {
204 if (j == jj)
205 continue;
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);
215 }
216 }
217 }
218 }
219 }
220}