package com.opengamma.analytics.financial.interestrate.payments.provider;
import static org.testng.AssertJUnit.assertEquals;
import org.testng.annotations.Test;
import org.threeten.bp.Period;
import org.threeten.bp.ZonedDateTime;
import com.opengamma.analytics.financial.instrument.index.GeneratorDeposit;
import com.opengamma.analytics.financial.instrument.index.GeneratorSwapFixedIbor;
import com.opengamma.analytics.financial.instrument.index.GeneratorSwapFixedIborMaster;
import com.opengamma.analytics.financial.instrument.index.IborIndex;
import com.opengamma.analytics.financial.instrument.index.IndexSwap;
import com.opengamma.analytics.financial.instrument.index.generator.EURDeposit;
import com.opengamma.analytics.financial.instrument.payment.CapFloorCMSSpreadDefinition;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CapFloorCMSSpread;
import com.opengamma.analytics.financial.model.interestrate.TestsDataSetG2pp;
import com.opengamma.analytics.financial.model.interestrate.definition.G2ppPiecewiseConstantParameters;
import com.opengamma.analytics.financial.provider.description.MulticurveProviderDiscountDataSets;
import com.opengamma.analytics.financial.provider.description.interestrate.G2ppProviderDiscount;
import com.opengamma.analytics.financial.provider.description.interestrate.MulticurveProviderDiscount;
import com.opengamma.analytics.financial.schedule.ScheduleCalculator;
import com.opengamma.financial.convention.calendar.Calendar;
import com.opengamma.financial.convention.daycount.DayCount;
import com.opengamma.financial.convention.daycount.DayCounts;
import com.opengamma.util.money.Currency;
import com.opengamma.util.money.MultipleCurrencyAmount;
import com.opengamma.util.test.TestGroup;
import com.opengamma.util.time.DateUtils;
/**
* Test.
*/
@Test(groups = TestGroup.UNIT)
public class CapFloorCMSSpreadG2ppMethodTest {
private static final MulticurveProviderDiscount MULTICURVES = MulticurveProviderDiscountDataSets.createMulticurveEurUsd();
private static final IborIndex EURIBOR3M = MulticurveProviderDiscountDataSets.getIndexesIborMulticurveEurUsd()[0];
private static final Currency EUR = EURIBOR3M.getCurrency();
private static final Calendar CALENDAR = MulticurveProviderDiscountDataSets.getEURCalendar();
private static final G2ppPiecewiseConstantParameters PARAMETERS_G2PP = TestsDataSetG2pp.createG2ppParameters1();
private static final G2ppProviderDiscount G2PP_MULTICURVES = new G2ppProviderDiscount(MULTICURVES, PARAMETERS_G2PP, EUR);
private static final GeneratorSwapFixedIbor EUR1YEURIBOR6M = GeneratorSwapFixedIborMaster.getInstance().getGenerator("EUR1YEURIBOR6M", CALENDAR);
private static final GeneratorDeposit GEN_EUR_DEPOSIT = new EURDeposit(CALENDAR);
private static final IndexSwap SWAP_EUR10Y = new IndexSwap(EUR1YEURIBOR6M, Period.ofYears(10));
private static final IndexSwap SWAP_EUR2Y = new IndexSwap(EUR1YEURIBOR6M, Period.ofYears(2));
private static final ZonedDateTime REFERENCE_DATE = DateUtils.getUTCDate(2008, 8, 18);
private static final ZonedDateTime FIXING_DATE = ScheduleCalculator.getAdjustedDate(REFERENCE_DATE, Period.ofMonths(60), GEN_EUR_DEPOSIT);
// CMS spread coupon
private static final double NOTIONAL = 100000000;
// private static final double BP1 = 1.0E-4; // 1 basis point
private static final ZonedDateTime ACCRUAL_START_DATE = ScheduleCalculator.getAdjustedDate(FIXING_DATE, EUR1YEURIBOR6M.getSpotLag(), CALENDAR);
private static final ZonedDateTime ACCRUAL_END_DATE = ScheduleCalculator.getAdjustedDate(ACCRUAL_START_DATE, Period.ofMonths(6), GEN_EUR_DEPOSIT);
private static final ZonedDateTime PAYMENT_DATE = ACCRUAL_END_DATE;
private static final DayCount PAYMENT_DAY_COUNT = DayCounts.ACT_360;
private static final double PAYMENT_ACCRUAL_FACTOR = PAYMENT_DAY_COUNT.getDayCountFraction(ACCRUAL_START_DATE, ACCRUAL_END_DATE);
private static final double STRIKE = 0.0010; // 10 bps
private static final boolean IS_CAP = true;
private static final CapFloorCMSSpreadDefinition CMS_SPREAD_DEFINITION = CapFloorCMSSpreadDefinition.from(PAYMENT_DATE, ACCRUAL_START_DATE, ACCRUAL_END_DATE, PAYMENT_ACCRUAL_FACTOR, NOTIONAL,
SWAP_EUR10Y, SWAP_EUR2Y, STRIKE, IS_CAP, CALENDAR, CALENDAR);
// Derivatives
private static final CapFloorCMSSpread CMS_SPREAD = (CapFloorCMSSpread) CMS_SPREAD_DEFINITION.toDerivative(REFERENCE_DATE);
// Method and calculators
private static final CapFloorCMSSpreadG2ppNumericalIntegrationMethod METHOD_NI = CapFloorCMSSpreadG2ppNumericalIntegrationMethod.getInstance();
private static final double TOLERANCE_PV = 1.0E-2; // 0.01 currency unit for 100m notional.
@Test
/**
* Tests the present value against a previous run.
*/
public void presentValue() {
final MultipleCurrencyAmount pv = METHOD_NI.presentValue(CMS_SPREAD, G2PP_MULTICURVES);
final double pvPreviousRun = 102469.279; // 5Y - 6M - strike 10bp
assertEquals("CMS spread: G2++ - present value", pvPreviousRun, pv.getAmount(EUR), TOLERANCE_PV);
}
@Test
/**
* Tests the present value by numerical integration vs approximation.
*/
public void presentValueNIntegrationVsApproximation() {
// TODO
// double[] forward = new double[] {PRC.visit(CMS_SPREAD.getUnderlyingSwap1(), CURVES), PRC.visit(CMS_SPREAD.getUnderlyingSwap2(), CURVES)};
// double atm = forward[0] - forward[1];
// double[] shift = new double[] {-0.0100, -0.0050, 0.0, 0.0050, 0.0100};
// double[] pvNI = new double[shift.length];
// double[] pvApprox = new double[shift.length];
// for (int loopstrike = 0; loopstrike < shift.length; loopstrike++) {
// CapFloorCMSSpreadDefinition cmsSpreadDefinition = CapFloorCMSSpreadDefinition.from(PAYMENT_DATE, ACCRUAL_START_DATE, ACCRUAL_END_DATE, PAYMENT_ACCRUAL_FACTOR, NOTIONAL, SWAP_USD10Y, SWAP_USD2Y,
// atm + shift[loopstrike], IS_CAP);
// CapFloorCMSSpread cmsSpread = (CapFloorCMSSpread) cmsSpreadDefinition.toDerivative(REFERENCE_DATE, CURVE_NAMES);
// pvNI[loopstrike] = METHOD_NI.presentValue(cmsSpread, BUNDLE_G2PP).getAmount() / NOTIONAL / BP1;
// pvApprox[loopstrike] = METHOD_APPROX.presentValue(cmsSpread, BUNDLE_G2PP).getAmount() / NOTIONAL / BP1;
// assertEquals("CMS spread: G2++ - present value", pvNI[loopstrike], pvApprox[loopstrike], TOLERANCE_PV_APPROX);
// }
}
}