/**
* Copyright (C) 2015 - 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 org.testng.annotations.Test;
import org.threeten.bp.Period;
import org.threeten.bp.ZoneId;
import org.threeten.bp.ZonedDateTime;
import com.opengamma.analytics.financial.instrument.bond.BondFixedSecurityDefinition;
import com.opengamma.analytics.financial.instrument.future.BondFuturesSecurityDefinition;
import com.opengamma.analytics.financial.instrument.future.BondFuturesTransactionDefinition;
import com.opengamma.analytics.financial.interestrate.bond.definition.BondFixedSecurity;
import com.opengamma.analytics.financial.interestrate.bond.provider.BondSecurityDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.future.calculator.FuturesPriceIssuerCalculator;
import com.opengamma.analytics.financial.interestrate.future.derivative.BondFuturesSecurity;
import com.opengamma.analytics.financial.interestrate.future.derivative.BondFuturesTransaction;
import com.opengamma.analytics.financial.legalentity.LegalEntity;
import com.opengamma.analytics.financial.legalentity.LegalEntityFilter;
import com.opengamma.analytics.financial.legalentity.LegalEntityShortName;
import com.opengamma.analytics.financial.legalentity.Region;
import com.opengamma.analytics.financial.legalentity.Sector;
import com.opengamma.analytics.financial.model.interestrate.curve.YieldPeriodicCurve;
import com.opengamma.analytics.financial.provider.calculator.discounting.PV01CurveParametersCalculator;
import com.opengamma.analytics.financial.provider.calculator.issuer.CleanPriceFromCurvesCalculator;
import com.opengamma.analytics.financial.provider.calculator.issuer.PresentValueCurveSensitivityIssuerCalculator;
import com.opengamma.analytics.financial.provider.calculator.issuer.PresentValueIssuerCalculator;
import com.opengamma.analytics.financial.provider.description.interestrate.IssuerProviderDiscount;
import com.opengamma.analytics.financial.provider.description.interestrate.IssuerProviderIssuerDecoratedSpreadPeriodic;
import com.opengamma.analytics.financial.provider.description.interestrate.ParameterIssuerProviderInterface;
import com.opengamma.analytics.financial.provider.sensitivity.parameter.ParameterSensitivityParameterCalculator;
import com.opengamma.analytics.math.curve.ConstantDoublesCurve;
import com.opengamma.analytics.math.curve.InterpolatedDoublesCurve;
import com.opengamma.analytics.math.interpolation.CombinedInterpolatorExtrapolatorFactory;
import com.opengamma.analytics.math.interpolation.Interpolator1D;
import com.opengamma.analytics.math.interpolation.Interpolator1DFactory;
import com.opengamma.analytics.math.matrix.DoubleMatrix1D;
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.daycount.DayCount;
import com.opengamma.financial.convention.daycount.DayCounts;
import com.opengamma.financial.convention.yield.SimpleYieldConvention;
import com.opengamma.financial.convention.yield.YieldConvention;
import com.opengamma.util.i18n.Country;
import com.opengamma.util.money.Currency;
import com.opengamma.util.money.MultipleCurrencyAmount;
import com.opengamma.util.test.TestGroup;
import com.opengamma.util.tuple.Pairs;
/**
*
*/
@Test(groups = TestGroup.UNIT)
public class BondFuturesTransactionAnnuallyCompoundingE2ETest {
private static final BondAndSTIRFuturesE2EExamplesData DATA = new BondAndSTIRFuturesE2EExamplesData();
private static final Calendar EUR_CALENDAR = DATA.getEURCalendar();
private static final Calendar GBP_CALENDAR = DATA.getGBPCalendar();
private static final Currency EUR = Currency.EUR;
private static final Currency GBP = Currency.GBP;
private static final ZonedDateTime VALUATION_DATE = ZonedDateTime.of(2014, 2, 17, 9, 0, 0, 0, ZoneId.of("Z"));
/* names */
private static final String ISSUER_NAME_LGT = "LGT GBP";
private static final String ISSUER_NAME_SCH = "SCH EUR";
private static final String ISSUER_NAME_BUN = "BUN EUR";
private static final String ISSUER_NAME_BOB = "BOB EUR";
private static final String CURVE_NAME_LGT = "LGT GBPBond";
private static final String CURVE_NAME_SCH = "SCH EURBond";
private static final String CURVE_NAME_BUN = "BUN EURBond";
private static final String CURVE_NAME_BOB = "BOB EURBond";
/* issuer curves */
private static final Interpolator1D INTERPOLATOR = CombinedInterpolatorExtrapolatorFactory.getInterpolator(
Interpolator1DFactory.LINEAR, Interpolator1DFactory.FLAT_EXTRAPOLATOR, Interpolator1DFactory.LINEAR_EXTRAPOLATOR);
private static final int NUM_PERIODS = 1;
private static final IssuerProviderDiscount ISSUER_PROVIDER_LGT = new IssuerProviderDiscount();
static {
InterpolatedDoublesCurve interpolatedCurve = InterpolatedDoublesCurve.fromSorted(DATA.getTimeLGT(),
DATA.getRateLGT(), INTERPOLATOR, CURVE_NAME_LGT);
YieldPeriodicCurve yieldCurve = YieldPeriodicCurve.from(NUM_PERIODS, interpolatedCurve);
LegalEntityFilter<LegalEntity> filter = new LegalEntityShortName();
ISSUER_PROVIDER_LGT.setCurve(Pairs.of((Object) ISSUER_NAME_LGT, filter), yieldCurve);
ConstantDoublesCurve constantDoublesCurve = ConstantDoublesCurve.from(DATA.getRepoLGT());
YieldPeriodicCurve repoCurve = YieldPeriodicCurve.from(NUM_PERIODS, constantDoublesCurve);
ISSUER_PROVIDER_LGT.setCurve(GBP, repoCurve);
}
private static final IssuerProviderDiscount ISSUER_PROVIDER_SCH = new IssuerProviderDiscount();
static {
InterpolatedDoublesCurve interpolatedCurve = InterpolatedDoublesCurve.fromSorted(DATA.getTimeGER(),
DATA.getRateGER(), INTERPOLATOR, CURVE_NAME_SCH);
YieldPeriodicCurve yieldCurve = YieldPeriodicCurve.from(NUM_PERIODS, interpolatedCurve);
LegalEntityFilter<LegalEntity> filter = new LegalEntityShortName();
ISSUER_PROVIDER_SCH.setCurve(Pairs.of((Object) ISSUER_NAME_SCH, filter), yieldCurve);
ConstantDoublesCurve constantDoublesCurve = ConstantDoublesCurve.from(DATA.getRepoSCH());
YieldPeriodicCurve repoCurve = YieldPeriodicCurve.from(NUM_PERIODS, constantDoublesCurve);
ISSUER_PROVIDER_SCH.setCurve(EUR, repoCurve);
}
private static final IssuerProviderDiscount ISSUER_PROVIDER_BUN = new IssuerProviderDiscount();
static {
InterpolatedDoublesCurve interpolatedCurve = InterpolatedDoublesCurve.fromSorted(DATA.getTimeGER(),
DATA.getRateGER(), INTERPOLATOR, CURVE_NAME_BUN);
YieldPeriodicCurve yieldCurve = YieldPeriodicCurve.from(NUM_PERIODS, interpolatedCurve);
LegalEntityFilter<LegalEntity> filter = new LegalEntityShortName();
ISSUER_PROVIDER_BUN.setCurve(Pairs.of((Object) ISSUER_NAME_BUN, filter), yieldCurve);
ConstantDoublesCurve constantDoublesCurve = ConstantDoublesCurve.from(DATA.getRepoBUN());
YieldPeriodicCurve repoCurve = YieldPeriodicCurve.from(NUM_PERIODS, constantDoublesCurve);
ISSUER_PROVIDER_BUN.setCurve(EUR, repoCurve);
}
private static final IssuerProviderDiscount ISSUER_PROVIDER_BOB = new IssuerProviderDiscount();
static {
InterpolatedDoublesCurve interpolatedCurve = InterpolatedDoublesCurve.fromSorted(DATA.getTimeGER(),
DATA.getRateGER(), INTERPOLATOR, CURVE_NAME_BOB);
YieldPeriodicCurve yieldCurve = YieldPeriodicCurve.from(NUM_PERIODS, interpolatedCurve);
LegalEntityFilter<LegalEntity> filter = new LegalEntityShortName();
ISSUER_PROVIDER_BOB.setCurve(Pairs.of((Object) ISSUER_NAME_BOB, filter), yieldCurve);
ConstantDoublesCurve constantDoublesCurve = ConstantDoublesCurve.from(DATA.getRepoBOB());
YieldPeriodicCurve repoCurve = YieldPeriodicCurve.from(NUM_PERIODS, constantDoublesCurve);
ISSUER_PROVIDER_BOB.setCurve(EUR, repoCurve);
}
/* Common setting */
private static final int QUANTITY = 1;
private static final double NOTIONAL = 1000.0;
private static final BusinessDayConvention BUSINESS_DAY = BusinessDayConventions.FOLLOWING;
private static final DayCount DAY_COUNT = DayCounts.ACT_ACT_ICMA;
private static ZonedDateTime TRADE_DATE = ZonedDateTime.of(2008, 8, 27, 1, 0, 0, 0, ZoneId.of("Z")); // 2008-08-27T01:00Z
private static final double TRADE_PRICE = 0.0;
private static final double LAST_MARGIN_PRICE = 0.0;
/* Long Gilt bond futures */
private static final BondFuturesTransaction TRANSACTION_LGT;
private static final double BOND_MARKET_PRICE_LGT = 120.0325;
static {
ZonedDateTime tradingLastDate = ZonedDateTime.of(2014, 3, 31, 23, 59, 0, 0, ZoneId.of("Z")); // 2014-03-31T23:59Z
ZonedDateTime noticeFirstDate = ZonedDateTime.of(2014, 3, 31, 23, 59, 0, 0, ZoneId.of("Z"));
ZonedDateTime noticeLastDate = ZonedDateTime.of(2014, 3, 31, 23, 59, 0, 0, ZoneId.of("Z"));
ZonedDateTime deliveryFirstDate = ZonedDateTime.of(2014, 3, 31, 23, 59, 0, 0, ZoneId.of("Z"));
ZonedDateTime deliveryLastDate = ZonedDateTime.of(2014, 3, 31, 23, 59, 0, 0, ZoneId.of("Z"));
ZonedDateTime firstAccrualDate = ZonedDateTime.of(2001, 9, 27, 0, 0, 0, 0, ZoneId.of("Z")); // 2001-09-27T00:00Z
ZonedDateTime firstCouponDate = ZonedDateTime.of(2002, 3, 7, 0, 0, 0, 0, ZoneId.of("Z")); // 2002-03-07T00:00Z
ZonedDateTime maturityDate = ZonedDateTime.of(2025, 3, 7, 0, 0, 0, 0, ZoneId.of("Z")); // 2025-03-07T00:00Z
Period paymentPeriod = Period.ofMonths(6);
double fixedRate = 0.05;
int settlementDays = 1;
YieldConvention yieldConvention = SimpleYieldConvention.UK_BUMP_DMO_METHOD;
boolean isEOM = false;
LegalEntity legalEntity = new LegalEntity(null, ISSUER_NAME_LGT, null, Sector.of("GB"), Region.of("GB",
Country.of("GB"), GBP));
BondFixedSecurityDefinition bondFixed = BondFixedSecurityDefinition.from(GBP, firstAccrualDate, firstCouponDate,
maturityDate, paymentPeriod, fixedRate, settlementDays, GBP_CALENDAR, DAY_COUNT, BUSINESS_DAY, yieldConvention,
isEOM, legalEntity);
BondFixedSecurityDefinition[] deliveryBasket = new BondFixedSecurityDefinition[] {bondFixed };
double[] conversionFactor = new double[] {1.088405 };
BondFuturesSecurityDefinition bondFuturesDefinition = new BondFuturesSecurityDefinition(tradingLastDate,
noticeFirstDate, noticeLastDate, deliveryFirstDate, deliveryLastDate, NOTIONAL, deliveryBasket,
conversionFactor);
BondFuturesTransactionDefinition transactionDefinition = new BondFuturesTransactionDefinition(
bondFuturesDefinition, QUANTITY, TRADE_DATE, TRADE_PRICE);
TRANSACTION_LGT = transactionDefinition.toDerivative(VALUATION_DATE, LAST_MARGIN_PRICE);
}
/* Schatz */
private static final BondFuturesTransaction TRANSACTION_SCH;
private static final double BOND_MARKET_PRICE_SCH = 109.17;
static {
ZonedDateTime tradingLastDate = ZonedDateTime.of(2014, 9, 10, 23, 59, 0, 0, ZoneId.of("Z")); // 2014-09-10T23:59Z
ZonedDateTime noticeFirstDate = ZonedDateTime.of(2014, 9, 10, 23, 59, 0, 0, ZoneId.of("Z"));
ZonedDateTime noticeLastDate = ZonedDateTime.of(2014, 9, 10, 23, 59, 0, 0, ZoneId.of("Z"));
ZonedDateTime deliveryFirstDate = ZonedDateTime.of(2014, 9, 10, 23, 59, 0, 0, ZoneId.of("Z"));
ZonedDateTime deliveryLastDate = ZonedDateTime.of(2014, 9, 10, 23, 59, 0, 0, ZoneId.of("Z"));
ZonedDateTime firstAccrualDate = ZonedDateTime.of(2006, 5, 19, 0, 0, 0, 0, ZoneId.of("Z")); // 2006-05-19T00:00Z
ZonedDateTime firstCouponDate = ZonedDateTime.of(2007, 7, 4, 0, 0, 0, 0, ZoneId.of("Z")); // 2007-07-04T00:00Z
ZonedDateTime maturityDate = ZonedDateTime.of(2016, 7, 4, 0, 0, 0, 0, ZoneId.of("Z")); // 2016-07-04T00:00Z
Period paymentPeriod = Period.ofMonths(12);
double fixedRate = 0.04;
int settlementDays = 3;
YieldConvention yieldConvention = SimpleYieldConvention.GERMAN_BOND;
boolean isEOM = false;
LegalEntity legalEntity = new LegalEntity(null, ISSUER_NAME_SCH, null, Sector.of("EU"), Region.of("EU",
Country.of("EU"), EUR));
BondFixedSecurityDefinition bondFixed = BondFixedSecurityDefinition.from(EUR, firstAccrualDate, firstCouponDate,
maturityDate, paymentPeriod, fixedRate, settlementDays, EUR_CALENDAR, DAY_COUNT, BUSINESS_DAY, yieldConvention,
isEOM, legalEntity);
BondFixedSecurityDefinition[] deliveryBasket = new BondFixedSecurityDefinition[] {bondFixed };
double[] conversionFactor = new double[] {0.966395 };
BondFuturesSecurityDefinition bondFuturesDefinition = new BondFuturesSecurityDefinition(tradingLastDate,
noticeFirstDate, noticeLastDate, deliveryFirstDate, deliveryLastDate, NOTIONAL, deliveryBasket,
conversionFactor);
BondFuturesTransactionDefinition transactionDefinition = new BondFuturesTransactionDefinition(
bondFuturesDefinition, QUANTITY, TRADE_DATE, TRADE_PRICE);
TRANSACTION_SCH = transactionDefinition.toDerivative(VALUATION_DATE, LAST_MARGIN_PRICE);
}
/* Bund */
private static final BondFuturesTransaction TRANSACTION_BUN;
private static final double BOND_MARKET_PRICE_BUN = 103.61;
static {
ZonedDateTime tradingLastDate = ZonedDateTime.of(2014, 9, 10, 23, 59, 0, 0, ZoneId.of("Z")); // 2014-09-10T23:59Z
ZonedDateTime noticeFirstDate = ZonedDateTime.of(2014, 9, 10, 23, 59, 0, 0, ZoneId.of("Z"));
ZonedDateTime noticeLastDate = ZonedDateTime.of(2014, 9, 10, 23, 59, 0, 0, ZoneId.of("Z"));
ZonedDateTime deliveryFirstDate = ZonedDateTime.of(2014, 9, 10, 23, 59, 0, 0, ZoneId.of("Z"));
ZonedDateTime deliveryLastDate = ZonedDateTime.of(2014, 9, 10, 23, 59, 0, 0, ZoneId.of("Z"));
ZonedDateTime firstAccrualDate = ZonedDateTime.of(2013, 9, 13, 0, 0, 0, 0, ZoneId.of("Z")); // 2013-09-13T00:00Z
ZonedDateTime firstCouponDate = ZonedDateTime.of(2014, 8, 15, 0, 0, 0, 0, ZoneId.of("Z")); // 2014-08-15T00:00Z
ZonedDateTime maturityDate = ZonedDateTime.of(2023, 8, 15, 0, 0, 0, 0, ZoneId.of("Z")); // 2023-08-15T00:00Z
Period paymentPeriod = Period.ofMonths(12);
double fixedRate = 0.02;
int settlementDays = 3;
YieldConvention yieldConvention = SimpleYieldConvention.GERMAN_BOND;
boolean isEOM = false;
LegalEntity legalEntity = new LegalEntity(null, ISSUER_NAME_BUN, null, Sector.of("EU"), Region.of("EU",
Country.of("EU"), EUR));
BondFixedSecurityDefinition bondFixed = BondFixedSecurityDefinition.from(EUR, firstAccrualDate, firstCouponDate,
maturityDate, paymentPeriod, fixedRate, settlementDays, EUR_CALENDAR, DAY_COUNT, BUSINESS_DAY, yieldConvention,
isEOM, legalEntity);
BondFixedSecurityDefinition[] deliveryBasket = new BondFixedSecurityDefinition[] {bondFixed };
double[] conversionFactor = new double[] {0.729535 };
BondFuturesSecurityDefinition bondFuturesDefinition = new BondFuturesSecurityDefinition(tradingLastDate,
noticeFirstDate, noticeLastDate, deliveryFirstDate, deliveryLastDate, NOTIONAL, deliveryBasket,
conversionFactor);
BondFuturesTransactionDefinition transactionDefinition = new BondFuturesTransactionDefinition(
bondFuturesDefinition, QUANTITY, TRADE_DATE, TRADE_PRICE);
TRANSACTION_BUN = transactionDefinition.toDerivative(VALUATION_DATE, LAST_MARGIN_PRICE);
}
/* Bobl */
private static final BondFuturesTransaction TRANSACTION_BOB;
private static final double BOND_MARKET_PRICE_BOB = 115.195;
static {
ZonedDateTime tradingLastDate = ZonedDateTime.of(2014, 6, 10, 23, 59, 0, 0, ZoneId.of("Z")); // 2014-06-10T23:59Z
ZonedDateTime noticeFirstDate = ZonedDateTime.of(2014, 6, 10, 23, 59, 0, 0, ZoneId.of("Z"));
ZonedDateTime noticeLastDate = ZonedDateTime.of(2014, 6, 10, 23, 59, 0, 0, ZoneId.of("Z"));
ZonedDateTime deliveryFirstDate = ZonedDateTime.of(2014, 6, 10, 23, 59, 0, 0, ZoneId.of("Z"));
ZonedDateTime deliveryLastDate = ZonedDateTime.of(2014, 6, 10, 23, 59, 0, 0, ZoneId.of("Z"));
ZonedDateTime firstAccrualDate = ZonedDateTime.of(2008, 11, 14, 0, 0, 0, 0, ZoneId.of("Z")); // 2008-11-14T00:00Z
ZonedDateTime firstCouponDate = ZonedDateTime.of(2010, 1, 4, 0, 0, 0, 0, ZoneId.of("Z")); // 2010-01-04T00:00Z
ZonedDateTime maturityDate = ZonedDateTime.of(2019, 1, 4, 0, 0, 0, 0, ZoneId.of("Z")); // 2019-01-04T00:00Z
Period paymentPeriod = Period.ofMonths(12);
double fixedRate = 0.0375;
int settlementDays = 3;
YieldConvention yieldConvention = SimpleYieldConvention.GERMAN_BOND;
boolean isEOM = false;
LegalEntity legalEntity = new LegalEntity(null, ISSUER_NAME_BOB, null, Sector.of("EU"), Region.of("EU",
Country.of("EU"), EUR));
BondFixedSecurityDefinition bondFixed = BondFixedSecurityDefinition.from(EUR, firstAccrualDate, firstCouponDate,
maturityDate, paymentPeriod, fixedRate, settlementDays, EUR_CALENDAR, DAY_COUNT, BUSINESS_DAY, yieldConvention,
isEOM, legalEntity);
BondFixedSecurityDefinition[] deliveryBasket = new BondFixedSecurityDefinition[] {bondFixed };
double[] conversionFactor = new double[] {0.912067 };
BondFuturesSecurityDefinition bondFuturesDefinition = new BondFuturesSecurityDefinition(
tradingLastDate, noticeFirstDate, noticeLastDate, deliveryFirstDate, deliveryLastDate, NOTIONAL,
deliveryBasket, conversionFactor);
BondFuturesTransactionDefinition transactionDefinition = new BondFuturesTransactionDefinition(
bondFuturesDefinition, QUANTITY, TRADE_DATE, TRADE_PRICE);
TRANSACTION_BOB = transactionDefinition.toDerivative(VALUATION_DATE, LAST_MARGIN_PRICE);
}
/* underlying calculators */
private static final BondSecurityDiscountingMethod BOND_METHOD = BondSecurityDiscountingMethod.getInstance();
/* calculator */
private static final PresentValueIssuerCalculator PVIC = PresentValueIssuerCalculator.getInstance();
private static final PresentValueCurveSensitivityIssuerCalculator PVCSIC = PresentValueCurveSensitivityIssuerCalculator
.getInstance();
private static final FuturesPriceIssuerCalculator FPIC = FuturesPriceIssuerCalculator.getInstance();
private static final CleanPriceFromCurvesCalculator BCPCC = CleanPriceFromCurvesCalculator.getInstance();
private static final ParameterSensitivityParameterCalculator<ParameterIssuerProviderInterface> PSSFC =
new ParameterSensitivityParameterCalculator<>(PVCSIC);
private static final PV01CurveParametersCalculator<ParameterIssuerProviderInterface> PV01PC =
new PV01CurveParametersCalculator<>(PVCSIC);
private static final double HUNDRED = 100.0;
private static final double BP1 = 1.0E-4;
private static final double TOL = 1.0e-12;
/**
* LGT.
*/
@Test
public void LGTTest() {
BondFuturesSecurity futures = TRANSACTION_LGT.getUnderlyingSecurity();
BondFixedSecurity bondAtSpot = futures.getDeliveryBasketAtSpotDate()[0];
LegalEntity legalEntity = bondAtSpot.getIssuerEntity();
double spreadComputed = BOND_METHOD.zSpreadFromCurvesAndClean(bondAtSpot, ISSUER_PROVIDER_LGT,
BOND_MARKET_PRICE_LGT / HUNDRED, true, NUM_PERIODS) / BP1;
IssuerProviderIssuerDecoratedSpreadPeriodic curveWithSpread = new IssuerProviderIssuerDecoratedSpreadPeriodic(
ISSUER_PROVIDER_LGT, legalEntity, spreadComputed * BP1, NUM_PERIODS);
double priceFuturesComputed = futures.accept(FPIC, curveWithSpread) * HUNDRED;
MultipleCurrencyAmount pvTransactionComputed = TRANSACTION_LGT.accept(PVIC, curveWithSpread);
DoubleMatrix1D bucketedTransactionComputed = PSSFC.calculateSensitivity(TRANSACTION_LGT,
curveWithSpread).multipliedBy(BP1).getSensitivity(CURVE_NAME_LGT, GBP);
double pv01TransactionComputed = TRANSACTION_LGT.accept(PV01PC, curveWithSpread).getMap()
.get(Pairs.of(CURVE_NAME_LGT, GBP));
double[] bucketedTransactionExpected = new double[] {0.0, 0.0, 0.0, 0.0, -0.0011119840027780888,
-0.003996991037022415, -0.008986353698034574, -0.013184094172271864, -0.016983364690368513,
-0.02042205605039133, -0.023650552902335198, -0.026627584708890897, -0.029104349648227185,
-0.031245403123803063, -0.6130414257392747, -0.15389415105453183, 0.0, 0.0 };
assertRelative("LGT", 2.1717086134866257, spreadComputed, TOL);
assertRelative("LGT", 109.78905882774708, priceFuturesComputed, TOL);
assertRelative("LGT", 1097.8905882774707, pvTransactionComputed.getAmount(GBP), TOL);
assertArrayRelative("LGT", bucketedTransactionExpected, bucketedTransactionComputed.getData(), TOL);
assertRelative("LGT", -0.9422483108279297, pv01TransactionComputed, TOL);
}
/**
* SCH
*/
@Test
public void SCHTest() {
BondFuturesSecurity futures = TRANSACTION_SCH.getUnderlyingSecurity();
BondFixedSecurity bondAtSpot = futures.getDeliveryBasketAtSpotDate()[0];
LegalEntity legalEntity = bondAtSpot.getIssuerEntity();
double spreadComputed = BOND_METHOD.zSpreadFromCurvesAndClean(bondAtSpot, ISSUER_PROVIDER_SCH,
BOND_MARKET_PRICE_SCH / HUNDRED, true, NUM_PERIODS) / BP1;
IssuerProviderIssuerDecoratedSpreadPeriodic curveWithSpread = new IssuerProviderIssuerDecoratedSpreadPeriodic(
ISSUER_PROVIDER_SCH, legalEntity, spreadComputed * BP1, NUM_PERIODS);
double priceFuturesComputed = futures.accept(FPIC, curveWithSpread) * HUNDRED;
MultipleCurrencyAmount pvTransactionComputed = TRANSACTION_SCH.accept(PVIC, curveWithSpread);
DoubleMatrix1D bucketedTransactionComputed = PSSFC.calculateSensitivity(TRANSACTION_SCH,
curveWithSpread).multipliedBy(BP1).getSensitivity(CURVE_NAME_SCH, EUR);
double pv01TransactionComputed = TRANSACTION_SCH.accept(PV01PC, curveWithSpread).getMap()
.get(Pairs.of(CURVE_NAME_SCH, EUR));
double[] bucketedTransactionExpected = new double[] {0.0, 0.0, 0.0, 0.0, 0.0, -0.003533013095042371,
-0.16093837199377917, -0.09595099930211884, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
assertRelative("SCH", -2.861164353149736, spreadComputed, TOL);
assertRelative("SCH", 110.66399796476674, priceFuturesComputed, TOL);
assertRelative("SCH", 1106.6399796476674, pvTransactionComputed.getAmount(EUR), TOL);
assertArrayRelative("SCH", bucketedTransactionExpected, bucketedTransactionComputed.getData(), TOL);
assertRelative("SCH", -0.26042238439094034, pv01TransactionComputed, TOL);
}
/**
* BUN
*/
@Test
public void BUNTest() {
BondFuturesSecurity futures = TRANSACTION_BUN.getUnderlyingSecurity();
BondFixedSecurity bondAtSpot = futures.getDeliveryBasketAtSpotDate()[0];
LegalEntity legalEntity = bondAtSpot.getIssuerEntity();
double spreadComputed = BOND_METHOD.zSpreadFromCurvesAndClean(bondAtSpot, ISSUER_PROVIDER_BUN,
BOND_MARKET_PRICE_BUN / HUNDRED, true, NUM_PERIODS) / BP1;
IssuerProviderIssuerDecoratedSpreadPeriodic curveWithSpread = new IssuerProviderIssuerDecoratedSpreadPeriodic(
ISSUER_PROVIDER_BUN, legalEntity, spreadComputed * BP1, NUM_PERIODS);
double priceFuturesComputed = futures.accept(FPIC, curveWithSpread) * HUNDRED;
MultipleCurrencyAmount pvTransactionComputed = TRANSACTION_BUN.accept(PVIC, curveWithSpread);
DoubleMatrix1D bucketedTransactionComputed = PSSFC.calculateSensitivity(TRANSACTION_BUN,
curveWithSpread).multipliedBy(BP1).getSensitivity(CURVE_NAME_BUN, EUR);
double pv01TransactionComputed = TRANSACTION_BUN.accept(PV01PC, curveWithSpread).getMap()
.get(Pairs.of(CURVE_NAME_BUN, EUR));
double[] bucketedTransactionExpected = new double[] {0.0, 0.0, 0.0, 0.0, 0.0, -0.0020630116900443086,
-0.0054843715526430095, -0.008148189182456278, -0.010718682062030957, -0.013166067751900188,
-0.015372982184702157, -0.017654524090719107, -0.019525991723930332, -0.5797885890116127, -0.5483676217067257,
0.0, 0.0, 0.0 };
assertRelative("BUN", 0.807136177649383, spreadComputed, TOL);
assertRelative("BUN", 140.57600798338933, priceFuturesComputed, TOL);
assertRelative("BUN", 1405.760079833893, pvTransactionComputed.getAmount(EUR), TOL);
assertArrayRelative("BUN", bucketedTransactionExpected, bucketedTransactionComputed.getData(), TOL);
assertRelative("BUN", -1.2202900309567646, pv01TransactionComputed, TOL);
}
/**
* BOB
*/
@Test
public void BOBTest() {
BondFuturesSecurity futures = TRANSACTION_BOB.getUnderlyingSecurity();
BondFixedSecurity bondAtSpot = futures.getDeliveryBasketAtSpotDate()[0];
LegalEntity legalEntity = bondAtSpot.getIssuerEntity();
double spreadComputed = BOND_METHOD.zSpreadFromCurvesAndClean(bondAtSpot, ISSUER_PROVIDER_BOB,
BOND_MARKET_PRICE_BOB / HUNDRED, true, NUM_PERIODS) / BP1;
IssuerProviderIssuerDecoratedSpreadPeriodic curveWithSpread = new IssuerProviderIssuerDecoratedSpreadPeriodic(
ISSUER_PROVIDER_BOB, legalEntity, spreadComputed * BP1, NUM_PERIODS);
double priceFuturesComputed = futures.accept(FPIC, curveWithSpread) * HUNDRED;
MultipleCurrencyAmount pvTransactionComputed = TRANSACTION_BOB.accept(PVIC, curveWithSpread);
DoubleMatrix1D bucketedTransactionComputed = PSSFC.calculateSensitivity(TRANSACTION_BOB,
curveWithSpread).multipliedBy(BP1).getSensitivity(CURVE_NAME_BOB, EUR);
double pv01TransactionComputed = TRANSACTION_BOB.accept(PV01PC, curveWithSpread).getMap()
.get(Pairs.of(CURVE_NAME_BOB, EUR));
double[] bucketedTransactionExpected = new double[] {0.0, 0.0, 0.0, 0.0, -8.420329901424389E-4,
-0.0037102197939933314, -0.008197870450731125, -0.01223305313780289, -0.07834737330655409,
-0.47100941424888865, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
assertRelative("BOB", -4.008114404255493, spreadComputed, TOL);
assertRelative("BOB", 125.01222173864888, priceFuturesComputed, TOL);
assertRelative("BOB", 1250.1222173864887, pvTransactionComputed.getAmount(EUR), TOL);
assertArrayRelative("BOB", bucketedTransactionExpected, bucketedTransactionComputed.getData(), TOL);
assertRelative("BOB", -0.5743399639281125, pv01TransactionComputed, TOL);
}
/**
* Test correct method and data are used by calculators, and check rescalings.
*/
@Test
public void calculatorTest() {
double sampleSpread = 0.034;
BondFuturesSecurity futures = TRANSACTION_SCH.getUnderlyingSecurity();
BondFixedSecurity bondAtDeliv = futures.getDeliveryBasketAtDeliveryDate()[0]; // future delivery
BondFixedSecurity bondAtSpot = futures.getDeliveryBasketAtSpotDate()[0]; // spot
LegalEntity legalEntity = bondAtDeliv.getIssuerEntity();
IssuerProviderIssuerDecoratedSpreadPeriodic curveWithSpread = new IssuerProviderIssuerDecoratedSpreadPeriodic(
ISSUER_PROVIDER_SCH, legalEntity, sampleSpread, NUM_PERIODS);
/* bond clean price - including factor */
MultipleCurrencyAmount pv = BOND_METHOD.presentValue(bondAtSpot, curveWithSpread);
double cleanPriceFromPV = HUNDRED * (pv.getAmount(EUR) / curveWithSpread.getMulticurveProvider()
.getDiscountFactor(EUR, bondAtSpot.getSettlementTime()) - bondAtSpot.getAccruedInterest());
double cleanPriceExpected = BOND_METHOD.cleanPriceFromCurves(bondAtSpot, curveWithSpread) * HUNDRED;
double cleanPrice = bondAtSpot.accept(BCPCC, curveWithSpread);
assertRelative("calculatorTest", cleanPriceExpected, cleanPrice, TOL);
assertRelative("calculatorTest", cleanPriceFromPV, cleanPrice, TOL);
/* spread - including double factor, input should be un-factored */
double computedSpread = BOND_METHOD.zSpreadFromCurvesAndClean(bondAtSpot, ISSUER_PROVIDER_SCH,
cleanPrice / HUNDRED, true, NUM_PERIODS);
assertRelative("calculatorTest", sampleSpread, computedSpread, TOL);
/* futures price - excluding factor and notional */
double futuresPriceComputed = futures.accept(FPIC, curveWithSpread) * HUNDRED;
double futuresPriceExpected = bondAtDeliv.accept(BCPCC, curveWithSpread) /
futures.getConversionFactor()[0];
assertRelative("calculatorTest", futuresPriceExpected, futuresPriceComputed, TOL);
/* futures transaction pv - including notional but excluding factor */
MultipleCurrencyAmount pvComputed = TRANSACTION_SCH.accept(PVIC, curveWithSpread);
double pvExpected = bondAtDeliv.accept(BCPCC, curveWithSpread) * futures.getNotional() / HUNDRED /
futures.getConversionFactor()[0];
assertRelative("calculatorTest", pvExpected, pvComputed.getAmount(EUR), TOL);
}
private static void assertArrayRelative(String message, double[] expected, double[] obtained, double relativeTol) {
int nData = expected.length;
assertEquals(message, nData, obtained.length);
for (int i = 0; i < nData; ++i) {
assertRelative(message, expected[i], obtained[i], relativeTol);
}
}
private static void assertRelative(String message, double expected, double obtained, double relativeTol) {
double ref = Math.max(Math.abs(expected), 1.0);
assertEquals(message, expected, obtained, ref * relativeTol);
}
}