/** Tests on the construction of interest rate future option with up-front payment. */ public class InterestRateFutureOptionMarginSecurityTest { // EURIBOR 3M Index private static final Period TENOR = Period.ofMonths(3); private static final int SETTLEMENT_DAYS = 2; private static final Calendar CALENDAR = new MondayToFridayCalendar("A"); private static final DayCount DAY_COUNT_INDEX = DayCountFactory.INSTANCE.getDayCount("Actual/360"); private static final BusinessDayConvention BUSINESS_DAY = BusinessDayConventionFactory.INSTANCE.getBusinessDayConvention("Modified Following"); private static final boolean IS_EOM = true; private static final Currency CUR = Currency.EUR; private static final IborIndex IBOR_INDEX = new IborIndex(CUR, TENOR, SETTLEMENT_DAYS, DAY_COUNT_INDEX, BUSINESS_DAY, IS_EOM); // Future private static final ZonedDateTime SPOT_LAST_TRADING_DATE = DateUtils.getUTCDate(2012, 9, 19); private static final ZonedDateTime LAST_TRADING_DATE = ScheduleCalculator.getAdjustedDate(SPOT_LAST_TRADING_DATE, -SETTLEMENT_DAYS, CALENDAR); private static final double NOTIONAL = 1000000.0; // 1m private static final double FUTURE_FACTOR = 0.25; private static final String NAME = "EDU2"; private static final double STRIKE = 0.9850; private static final InterestRateFutureSecurityDefinition EDU2_DEFINITION = new InterestRateFutureSecurityDefinition( LAST_TRADING_DATE, IBOR_INDEX, NOTIONAL, FUTURE_FACTOR, NAME, CALENDAR); private static final ZonedDateTime REFERENCE_DATE = DateUtils.getUTCDate(2010, 8, 18); private static final String DISCOUNTING_CURVE_NAME = "Funding"; private static final String FORWARD_CURVE_NAME = "Forward"; private static final String[] CURVES = {DISCOUNTING_CURVE_NAME, FORWARD_CURVE_NAME}; private static final InterestRateFutureSecurity EDU2 = EDU2_DEFINITION.toDerivative(REFERENCE_DATE, CURVES); // Option private static final ZonedDateTime EXPIRATION_DATE = DateUtils.getUTCDate(2011, 9, 16); private static final DayCount ACT_ACT = DayCountFactory.INSTANCE.getDayCount("Actual/Actual ISDA"); private static final double EXPIRATION_TIME = ACT_ACT.getDayCountFraction(REFERENCE_DATE, EXPIRATION_DATE); private static final boolean IS_CALL = true; private static final InterestRateFutureOptionPremiumSecurity OPTION_EDU2 = new InterestRateFutureOptionPremiumSecurity(EDU2, EXPIRATION_TIME, STRIKE, IS_CALL); @Test(expectedExceptions = IllegalArgumentException.class) public void testNullUnderlying() { new InterestRateFutureOptionPremiumSecurity(null, EXPIRATION_TIME, STRIKE, IS_CALL); } @Test public void getter() { assertEquals(EDU2, OPTION_EDU2.getUnderlyingFuture()); assertEquals(EXPIRATION_TIME, OPTION_EDU2.getExpirationTime()); assertEquals(STRIKE, OPTION_EDU2.getStrike()); assertEquals(IS_CALL, OPTION_EDU2.isCall()); assertEquals(DISCOUNTING_CURVE_NAME, OPTION_EDU2.getDiscountingCurveName()); assertEquals(FORWARD_CURVE_NAME, OPTION_EDU2.getForwardCurveName()); } @Test /** Tests the equal and hash code methods. */ public void equalHash() { final InterestRateFutureOptionPremiumSecurity newOption = new InterestRateFutureOptionPremiumSecurity(EDU2, EXPIRATION_TIME, STRIKE, IS_CALL); assertTrue(OPTION_EDU2.equals(newOption)); assertEquals(OPTION_EDU2.hashCode(), newOption.hashCode()); InterestRateFutureOptionPremiumSecurity modifiedOption; modifiedOption = new InterestRateFutureOptionPremiumSecurity(EDU2, EXPIRATION_TIME - 0.01, STRIKE, IS_CALL); assertFalse(OPTION_EDU2.equals(modifiedOption)); modifiedOption = new InterestRateFutureOptionPremiumSecurity(EDU2, EXPIRATION_TIME, STRIKE + 0.01, IS_CALL); assertFalse(OPTION_EDU2.equals(modifiedOption)); modifiedOption = new InterestRateFutureOptionPremiumSecurity(EDU2, EXPIRATION_TIME, STRIKE, !IS_CALL); assertFalse(OPTION_EDU2.equals(modifiedOption)); } }
/** * Tests for the methods related to interest rate securities pricing with Hull-White model convexity * adjustment. */ @Test(groups = TestGroup.UNIT) public class InterestRateFutureSecurityHullWhiteMethodTest { private static final MulticurveProviderDiscount MULTICURVES = MulticurveProviderDiscountDataSets.createMulticurveEurUsd(); private static final IborIndex[] INDEX_LIST = MulticurveProviderDiscountDataSets.getIndexesIborMulticurveEurUsd(); private static final IborIndex EURIBOR3M = INDEX_LIST[0]; private static final Currency EUR = EURIBOR3M.getCurrency(); private static final Calendar CALENDAR = MulticurveProviderDiscountDataSets.getEURCalendar(); // Future private static final ZonedDateTime SPOT_LAST_TRADING_DATE = DateUtils.getUTCDate(2012, 9, 19); private static final ZonedDateTime LAST_TRADING_DATE = ScheduleCalculator.getAdjustedDate(SPOT_LAST_TRADING_DATE, -EURIBOR3M.getSpotLag(), CALENDAR); private static final double NOTIONAL = 1000000.0; // 1m private static final double FUTURE_FACTOR = 0.25; private static final String NAME = "ERU2"; private static final ZonedDateTime REFERENCE_DATE = DateUtils.getUTCDate(2011, 5, 12); private static final InterestRateFutureSecurityDefinition ERU2_DEFINITION = new InterestRateFutureSecurityDefinition( LAST_TRADING_DATE, EURIBOR3M, NOTIONAL, FUTURE_FACTOR, NAME, CALENDAR); private static final InterestRateFutureSecurity ERU2 = ERU2_DEFINITION.toDerivative(REFERENCE_DATE); private static final double MEAN_REVERSION = 0.01; private static final double[] VOLATILITY = new double[] {0.01, 0.011, 0.012, 0.013, 0.014}; private static final double[] VOLATILITY_TIME = new double[] {0.5, 1.0, 2.0, 5.0}; private static final HullWhiteOneFactorPiecewiseConstantParameters MODEL_PARAMETERS = new HullWhiteOneFactorPiecewiseConstantParameters( MEAN_REVERSION, VOLATILITY, VOLATILITY_TIME); private static final HullWhiteOneFactorProviderDiscount HW_MULTICURVES = new HullWhiteOneFactorProviderDiscount(MULTICURVES, MODEL_PARAMETERS, EUR); private static final HullWhiteOneFactorPiecewiseConstantInterestRateModel MODEL = new HullWhiteOneFactorPiecewiseConstantInterestRateModel(); private static final InterestRateFutureSecurityHullWhiteMethod METHOD_IRFUT_HW = InterestRateFutureSecurityHullWhiteMethod.getInstance(); private static final MarketQuoteHullWhiteCalculator MQHWC = MarketQuoteHullWhiteCalculator.getInstance(); private static final MarketQuoteCurveSensitivityHullWhiteCalculator MQCSHWC = MarketQuoteCurveSensitivityHullWhiteCalculator.getInstance(); private static final ConvexityAdjustmentHullWhiteCalculator CAHWC = ConvexityAdjustmentHullWhiteCalculator.getInstance(); private static final ParRateHullWhiteCalculator PRHWC = ParRateHullWhiteCalculator.getInstance(); private static final double SHIFT_FD = 1.0E-6; private static final SimpleParameterSensitivityParameterCalculator< HullWhiteOneFactorProviderInterface> SPSHWC = new SimpleParameterSensitivityParameterCalculator<>(MQCSHWC); private static final SimpleParameterSensitivityHullWhiteDiscountInterpolatedFDCalculator SPSHWC_FD = new SimpleParameterSensitivityHullWhiteDiscountInterpolatedFDCalculator(MQHWC, SHIFT_FD); private static final double TOLERANCE_PRICE = 1.0E-10; private static final double TOLERANCE_PRICE_DELTA = 1.0E-8; @Test /** Test the price computed from the curves and HW parameters. */ public void price() { final double price = METHOD_IRFUT_HW.price(ERU2, HW_MULTICURVES); final double forward = MULTICURVES.getSimplyCompoundForwardRate( EURIBOR3M, ERU2.getFixingPeriodStartTime(), ERU2.getFixingPeriodEndTime(), ERU2.getFixingPeriodAccrualFactor()); final double factor = MODEL.futuresConvexityFactor( MODEL_PARAMETERS, ERU2.getTradingLastTime(), ERU2.getFixingPeriodStartTime(), ERU2.getFixingPeriodEndTime()); final double expectedPrice = 1.0 - factor * forward + (1 - factor) / ERU2.getFixingPeriodAccrualFactor(); assertEquals( "InterestRateFutureSecurityHullWhiteProviderMethod: price", expectedPrice, price, TOLERANCE_PRICE); } @Test /** Test the par rate computed from the curves and HW parameters. Par rate = 1-price. */ public void parRate() { final double price = METHOD_IRFUT_HW.price(ERU2, HW_MULTICURVES); final double parRateExpected = 1.0d - price; final double parRateComputed = METHOD_IRFUT_HW.parRate(ERU2, HW_MULTICURVES); assertEquals( "InterestRateFutureSecurityHullWhiteProviderMethod: parRate", parRateExpected, parRateComputed, TOLERANCE_PRICE); } @Test /** Test the par rate computed from the method and the calculator. */ public void parRateMethodVsCalculator() { final double parRateMethod = METHOD_IRFUT_HW.parRate(ERU2, HW_MULTICURVES); final double parRateCalculator = ERU2.accept(PRHWC, HW_MULTICURVES); assertEquals( "InterestRateFutureSecurityHullWhiteProviderMethod: parRate", parRateMethod, parRateCalculator, TOLERANCE_PRICE); } @Test /** Test the price as "MarketQuote" */ public void marketQuote() { final double priceMethod = METHOD_IRFUT_HW.price(ERU2, HW_MULTICURVES); final double marketQuote = ERU2.accept(MQHWC, HW_MULTICURVES); assertEquals( "InterestRateFutureSecurityHullWhiteProviderMethod: price", priceMethod, marketQuote, TOLERANCE_PRICE); } @Test /** Test the convexity adjustment */ public void convexityAdjustment() { final double price = METHOD_IRFUT_HW.price(ERU2, HW_MULTICURVES); final double forward = MULTICURVES.getSimplyCompoundForwardRate( EURIBOR3M, ERU2.getFixingPeriodStartTime(), ERU2.getFixingPeriodEndTime(), ERU2.getFixingPeriodAccrualFactor()); final double convexityAdjustment = METHOD_IRFUT_HW.convexityAdjustment(ERU2, HW_MULTICURVES); assertEquals( "InterestRateFutureSecurityHullWhiteProviderMethod: convexity adjustment", price - (1.0d - forward), convexityAdjustment, TOLERANCE_PRICE); final double caCalculator = ERU2.accept(CAHWC, HW_MULTICURVES); assertEquals( "DeliverableSwapFuturesSecurityDefinition: convexity adjustment", caCalculator, convexityAdjustment, TOLERANCE_PRICE); } @Test /** Test the price curve sensitivity versus a finite difference computation. */ public void priceCurveSensitivity() { final SimpleParameterSensitivity pcsExact = SPSHWC.calculateSensitivity(ERU2, HW_MULTICURVES, MULTICURVES.getAllNames()); final SimpleParameterSensitivity pcsFD = SPSHWC_FD.calculateSensitivity(ERU2, HW_MULTICURVES); AssertSensitivityObjects.assertEquals( "DeliverableSwapFuturesSecurityHullWhiteMethod: priceCurveSensitivity", pcsExact, pcsFD, TOLERANCE_PRICE_DELTA); } }