public void test_volatility_sensitivity() { double eps = 1.0e-6; int nData = TIME.size(); for (int i = 0; i < NB_TEST; i++) { SwaptionSensitivity point = SwaptionSensitivity.of( CONVENTION, TEST_OPTION_EXPIRY[i], TENOR.get(i), TEST_STRIKE, TEST_FORWARD, GBP, TEST_SENSITIVITY[i]); SurfaceCurrencyParameterSensitivity sensi = PROVIDER_WITH_PARAM.surfaceCurrencyParameterSensitivity(point); Map<DoublesPair, Double> map = new HashMap<DoublesPair, Double>(); for (int j = 0; j < nData; ++j) { DoubleArray volDataUp = VOL.subArray(0, nData).with(j, VOL.get(j) + eps); DoubleArray volDataDw = VOL.subArray(0, nData).with(j, VOL.get(j) - eps); InterpolatedNodalSurface paramUp = InterpolatedNodalSurface.of( METADATA_WITH_PARAM, TIME, TENOR, volDataUp, INTERPOLATOR_2D); InterpolatedNodalSurface paramDw = InterpolatedNodalSurface.of( METADATA_WITH_PARAM, TIME, TENOR, volDataDw, INTERPOLATOR_2D); BlackVolatilityExpiryTenorSwaptionProvider provUp = BlackVolatilityExpiryTenorSwaptionProvider.of( paramUp, CONVENTION, ACT_365F, VALUATION_DATE_TIME); BlackVolatilityExpiryTenorSwaptionProvider provDw = BlackVolatilityExpiryTenorSwaptionProvider.of( paramDw, CONVENTION, ACT_365F, VALUATION_DATE_TIME); double volUp = provUp.getVolatility(TEST_OPTION_EXPIRY[i], TEST_TENOR[i], TEST_STRIKE, TEST_FORWARD); double volDw = provDw.getVolatility(TEST_OPTION_EXPIRY[i], TEST_TENOR[i], TEST_STRIKE, TEST_FORWARD); double fd = 0.5 * (volUp - volDw) / eps; map.put(DoublesPair.of(TIME.get(j), TENOR.get(j)), fd); } SurfaceCurrencyParameterSensitivity sensiFromNoMetadata = PROVIDER.surfaceCurrencyParameterSensitivity(point); List<SurfaceParameterMetadata> list = sensi.getMetadata().getParameterMetadata().get(); DoubleArray computed = sensi.getSensitivity(); assertEquals(computed.size(), nData); for (int j = 0; j < list.size(); ++j) { SwaptionSurfaceExpiryTenorNodeMetadata metadata = (SwaptionSurfaceExpiryTenorNodeMetadata) list.get(i); double expected = map.get(DoublesPair.of(metadata.getYearFraction(), metadata.getTenor())); assertEquals(computed.get(i), expected, eps); assertTrue( sensiFromNoMetadata.getMetadata().getParameterMetadata().get().contains(metadata)); } } }
private void testPriceSensitivityBlackVolatility( SurfaceCurrencyParameterSensitivity computed, Function<BlackVolatilityBondFutureProvider, Double> valueFn) { List<SurfaceParameterMetadata> list = computed.getMetadata().getParameterMetadata().get(); int nVol = VOL.size(); assertEquals(list.size(), nVol); for (int i = 0; i < nVol; ++i) { double[] volUp = Arrays.copyOf(VOL.toArray(), nVol); double[] volDw = Arrays.copyOf(VOL.toArray(), nVol); volUp[i] += EPS; volDw[i] -= EPS; InterpolatedNodalSurface sfUp = InterpolatedNodalSurface.of( METADATA, TIME, MONEYNESS, DoubleArray.copyOf(volUp), INTERPOLATOR_2D); InterpolatedNodalSurface sfDw = InterpolatedNodalSurface.of( METADATA, TIME, MONEYNESS, DoubleArray.copyOf(volDw), INTERPOLATOR_2D); BlackVolatilityExpLogMoneynessBondFutureProvider provUp = BlackVolatilityExpLogMoneynessBondFutureProvider.of( sfUp, FUTURE_SECURITY_ID, ACT_365F, VALUATION_DATE_TIME); BlackVolatilityExpLogMoneynessBondFutureProvider provDw = BlackVolatilityExpLogMoneynessBondFutureProvider.of( sfDw, FUTURE_SECURITY_ID, ACT_365F, VALUATION_DATE_TIME); double expected = 0.5 * (valueFn.apply(provUp) - valueFn.apply(provDw)) / EPS; int index = -1; for (int j = 0; j < nVol; ++j) { GenericVolatilitySurfaceYearFractionMetadata meta = (GenericVolatilitySurfaceYearFractionMetadata) list.get(j); if (meta.getYearFraction() == TIME.get(i) && meta.getStrike().getValue() == MONEYNESS.get(i)) { index = j; continue; } } assertEquals(computed.getSensitivity().get(index), expected, EPS); } }