/** * Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.sesame.bondfuture; import static org.mockito.Mockito.mock; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.threeten.bp.LocalDate; import org.threeten.bp.LocalTime; import org.threeten.bp.OffsetTime; import org.threeten.bp.Period; import org.threeten.bp.ZoneOffset; import org.threeten.bp.ZonedDateTime; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.opengamma.analytics.financial.legalentity.LegalEntity; import com.opengamma.analytics.financial.legalentity.LegalEntityFilter; import com.opengamma.analytics.financial.legalentity.LegalEntityShortName; import com.opengamma.analytics.financial.model.interestrate.curve.YieldAndDiscountCurve; import com.opengamma.analytics.financial.model.interestrate.curve.YieldCurve; import com.opengamma.analytics.financial.model.volatility.surface.VolatilitySurface; import com.opengamma.analytics.financial.provider.curve.CurveBuildingBlockBundle; import com.opengamma.analytics.financial.provider.description.interestrate.IssuerProviderDiscount; import com.opengamma.analytics.financial.provider.description.interestrate.MulticurveProviderDiscount; import com.opengamma.analytics.math.curve.InterpolatedDoublesCurve; import com.opengamma.analytics.math.interpolation.CombinedInterpolatorExtrapolatorFactory; import com.opengamma.analytics.math.interpolation.GridInterpolator2D; import com.opengamma.analytics.math.interpolation.Interpolator1D; import com.opengamma.analytics.math.interpolation.Interpolator1DFactory; import com.opengamma.analytics.math.surface.InterpolatedDoublesSurface; import com.opengamma.core.config.ConfigSource; import com.opengamma.core.convention.ConventionSource; import com.opengamma.core.historicaltimeseries.HistoricalTimeSeriesSource; import com.opengamma.core.holiday.HolidaySource; import com.opengamma.core.holiday.impl.WeekendHolidaySource; import com.opengamma.core.id.ExternalSchemes; import com.opengamma.core.legalentity.LegalEntitySource; import com.opengamma.core.position.Counterparty; import com.opengamma.core.position.impl.SimpleCounterparty; import com.opengamma.core.position.impl.SimpleTrade; import com.opengamma.core.region.RegionSource; import com.opengamma.core.security.SecuritySource; import com.opengamma.financial.analytics.curve.exposure.CurrencyExposureFunction; import com.opengamma.financial.analytics.curve.exposure.ExposureFunctions; import com.opengamma.financial.convention.ConventionBundleMaster; import com.opengamma.financial.convention.ConventionBundleSource; import com.opengamma.financial.convention.DefaultConventionBundleSource; import com.opengamma.financial.convention.InMemoryConventionBundleMaster; import com.opengamma.financial.convention.daycount.DayCount; import com.opengamma.financial.convention.daycount.DayCounts; import com.opengamma.financial.convention.frequency.Frequency; import com.opengamma.financial.convention.frequency.PeriodFrequency; import com.opengamma.financial.convention.yield.YieldConvention; import com.opengamma.financial.convention.yield.YieldConventionFactory; import com.opengamma.financial.currency.CurrencyMatrix; import com.opengamma.financial.security.bond.BondSecurity; import com.opengamma.financial.security.bond.GovernmentBondSecurity; import com.opengamma.financial.security.future.BondFutureDeliverable; import com.opengamma.financial.security.future.BondFutureSecurity; import com.opengamma.financial.security.option.BondFutureOptionSecurity; import com.opengamma.financial.security.option.EuropeanExerciseType; import com.opengamma.financial.security.option.ExerciseType; import com.opengamma.financial.security.option.OptionType; import com.opengamma.id.ExternalId; import com.opengamma.master.region.RegionMaster; import com.opengamma.master.region.impl.InMemoryRegionMaster; import com.opengamma.master.region.impl.MasterRegionSource; import com.opengamma.master.region.impl.RegionFileReader; import com.opengamma.master.security.SecurityDocument; import com.opengamma.master.security.SecurityMaster; import com.opengamma.master.security.impl.InMemorySecurityMaster; import com.opengamma.master.security.impl.MasterSecuritySource; import com.opengamma.sesame.IssuerProviderBundle; import com.opengamma.sesame.marketdata.IssuerMulticurveId; import com.opengamma.sesame.marketdata.MarketDataEnvironment; import com.opengamma.sesame.marketdata.MarketDataEnvironmentBuilder; import com.opengamma.sesame.marketdata.VolatilitySurfaceId; import com.opengamma.sesame.trade.BondFutureOptionTrade; import com.opengamma.sesame.trade.BondFutureTrade; import com.opengamma.util.money.Currency; import com.opengamma.util.time.DateUtils; import com.opengamma.util.time.Expiry; import com.opengamma.util.tuple.Pair; import com.opengamma.util.tuple.Pairs; /** * Test data for bond futures and bond future options */ public class BondFutureTestData { private static ExternalId BOND_ID = ExternalSchemes.isinSecurityId("10Y JGB"); private static ExternalId BOND_FUTURE_ID = ExternalSchemes.isinSecurityId("JBU5"); private static ExternalId BOND_FUTURE_OPTION_ID = ExternalSchemes.isinSecurityId("JBN_146_5"); private static String VOL_ID = "PUT_" + BOND_FUTURE_ID.getValue(); private static String JP_NAME = "JP GOVT"; public static final ZonedDateTime VALUATION_TIME = DateUtils.getUTCDate(2015, 5, 12); public static BondFutureOptionTrade createBondFutureOptionTrade() { Counterparty counterparty = new SimpleCounterparty(ExternalId.of(Counterparty.DEFAULT_SCHEME, "COUNTERPARTY")); BigDecimal tradeQuantity = BigDecimal.valueOf(-100); LocalDate tradeDate = LocalDate.of(2000, 1, 1); OffsetTime tradeTime = OffsetTime.of(LocalTime.of(0, 0), ZoneOffset.UTC); SimpleTrade trade = new SimpleTrade(createBondFutureOptionSecurity(), tradeQuantity, counterparty, tradeDate, tradeTime); trade.setPremium(0.0); trade.setPremiumCurrency(Currency.JPY); return new BondFutureOptionTrade(trade); } private static BondFutureOptionSecurity createBondFutureOptionSecurity() { String tradingExchange = ""; String settlementExchange = ""; Expiry expiry = new Expiry(DateUtils.getUTCDate(2015, 6, 30)); ExerciseType exerciseType = new EuropeanExerciseType(); ExternalId underlyingId = BOND_FUTURE_ID; double pointValue = 1; Currency currency = Currency.JPY; double strike = 1.465; OptionType optionType = OptionType.PUT; boolean margined = false; BondFutureOptionSecurity security = new BondFutureOptionSecurity(tradingExchange, settlementExchange, expiry, exerciseType, underlyingId, pointValue, margined, currency, strike, optionType); security.setExternalIdBundle(BOND_FUTURE_OPTION_ID.toBundle()); return security; } public static BondFutureTrade createBondFutureTrade() { Counterparty counterparty = new SimpleCounterparty(ExternalId.of(Counterparty.DEFAULT_SCHEME, "COUNTERPARTY")); BigDecimal tradeQuantity = BigDecimal.valueOf(1); LocalDate tradeDate = LocalDate.of(2000, 1, 1); OffsetTime tradeTime = OffsetTime.of(LocalTime.of(0, 0), ZoneOffset.UTC); SimpleTrade trade = new SimpleTrade(createBondFutureSecurity(), tradeQuantity, counterparty, tradeDate, tradeTime); trade.setPremium(0.0); trade.setPremiumCurrency(Currency.JPY); return new BondFutureTrade(trade); } private static BondFutureSecurity createBondFutureSecurity() { Currency currency = Currency.JPY; Expiry expiry = new Expiry(DateUtils.getUTCDate(2015, 9, 9)); String tradingExchange = ""; String settlementExchange = ""; double unitAmount = 100_000_000; Collection<BondFutureDeliverable> basket = new ArrayList<>(); BondFutureDeliverable bondFutureDeliverable = new BondFutureDeliverable(BOND_ID.toBundle(), 0.706302); basket.add(bondFutureDeliverable); ZonedDateTime firstDeliveryDate = DateUtils.getUTCDate(2015, 9, 18); ZonedDateTime lastDeliveryDate = DateUtils.getUTCDate(2015, 9, 18); String category = "test"; BondFutureSecurity security = new BondFutureSecurity(expiry, tradingExchange, settlementExchange, currency, unitAmount, basket, firstDeliveryDate, lastDeliveryDate, category); security.setExternalIdBundle(BOND_FUTURE_ID.toBundle()); return security; } private static BondSecurity createGovernmentBondSecurity() { String issuerName = "JP GOVT"; String issuerDomicile = "JP"; String issuerType = "Sovereign"; Currency currency = Currency.JPY; YieldConvention yieldConvention = YieldConventionFactory.INSTANCE.getYieldConvention("STREET CONVENTION"); DayCount dayCountConvention = DayCounts.ACT_ACT_ISDA; Period couponPeriod = Period.parse("P6M"); String couponType = "Fixed"; double couponRate = 0.80; Frequency couponFrequency = PeriodFrequency.of(couponPeriod); ZonedDateTime maturityDate = DateUtils.getUTCDate(2022, 9, 20); ZonedDateTime firstCouponDate = DateUtils.getUTCDate(2013, 3, 20); ZonedDateTime interestAccrualDate = DateUtils.getUTCDate(2012, 9, 20); ZonedDateTime settlementDate = DateUtils.getUTCDate(2022, 9, 20); Expiry lastTradeDate = new Expiry(maturityDate); double issuancePrice = 1.0; double totalAmountIssued = 1.0; double minimumAmount = 1.0; double minimumIncrement = 1.0; double parAmount = 1.0; double redemptionValue = 1.0; GovernmentBondSecurity bond = new GovernmentBondSecurity(issuerName, issuerType, issuerDomicile, issuerType, currency, yieldConvention, lastTradeDate, couponType, couponRate, couponFrequency, dayCountConvention, interestAccrualDate, settlementDate, firstCouponDate, issuancePrice, totalAmountIssued, minimumAmount, minimumIncrement, parAmount, redemptionValue); bond.setExternalIdBundle(BOND_ID.toBundle()); return bond; } public static ExposureFunctions createExposureFunction() { List<String> exposureFunctions = ImmutableList.of(CurrencyExposureFunction.NAME); Map<ExternalId, String> idsToNames = new HashMap<>(); idsToNames.put(ExternalId.of("CurrencyISO", "JPY"), "IssuerMultiCurve"); return new ExposureFunctions("Exposure", exposureFunctions, idsToNames); } public static ImmutableMap<Class<?>, Object> generateBaseComponents() { return generateComponentMap(getRegionSource(), getHolidaySource(), mock(HistoricalTimeSeriesSource.class), getSecuritySource(), mock(ConfigSource.class), mock(ConventionSource.class), getConventionBundleSource(), mock(LegalEntitySource.class), mock(CurrencyMatrix.class)); } private static HolidaySource getHolidaySource() { return new WeekendHolidaySource(); } private static RegionSource getRegionSource() { RegionMaster master = new InMemoryRegionMaster(); RegionFileReader.createPopulated(master); return new MasterRegionSource(master); } private static ConventionBundleSource getConventionBundleSource() { ConventionBundleMaster master = new InMemoryConventionBundleMaster(); return new DefaultConventionBundleSource(master); } private static SecuritySource getSecuritySource() { SecurityMaster master = new InMemorySecurityMaster(); master.add(new SecurityDocument(createGovernmentBondSecurity())); master.add(new SecurityDocument(createBondFutureSecurity())); return new MasterSecuritySource(master); } private static ImmutableMap<Class<?>, Object> generateComponentMap(Object... components) { ImmutableMap.Builder<Class<?>, Object> builder = ImmutableMap.builder(); for (Object component : components) { builder.put(component.getClass().getInterfaces()[0], component); } return builder.build(); } public static MarketDataEnvironment createMarketDataEnvironment() { MarketDataEnvironmentBuilder builder = new MarketDataEnvironmentBuilder(); builder.add(IssuerMulticurveId.of("IssuerMultiCurve"), createIssuerBundle()); builder.add(VolatilitySurfaceId.of(VOL_ID), createVolatilitySurface()); builder.valuationTime(VALUATION_TIME); return builder.build(); } private static IssuerProviderBundle createIssuerBundle() { Map<Pair<Object, LegalEntityFilter<LegalEntity>>, YieldAndDiscountCurve> issuer = new LinkedHashMap<>(); Pair<Object, LegalEntityFilter<LegalEntity>> key = Pairs.<Object, LegalEntityFilter<LegalEntity>>of(JP_NAME, new LegalEntityShortName()); issuer.put(key, createIssuerCurve()); return new IssuerProviderBundle(new IssuerProviderDiscount(createDiscountingCurve(), issuer), new CurveBuildingBlockBundle()); } private static YieldAndDiscountCurve createIssuerCurve() { String name = "JPY-JP-GOVT"; Interpolator1D linearFlat = CombinedInterpolatorExtrapolatorFactory.getInterpolator(Interpolator1DFactory.LINEAR, Interpolator1DFactory.FLAT_EXTRAPOLATOR, Interpolator1DFactory.FLAT_EXTRAPOLATOR); double[] time = {0.5, 1.0, 2.0, 5.0, 7.0, 10.0, 20.0}; double[] zc = {-0.0001, -0.0002, -0.0002, 0.0012, 0.0030, 0.0045, 0.0115}; InterpolatedDoublesCurve curve = new InterpolatedDoublesCurve(time, zc, linearFlat, true, name); return new YieldCurve(name, curve); } private static MulticurveProviderDiscount createDiscountingCurve() { String name = "JPY Discounting"; Interpolator1D linearFlat = CombinedInterpolatorExtrapolatorFactory.getInterpolator(Interpolator1DFactory.LINEAR, Interpolator1DFactory.FLAT_EXTRAPOLATOR, Interpolator1DFactory.FLAT_EXTRAPOLATOR); double[] time = {0.003, 0.25, 0.5, 1.0, 2.0, 5.0, 10.0}; double[] zc = {0.0006, 0.0006, 0.0006, 0.0006, 0.0007, 0.0020, 0.0050}; InterpolatedDoublesCurve curve = new InterpolatedDoublesCurve(time, zc, linearFlat, true, name); MulticurveProviderDiscount multicurve = new MulticurveProviderDiscount(); multicurve.setCurve(Currency.JPY, new YieldCurve(name, curve)); return multicurve; } private static VolatilitySurface createVolatilitySurface() { Interpolator1D linearFlat = CombinedInterpolatorExtrapolatorFactory.getInterpolator(Interpolator1DFactory.LINEAR, Interpolator1DFactory.FLAT_EXTRAPOLATOR, Interpolator1DFactory.FLAT_EXTRAPOLATOR); GridInterpolator2D interpolator2D = new GridInterpolator2D(linearFlat, linearFlat); InterpolatedDoublesSurface surface = InterpolatedDoublesSurface.from( new double[] {19.0/365.0, 19.0/365.0, 19.0/365.0, 19.0/365.0, 49.0/365.0, 49.0/365.0, 49.0/365.0, 49.0/365.0}, new double[] {1.45, 1.46, 1.47, 1.48, 1.45, 1.46, 1.47, 1.48}, new double[] {0.035, 0.032, 0.031, 0.028, 0.0325, 0.0315, 0.0305, 0.0295}, interpolator2D ); return new VolatilitySurface(surface); } }