/** * Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.tutorial.datasets; import java.util.LinkedHashMap; import org.apache.commons.lang.ArrayUtils; import org.threeten.bp.LocalDate; import org.threeten.bp.ZonedDateTime; import com.opengamma.analytics.financial.curve.interestrate.generator.GeneratorCurveYieldInterpolated; import com.opengamma.analytics.financial.curve.interestrate.generator.GeneratorYDCurve; import com.opengamma.analytics.financial.datasets.CalendarGBP; import com.opengamma.analytics.financial.forex.method.FXMatrix; import com.opengamma.analytics.financial.instrument.InstrumentDefinition; import com.opengamma.analytics.financial.instrument.NotionalProvider; import com.opengamma.analytics.financial.instrument.annuity.AdjustedDateParameters; import com.opengamma.analytics.financial.instrument.annuity.AnnuityCouponFixedDefinition; import com.opengamma.analytics.financial.instrument.annuity.AnnuityDefinition; import com.opengamma.analytics.financial.instrument.annuity.CompoundingMethod; import com.opengamma.analytics.financial.instrument.annuity.FixedAnnuityDefinitionBuilder; import com.opengamma.analytics.financial.instrument.annuity.FloatingAnnuityDefinitionBuilder; import com.opengamma.analytics.financial.instrument.annuity.OffsetAdjustedDateParameters; import com.opengamma.analytics.financial.instrument.annuity.OffsetType; import com.opengamma.analytics.financial.instrument.index.GeneratorAttribute; import com.opengamma.analytics.financial.instrument.index.GeneratorInstrument; import com.opengamma.analytics.financial.instrument.index.GeneratorSwapFixedON; import com.opengamma.analytics.financial.instrument.index.GeneratorSwapFixedONMaster; import com.opengamma.analytics.financial.instrument.index.IborIndex; import com.opengamma.analytics.financial.instrument.index.IndexON; import com.opengamma.analytics.financial.instrument.payment.CouponDefinition; import com.opengamma.analytics.financial.instrument.payment.CouponFixedDefinition; import com.opengamma.analytics.financial.instrument.payment.PaymentDefinition; import com.opengamma.analytics.financial.instrument.swap.SwapCouponFixedCouponDefinition; import com.opengamma.analytics.financial.provider.calculator.discounting.ParSpreadMarketQuoteCurveSensitivityDiscountingCalculator; import com.opengamma.analytics.financial.provider.calculator.discounting.ParSpreadMarketQuoteDiscountingCalculator; import com.opengamma.analytics.financial.provider.calculator.generic.LastTimeCalculator; import com.opengamma.analytics.financial.provider.curve.CurveBuildingBlockBundle; import com.opengamma.analytics.financial.provider.curve.CurveCalibrationConventionDataSets; import com.opengamma.analytics.financial.provider.curve.CurveCalibrationTestsUtils; import com.opengamma.analytics.financial.provider.curve.multicurve.MulticurveDiscountBuildingRepository; import com.opengamma.analytics.financial.provider.description.interestrate.MulticurveProviderDiscount; import com.opengamma.analytics.math.interpolation.CombinedInterpolatorExtrapolatorFactory; import com.opengamma.analytics.math.interpolation.Interpolator1D; import com.opengamma.analytics.math.interpolation.Interpolator1DFactory; import com.opengamma.financial.convention.businessday.BusinessDayConventionFactory; import com.opengamma.financial.convention.calendar.Calendar; import com.opengamma.financial.convention.rolldate.RollConvention; import com.opengamma.timeseries.precise.zdt.ImmutableZonedDateTimeDoubleTimeSeries; import com.opengamma.timeseries.precise.zdt.ZonedDateTimeDoubleTimeSeries; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.money.Currency; import com.opengamma.util.time.DateUtils; import com.opengamma.util.tuple.Pair; /** * Curves calibration in GBP: * DSCON-OIS/LIBOR6M-FRAIRS * Recent market data. Standard instruments. */ public class RecentDataSetsMulticurveOisMeetingDatesGbp { private static final Interpolator1D INTERPOLATOR_LINEAR = CombinedInterpolatorExtrapolatorFactory.getInterpolator(Interpolator1DFactory.LINEAR, Interpolator1DFactory.FLAT_EXTRAPOLATOR, Interpolator1DFactory.FLAT_EXTRAPOLATOR); private static final LastTimeCalculator MATURITY_CALCULATOR = LastTimeCalculator.getInstance(); private static final Calendar LON = new CalendarGBP("LON"); private static final Currency GBP = Currency.GBP; private static final FXMatrix FX_MATRIX = new FXMatrix(GBP); private static final double NOTIONAL = 1.0; private static final NotionalProvider NOTIONAL_PROV = new NotionalProvider() { @Override public double getAmount(final LocalDate date) { return NOTIONAL; } }; private static final GeneratorSwapFixedONMaster GENERATOR_OIS_MASTER = GeneratorSwapFixedONMaster.getInstance(); private static final GeneratorSwapFixedON GENERATOR_OIS_GBP = GENERATOR_OIS_MASTER.getGenerator("GBP1YSONIA", LON); private static final IndexON GBPSONIA = GENERATOR_OIS_GBP.getIndex(); private static final AdjustedDateParameters ADJUSTED_DATE_ON = new AdjustedDateParameters(LON, GENERATOR_OIS_GBP.getBusinessDayConvention()); private static final OffsetAdjustedDateParameters OFFSET_FIXING = new OffsetAdjustedDateParameters(0, OffsetType.BUSINESS, LON, BusinessDayConventionFactory.of("Following")); private static final String CURVE_NAME_DSC_GBP = "GBP-DSCON-OIS"; /** Data as of 16-Jul-2014 */ /** Market values for the dsc GBP curve */ private static final double[] DSC_GBP_MARKET_QUOTES = new double[] { 0.0050, 0.00455, 0.00468, 0.004988, 0.006238, 0.006475, 0.00675 }; /** Tenors for the dsc GBP curve */ private static final ZonedDateTime[] DSC_2_GBP_DATES = new ZonedDateTime[] { DateUtils.getUTCDate(2014, 8, 7), DateUtils.getUTCDate(2014, 9, 4), DateUtils.getUTCDate(2014, 10, 9), DateUtils.getUTCDate(2014, 11, 6), DateUtils.getUTCDate(2014, 12, 4), DateUtils.getUTCDate(2015, 1, 8), DateUtils.getUTCDate(2015, 2, 5) }; private static final int NB_DATES = DSC_2_GBP_DATES.length; /** Units of curves */ private static final int NB_UNITS = 1; private static final int NB_BLOCKS = 1; private static final GeneratorYDCurve[][][] GENERATORS_UNITS = new GeneratorYDCurve[NB_BLOCKS][][]; private static final String[][][] NAMES_UNITS = new String[NB_BLOCKS][][]; private static final MulticurveProviderDiscount KNOWN_DATA = new MulticurveProviderDiscount(FX_MATRIX); private static final LinkedHashMap<String, Currency> DSC_MAP = new LinkedHashMap<>(); private static final LinkedHashMap<String, IndexON[]> FWD_ON_MAP = new LinkedHashMap<>(); private static final LinkedHashMap<String, IborIndex[]> FWD_IBOR_MAP = new LinkedHashMap<>(); static { for (int loopblock = 0; loopblock < NB_BLOCKS; loopblock++) { GENERATORS_UNITS[loopblock] = new GeneratorYDCurve[NB_UNITS][]; NAMES_UNITS[loopblock] = new String[NB_UNITS][]; } final GeneratorYDCurve genIntLin = new GeneratorCurveYieldInterpolated(MATURITY_CALCULATOR, INTERPOLATOR_LINEAR); GENERATORS_UNITS[0][0] = new GeneratorYDCurve[] {genIntLin }; NAMES_UNITS[0][0] = new String[] {CURVE_NAME_DSC_GBP }; DSC_MAP.put(CURVE_NAME_DSC_GBP, GBP); FWD_ON_MAP.put(CURVE_NAME_DSC_GBP, new IndexON[] {GBPSONIA }); } @SuppressWarnings({"unchecked", "rawtypes" }) public static InstrumentDefinition<?>[] getDefinitions(final double[] marketQuotes, final GeneratorInstrument[] generators, final GeneratorAttribute[] attribute, final ZonedDateTime referenceDate) { final InstrumentDefinition<?>[] definitions = new InstrumentDefinition<?>[marketQuotes.length]; for (int loopmv = 0; loopmv < marketQuotes.length; loopmv++) { definitions[loopmv] = generators[loopmv].generateInstrument(referenceDate, marketQuotes[loopmv], NOTIONAL, attribute[loopmv]); } return definitions; } /** Calculators */ private static final ParSpreadMarketQuoteDiscountingCalculator PSMQC = ParSpreadMarketQuoteDiscountingCalculator.getInstance(); private static final ParSpreadMarketQuoteCurveSensitivityDiscountingCalculator PSMQCSC = ParSpreadMarketQuoteCurveSensitivityDiscountingCalculator.getInstance(); private static final MulticurveDiscountBuildingRepository CURVE_BUILDING_REPOSITORY = CurveCalibrationConventionDataSets.curveBuildingRepositoryMulticurve(); /** * Calibrate curves with hard-coded date and with calibration date the date provided. The curves are discounting/overnight forward, * Libor3M forward, Libor1M forward and Libor6M forward. * @param calibrationDate The calibration date. * @return The curves and the Jacobian matrices. */ public static Pair<MulticurveProviderDiscount, CurveBuildingBlockBundle> getCurvesGbpOis(ZonedDateTime calibrationDate) { InstrumentDefinition<?>[][][] definitionsUnits = new InstrumentDefinition<?>[NB_UNITS][][]; ZonedDateTime[] dates = new ZonedDateTime[NB_DATES + 1]; dates[0] = calibrationDate; System.arraycopy(DSC_2_GBP_DATES, 0, dates, 1, NB_DATES); InstrumentDefinition<?>[] definitionsDsc = generateDatesOis(dates, DSC_GBP_MARKET_QUOTES); definitionsUnits[0] = new InstrumentDefinition<?>[][] {definitionsDsc }; return CurveCalibrationTestsUtils.makeCurvesFromDefinitionsMulticurve(calibrationDate, definitionsUnits, GENERATORS_UNITS[0], NAMES_UNITS[0], KNOWN_DATA, PSMQC, PSMQCSC, false, DSC_MAP, FWD_ON_MAP, FWD_IBOR_MAP, CURVE_BUILDING_REPOSITORY, TS_FIXED_OIS_GBP_WITH_TODAY, TS_FIXED_OIS_GBP_WITHOUT_TODAY, TS_FIXED_IBOR_GBP6M_WITH_LAST, TS_FIXED_IBOR_GBP6M_WITHOUT_LAST); } /** * Calibrate curves with hard-coded date and with calibration date the date provided. The curves are * discounting/overnight forward, Libor3M forward, Libor1M forward and Libor6M forward. * Adding instruments from standard curve up to next BOE meeting date. * @param calibrationDate The calibration date. * @return The curves and the Jacobian matrices. */ public static Pair<MulticurveProviderDiscount, CurveBuildingBlockBundle> getCurvesGbpOisWithStdInstruments( ZonedDateTime calibrationDate) { InstrumentDefinition<?>[][][] definitionsUnits = new InstrumentDefinition<?>[NB_UNITS][][]; InstrumentDefinition<?>[] definitionsDsc = generateDatesOis(DSC_2_GBP_DATES, ArrayUtils.subarray(DSC_GBP_MARKET_QUOTES, 1, DSC_GBP_MARKET_QUOTES.length)); /// Adding instruments to cover period between calibrationDate and first date of BOE instruments InstrumentDefinition<?>[] definitionsOis = RecentDataSetsMulticurveStandardGbp.getDefinitionForFirstInstruments(calibrationDate, DSC_2_GBP_DATES[0]); InstrumentDefinition<?>[] definitions = (InstrumentDefinition<?>[]) ArrayUtils.addAll(definitionsOis, definitionsDsc); definitionsUnits[0] = new InstrumentDefinition<?>[][] {definitions}; return CurveCalibrationTestsUtils.makeCurvesFromDefinitionsMulticurve(calibrationDate, definitionsUnits, GENERATORS_UNITS[0], NAMES_UNITS[0], KNOWN_DATA, PSMQC, PSMQCSC, false, DSC_MAP, FWD_ON_MAP, FWD_IBOR_MAP, CURVE_BUILDING_REPOSITORY, TS_FIXED_OIS_GBP_WITH_TODAY, TS_FIXED_OIS_GBP_WITHOUT_TODAY, TS_FIXED_IBOR_GBP6M_WITH_LAST, TS_FIXED_IBOR_GBP6M_WITHOUT_LAST); } /** * Returns the array of overnight index used in the curve data set. * @return The array: GBPSONIA */ public static IndexON[] indexONArray() { return new IndexON[] {GBPSONIA }; } /** * Returns the array of calendars used in the curve data set. * @return The array: NYC */ public static Calendar[] calendarArray() { return new Calendar[] {LON }; } /** * Returns an array with one time series corresponding to the GBP SONIA fixing up to and including the last date. * @return */ public static ZonedDateTimeDoubleTimeSeries fixingGbpSoniaWithLast() { return TS_ON_GBP_WITH_TODAY; } /** * Returns an array with one time series corresponding to the GBP SONIA fixing up to and including the last date. * @return */ public static ZonedDateTimeDoubleTimeSeries fixingGbpSoniaWithoutLast() { return TS_ON_GBP_WITHOUT_TODAY; } private static final ZonedDateTimeDoubleTimeSeries TS_EMPTY = ImmutableZonedDateTimeDoubleTimeSeries.ofEmptyUTC(); private static final ZonedDateTimeDoubleTimeSeries TS_ON_GBP_WITH_TODAY = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC( new ZonedDateTime[] {DateUtils.getUTCDate(2014, 7, 1), DateUtils.getUTCDate(2014, 7, 2), DateUtils.getUTCDate(2014, 7, 3), DateUtils.getUTCDate(2014, 7, 4), DateUtils.getUTCDate(2014, 7, 7), DateUtils.getUTCDate(2014, 7, 8), DateUtils.getUTCDate(2014, 7, 9), DateUtils.getUTCDate(2014, 7, 10), DateUtils.getUTCDate(2014, 7, 11), DateUtils.getUTCDate(2014, 7, 14), DateUtils.getUTCDate(2014, 7, 15), DateUtils.getUTCDate(2014, 7, 16), DateUtils.getUTCDate(2014, 7, 17), DateUtils.getUTCDate(2014, 7, 18), DateUtils.getUTCDate(2014, 7, 21), DateUtils.getUTCDate(2014, 7, 22), DateUtils.getUTCDate(2014, 7, 23), DateUtils.getUTCDate(2014, 7, 24), DateUtils.getUTCDate(2014, 7, 25), DateUtils.getUTCDate(2014, 7, 28) }, new double[] {0.002318, 0.002346, 0.002321, 0.002331, 0.002341, 0.002336, 0.002341, 0.002336, 0.002336, 0.002326, 0.002331, 0.002336, 0.002336, 0.002316, 0.002331, 0.002326, 0.002341, 0.002351, 0.002341, 0.002341 }); private static final ZonedDateTimeDoubleTimeSeries TS_ON_GBP_WITHOUT_TODAY = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC( new ZonedDateTime[] {DateUtils.getUTCDate(2014, 7, 1), DateUtils.getUTCDate(2014, 7, 2), DateUtils.getUTCDate(2014, 7, 3), DateUtils.getUTCDate(2014, 7, 4), DateUtils.getUTCDate(2014, 7, 7), DateUtils.getUTCDate(2014, 7, 8), DateUtils.getUTCDate(2014, 7, 9), DateUtils.getUTCDate(2014, 7, 10), DateUtils.getUTCDate(2014, 7, 11), DateUtils.getUTCDate(2014, 7, 14), DateUtils.getUTCDate(2014, 7, 15), DateUtils.getUTCDate(2014, 7, 16), DateUtils.getUTCDate(2014, 7, 17), DateUtils.getUTCDate(2014, 7, 18), DateUtils.getUTCDate(2014, 7, 21), DateUtils.getUTCDate(2014, 7, 22), DateUtils.getUTCDate(2014, 7, 23), DateUtils.getUTCDate(2014, 7, 24), DateUtils.getUTCDate(2014, 7, 25) }, new double[] {0.002318, 0.002346, 0.002321, 0.002331, 0.002341, 0.002336, 0.002341, 0.002336, 0.002336, 0.002326, 0.002331, 0.002336, 0.002336, 0.002316, 0.002331, 0.002326, 0.002341, 0.002351, 0.002341 }); private static final ZonedDateTimeDoubleTimeSeries[] TS_FIXED_OIS_GBP_WITH_TODAY = new ZonedDateTimeDoubleTimeSeries[] {TS_EMPTY, TS_ON_GBP_WITH_TODAY }; private static final ZonedDateTimeDoubleTimeSeries[] TS_FIXED_OIS_GBP_WITHOUT_TODAY = new ZonedDateTimeDoubleTimeSeries[] {TS_EMPTY, TS_ON_GBP_WITHOUT_TODAY }; private static final ZonedDateTimeDoubleTimeSeries TS_IBOR_GBP6M_WITH_LAST = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC( new ZonedDateTime[] {DateUtils.getUTCDate(2014, 7, 1), DateUtils.getUTCDate(2014, 7, 2), DateUtils.getUTCDate(2014, 7, 3), DateUtils.getUTCDate(2014, 7, 4), DateUtils.getUTCDate(2014, 7, 7), DateUtils.getUTCDate(2014, 7, 8), DateUtils.getUTCDate(2014, 7, 9), DateUtils.getUTCDate(2014, 7, 10), DateUtils.getUTCDate(2014, 7, 11), DateUtils.getUTCDate(2014, 7, 14), DateUtils.getUTCDate(2014, 7, 15), DateUtils.getUTCDate(2014, 7, 16), DateUtils.getUTCDate(2014, 7, 17), DateUtils.getUTCDate(2014, 7, 18), DateUtils.getUTCDate(2014, 7, 21), DateUtils.getUTCDate(2014, 7, 22), DateUtils.getUTCDate(2014, 7, 23), DateUtils.getUTCDate(2014, 7, 24), DateUtils.getUTCDate(2014, 7, 25), DateUtils.getUTCDate(2014, 7, 28) }, new double[] {0.002318, 0.002346, 0.002321, 0.002331, 0.002341, 0.002336, 0.002341, 0.002336, 0.002336, 0.002326, 0.002331, 0.002336, 0.002336, 0.002316, 0.002331, 0.002326, 0.002341, 0.002351, 0.002341, 0.002341 }); private static final ZonedDateTimeDoubleTimeSeries TS_IBOR_GBP6M_WITHOUT_LAST = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC( new ZonedDateTime[] {DateUtils.getUTCDate(2014, 7, 1), DateUtils.getUTCDate(2014, 7, 2), DateUtils.getUTCDate(2014, 7, 3), DateUtils.getUTCDate(2014, 7, 4), DateUtils.getUTCDate(2014, 7, 7), DateUtils.getUTCDate(2014, 7, 8), DateUtils.getUTCDate(2014, 7, 9), DateUtils.getUTCDate(2014, 7, 10), DateUtils.getUTCDate(2014, 7, 11), DateUtils.getUTCDate(2014, 7, 14), DateUtils.getUTCDate(2014, 7, 15), DateUtils.getUTCDate(2014, 7, 16), DateUtils.getUTCDate(2014, 7, 17), DateUtils.getUTCDate(2014, 7, 18), DateUtils.getUTCDate(2014, 7, 21), DateUtils.getUTCDate(2014, 7, 22), DateUtils.getUTCDate(2014, 7, 23), DateUtils.getUTCDate(2014, 7, 24), DateUtils.getUTCDate(2014, 7, 25) }, new double[] {0.002318, 0.002346, 0.002321, 0.002331, 0.002341, 0.002336, 0.002341, 0.002336, 0.002336, 0.002326, 0.002331, 0.002336, 0.002336, 0.002316, 0.002331, 0.002326, 0.002341, 0.002351, 0.002341 }); private static final ZonedDateTimeDoubleTimeSeries[] TS_FIXED_IBOR_GBP6M_WITH_LAST = new ZonedDateTimeDoubleTimeSeries[] {TS_IBOR_GBP6M_WITH_LAST }; private static final ZonedDateTimeDoubleTimeSeries[] TS_FIXED_IBOR_GBP6M_WITHOUT_LAST = new ZonedDateTimeDoubleTimeSeries[] {TS_IBOR_GBP6M_WITHOUT_LAST }; private static InstrumentDefinition<?>[] generateDatesOis(ZonedDateTime[] dates, double[] fixedRate) { ArgumentChecker.isTrue(dates.length == fixedRate.length + 1, "dates and rate lengths not compatible"); int nbSwap = dates.length - 1; SwapCouponFixedCouponDefinition[] swap = new SwapCouponFixedCouponDefinition[nbSwap]; for (int loopimm = 0; loopimm < nbSwap; loopimm++) { PaymentDefinition[] cpn = new FixedAnnuityDefinitionBuilder(). payer(true). currency(GBP). notional(NOTIONAL_PROV). startDate(dates[loopimm].toLocalDate()). endDate(dates[loopimm + 1].toLocalDate()). dayCount(GBPSONIA.getDayCount()). accrualPeriodFrequency(GENERATOR_OIS_GBP.getLegsPeriod()). rate(fixedRate[loopimm]). accrualPeriodParameters(ADJUSTED_DATE_ON). build().getPayments(); CouponFixedDefinition[] cpnFixed = new CouponFixedDefinition[cpn.length]; for (int loopcpn = 0; loopcpn < cpn.length; loopcpn++) { cpnFixed[loopcpn] = (CouponFixedDefinition) cpn[loopcpn]; } AnnuityCouponFixedDefinition fixedLegDefinition = new AnnuityCouponFixedDefinition(cpnFixed, LON); AnnuityDefinition<? extends CouponDefinition> onLegDefinition = (AnnuityDefinition<? extends CouponDefinition>) new FloatingAnnuityDefinitionBuilder(). payer(false). notional(NOTIONAL_PROV). startDate(dates[loopimm].toLocalDate()). endDate(dates[loopimm + 1].toLocalDate()). index(GBPSONIA). accrualPeriodFrequency(GENERATOR_OIS_GBP.getLegsPeriod()). rollDateAdjuster(RollConvention.NONE.getRollDateAdjuster(0)). resetDateAdjustmentParameters(ADJUSTED_DATE_ON). accrualPeriodParameters(ADJUSTED_DATE_ON). dayCount(GBPSONIA.getDayCount()). fixingDateAdjustmentParameters(OFFSET_FIXING). currency(GBP). compoundingMethod(CompoundingMethod.FLAT). build(); swap[loopimm] = new SwapCouponFixedCouponDefinition(fixedLegDefinition, onLegDefinition); } return swap; } }