@Override protected Object propertyGet(Bean bean, String propertyName, boolean quiet) { switch (propertyName.hashCode()) { case 2039569265: // convention return ((NormalSwaptionExpiryTenorVolatilities) bean).getConvention(); case -949589828: // valuationDateTime return ((NormalSwaptionExpiryTenorVolatilities) bean).getValuationDateTime(); case -1853231955: // surface return ((NormalSwaptionExpiryTenorVolatilities) bean).getSurface(); } return super.propertyGet(bean, propertyName, quiet); }
@Override public NormalSwaptionExpiryTenorVolatilities build() { return new NormalSwaptionExpiryTenorVolatilities( convention, valuationDateTime, surface); }
public void test_volatility() { for (int i = 0; i < NB_TEST; i++) { double expiryTime = VOLS.relativeTime(TEST_OPTION_EXPIRY[i]); double volExpected = SURFACE.zValue(expiryTime, TEST_TENOR[i]); double volComputed = VOLS.volatility(TEST_OPTION_EXPIRY[i], TEST_TENOR[i], TEST_STRIKE, TEST_FORWARD); assertEquals(volComputed, volExpected, TOLERANCE_VOL); } }
int nData = TIME.size(); for (int i = 0; i < NB_TEST; i++) { double expiryTime = VOLS.relativeTime(TEST_OPTION_EXPIRY[i]); SwaptionSensitivity point = SwaptionSensitivity.of( VOLS.getName(), expiryTime, TEST_TENOR[i], TEST_STRIKE, TEST_FORWARD, GBP, TEST_SENSITIVITY[i]); CurrencyParameterSensitivities sensActual = VOLS.parameterSensitivity(point); CurrencyParameterSensitivity sensi = sensActual.getSensitivity(SURFACE.getName(), GBP); DoubleArray computed = sensi.getSensitivity(); InterpolatedNodalSurface.of(METADATA, TIME, TENOR, volDataDw, INTERPOLATOR_2D); NormalSwaptionExpiryTenorVolatilities provUp = NormalSwaptionExpiryTenorVolatilities.of(CONVENTION, VAL_DATE_TIME, paramUp); NormalSwaptionExpiryTenorVolatilities provDw = NormalSwaptionExpiryTenorVolatilities.of(CONVENTION, VAL_DATE_TIME, paramDw); double volUp = provUp.volatility(TEST_OPTION_EXPIRY[i], TEST_TENOR[i], TEST_STRIKE, TEST_FORWARD); double volDw = provDw.volatility(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);
@Override public CurrencyParameterSensitivities parameterSensitivity(PointSensitivities pointSensitivities) { CurrencyParameterSensitivities sens = CurrencyParameterSensitivities.empty(); for (PointSensitivity point : pointSensitivities.getSensitivities()) { if (point instanceof SwaptionSensitivity) { SwaptionSensitivity pt = (SwaptionSensitivity) point; if (pt.getVolatilitiesName().equals(getName())) { sens = sens.combinedWith(parameterSensitivity(pt)); } } } return sens; }
public void present_value_sensitivityNormalVolatility_FD() { double shiftVol = 1.0E-4; CurrencyAmount pvP = PRICER_SWAPTION_NORMAL.presentValue(SWAPTION_LONG_PAY, MULTI_USD, SwaptionNormalVolatilityDataSets.normalVolSwaptionProviderUsdStsShifted(shiftVol)); CurrencyAmount pvM = PRICER_SWAPTION_NORMAL.presentValue(SWAPTION_LONG_PAY, MULTI_USD, SwaptionNormalVolatilityDataSets.normalVolSwaptionProviderUsdStsShifted(-shiftVol)); double pvnvsFd = (pvP.getAmount() - pvM.getAmount()) / (2 * shiftVol); SwaptionSensitivity pvnvsAd = PRICER_SWAPTION_NORMAL .presentValueSensitivityModelParamsVolatility(SWAPTION_LONG_PAY, MULTI_USD, NORMAL_VOLS_USD_STD); assertEquals(pvnvsAd.getCurrency(), USD); assertEquals(pvnvsAd.getSensitivity(), pvnvsFd, TOLERANCE_PV_VEGA); assertEquals(pvnvsAd.getVolatilitiesName(), NORMAL_VOLS_USD_STD.getName()); assertEquals(pvnvsAd.getExpiry(), NORMAL_VOLS_USD_STD.relativeTime(SWAPTION_LONG_PAY.getExpiry())); assertEquals(pvnvsAd.getTenor(), SWAP_TENOR_YEAR, TOLERANCE_RATE); assertEquals(pvnvsAd.getStrike(), STRIKE, TOLERANCE_RATE); double forward = PRICER_SWAP.parRate(RSWAP_REC, MULTI_USD); assertEquals(pvnvsAd.getForward(), forward, TOLERANCE_RATE); }
public void test_valuationDate() { assertEquals(VOLS.getValuationDateTime(), VAL_DATE_TIME); }
public void test_swapConvention() { assertEquals(VOLS.getConvention(), CONVENTION); }
public void coverage() { NormalSwaptionExpiryTenorVolatilities test1 = NormalSwaptionExpiryTenorVolatilities.of(CONVENTION, VAL_DATE_TIME, SURFACE); coverImmutableBean(test1); NormalSwaptionExpiryTenorVolatilities test2 = NormalSwaptionExpiryTenorVolatilities.of(CONVENTION, VAL_DATE.atStartOfDay(ZoneOffset.UTC), SURFACE); coverBeanEquals(test1, test2); }
public void test_relativeTime() { double test1 = VOLS.relativeTime(VAL_DATE_TIME); assertEquals(test1, 0d); double test2 = VOLS.relativeTime(date(2018, 2, 17).atStartOfDay(LONDON_ZONE)); double test3 = VOLS.relativeTime(date(2012, 2, 17).atStartOfDay(LONDON_ZONE)); assertEquals(test2, -test3); // consistency checked }
public void test_presentValueSensitivityNormalVolatility() { SwaptionSensitivity computedRec = PRICER_SWAPTION .presentValueSensitivityModelParamsVolatility(SWAPTION_REC_LONG, RATE_PROVIDER, VOLS); CurrencyAmount pvRecUp = PRICER_SWAPTION.presentValue(SWAPTION_REC_LONG, RATE_PROVIDER, SwaptionNormalVolatilityDataSets.normalVolSwaptionProviderUsdStsShifted(FD_EPS)); CurrencyAmount pvRecDw = PRICER_SWAPTION.presentValue(SWAPTION_REC_LONG, RATE_PROVIDER, SwaptionNormalVolatilityDataSets.normalVolSwaptionProviderUsdStsShifted(-FD_EPS)); double expectedRec = 0.5 * (pvRecUp.getAmount() - pvRecDw.getAmount()) / FD_EPS; assertEquals(computedRec.getCurrency(), USD); assertEquals(computedRec.getSensitivity(), expectedRec, FD_EPS * NOTIONAL); assertEquals(computedRec.getVolatilitiesName(), VOLS.getName()); assertEquals(computedRec.getExpiry(), VOLS.relativeTime(SWAPTION_REC_LONG.getExpiry())); assertEquals(computedRec.getTenor(), SWAP_TENOR_YEAR, TOL); assertEquals(computedRec.getStrike(), STRIKE, TOL); assertEquals(computedRec.getForward(), PRICER_SWAP.parRate(RSWAP_REC, RATE_PROVIDER), TOL); SwaptionSensitivity computedPay = PRICER_SWAPTION .presentValueSensitivityModelParamsVolatility(SWAPTION_PAY_SHORT, RATE_PROVIDER, VOLS); CurrencyAmount pvUpPay = PRICER_SWAPTION.presentValue(SWAPTION_PAY_SHORT, RATE_PROVIDER, SwaptionNormalVolatilityDataSets.normalVolSwaptionProviderUsdStsShifted(FD_EPS)); CurrencyAmount pvDwPay = PRICER_SWAPTION.presentValue(SWAPTION_PAY_SHORT, RATE_PROVIDER, SwaptionNormalVolatilityDataSets.normalVolSwaptionProviderUsdStsShifted(-FD_EPS)); double expectedPay = 0.5 * (pvUpPay.getAmount() - pvDwPay.getAmount()) / FD_EPS; assertEquals(computedPay.getCurrency(), USD); assertEquals(computedPay.getSensitivity(), expectedPay, FD_EPS * NOTIONAL); assertEquals(computedPay.getVolatilitiesName(), VOLS.getName()); assertEquals(computedPay.getExpiry(), VOLS.relativeTime(SWAPTION_PAY_SHORT.getExpiry())); assertEquals(computedPay.getTenor(), SWAP_TENOR_YEAR, TOL); assertEquals(computedPay.getStrike(), STRIKE, TOL); assertEquals(computedPay.getForward(), PRICER_SWAP.parRate(RSWAP_PAY, RATE_PROVIDER), TOL); }
public static NormalSwaptionExpiryTenorVolatilities normalVolSwaptionProviderUsdStd(LocalDate valuationDate) { return NormalSwaptionExpiryTenorVolatilities.of( USD_1Y_LIBOR3M, valuationDate.atTime(VAL_TIME_STD).atZone(VAL_ZONE_STD), SURFACE_STD); }
public void present_value_formula() { double forward = PRICER_SWAP.parRate(RSWAP_REC, MULTI_USD); double pvbp = PRICER_SWAP.getLegPricer().pvbp(RSWAP_REC.getLegs(SwapLegType.FIXED).get(0), MULTI_USD); double volatility = NORMAL_VOLS_USD_STD.volatility(SWAPTION_LONG_REC.getExpiry(), SWAP_TENOR_YEAR, STRIKE, forward); NormalFunctionData normalData = NormalFunctionData.of(forward, Math.abs(pvbp), volatility); double expiry = NORMAL_VOLS_USD_STD.relativeTime(SWAPTION_LONG_REC.getExpiry()); EuropeanVanillaOption option = EuropeanVanillaOption.of(STRIKE, expiry, PutCall.PUT); double pvExpected = NORMAL.getPriceFunction(option).apply(normalData); CurrencyAmount pvComputed = PRICER_SWAPTION_NORMAL.presentValue(SWAPTION_LONG_REC, MULTI_USD, NORMAL_VOLS_USD_STD); assertEquals(pvComputed.getCurrency(), USD); assertEquals(pvComputed.getAmount(), pvExpected, TOLERANCE_PV); }
private Object readResolve() { return new NormalSwaptionExpiryTenorVolatilities(convention, valuationDateTime, surface); }
/** * Returns the swaption normal volatility surface shifted by a given amount. The shift is parallel. * @param shift the shift * @return the swaption normal volatility surface */ public static NormalSwaptionExpiryTenorVolatilities normalVolSwaptionProviderUsdStsShifted(double shift) { DoubleArray volShifted = NORMAL_VOL.map(v -> v + shift); return NormalSwaptionExpiryTenorVolatilities.of( USD_1Y_LIBOR3M, VAL_DATE_TIME_STD, SURFACE_STD.withZValues(volShifted)); }
public void present_value_delta_formula() { double forward = PRICER_SWAP.parRate(RSWAP_REC, MULTI_USD); double pvbp = PRICER_SWAP.getLegPricer().pvbp(RSWAP_REC.getLegs(SwapLegType.FIXED).get(0), MULTI_USD); double volatility = NORMAL_VOLS_USD_STD.volatility(SWAPTION_LONG_REC.getExpiry(), SWAP_TENOR_YEAR, STRIKE, forward); NormalFunctionData normalData = NormalFunctionData.of(forward, Math.abs(pvbp), volatility); double expiry = NORMAL_VOLS_USD_STD.relativeTime(SWAPTION_LONG_REC.getExpiry()); EuropeanVanillaOption option = EuropeanVanillaOption.of(STRIKE, expiry, PutCall.PUT); double pvDeltaExpected = NORMAL.getDelta(option, normalData); CurrencyAmount pvDeltaComputed = PRICER_SWAPTION_NORMAL.presentValueDelta(SWAPTION_LONG_REC, MULTI_USD, NORMAL_VOLS_USD_STD); assertEquals(pvDeltaComputed.getCurrency(), USD); assertEquals(pvDeltaComputed.getAmount(), pvDeltaExpected, TOLERANCE_PV); }
/** * Obtains an instance from the implied volatility surface and the date-time for which it is valid. * <p> * The surface is specified by an instance of {@link Surface}, such as {@link InterpolatedNodalSurface}. * The surface must contain the correct metadata: * <ul> * <li>The x-value type must be {@link ValueType#YEAR_FRACTION} * <li>The y-value type must be {@link ValueType#YEAR_FRACTION} * <li>The z-value type must be {@link ValueType#NORMAL_VOLATILITY} * <li>The day count must be set in the additional information using {@link SurfaceInfoType#DAY_COUNT} * </ul> * Suitable surface metadata can be created using * {@link Surfaces#normalVolatilityByExpiryTenor(String, DayCount)}. * * @param convention the swap convention that the volatilities are to be used for * @param valuationDateTime the valuation date-time * @param surface the implied volatility surface * @return the volatilities */ public static NormalSwaptionExpiryTenorVolatilities of( FixedIborSwapConvention convention, ZonedDateTime valuationDateTime, Surface surface) { return new NormalSwaptionExpiryTenorVolatilities(convention, valuationDateTime, surface); }
public void present_value_gamma_formula() { double forward = PRICER_SWAP.parRate(RSWAP_REC, MULTI_USD); double pvbp = PRICER_SWAP.getLegPricer().pvbp(RSWAP_REC.getLegs(SwapLegType.FIXED).get(0), MULTI_USD); double volatility = NORMAL_VOLS_USD_STD.volatility(SWAPTION_LONG_REC.getExpiry(), SWAP_TENOR_YEAR, STRIKE, forward); NormalFunctionData normalData = NormalFunctionData.of(forward, Math.abs(pvbp), volatility); double expiry = NORMAL_VOLS_USD_STD.relativeTime(SWAPTION_LONG_REC.getExpiry()); EuropeanVanillaOption option = EuropeanVanillaOption.of(STRIKE, expiry, PutCall.PUT); double pvGammaExpected = NORMAL.getGamma(option, normalData); CurrencyAmount pvGammaComputed = PRICER_SWAPTION_NORMAL.presentValueGamma(SWAPTION_LONG_REC, MULTI_USD, NORMAL_VOLS_USD_STD); assertEquals(pvGammaComputed.getCurrency(), USD); assertEquals(pvGammaComputed.getAmount(), pvGammaExpected, TOLERANCE_PV); }