/** * Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.strata.pricer.swaption; import static com.opengamma.strata.basics.currency.Currency.USD; import static com.opengamma.strata.basics.date.BusinessDayConventions.MODIFIED_FOLLOWING; import static com.opengamma.strata.basics.date.DayCounts.ACT_365F; import static com.opengamma.strata.basics.date.DayCounts.THIRTY_U_360; import static com.opengamma.strata.basics.date.HolidayCalendarIds.USNY; import static com.opengamma.strata.basics.index.IborIndices.USD_LIBOR_3M; import static com.opengamma.strata.market.curve.interpolator.CurveInterpolators.LINEAR; import java.time.LocalDate; import java.time.LocalTime; import java.time.ZoneId; import java.time.ZonedDateTime; import com.opengamma.strata.basics.date.BusinessDayAdjustment; import com.opengamma.strata.basics.schedule.Frequency; import com.opengamma.strata.collect.array.DoubleArray; import com.opengamma.strata.market.surface.InterpolatedNodalSurface; import com.opengamma.strata.market.surface.Surface; import com.opengamma.strata.market.surface.SurfaceMetadata; import com.opengamma.strata.market.surface.Surfaces; import com.opengamma.strata.market.surface.interpolator.GridSurfaceInterpolator; import com.opengamma.strata.market.surface.interpolator.SurfaceInterpolator; import com.opengamma.strata.pricer.datasets.RatesProviderDataSets; import com.opengamma.strata.product.swap.type.FixedIborSwapConvention; import com.opengamma.strata.product.swap.type.FixedRateSwapLegConvention; import com.opengamma.strata.product.swap.type.IborRateSwapLegConvention; import com.opengamma.strata.product.swap.type.ImmutableFixedIborSwapConvention; /** * Black volatility data sets for testing. */ public class SwaptionNormalVolatilityDataSets { private static final double BP1 = 1.0E-4; private static final SurfaceInterpolator INTERPOLATOR_2D = GridSurfaceInterpolator.of(LINEAR, LINEAR); // ===== Standard figures for testing ===== private static final DoubleArray TIMES = DoubleArray.of(0.5, 0.5, 0.5, 0.5, 0.5, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 10, 10, 10, 10, 10); private static final DoubleArray TENORS = DoubleArray.of(1, 2, 5, 10, 30, 1, 2, 5, 10, 30, 1, 2, 5, 10, 30, 1, 2, 5, 10, 30); private static final DoubleArray NORMAL_VOL = DoubleArray.of( 0.010, 0.011, 0.012, 0.013, 0.014, 0.011, 0.012, 0.013, 0.014, 0.015, 0.012, 0.013, 0.014, 0.015, 0.016, 0.013, 0.014, 0.015, 0.016, 0.017); private static final BusinessDayAdjustment MOD_FOL_US = BusinessDayAdjustment.of(MODIFIED_FOLLOWING, USNY); private static final FixedRateSwapLegConvention USD_FIXED_1Y_30U360 = FixedRateSwapLegConvention.of(USD, THIRTY_U_360, Frequency.P6M, MOD_FOL_US); private static final IborRateSwapLegConvention USD_IBOR_LIBOR3M = IborRateSwapLegConvention.of(USD_LIBOR_3M); public static final FixedIborSwapConvention USD_1Y_LIBOR3M = ImmutableFixedIborSwapConvention.of("USD-Swap", USD_FIXED_1Y_30U360, USD_IBOR_LIBOR3M); private static final SurfaceMetadata METADATA = Surfaces.normalVolatilityByExpiryTenor("Normal Vol", ACT_365F); private static final InterpolatedNodalSurface SURFACE_STD = InterpolatedNodalSurface.of(METADATA, TIMES, TENORS, NORMAL_VOL, INTERPOLATOR_2D); private static final LocalDate VAL_DATE_STD = RatesProviderDataSets.VAL_DATE_2014_01_22; private static final LocalTime VAL_TIME_STD = LocalTime.of(13, 45); private static final ZoneId VAL_ZONE_STD = ZoneId.of("Europe/London"); private static final ZonedDateTime VAL_DATE_TIME_STD = VAL_DATE_STD.atTime(VAL_TIME_STD).atZone(VAL_ZONE_STD); public static final NormalSwaptionExpiryTenorVolatilities NORMAL_SWAPTION_VOLS_USD_STD = NormalSwaptionExpiryTenorVolatilities.of(USD_1Y_LIBOR3M, VAL_DATE_TIME_STD, SURFACE_STD); /** * 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 static NormalSwaptionExpiryTenorVolatilities normalVolSwaptionProviderUsdStd(LocalDate valuationDate) { return NormalSwaptionExpiryTenorVolatilities.of( USD_1Y_LIBOR3M, valuationDate.atTime(VAL_TIME_STD).atZone(VAL_ZONE_STD), SURFACE_STD); } // ===== Flat volatilities for testing ===== private static final DoubleArray TIMES_FLAT = DoubleArray.of(0, 0, 100, 100); private static final DoubleArray TENOR_FLAT = DoubleArray.of(0, 30, 0, 30); private static final DoubleArray NORMAL_VOL_FLAT = DoubleArray.of(0.01, 0.01, 0.01, 0.01); private static final InterpolatedNodalSurface SURFACE_FLAT = InterpolatedNodalSurface.of(METADATA, TIMES_FLAT, TENOR_FLAT, NORMAL_VOL_FLAT, INTERPOLATOR_2D); public static final NormalSwaptionExpiryTenorVolatilities NORMAL_SWAPTION_VOLS_USD_FLAT = NormalSwaptionExpiryTenorVolatilities.of(USD_1Y_LIBOR3M, VAL_DATE_TIME_STD, SURFACE_FLAT); // ===== Market data as of 2014-03-20 ===== private static final DoubleArray TIMES_20150320 = DoubleArray.of( 0.25, 0.25, 0.25, 0.25, 0.25, 0.50, 0.50, 0.50, 0.50, 0.50, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0, 2.0, 5.0, 5.0, 5.0, 5.0, 5.0, 10.0, 10.0, 10.0, 10.0, 10.0); private static final DoubleArray TENORS_20150320 = DoubleArray.of( 1.0, 2.0, 5.0, 10.0, 30.0, 1.0, 2.0, 5.0, 10.0, 30.0, 1.0, 2.0, 5.0, 10.0, 30.0, 1.0, 2.0, 5.0, 10.0, 30.0, 1.0, 2.0, 5.0, 10.0, 30.0, 1.0, 2.0, 5.0, 10.0, 30.0); private static final DoubleArray NORMAL_VOL_20150320_BP = DoubleArray.of( 43.6, 65.3, 88, 87.5, 88, // 3M 55.5, 72.2, 90.3, 89.3, 88.6, // 6M 72.6, 82.7, 91.6, 89.8, 87.3, // 1Y 90.4, 91.9, 93.4, 84.7, 93.5, // 2Y 99.3, 96.8, 94.3, 88.6, 77.3, // 5Y 88.4, 85.9, 82.2, 76.7, 65.1); // 10Y private static final DoubleArray NORMAL_VOL_20150320 = NORMAL_VOL_20150320_BP.map(v -> v * BP1); private static final Surface SURFACE_20150320 = InterpolatedNodalSurface.of(METADATA, TIMES_20150320, TENORS_20150320, NORMAL_VOL_20150320, INTERPOLATOR_2D); private static final LocalDate VAL_DATE_20150320 = LocalDate.of(2015, 3, 20); private static final LocalTime VAL_TIME_20150320 = LocalTime.of(18, 00); private static final ZoneId VAL_ZONE_20150320 = ZoneId.of("Europe/London"); public static final NormalSwaptionExpiryTenorVolatilities NORMAL_SWAPTION_VOLS_USD_20150320 = NormalSwaptionExpiryTenorVolatilities.of( USD_1Y_LIBOR3M, VAL_DATE_20150320.atTime(VAL_TIME_20150320).atZone(VAL_ZONE_20150320), SURFACE_20150320); }