/** * Copyright (C) 2016 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.strata.pricer.capfloor; import static com.opengamma.strata.basics.currency.Currency.EUR; import static com.opengamma.strata.basics.date.DayCounts.ACT_ACT_ISDA; import static com.opengamma.strata.basics.index.IborIndices.EUR_EURIBOR_3M; import static com.opengamma.strata.basics.index.IborIndices.EUR_EURIBOR_6M; import static com.opengamma.strata.market.curve.interpolator.CurveInterpolators.LINEAR; import java.time.LocalDate; import java.time.ZonedDateTime; import com.google.common.collect.ImmutableMap; import com.opengamma.strata.basics.currency.FxMatrix; import com.opengamma.strata.basics.index.IborIndex; import com.opengamma.strata.collect.array.DoubleArray; import com.opengamma.strata.collect.timeseries.LocalDateDoubleTimeSeries; import com.opengamma.strata.market.curve.ConstantCurve; import com.opengamma.strata.market.curve.Curve; import com.opengamma.strata.market.curve.CurveMetadata; import com.opengamma.strata.market.curve.CurveName; import com.opengamma.strata.market.curve.Curves; import com.opengamma.strata.market.curve.InterpolatedNodalCurve; import com.opengamma.strata.market.curve.interpolator.CurveInterpolator; import com.opengamma.strata.market.curve.interpolator.CurveInterpolators; 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.rate.ImmutableRatesProvider; /** * Data set of Ibor caplet/floorlet. */ public class IborCapletFloorletDataSet { // Rates provider private static final CurveInterpolator INTERPOLATOR = CurveInterpolators.LINEAR; private static final DoubleArray DSC_TIME = DoubleArray.of(0.0, 0.5, 1.0, 2.0, 5.0, 10.0); private static final DoubleArray DSC_RATE = DoubleArray.of(0.0150, 0.0125, 0.0150, 0.0175, 0.0150, 0.0150); /** discounting curve name */ public static final CurveName DSC_NAME = CurveName.of("EUR Dsc"); private static final CurveMetadata META_DSC = Curves.zeroRates(DSC_NAME, ACT_ACT_ISDA); private static final InterpolatedNodalCurve DSC_CURVE = InterpolatedNodalCurve.of(META_DSC, DSC_TIME, DSC_RATE, INTERPOLATOR); private static final DoubleArray FWD3_TIME = DoubleArray.of(0.0, 0.5, 1.0, 2.0, 3.0, 4.0, 5.0, 10.0); private static final DoubleArray FWD3_RATE = DoubleArray.of(0.0150, 0.0125, 0.0150, 0.0175, 0.0175, 0.0190, 0.0200, 0.0210); /** Forward curve name */ public static final CurveName FWD3_NAME = CurveName.of("EUR EURIBOR 3M"); private static final CurveMetadata META_FWD3 = Curves.zeroRates(FWD3_NAME, ACT_ACT_ISDA); private static final InterpolatedNodalCurve FWD3_CURVE = InterpolatedNodalCurve.of(META_FWD3, FWD3_TIME, FWD3_RATE, INTERPOLATOR); private static final DoubleArray FWD6_TIME = DoubleArray.of(0.0, 0.5, 1.0, 2.0, 5.0, 10.0); private static final DoubleArray FWD6_RATE = DoubleArray.of(0.0150, 0.0125, 0.0150, 0.0175, 0.0150, 0.0150); /** Forward curve name */ public static final CurveName FWD6_NAME = CurveName.of("EUR EURIBOR 6M"); private static final CurveMetadata META_FWD6 = Curves.zeroRates(FWD6_NAME, ACT_ACT_ISDA); private static final InterpolatedNodalCurve FWD6_CURVE = InterpolatedNodalCurve.of(META_FWD6, FWD6_TIME, FWD6_RATE, INTERPOLATOR); /** * Creates rates provider with specified valuation date. * * @param valuationDate the valuation date * @return the rates provider */ public static ImmutableRatesProvider createRatesProvider(LocalDate valuationDate) { return ImmutableRatesProvider.builder(valuationDate) .discountCurves(ImmutableMap.of(EUR, DSC_CURVE)) .indexCurves(ImmutableMap.of(EUR_EURIBOR_3M, FWD3_CURVE, EUR_EURIBOR_6M, FWD6_CURVE)) .fxRateProvider(FxMatrix.empty()) .build(); } /** * Creates rates provider with specified valuation date and time series of the index. * * @param valuationDate the valuation date * @param index the index * @param timeSeries the time series * @return the rates provider */ public static ImmutableRatesProvider createRatesProvider( LocalDate valuationDate, IborIndex index, LocalDateDoubleTimeSeries timeSeries) { return ImmutableRatesProvider.builder(valuationDate) .discountCurves(ImmutableMap.of(EUR, DSC_CURVE)) .indexCurves(ImmutableMap.of(EUR_EURIBOR_3M, FWD3_CURVE, EUR_EURIBOR_6M, FWD6_CURVE)) .fxRateProvider(FxMatrix.empty()) .timeSeries(index, timeSeries) .build(); } // Black volatilities provider private static final SurfaceInterpolator INTERPOLATOR_2D = GridSurfaceInterpolator.of(LINEAR, LINEAR); private static final DoubleArray EXPIRIES = DoubleArray.of(0.5, 0.5, 0.5, 1.0, 1.0, 1.0, 5.0, 5.0, 5.0); private static final DoubleArray STRIKES = DoubleArray.of(0.01, 0.02, 0.03, 0.01, 0.02, 0.03, 0.01, 0.02, 0.03); private static final DoubleArray BLACK_VOLS = DoubleArray.of(0.35, 0.30, 0.28, 0.34, 0.25, 0.23, 0.25, 0.20, 0.18); private static final SurfaceMetadata BLACK_METADATA = Surfaces.blackVolatilityByExpiryStrike("Black Vol", ACT_ACT_ISDA); private static final Surface BLACK_SURFACE_EXP_STR = InterpolatedNodalSurface.of(BLACK_METADATA, EXPIRIES, STRIKES, BLACK_VOLS, INTERPOLATOR_2D); // Black volatilities provider with shift /** constant shift */ public static final double SHIFT = 5.0e-2; private static final DoubleArray SHIFTED_STRIKES = DoubleArray.of(STRIKES.size(), i -> STRIKES.get(i) + SHIFT); private static final SurfaceMetadata SHIFTED_BLACK_METADATA = Surfaces.blackVolatilityByExpiryStrike("Shifted Black vol", ACT_ACT_ISDA); private static final Surface SHIFTED_BLACK_SURFACE_EXP_STR = InterpolatedNodalSurface.of(SHIFTED_BLACK_METADATA, EXPIRIES, SHIFTED_STRIKES, BLACK_VOLS, INTERPOLATOR_2D); private static final Curve SHIFT_CURVE = ConstantCurve.of("const shift", SHIFT); /** * Creates volatilities provider with specified date and index. * * @param valuationDate the valuation date * @param index the index * @return the volatilities provider */ public static BlackIborCapletFloorletExpiryStrikeVolatilities createBlackVolatilities( ZonedDateTime valuationDate, IborIndex index) { return BlackIborCapletFloorletExpiryStrikeVolatilities.of(index, valuationDate, BLACK_SURFACE_EXP_STR); } /** * Creates shifted Black volatilities provider with specified date and index. * * @param valuationDate the valuation date * @param index the index * @return the volatilities provider */ public static ShiftedBlackIborCapletFloorletExpiryStrikeVolatilities createShiftedBlackVolatilities( ZonedDateTime valuationDate, IborIndex index) { return ShiftedBlackIborCapletFloorletExpiryStrikeVolatilities.of( index, valuationDate, SHIFTED_BLACK_SURFACE_EXP_STR, SHIFT_CURVE); } // Normal volatilities provider private static final DoubleArray NORMAL_VOLS = DoubleArray.of(0.09, 0.08, 0.05, 0.07, 0.05, 0.04, 0.06, 0.05, 0.03); private static final SurfaceMetadata NORMAL_METADATA = Surfaces.normalVolatilityByExpiryStrike("Normal Vol", ACT_ACT_ISDA); private static final Surface NORMAL_SURFACE_EXP_STR = InterpolatedNodalSurface.of(NORMAL_METADATA, EXPIRIES, STRIKES, NORMAL_VOLS, INTERPOLATOR_2D); /** * Creates volatilities provider with specified date and index. * * @param valuationDate the valuation date * @param index the index * @return the volatilities provider */ public static NormalIborCapletFloorletExpiryStrikeVolatilities createNormalVolatilities( ZonedDateTime valuationDate, IborIndex index) { return NormalIborCapletFloorletExpiryStrikeVolatilities.of(index, valuationDate, NORMAL_SURFACE_EXP_STR); } }