/** * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.instrument.varianceswap; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; import org.testng.annotations.Test; import org.testng.internal.junit.ArrayAsserts; import org.threeten.bp.LocalDate; import org.threeten.bp.ZoneId; import org.threeten.bp.ZonedDateTime; import com.opengamma.AnalyticsTestBase; import com.opengamma.analytics.financial.instrument.cash.CashDefinition; import com.opengamma.analytics.financial.schedule.NoHolidayCalendar; import com.opengamma.analytics.financial.varianceswap.VarianceSwap; import com.opengamma.financial.convention.calendar.Calendar; import com.opengamma.financial.convention.calendar.MondayToFridayCalendar; import com.opengamma.financial.convention.frequency.PeriodFrequency; import com.opengamma.timeseries.date.localdate.ImmutableLocalDateDoubleTimeSeries; import com.opengamma.timeseries.date.localdate.LocalDateDoubleTimeSeries; import com.opengamma.util.money.Currency; import com.opengamma.util.test.TestGroup; /** * Tests the variance swap definition object. */ @Test(groups = TestGroup.UNIT) public class VarianceSwapDefinitionTest extends AnalyticsTestBase { /** The current date */ private static final ZonedDateTime NOW = ZonedDateTime.of(2014, 02, 27, 12, 0, 0, 0, ZoneId.of("UTC")); /** The settlement date */ private static final ZonedDateTime T_PLUS_2 = NOW.plusDays(2); /** The maturity date */ private static final ZonedDateTime PLUS_5Y = NOW.plusYears(5); /** The observation frequency */ private static final PeriodFrequency OBSERVATION_FREQUENCY = PeriodFrequency.DAILY; /** The currency */ private static final Currency CCY = Currency.EUR; /** The calendar */ private static final Calendar WEEKENDCAL = new MondayToFridayCalendar("WEEKEND"); /** The number of observations per year */ private static final double OBS_PER_YEAR = 250; /** The volatility strike */ private static final double VOL_STRIKE = 0.25; /** The volatility notional */ private static final double VOL_NOTIONAL = 1.0E6; /** A variance swap definition */ private static final VarianceSwapDefinition DEFINITION = new VarianceSwapDefinition(T_PLUS_2, PLUS_5Y, PLUS_5Y, CCY, WEEKENDCAL, OBS_PER_YEAR, VOL_STRIKE, VOL_NOTIONAL); /** * @throws Exception If a variance swap definition cannot be created from the inputs */ private VarianceSwapDefinitionTest() throws Exception { super(VarianceSwapDefinition.class, new Object[] {T_PLUS_2, PLUS_5Y, PLUS_5Y, CCY, WEEKENDCAL, OBS_PER_YEAR, VOL_STRIKE, VOL_NOTIONAL }, new Class[] {ZonedDateTime.class, ZonedDateTime.class, ZonedDateTime.class, Currency.class, Calendar.class, double.class, double.class, double.class }, new boolean[] {true, true, true, true, true, false, false, false }); } /** * Tests the getters. */ @Test public void testGetters() { assertEquals(OBS_PER_YEAR, DEFINITION.getAnnualizationFactor()); assertEquals(WEEKENDCAL, DEFINITION.getCalendar()); assertEquals(CCY, DEFINITION.getCurrency()); assertEquals(PLUS_5Y, DEFINITION.getObsEndDate()); assertEquals(1303, DEFINITION.getObsExpected()); assertEquals(T_PLUS_2, DEFINITION.getObsStartDate()); assertEquals(PLUS_5Y, DEFINITION.getSettlementDate()); assertEquals(VOL_NOTIONAL / VOL_STRIKE / 2, DEFINITION.getVarNotional()); assertEquals(VOL_STRIKE * VOL_STRIKE, DEFINITION.getVarStrike()); assertEquals(VOL_NOTIONAL, DEFINITION.getVolNotional()); assertEquals(VOL_STRIKE, DEFINITION.getVolStrike()); } /** * Tests the hashcode and equals methods. */ @Test public void testHashCodeEquals() { VarianceSwapDefinition other = new VarianceSwapDefinition(T_PLUS_2, PLUS_5Y, PLUS_5Y, CCY, WEEKENDCAL, OBS_PER_YEAR, VOL_STRIKE, VOL_NOTIONAL); assertEquals(DEFINITION, DEFINITION); assertEquals(DEFINITION, other); assertEquals(DEFINITION.hashCode(), other.hashCode()); assertFalse(DEFINITION.equals(null)); assertFalse(DEFINITION.equals(new CashDefinition(CCY, NOW, PLUS_5Y, VOL_NOTIONAL, VOL_STRIKE, 5))); other = new VarianceSwapDefinition(T_PLUS_2.plusDays(1), PLUS_5Y, PLUS_5Y, CCY, WEEKENDCAL, OBS_PER_YEAR, VOL_STRIKE, VOL_NOTIONAL); assertFalse(other.equals(DEFINITION)); other = new VarianceSwapDefinition(T_PLUS_2, PLUS_5Y.plusDays(1), PLUS_5Y, CCY, WEEKENDCAL, OBS_PER_YEAR, VOL_STRIKE, VOL_NOTIONAL); assertFalse(other.equals(DEFINITION)); other = new VarianceSwapDefinition(T_PLUS_2, PLUS_5Y, PLUS_5Y.plusDays(1), CCY, WEEKENDCAL, OBS_PER_YEAR, VOL_STRIKE, VOL_NOTIONAL); assertFalse(other.equals(DEFINITION)); other = new VarianceSwapDefinition(T_PLUS_2, PLUS_5Y, PLUS_5Y, Currency.USD, WEEKENDCAL, OBS_PER_YEAR, VOL_STRIKE, VOL_NOTIONAL); assertFalse(other.equals(DEFINITION)); other = new VarianceSwapDefinition(T_PLUS_2, PLUS_5Y, PLUS_5Y, CCY, new NoHolidayCalendar(), OBS_PER_YEAR, VOL_STRIKE, VOL_NOTIONAL); assertFalse(other.equals(DEFINITION)); other = new VarianceSwapDefinition(T_PLUS_2, PLUS_5Y, PLUS_5Y, CCY, WEEKENDCAL, OBS_PER_YEAR + 1, VOL_STRIKE, VOL_NOTIONAL); assertFalse(other.equals(DEFINITION)); other = new VarianceSwapDefinition(T_PLUS_2, PLUS_5Y, PLUS_5Y, CCY, WEEKENDCAL, OBS_PER_YEAR, VOL_STRIKE + 0.01, VOL_NOTIONAL); assertFalse(other.equals(DEFINITION)); other = new VarianceSwapDefinition(T_PLUS_2, PLUS_5Y, PLUS_5Y, CCY, WEEKENDCAL, OBS_PER_YEAR, VOL_STRIKE, VOL_NOTIONAL * 10); assertFalse(other.equals(DEFINITION)); } /** * Tests the static constructors. */ @Test public void testStaticConstruction() { VarianceSwapDefinition definition = VarianceSwapDefinition.fromVegaParams(T_PLUS_2, PLUS_5Y, PLUS_5Y, CCY, WEEKENDCAL, OBS_PER_YEAR, VOL_STRIKE, VOL_NOTIONAL); assertEquals(DEFINITION, definition); definition = VarianceSwapDefinition.fromVarianceParams(T_PLUS_2, PLUS_5Y, PLUS_5Y, CCY, WEEKENDCAL, OBS_PER_YEAR, VOL_STRIKE * VOL_STRIKE, VOL_NOTIONAL / VOL_STRIKE / 2); assertEquals(DEFINITION, definition); } /** * Tests creation of a forward-starting variance swap derivative */ @SuppressWarnings("deprecation") @Test public void testForwardStarting() { final VarianceSwap varianceSwap = DEFINITION.toDerivative(NOW, ImmutableLocalDateDoubleTimeSeries.EMPTY_SERIES); assertEquals(OBS_PER_YEAR, varianceSwap.getAnnualizationFactor()); assertEquals(CCY, varianceSwap.getCurrency()); assertEquals(0, varianceSwap.getObsDisrupted()); ArrayAsserts.assertArrayEquals(new double[0], varianceSwap.getObservations(), 0); ArrayAsserts.assertArrayEquals(new double[0], varianceSwap.getObservationWeights(), 0); assertEquals(1303, varianceSwap.getObsExpected()); assertEquals(5, varianceSwap.getTimeToObsEnd(), 0); assertEquals(2. / 365, varianceSwap.getTimeToObsStart(), 0); assertEquals(5, varianceSwap.getTimeToSettlement(), 0); assertEquals(VOL_NOTIONAL / VOL_STRIKE / 2, varianceSwap.getVarNotional(), 0); assertEquals(VOL_STRIKE * VOL_STRIKE, varianceSwap.getVarStrike()); assertEquals(VOL_NOTIONAL, varianceSwap.getVolNotional()); assertEquals(VOL_STRIKE, varianceSwap.getVolStrike(), 0); assertEquals(varianceSwap, DEFINITION.toDerivative(NOW)); } /** * Tests creation of a seasoned variance swap derivative */ @Test public void testSeasoned() { final VarianceSwapDefinition definition = new VarianceSwapDefinition(NOW, PLUS_5Y, PLUS_5Y, CCY, new NoHolidayCalendar(), OBS_PER_YEAR, VOL_STRIKE, VOL_NOTIONAL); final LocalDate[] dates = new LocalDate[365]; final double[] vars = new double[365]; LocalDate date = NOW.toLocalDate(); for (int i = 0; i < 365; i++) { dates[i] = date; vars[i] = 0.01; date = date.plusDays(1); } final LocalDateDoubleTimeSeries ts = ImmutableLocalDateDoubleTimeSeries.of(dates, vars); final VarianceSwap varianceSwap = definition.toDerivative(NOW.plusYears(1), ts); assertEquals(OBS_PER_YEAR, varianceSwap.getAnnualizationFactor()); assertEquals(CCY, varianceSwap.getCurrency()); assertEquals(0, varianceSwap.getObsDisrupted()); ArrayAsserts.assertArrayEquals(vars, varianceSwap.getObservations(), 0); ArrayAsserts.assertArrayEquals(new double[0], varianceSwap.getObservationWeights(), 0); assertEquals(1827, varianceSwap.getObsExpected()); assertEquals(4, varianceSwap.getTimeToObsEnd(), 0); assertEquals(-1, varianceSwap.getTimeToObsStart(), 0); assertEquals(4, varianceSwap.getTimeToSettlement(), 0); assertEquals(VOL_NOTIONAL / VOL_STRIKE / 2, varianceSwap.getVarNotional(), 0); assertEquals(VOL_STRIKE * VOL_STRIKE, varianceSwap.getVarStrike()); assertEquals(VOL_NOTIONAL, varianceSwap.getVolNotional()); assertEquals(VOL_STRIKE, varianceSwap.getVolStrike(), 0); } }