/** * Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.interestrate.future.provider; import static org.testng.AssertJUnit.assertEquals; import java.util.Map.Entry; import org.testng.annotations.Test; import org.threeten.bp.ZonedDateTime; import com.opengamma.analytics.financial.instrument.future.BondFuturesDataSets; import com.opengamma.analytics.financial.instrument.future.BondFuturesOptionMarginSecurityDefinition; import com.opengamma.analytics.financial.instrument.future.BondFuturesSecurityDefinition; import com.opengamma.analytics.financial.interestrate.future.derivative.BondFuturesOptionMarginSecurity; import com.opengamma.analytics.financial.interestrate.sensitivity.PresentValueBlackBondFuturesCubeSensitivity; import com.opengamma.analytics.financial.legalentity.LegalEntity; import com.opengamma.analytics.financial.model.option.pricing.analytic.formula.BlackFunctionData; import com.opengamma.analytics.financial.model.option.pricing.analytic.formula.BlackPriceFunction; import com.opengamma.analytics.financial.model.option.pricing.analytic.formula.EuropeanVanillaOption; import com.opengamma.analytics.financial.provider.description.IssuerProviderDiscountDataSets; import com.opengamma.analytics.financial.provider.description.StandardDataSetsBlack; import com.opengamma.analytics.financial.provider.description.interestrate.BlackBondFuturesFlatProviderDiscount; import com.opengamma.analytics.financial.provider.description.interestrate.IssuerProviderDiscount; import com.opengamma.analytics.math.surface.InterpolatedDoublesSurface; import com.opengamma.util.test.TestGroup; import com.opengamma.util.time.DateUtils; import com.opengamma.util.tuple.Triple; /** * Test. */ @Test(groups = TestGroup.UNIT) public class BondFuturesOptionMarginSecurityBlackFlatMethodTest { /** Bond future option: Bobl */ private static final BondFuturesSecurityDefinition BOBLM4_DEFINITION = BondFuturesDataSets.boblM4Definition(); private static final ZonedDateTime REFERENCE_DATE = DateUtils.getUTCDate(2014, 3, 31); private static final double STRIKE_125 = 1.25; private static final ZonedDateTime EXPIRY_DATE_OPT = DateUtils.getUTCDate(2014, 6, 5); private static final ZonedDateTime LAST_TRADING_DATE_OPT = DateUtils.getUTCDate(2014, 6, 4); private static final boolean IS_CALL = true; private static final BondFuturesOptionMarginSecurityDefinition CALL_BOBL_125_DEFINITION = new BondFuturesOptionMarginSecurityDefinition(BOBLM4_DEFINITION, LAST_TRADING_DATE_OPT, EXPIRY_DATE_OPT, STRIKE_125, IS_CALL); private static final BondFuturesOptionMarginSecurity CALL_BOBL_125 = CALL_BOBL_125_DEFINITION.toDerivative(REFERENCE_DATE); /** Black surface expiry/delay */ final private static InterpolatedDoublesSurface BLACK_SURFACE = StandardDataSetsBlack.blackSurfaceExpiryDelay(); /** Curves for a specific issuer name */ private static final IssuerProviderDiscount ISSUER_SPECIFIC_MULTICURVES = IssuerProviderDiscountDataSets.getIssuerSpecificProvider(); /** The legal entity */ private static final LegalEntity[] LEGAL_ENTITIES = IssuerProviderDiscountDataSets.getIssuers(); private static final LegalEntity LEGAL_ENTITY_GERMANY = LEGAL_ENTITIES[2]; /** The Black bond futures provider **/ private static final BlackBondFuturesFlatProviderDiscount BLACK_FLAT_BNDFUT = new BlackBondFuturesFlatProviderDiscount(ISSUER_SPECIFIC_MULTICURVES, BLACK_SURFACE, LEGAL_ENTITY_GERMANY); /** Methods and calculators */ private static final BondFuturesOptionMarginSecurityBlackBondFuturesMethod METHOD_OPT = BondFuturesOptionMarginSecurityBlackBondFuturesMethod.getDefaultInstance(); private static final BondFuturesSecurityDiscountingMethod METHOD_FUTURE = BondFuturesSecurityDiscountingMethod.getInstance(); private static final BlackPriceFunction BLACK_FUNCTION = new BlackPriceFunction(); /** Tolerances */ private static final double TOLERANCE_RATE = 1.0E-10; private static final double TOLERANCE_DELTA = 1.0E-8; public void impliedVolatility() { final double delay = CALL_BOBL_125.getUnderlyingFuture().getNoticeLastTime() - CALL_BOBL_125.getExpirationTime(); final double expiry = CALL_BOBL_125.getExpirationTime(); final double ivExpected = BLACK_SURFACE.getZValue(expiry, delay); final double ivComputed = METHOD_OPT.impliedVolatility(CALL_BOBL_125, BLACK_FLAT_BNDFUT); assertEquals("BondFuturesOptionMarginSecurityBlackFlatMethod: impliedVolatility", ivExpected, ivComputed, TOLERANCE_RATE); } public void futurePrice() { final double priceExpected = METHOD_FUTURE.price(CALL_BOBL_125.getUnderlyingFuture(), ISSUER_SPECIFIC_MULTICURVES); final double priceComputed = METHOD_OPT.underlyingFuturePrice(CALL_BOBL_125, ISSUER_SPECIFIC_MULTICURVES); assertEquals("BondFuturesOptionMarginSecurityBlackFlatMethod: underlying futures price", priceExpected, priceComputed, TOLERANCE_RATE); } public void priceFromFuturesPrice() { final double price = 1.26; final EuropeanVanillaOption option = new EuropeanVanillaOption(STRIKE_125, CALL_BOBL_125.getExpirationTime(), CALL_BOBL_125.isCall()); final double volatility = METHOD_OPT.impliedVolatility(CALL_BOBL_125, BLACK_FLAT_BNDFUT); final BlackFunctionData dataBlack = new BlackFunctionData(price, 1.0, volatility); final double priceExpected = BLACK_FUNCTION.getPriceFunction(option).evaluate(dataBlack); final double priceComputed = METHOD_OPT.price(CALL_BOBL_125, BLACK_FLAT_BNDFUT, price); assertEquals("BondFuturesOptionMarginSecurityBlackFlatMethod: underlying futures price", priceExpected, priceComputed, TOLERANCE_RATE); } public void priceFromCurves() { final double priceFutures = METHOD_FUTURE.price(CALL_BOBL_125.getUnderlyingFuture(), ISSUER_SPECIFIC_MULTICURVES); final double priceExpected = METHOD_OPT.price(CALL_BOBL_125, BLACK_FLAT_BNDFUT, priceFutures); final double priceComputed = METHOD_OPT.price(CALL_BOBL_125, BLACK_FLAT_BNDFUT); assertEquals("BondFuturesOptionMarginSecurityBlackFlatMethod: underlying futures price", priceExpected, priceComputed, TOLERANCE_RATE); } public void priceBlackSensitivity() { final double priceFutures = METHOD_FUTURE.price(CALL_BOBL_125.getUnderlyingFuture(), ISSUER_SPECIFIC_MULTICURVES); final EuropeanVanillaOption option = new EuropeanVanillaOption(STRIKE_125, CALL_BOBL_125.getExpirationTime(), CALL_BOBL_125.isCall()); final double expiry = CALL_BOBL_125.getExpirationTime(); final double delay = CALL_BOBL_125.getUnderlyingFuture().getNoticeLastTime() - CALL_BOBL_125.getExpirationTime(); final double volatility = BLACK_SURFACE.getZValue(expiry, delay); final BlackFunctionData dataBlack = new BlackFunctionData(priceFutures, 1.0, volatility); final double[] priceAD = BLACK_FUNCTION.getPriceAdjoint(option, dataBlack); final double vega = priceAD[2]; final PresentValueBlackBondFuturesCubeSensitivity vegaComputed = METHOD_OPT.priceBlackSensitivity(CALL_BOBL_125, BLACK_FLAT_BNDFUT); assertEquals("BondFuturesOptionMarginSecurityBlackFlatMethod: Black parameters sensitivity", vega, vegaComputed.getSensitivity().toSingleValue(), TOLERANCE_DELTA); assertEquals("BondFuturesOptionMarginSecurityBlackFlatMethod: Black parameters sensitivity", 1, vegaComputed.getSensitivity().getMap().size()); final Entry<Triple<Double, Double, Double>, Double> point = vegaComputed.getSensitivity().getMap().entrySet().iterator().next(); assertEquals("BondFuturesOptionMarginSecurityBlackFlatMethod: Black parameters sensitivity", CALL_BOBL_125.getExpirationTime(), point.getKey().getFirst(), TOLERANCE_RATE); assertEquals("BondFuturesOptionMarginSecurityBlackFlatMethod: Black parameters sensitivity", CALL_BOBL_125.getUnderlyingFuture().getTradingLastTime() - CALL_BOBL_125.getExpirationTime(), point.getKey().getSecond(), TOLERANCE_RATE); assertEquals("BondFuturesOptionMarginSecurityBlackFlatMethod: Black parameters sensitivity", CALL_BOBL_125.getStrike(), point.getKey().getThird(), TOLERANCE_RATE); } }