/**
* 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.LinkedHashMap;
import org.testng.annotations.Test;
import org.threeten.bp.ZonedDateTime;
import com.opengamma.analytics.financial.datasets.CalendarTarget;
import com.opengamma.analytics.financial.instrument.future.InterestRateFutureOptionMarginSecurityDefinition;
import com.opengamma.analytics.financial.instrument.future.InterestRateFutureOptionMarginTransactionDefinition;
import com.opengamma.analytics.financial.instrument.future.InterestRateFutureSecurityDefinition;
import com.opengamma.analytics.financial.instrument.index.IborIndex;
import com.opengamma.analytics.financial.interestrate.datasets.StandardDataSetsMulticurveEUR;
import com.opengamma.analytics.financial.interestrate.future.derivative.InterestRateFutureOptionMarginTransaction;
import com.opengamma.analytics.financial.provider.calculator.blackstirfutures.PresentValueBlackSTIRFutureOptionCalculator;
import com.opengamma.analytics.financial.provider.calculator.blackstirfutures.PresentValueCurveSensitivityBlackSTIRFutureOptionCalculator;
import com.opengamma.analytics.financial.provider.calculator.generic.MarketQuoteSensitivityBlockCalculator;
import com.opengamma.analytics.financial.provider.curve.CurveBuildingBlockBundle;
import com.opengamma.analytics.financial.provider.description.StandardDataSetsBlack;
import com.opengamma.analytics.financial.provider.description.interestrate.BlackSTIRFuturesExpLogMoneynessProviderDiscount;
import com.opengamma.analytics.financial.provider.description.interestrate.BlackSTIRFuturesProviderInterface;
import com.opengamma.analytics.financial.provider.description.interestrate.MulticurveProviderDiscount;
import com.opengamma.analytics.financial.provider.sensitivity.multicurve.MultipleCurrencyParameterSensitivity;
import com.opengamma.analytics.financial.provider.sensitivity.parameter.ParameterSensitivityParameterCalculator;
import com.opengamma.analytics.financial.schedule.ScheduleCalculator;
import com.opengamma.analytics.financial.util.AssertSensitivityObjects;
import com.opengamma.analytics.math.matrix.DoubleMatrix1D;
import com.opengamma.analytics.math.surface.InterpolatedDoublesSurface;
import com.opengamma.financial.convention.calendar.Calendar;
import com.opengamma.util.money.Currency;
import com.opengamma.util.money.MultipleCurrencyAmount;
import com.opengamma.util.test.TestGroup;
import com.opengamma.util.time.DateUtils;
import com.opengamma.util.tuple.ObjectsPair;
import com.opengamma.util.tuple.Pair;
/**
* Tests with hard-coded market data related to options on STIR futures with Black implied volatility
* specified on expiry and log-moneyness dimensions.
*/
@Test(groups = TestGroup.UNIT)
public class STIRFuturesOptionMarginTransactionBlackExpLogMoneynessMethodE2ETest {
/** Data */
private static final IborIndex[] INDEX_IBOR_LIST = StandardDataSetsMulticurveEUR.indexIborArrayEUROisE3();
private static final IborIndex EUREURIBOR3M = INDEX_IBOR_LIST[0];
private static final Calendar CALENDAR = StandardDataSetsMulticurveEUR.calendarArray()[0];
private static final Currency EUR = EUREURIBOR3M.getCurrency();
private static final ZonedDateTime REFERENCE_DATE = DateUtils.getUTCDate(2014, 2, 18);
private static final Pair<MulticurveProviderDiscount, CurveBuildingBlockBundle> MULTICURVE_PAIR =
StandardDataSetsMulticurveEUR.getCurvesEurOisE3();
private static final MulticurveProviderDiscount MULTICURVE = MULTICURVE_PAIR.getFirst();
private static final CurveBuildingBlockBundle BLOCK = MULTICURVE_PAIR.getSecond();
final private static InterpolatedDoublesSurface BLACK_SURFACE_LOGMONEY =
StandardDataSetsBlack.blackSurfaceExpiryLogMoneyness();
final private static BlackSTIRFuturesExpLogMoneynessProviderDiscount MULTICURVE_BLACK =
new BlackSTIRFuturesExpLogMoneynessProviderDiscount(MULTICURVE, BLACK_SURFACE_LOGMONEY, EUREURIBOR3M);
/** Option on STIR futures */
private static final ZonedDateTime LAST_TRADE_DATE = DateUtils.getUTCDate(2014, 12, 15);
private static final double NOTIONAL = 1000000.0; // 1m
private static final double FUTURE_FACTOR = 0.25;
private static final String NAME = "ERZ4";
private static final Calendar TARGET = new CalendarTarget("TARGET");
private static final InterestRateFutureSecurityDefinition ERZ4_DEFINITION =
new InterestRateFutureSecurityDefinition(LAST_TRADE_DATE, EUREURIBOR3M, NOTIONAL, FUTURE_FACTOR, NAME, TARGET);
private static final ZonedDateTime EXPIRY_DATE = DateUtils.getUTCDate(2014, 11, 17);
private static final double STRIKE_099 = 0.99;
private static final boolean IS_CALL = true;
private static final InterestRateFutureOptionMarginSecurityDefinition CALL_ERZ4_099_SEC_DEFINITION =
new InterestRateFutureOptionMarginSecurityDefinition(ERZ4_DEFINITION, EXPIRY_DATE, STRIKE_099, IS_CALL);
private static final InterestRateFutureOptionMarginSecurityDefinition PUT_ERZ4_099_SEC_DEFINITION =
new InterestRateFutureOptionMarginSecurityDefinition(ERZ4_DEFINITION, EXPIRY_DATE, STRIKE_099, !IS_CALL);
private static final int QUANTITY = 123;
private static final ZonedDateTime TRADE_DATE_1 = ScheduleCalculator.getAdjustedDate(REFERENCE_DATE, -1, CALENDAR);
private static final ZonedDateTime TRADE_DATE_2 = REFERENCE_DATE;
private static final double TRADE_PRICE = 0.01;
private static final InterestRateFutureOptionMarginTransactionDefinition CALL_ERZ4_099_TRA_1_DEFINITION =
new InterestRateFutureOptionMarginTransactionDefinition(CALL_ERZ4_099_SEC_DEFINITION,
QUANTITY, TRADE_DATE_1, TRADE_PRICE);
private static final InterestRateFutureOptionMarginTransactionDefinition CALL_ERZ4_099_TRA_2_DEFINITION =
new InterestRateFutureOptionMarginTransactionDefinition(CALL_ERZ4_099_SEC_DEFINITION,
QUANTITY, TRADE_DATE_2, TRADE_PRICE);
private static final InterestRateFutureOptionMarginTransactionDefinition PUT_ERZ4_099_TRA_1_DEFINITION =
new InterestRateFutureOptionMarginTransactionDefinition(PUT_ERZ4_099_SEC_DEFINITION,
QUANTITY, TRADE_DATE_2, TRADE_PRICE);
private static final double REFERENCE_PRICE = 0.02;
private static final InterestRateFutureOptionMarginTransaction CALL_ERZ4_099_TRA_1 =
CALL_ERZ4_099_TRA_1_DEFINITION.toDerivative(REFERENCE_DATE, REFERENCE_PRICE);
private static final InterestRateFutureOptionMarginTransaction CALL_ERZ4_099_TRA_2 =
CALL_ERZ4_099_TRA_2_DEFINITION.toDerivative(REFERENCE_DATE, REFERENCE_PRICE);
private static final InterestRateFutureOptionMarginTransaction PUT_ERZ4_099_TRA_1 =
PUT_ERZ4_099_TRA_1_DEFINITION.toDerivative(REFERENCE_DATE, REFERENCE_PRICE);
/** Methods and calculators */
private static final PresentValueBlackSTIRFutureOptionCalculator PVBFOC =
PresentValueBlackSTIRFutureOptionCalculator.getInstance();
private static final PresentValueCurveSensitivityBlackSTIRFutureOptionCalculator PVCSBFOC =
PresentValueCurveSensitivityBlackSTIRFutureOptionCalculator.getInstance();
private static final ParameterSensitivityParameterCalculator<BlackSTIRFuturesProviderInterface> PSSFC =
new ParameterSensitivityParameterCalculator<>(PVCSBFOC);
private static final MarketQuoteSensitivityBlockCalculator<BlackSTIRFuturesProviderInterface> MQSBC =
new MarketQuoteSensitivityBlockCalculator<>(PSSFC);
/** Tolerances */
private static final double TOLERANCE_PV = 1.0E-4;
private static final double TOLERANCE_PV_DELTA = 1.0E-2;
private static final double BP1 = 1.0E-4;
public void presentValue() {
final MultipleCurrencyAmount pvComputed1 = CALL_ERZ4_099_TRA_1.accept(PVBFOC, MULTICURVE_BLACK);
double pvExpected1 = -390258.6663437139;
assertEquals("STIRFuturesOptionMarginTransactionBlackExpLogMoneynessMethodE2ETest",
pvComputed1.getAmount(EUR), pvExpected1, TOLERANCE_PV);
final MultipleCurrencyAmount pvComputed2 = CALL_ERZ4_099_TRA_2.accept(PVBFOC, MULTICURVE_BLACK);
double pvExpected2 = -82758.66634371383;
assertEquals("STIRFuturesOptionMarginTransactionBlackExpLogMoneynessMethodE2ETest",
pvComputed2.getAmount(EUR), pvExpected2, TOLERANCE_PV);
final MultipleCurrencyAmount pvComputed3 = PUT_ERZ4_099_TRA_1.accept(PVBFOC, MULTICURVE_BLACK);
double pvExpected3 = -307492.22924060293;
assertEquals("STIRFuturesOptionMarginTransactionBlackExpLogMoneynessMethodE2ETest",
pvComputed3.getAmount(EUR), pvExpected3, TOLERANCE_PV);
}
@Test
/**
* Tests bucketed PV01 with a standard set of data against hard-coded values.
*/
public void BucketedPV01() {
final double[] deltaDsc = {-0.0003, -0.0003, 0.0000, 0.0000, -1.7044, -3.0201, -4.5627, 18.5730, 0.9670,
0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 };
final double[] deltaFwd = {2358.4356, 2438.3306, 2437.7080, -9265.1071, -897.3742, 0.0000, 0.0000, 0.0000,
0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000 };
final LinkedHashMap<Pair<String, Currency>, DoubleMatrix1D> sensitivity = new LinkedHashMap<>();
sensitivity.put(ObjectsPair.of(MULTICURVE.getName(EUR), EUR), new DoubleMatrix1D(deltaDsc));
sensitivity.put(ObjectsPair.of(MULTICURVE.getName(EUREURIBOR3M), EUR), new DoubleMatrix1D(deltaFwd));
final MultipleCurrencyParameterSensitivity pvpsExpected = new MultipleCurrencyParameterSensitivity(sensitivity);
final MultipleCurrencyParameterSensitivity pvpsComputed =
MQSBC.fromInstrument(CALL_ERZ4_099_TRA_1, MULTICURVE_BLACK, BLOCK).multipliedBy(BP1);
AssertSensitivityObjects.assertEquals("STIRFuturesOptionMarginTransactionBlackExpLogMoneynessMethodE2ETest:" +
" bucketed delts from standard curves", pvpsExpected, pvpsComputed, TOLERANCE_PV_DELTA);
}
}