/**
* Copyright (C) 2012 - 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.internal.junit.ArrayAsserts.assertArrayEquals;
import org.testng.annotations.Test;
import org.threeten.bp.Period;
import org.threeten.bp.ZonedDateTime;
import com.opengamma.analytics.financial.instrument.bond.BondFixedSecurityDefinition;
import com.opengamma.financial.convention.businessday.BusinessDayConvention;
import com.opengamma.financial.convention.businessday.BusinessDayConventions;
import com.opengamma.financial.convention.calendar.Calendar;
import com.opengamma.financial.convention.calendar.MondayToFridayCalendar;
import com.opengamma.financial.convention.daycount.DayCount;
import com.opengamma.financial.convention.daycount.DayCounts;
import com.opengamma.financial.convention.yield.YieldConvention;
import com.opengamma.financial.convention.yield.YieldConventionFactory;
import com.opengamma.util.money.Currency;
import com.opengamma.util.test.TestGroup;
import com.opengamma.util.time.DateUtils;
/**
* Test.
*/
@Test(groups = TestGroup.UNIT)
public class BondFutureConversionFactorMethodTest {
private static final BondFutureConversionFactorMethod METHOD_CONVERSION = new BondFutureConversionFactorMethod();
// ===== LIFFE Gilt =====
private static final Currency G_CUR = Currency.GBP;
private static final Period G_PAYMENT_TENOR = Period.ofMonths(6);
private static final Calendar G_CALENDAR = new MondayToFridayCalendar("A");
private static final DayCount G_DAY_COUNT = DayCounts.ACT_ACT_ICMA;
private static final BusinessDayConvention G_BUSINESS_DAY = BusinessDayConventions.FOLLOWING;
private static final boolean G_IS_EOM = false;
private static final int G_SETTLEMENT_DAYS = 2;
private static final int G_EX_COUPON = 7;
private static final YieldConvention G_YIELD_CONVENTION = YieldConventionFactory.INSTANCE.getYieldConvention("UK:BUMP/DMO METHOD");
private static final Period[] G_BOND_TENOR = new Period[] {Period.ofYears(4), Period.ofYears(4), Period.ofYears(4)};
private static final ZonedDateTime[] G_START_ACCRUAL_DATE = new ZonedDateTime[] {DateUtils.getUTCDate(2010, 3, 7), DateUtils.getUTCDate(2010, 9, 7), DateUtils.getUTCDate(2011, 1, 22)};
private static final double[] G_RATE = new double[] {0.0225, 0.0500, 0.0275};
private static final int G_NB_BOND = G_BOND_TENOR.length;
private static final ZonedDateTime[] G_MATURITY_DATE = new ZonedDateTime[G_NB_BOND];
private static final BondFixedSecurityDefinition[] G_BASKET_DEFINITION = new BondFixedSecurityDefinition[G_NB_BOND];
static {
for (int loopbasket = 0; loopbasket < G_NB_BOND; loopbasket++) {
G_MATURITY_DATE[loopbasket] = G_START_ACCRUAL_DATE[loopbasket].plus(G_BOND_TENOR[loopbasket]);
G_BASKET_DEFINITION[loopbasket] = BondFixedSecurityDefinition.from(G_CUR, G_MATURITY_DATE[loopbasket], G_START_ACCRUAL_DATE[loopbasket], G_PAYMENT_TENOR, G_RATE[loopbasket], G_SETTLEMENT_DAYS,
1.0, G_EX_COUPON, G_CALENDAR, G_DAY_COUNT, G_BUSINESS_DAY, G_YIELD_CONVENTION, G_IS_EOM, "UK Govt", "UK Govt");
}
}
private static final ZonedDateTime[] G_FIRST_DELIVERY_DATE = new ZonedDateTime[] {DateUtils.getUTCDate(2011, 12, 1), DateUtils.getUTCDate(2012, 3, 1)};
// Note: March contract involves ex-coupon periods.
private static final double TOLERANCE_FACTOR_LIFFE = 1.0E-7;
private static final double TOLERANCE_FACTOR_EURONEXT = 1.0E-6;
@Test
public void conversionFactorLiffe() {
double notionalCoupon = 0.03; // 3% notional coupon on short Gilt as of Dec 11 contract.
double[][] conversionFactorExternal = new double[][] { {0.9836635, 1.0526713, 0.9925377}, {0.9854333, 1.0481364, 0.9931048}}; // Mar12
double[][] conversionFactorComputed = new double[G_FIRST_DELIVERY_DATE.length][G_NB_BOND];
double[][] diff = new double[G_FIRST_DELIVERY_DATE.length][G_NB_BOND];
for (int loopexp = 0; loopexp < G_FIRST_DELIVERY_DATE.length; loopexp++) {
for (int loopbnd = 0; loopbnd < G_NB_BOND; loopbnd++) {
conversionFactorComputed[loopexp][loopbnd] = METHOD_CONVERSION.conversionFactorLiffe(G_BASKET_DEFINITION[loopbnd], G_FIRST_DELIVERY_DATE[loopexp], notionalCoupon);
diff[loopexp][loopbnd] = conversionFactorComputed[loopexp][loopbnd] - conversionFactorExternal[loopexp][loopbnd];
}
assertArrayEquals("Bond futures conversion factor: LIFFE", conversionFactorExternal[loopexp], conversionFactorComputed[loopexp], TOLERANCE_FACTOR_LIFFE);
}
}
// ===== EURONEXT Buxl =====
private static final Currency EUR = Currency.EUR;
private static final Period PAYMENT_TENOR_GER = Period.ofMonths(12);
private static final Calendar TARGET = new MondayToFridayCalendar("TARGET");
private static final DayCount DAY_COUNT_GER = DayCounts.ACT_ACT_ICMA;
private static final BusinessDayConvention BUSINESS_DAY_GER = BusinessDayConventions.FOLLOWING;
private static final boolean IS_EOM_GER = false;
private static final int SETTLEMENT_DAYS_GER = 3;
private static final int EX_COUPON_GER = 0;
private static final YieldConvention YIELD_CONVENTION_GER = YieldConventionFactory.INSTANCE.getYieldConvention("STREET CONVENTION"); //???
private static final ZonedDateTime[] MATURITY_DATE_BUXL = new ZonedDateTime[] {DateUtils.getUTCDate(2037, 1, 4), DateUtils.getUTCDate(2039, 7, 4), DateUtils.getUTCDate(2040, 7, 4),
DateUtils.getUTCDate(2042, 7, 4)};
private static final int NB_BOND_BUXL = MATURITY_DATE_BUXL.length;
private static final ZonedDateTime[] START_ACCURAL_DATE_BUXL = new ZonedDateTime[] {DateUtils.getUTCDate(2005, 1, 4), DateUtils.getUTCDate(2007, 1, 26), DateUtils.getUTCDate(2008, 7, 4),
DateUtils.getUTCDate(2010, 7, 4)};
private static final double[] RATE_BUXL = new double[] {0.04, 0.0425, 0.0475, 0.0325};
private static final BondFixedSecurityDefinition[] BASKET_DEFINITION_BUXL = new BondFixedSecurityDefinition[NB_BOND_BUXL];
static {
for (int loopbasket = 0; loopbasket < NB_BOND_BUXL; loopbasket++) {
BASKET_DEFINITION_BUXL[loopbasket] = BondFixedSecurityDefinition.from(EUR, MATURITY_DATE_BUXL[loopbasket], START_ACCURAL_DATE_BUXL[loopbasket], PAYMENT_TENOR_GER, RATE_BUXL[loopbasket],
SETTLEMENT_DAYS_GER, 1.0, EX_COUPON_GER, TARGET, DAY_COUNT_GER, BUSINESS_DAY_GER, YIELD_CONVENTION_GER, IS_EOM_GER, "GERMANY Govt", "Dsc");
}
}
private static final ZonedDateTime[] FIRST_DELIVERY_DATE_UNADJUSTED_BUXL = new ZonedDateTime[] {DateUtils.getUTCDate(2012, 3, 10), DateUtils.getUTCDate(2012, 6, 10)};
private static final ZonedDateTime[] FIRST_DELIVERY_DATE_BUXL = new ZonedDateTime[] {BUSINESS_DAY_GER.adjustDate(TARGET, FIRST_DELIVERY_DATE_UNADJUSTED_BUXL[0]),
BUSINESS_DAY_GER.adjustDate(TARGET, FIRST_DELIVERY_DATE_UNADJUSTED_BUXL[1])};
@Test
public void conversionFactorEuronext() {
double notionalCoupon = 0.04; // 4% notional coupon on BUXL
double[][] conversionFactorExternal = new double[][] { {0.999882, 1.040908, 1.125532, 0.869471}, {0.999807, 1.040828, 1.125072, 0.870130}}; // Mar12 - Jun12
double[][] conversionFactorComputed = new double[FIRST_DELIVERY_DATE_BUXL.length][NB_BOND_BUXL];
double[][] diff = new double[FIRST_DELIVERY_DATE_BUXL.length][NB_BOND_BUXL];
for (int loopexp = 0; loopexp < FIRST_DELIVERY_DATE_BUXL.length; loopexp++) {
for (int loopbnd = 0; loopbnd < NB_BOND_BUXL; loopbnd++) {
conversionFactorComputed[loopexp][loopbnd] = METHOD_CONVERSION.conversionFactorLiffe(BASKET_DEFINITION_BUXL[loopbnd], FIRST_DELIVERY_DATE_BUXL[loopexp], notionalCoupon);
diff[loopexp][loopbnd] = conversionFactorComputed[loopexp][loopbnd] - conversionFactorExternal[loopexp][loopbnd];
}
assertArrayEquals("Bond futures conversion factor: EURONEXT", conversionFactorExternal[loopexp], conversionFactorComputed[loopexp], TOLERANCE_FACTOR_EURONEXT);
}
}
}