/**
* Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.interestrate.bond.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.bond.BondCapitalIndexedSecurityDefinition;
import com.opengamma.analytics.financial.instrument.index.IndexPrice;
import com.opengamma.analytics.financial.instrument.inflation.CouponInflationZeroCouponInterpolationGearingDefinition;
import com.opengamma.analytics.financial.instrument.inflation.CouponInflationZeroCouponMonthlyGearingDefinition;
import com.opengamma.analytics.financial.interestrate.bond.definition.BondCapitalIndexedSecurity;
import com.opengamma.analytics.financial.interestrate.inflation.derivative.CouponInflationZeroCouponInterpolationGearing;
import com.opengamma.analytics.financial.interestrate.inflation.derivative.CouponInflationZeroCouponMonthlyGearing;
import com.opengamma.analytics.financial.interestrate.inflation.provider.CouponInflationZeroCouponInterpolationGearingDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.inflation.provider.CouponInflationZeroCouponMonthlyGearingDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.derivative.Coupon;
import com.opengamma.analytics.financial.provider.calculator.inflation.NetAmountInflationCalculator;
import com.opengamma.analytics.financial.provider.calculator.inflation.PresentValueCurveSensitivityDiscountingInflationCalculator;
import com.opengamma.analytics.financial.provider.calculator.inflation.PresentValueCurveSensitivityIssuerDiscountingInflationCalculator;
import com.opengamma.analytics.financial.provider.calculator.inflation.PresentValueDiscountingInflationCalculator;
import com.opengamma.analytics.financial.provider.calculator.inflationissuer.PresentValueDiscountingInflationIssuerCalculator;
import com.opengamma.analytics.financial.provider.description.MulticurveProviderDiscountDataSets;
import com.opengamma.analytics.financial.provider.description.inflation.InflationIssuerProviderDiscount;
import com.opengamma.analytics.financial.provider.description.inflation.InflationIssuerProviderInterface;
import com.opengamma.analytics.financial.provider.description.inflation.InflationProviderDecoratedMulticurve;
import com.opengamma.analytics.financial.provider.description.inflation.InflationProviderDiscount;
import com.opengamma.analytics.financial.provider.description.inflation.InflationProviderInterface;
import com.opengamma.analytics.financial.provider.description.inflation.ParameterInflationProviderInterface;
import com.opengamma.analytics.financial.provider.description.interestrate.MulticurveProviderDiscountingDecoratedIssuer;
import com.opengamma.analytics.financial.provider.description.interestrate.MulticurveProviderInterface;
import com.opengamma.analytics.financial.provider.sensitivity.inflation.MultipleCurrencyInflationSensitivity;
import com.opengamma.analytics.financial.provider.sensitivity.inflation.ParameterSensitivityInflationMulticurveDiscountInterpolatedFDCalculator;
import com.opengamma.analytics.financial.provider.sensitivity.inflation.ParameterSensitivityInflationParameterCalculator;
import com.opengamma.analytics.financial.provider.sensitivity.inflationissuer.ParameterSensitivityIssuerInflationMulticurveDiscountInterpolatedFDCalculator;
import com.opengamma.analytics.financial.provider.sensitivity.multicurve.MultipleCurrencyParameterSensitivity;
import com.opengamma.analytics.financial.util.AssertSensitivityObjects;
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.SimpleYieldConvention;
import com.opengamma.financial.convention.yield.YieldConvention;
import com.opengamma.financial.convention.yield.YieldConventionFactory;
import com.opengamma.timeseries.DoubleTimeSeries;
import com.opengamma.util.money.Currency;
import com.opengamma.util.money.MultipleCurrencyAmount;
import com.opengamma.util.test.TestGroup;
import com.opengamma.util.time.DateUtils;
/**
* Tests the present value of Capital inflation indexed bonds.
*/
@Test(groups = TestGroup.UNIT)
public class BondCapitalIndexedSecurityDiscountingMethodTest {
private static final InflationIssuerProviderDiscount MARKET = MulticurveProviderDiscountDataSets.createMarket1();
private static final IndexPrice[] PRICE_INDEXES = MulticurveProviderDiscountDataSets.getPriceIndexes();
private static final IndexPrice PRICE_INDEX_UKRPI = PRICE_INDEXES[1];
private static final IndexPrice PRICE_INDEX_USCPI = PRICE_INDEXES[2];
private static final IndexPrice PRICE_INDEX_AUDCPI = PRICE_INDEXES[3];
private static final String[] ISSUER_NAMES = MulticurveProviderDiscountDataSets.getIssuerNames();
private static final String ISSUER_US_GOVT = ISSUER_NAMES[0];
private static final String ISSUER_UK_GOVT = ISSUER_NAMES[1];
private static final String ISSUER_AUD_GOVT = ISSUER_NAMES[3];
private static final double SHIFT_FD = 1.0E-9;
private static final double TOLERANCE_PV_DELTA = 1.0E+2;
private static final double TOLERANCE_SENSI_DELTA = 1.0E-6;
private static final double TOLERANCE_YIELD = 1.0E-8;
private static final double TOLERANCE_PRICE = 1.0E-8;
private static final ZonedDateTime PRICING_DATE = DateUtils.getUTCDate(2011, 8, 8);
private static final BondCapitalIndexedSecurityDiscountingMethod METHOD_BOND_INFLATION =
new BondCapitalIndexedSecurityDiscountingMethod();
private static final CouponInflationZeroCouponMonthlyGearingDiscountingMethod METHOD_INFLATION_ZC_MONTHLY =
new CouponInflationZeroCouponMonthlyGearingDiscountingMethod();
private static final CouponInflationZeroCouponInterpolationGearingDiscountingMethod METHOD_INFLATION_ZC_INTERPOLATION =
new CouponInflationZeroCouponInterpolationGearingDiscountingMethod();
private static final PresentValueDiscountingInflationCalculator PVDIC = PresentValueDiscountingInflationCalculator.getInstance();
private static final NetAmountInflationCalculator NADIC = NetAmountInflationCalculator.getInstance();
private static final PresentValueDiscountingInflationIssuerCalculator PVDIIC = PresentValueDiscountingInflationIssuerCalculator.getInstance();
private static final ParameterSensitivityInflationMulticurveDiscountInterpolatedFDCalculator PS_PV_FDC =
new ParameterSensitivityInflationMulticurveDiscountInterpolatedFDCalculator(PVDIC, SHIFT_FD);
private static final ParameterSensitivityIssuerInflationMulticurveDiscountInterpolatedFDCalculator PS_PV_FDIC =
new ParameterSensitivityIssuerInflationMulticurveDiscountInterpolatedFDCalculator(PVDIIC, SHIFT_FD);
private static final PresentValueCurveSensitivityDiscountingInflationCalculator PVCSDC =
PresentValueCurveSensitivityDiscountingInflationCalculator.getInstance();
private static final ParameterSensitivityInflationParameterCalculator<ParameterInflationProviderInterface> PSC =
new ParameterSensitivityInflationParameterCalculator<>(PVCSDC);
private static final PresentValueCurveSensitivityIssuerDiscountingInflationCalculator PVCSDIC =
PresentValueCurveSensitivityIssuerDiscountingInflationCalculator.getInstance();
private static final ParameterSensitivityInflationParameterCalculator<InflationIssuerProviderInterface> PSIC =
new ParameterSensitivityInflationParameterCalculator<>(PVCSDIC);
// Treasury Indexed Bonds CAIN 3% Index-linked Treasury Stock 2025 - AU0000XCLWP8
private static final Calendar CALENDAR_AUD = new MondayToFridayCalendar("AUD");
private static final BusinessDayConvention BUSINESS_DAY_AUD = BusinessDayConventions.FOLLOWING;
private static final DayCount DAY_COUNT_CAIN = DayCounts.ACT_ACT_ISDA;
private static final boolean IS_EOM_CAIN = false;
private static final ZonedDateTime START_DATE_CAIN = DateUtils.getUTCDate(2009, 9, 30);
private static final ZonedDateTime FIRST_COUPON_DATE_CAIN = DateUtils.getUTCDate(2009, 12, 20);
private static final ZonedDateTime MATURITY_DATE_CAIN = DateUtils.getUTCDate(2025, 12, 20);
private static final YieldConvention YIELD_CONVENTION_CAIN = YieldConventionFactory.INSTANCE.getYieldConvention("UK:BUMP/DMO METHOD"); // To check
private static final int MONTH_LAG_CAIN = 6;
private static final double INDEX_START_CAIN = 173.60; // November 2001
private static final double NOTIONAL_CAIN = 1.00;
private static final double REAL_RATE_CAIN = 0.03;
private static final Period COUPON_PERIOD_CAIN = Period.ofMonths(3);
private static final int SETTLEMENT_DAYS_CAIN = 2;
// TODO: ex-coupon 7 days
private static final BondCapitalIndexedSecurityDefinition<CouponInflationZeroCouponMonthlyGearingDefinition> BOND_SECURITY_CAIN_DEFINITION = BondCapitalIndexedSecurityDefinition.fromMonthly(
PRICE_INDEX_AUDCPI, MONTH_LAG_CAIN, START_DATE_CAIN, INDEX_START_CAIN, FIRST_COUPON_DATE_CAIN, MATURITY_DATE_CAIN, COUPON_PERIOD_CAIN, NOTIONAL_CAIN, REAL_RATE_CAIN,
BUSINESS_DAY_AUD, SETTLEMENT_DAYS_CAIN, CALENDAR_AUD, DAY_COUNT_CAIN, YIELD_CONVENTION_CAIN, IS_EOM_CAIN, ISSUER_AUD_GOVT);
private static final DoubleTimeSeries<ZonedDateTime> AUD_CPI = MulticurveProviderDiscountDataSets.audCPIFrom2009();
private static final BondCapitalIndexedSecurity<Coupon> BOND_SECURITY_CAIN = BOND_SECURITY_CAIN_DEFINITION.toDerivative(PRICING_DATE, AUD_CPI);
@Test
/**
* Tests the present value computation.
*/
public void presentValueCAIN() {
final InflationProviderDiscount marketUKGovt = new InflationProviderDiscount();
marketUKGovt.setCurve(BOND_SECURITY_CAIN.getCurrency(), MARKET.getCurve(BOND_SECURITY_CAIN.getIssuerEntity()));
marketUKGovt.setCurve(PRICE_INDEX_AUDCPI, MARKET.getCurve(PRICE_INDEX_AUDCPI));
final MultipleCurrencyAmount pvNominal = METHOD_INFLATION_ZC_MONTHLY.presentValue((CouponInflationZeroCouponMonthlyGearing) BOND_SECURITY_CAIN.getNominal().getNthPayment(0), marketUKGovt);
MultipleCurrencyAmount pvCoupon = MultipleCurrencyAmount.of(BOND_SECURITY_CAIN.getCurrency(), 0.0);
for (int loopcpn = 0; loopcpn < BOND_SECURITY_CAIN.getCoupon().getNumberOfPayments(); loopcpn++) {
pvCoupon = pvCoupon.plus(BOND_SECURITY_CAIN.getCoupon().getNthPayment(loopcpn).accept(PVDIC, marketUKGovt));
}
final MultipleCurrencyAmount pvExpectd = pvNominal.plus(pvCoupon);
final MultipleCurrencyAmount pv = METHOD_BOND_INFLATION.presentValue(BOND_SECURITY_CAIN, MARKET);
assertEquals("Inflation Capital Indexed bond: present value", pvExpectd.getAmount(BOND_SECURITY_CAIN.getCurrency()), pv.getAmount(BOND_SECURITY_CAIN.getCurrency()), 1.0E-2);
}
@Test
/**
* Tests the present value Method vs Calculator.
*/
public void presentValueMethodVsCalculatorCAIN() {
final MultipleCurrencyAmount pvMethod = METHOD_BOND_INFLATION.presentValue(BOND_SECURITY_CAIN, MARKET);
final MultipleCurrencyAmount pvCalculator = BOND_SECURITY_CAIN.accept(PVDIIC, MARKET);
assertEquals("Inflation Capital Indexed bond: present value", pvMethod, pvCalculator);
}
@Test
/**
* Test the present value parameter curves sensitivity.
*/
public void presentValueParameterCurveSensitivityCAIN() {
final MultipleCurrencyParameterSensitivity pvicsFD = PS_PV_FDC.calculateSensitivity(BOND_SECURITY_CAIN.getCoupon(), MARKET.getInflationProvider());
final MultipleCurrencyParameterSensitivity pvicsExact = PSC.calculateSensitivity(BOND_SECURITY_CAIN.getCoupon(), MARKET.getInflationProvider(), MARKET.getAllNames());
AssertSensitivityObjects.assertEquals("Bond capital indexed security: presentValueParameterCurveSensitivity ", pvicsExact, pvicsFD, TOLERANCE_SENSI_DELTA);
}
@Test
/**
* Test the present value curves sensitivity.
*/
public void presentValueCurveSensitivityCAIN() {
MulticurveProviderInterface multicurveDecorated = new MulticurveProviderDiscountingDecoratedIssuer(
MARKET.getIssuerProvider(), BOND_SECURITY_CAIN.getCurrency(), BOND_SECURITY_CAIN.getIssuerEntity());
InflationProviderInterface creditDiscounting = new InflationProviderDecoratedMulticurve(
MARKET.getInflationProvider(), multicurveDecorated);
final MultipleCurrencyInflationSensitivity sensitivityNominal = BOND_SECURITY_CAIN.getNominal().accept(PVCSDC, creditDiscounting);
final MultipleCurrencyInflationSensitivity sensitivityCoupon = BOND_SECURITY_CAIN.getCoupon().accept(PVCSDC, creditDiscounting);
final MultipleCurrencyInflationSensitivity pvcisCalculated = sensitivityNominal.plus(sensitivityCoupon);
final MultipleCurrencyInflationSensitivity pvcisMethod = METHOD_BOND_INFLATION.presentValueCurveSensitivity(BOND_SECURITY_CAIN, MARKET);
AssertSensitivityObjects.assertEquals("Bond capital indexed security: presentValueCurveSensitivity ", pvcisCalculated, pvcisMethod, TOLERANCE_PV_DELTA);
}
// Index-Lined Gilt 2% Index-linked Treasury Stock 2035 - GB0031790826
private static final Calendar CALENDAR_GBP = new MondayToFridayCalendar("GBP");
private static final BusinessDayConvention BUSINESS_DAY_GBP = BusinessDayConventions.FOLLOWING;
private static final DayCount DAY_COUNT_GILT_1 = DayCounts.ACT_ACT_ISDA;
private static final boolean IS_EOM_GILT_1 = false;
private static final ZonedDateTime START_DATE_GILT_1 = DateUtils.getUTCDate(2002, 7, 11);
private static final ZonedDateTime FIRST_COUPON_DATE_GILT_1 = DateUtils.getUTCDate(2003, 1, 26);
private static final ZonedDateTime MATURITY_DATE_GILT_1 = DateUtils.getUTCDate(2035, 1, 26);
private static final YieldConvention YIELD_CONVENTION_GILT_1 = SimpleYieldConvention.UK_IL_BOND;
// YieldConventionFactory.INSTANCE.getYieldConvention("UK:BUMP/DMO METHOD"); // To check
private static final int MONTH_LAG_GILT_1 = 8;
private static final double INDEX_START_GILT_1 = 173.60; // November 2001
private static final double NOTIONAL_GILT_1 = 1.00;
private static final double REAL_RATE_GILT_1 = 0.02;
private static final Period COUPON_PERIOD_GILT_1 = Period.ofMonths(6);
private static final int SETTLEMENT_DAYS_GILT_1 = 2;
// TODO: ex-coupon 7 days
private static final BondCapitalIndexedSecurityDefinition<CouponInflationZeroCouponMonthlyGearingDefinition> BOND_SECURITY_GILT_1_DEFINITION = BondCapitalIndexedSecurityDefinition.fromMonthly(
PRICE_INDEX_UKRPI, MONTH_LAG_GILT_1, START_DATE_GILT_1, INDEX_START_GILT_1, FIRST_COUPON_DATE_GILT_1, MATURITY_DATE_GILT_1, COUPON_PERIOD_GILT_1, NOTIONAL_GILT_1, REAL_RATE_GILT_1,
BUSINESS_DAY_GBP, SETTLEMENT_DAYS_GILT_1, CALENDAR_GBP, DAY_COUNT_GILT_1, YIELD_CONVENTION_GILT_1, IS_EOM_GILT_1, ISSUER_UK_GOVT);
private static final DoubleTimeSeries<ZonedDateTime> UK_RPI = MulticurveProviderDiscountDataSets.ukRpiFrom2010();
private static final BondCapitalIndexedSecurity<Coupon> BOND_SECURITY_GILT_1 = BOND_SECURITY_GILT_1_DEFINITION.toDerivative(PRICING_DATE, UK_RPI);
@Test
/**
* Tests the present value computation.
*/
public void presentValueGilt1() {
final InflationProviderDiscount marketUKGovt = new InflationProviderDiscount();
marketUKGovt.setCurve(BOND_SECURITY_GILT_1.getCurrency(), MARKET.getCurve(BOND_SECURITY_GILT_1.getIssuerEntity()));
marketUKGovt.setCurve(PRICE_INDEX_UKRPI, MARKET.getCurve(PRICE_INDEX_UKRPI));
final MultipleCurrencyAmount pvNominal = METHOD_INFLATION_ZC_MONTHLY.presentValue((CouponInflationZeroCouponMonthlyGearing) BOND_SECURITY_GILT_1.getNominal().getNthPayment(0), marketUKGovt);
MultipleCurrencyAmount pvCoupon = MultipleCurrencyAmount.of(BOND_SECURITY_GILT_1.getCurrency(), 0.0);
for (int loopcpn = 0; loopcpn < BOND_SECURITY_GILT_1.getCoupon().getNumberOfPayments(); loopcpn++) {
pvCoupon = pvCoupon.plus(BOND_SECURITY_GILT_1.getCoupon().getNthPayment(loopcpn).accept(PVDIC, marketUKGovt));
}
final MultipleCurrencyAmount pvExpected = pvNominal.plus(pvCoupon);
final MultipleCurrencyAmount pv = METHOD_BOND_INFLATION.presentValue(BOND_SECURITY_GILT_1, MARKET);
assertEquals("Inflation Capital Indexed bond: present value",
pvExpected.getAmount(BOND_SECURITY_GILT_1.getCurrency()), pv.getAmount(BOND_SECURITY_GILT_1.getCurrency()), 1.0E-2);
}
@Test
/**
* Tests the present value Method vs Calculator.
*/
public void presentValueMethodVsCalculator() {
final MultipleCurrencyAmount pvMethod = METHOD_BOND_INFLATION.presentValue(BOND_SECURITY_GILT_1, MARKET);
final MultipleCurrencyAmount pvCalculator = BOND_SECURITY_GILT_1.accept(PVDIIC, MARKET);
assertEquals("Inflation Capital Indexed bond: present value", pvMethod, pvCalculator);
}
// 2% 10-YEAR TREASURY INFLATION-PROTECTED SECURITIES (TIPS) Due January 15, 2016 - US912828ET33
private static final Calendar CALENDAR_USD = new MondayToFridayCalendar("USD");
private static final BusinessDayConvention BUSINESS_DAY_USD = BusinessDayConventions.FOLLOWING;
private static final DayCount DAY_COUNT_TIPS_1 = DayCounts.ACT_ACT_ICMA;
private static final boolean IS_EOM_TIPS_1 = false;
private static final ZonedDateTime START_DATE_TIPS_1 = DateUtils.getUTCDate(2006, 1, 15);
private static final ZonedDateTime MATURITY_DATE_TIPS_1 = DateUtils.getUTCDate(2016, 1, 15);
private static final YieldConvention YIELD_CONVENTION_TIPS_1 = SimpleYieldConvention.US_IL_REAL;
private static final int MONTH_LAG_TIPS_1 = 3;
private static final double INDEX_START_TIPS_1 = 198.47742; // Date:
private static final double INDEX_START_TIPS = 176.3; // Date:
private static final double NOTIONAL_TIPS_1 = 100.00;
private static final double REAL_RATE_TIPS_1 = 0.02;
private static final Period COUPON_PERIOD_TIPS_1 = Period.ofMonths(6);
private static final int SETTLEMENT_DAYS_TIPS_1 = 1;
private static final BondCapitalIndexedSecurityDefinition<CouponInflationZeroCouponInterpolationGearingDefinition>
BOND_SECURITY_TIPS_1_DEFINITION = BondCapitalIndexedSecurityDefinition
.fromInterpolation(PRICE_INDEX_USCPI, MONTH_LAG_TIPS_1, START_DATE_TIPS_1, INDEX_START_TIPS_1,
MATURITY_DATE_TIPS_1, COUPON_PERIOD_TIPS_1, NOTIONAL_TIPS_1, REAL_RATE_TIPS_1, BUSINESS_DAY_USD,
SETTLEMENT_DAYS_TIPS_1, CALENDAR_USD, DAY_COUNT_TIPS_1, YIELD_CONVENTION_TIPS_1, IS_EOM_TIPS_1, ISSUER_US_GOVT);
private static final DoubleTimeSeries<ZonedDateTime> US_CPI = MulticurveProviderDiscountDataSets.usCpiFrom2009();
private static final BondCapitalIndexedSecurity<Coupon> BOND_SECURITY_TIPS_1 =
BOND_SECURITY_TIPS_1_DEFINITION.toDerivative(PRICING_DATE, US_CPI);
@Test
/**
* Tests the present value computation.
*/
public void presentValueTips1() {
final InflationProviderDiscount marketUSGovt = new InflationProviderDiscount();
marketUSGovt.setCurve(BOND_SECURITY_TIPS_1.getCurrency(), MARKET.getCurve(BOND_SECURITY_TIPS_1.getIssuerEntity()));
marketUSGovt.setCurve(PRICE_INDEX_USCPI, MARKET.getCurve(PRICE_INDEX_USCPI));
final MultipleCurrencyAmount pvNominal = METHOD_INFLATION_ZC_INTERPOLATION.presentValue(
(CouponInflationZeroCouponInterpolationGearing) BOND_SECURITY_TIPS_1.getNominal().getNthPayment(0),
marketUSGovt);
MultipleCurrencyAmount pvCoupon = MultipleCurrencyAmount.of(BOND_SECURITY_TIPS_1.getCurrency(), 0.0);
for (int loopcpn = 0; loopcpn < BOND_SECURITY_TIPS_1.getCoupon().getNumberOfPayments(); loopcpn++) {
pvCoupon = pvCoupon.plus(BOND_SECURITY_TIPS_1.getCoupon().getNthPayment(loopcpn).accept(PVDIC, marketUSGovt));
}
final MultipleCurrencyAmount pvExpected = pvNominal.plus(pvCoupon);
final MultipleCurrencyAmount pv = METHOD_BOND_INFLATION.presentValue(BOND_SECURITY_TIPS_1, MARKET);
assertEquals("Inflation Capital Indexed bond: present value",
pvExpected.getAmount(BOND_SECURITY_TIPS_1.getCurrency()),
pv.getAmount(BOND_SECURITY_TIPS_1.getCurrency()), 1.0E-2);
}
@Test
/**
* Tests the present value computation.
*/
public void presentValueFromCleanPriceRealTips1() {
final double cleanPriceReal = 1.05;
Currency ccy = BOND_SECURITY_TIPS_1.getCurrency();
final MultipleCurrencyAmount pv =
METHOD_BOND_INFLATION.presentValueFromCleanRealPrice(BOND_SECURITY_TIPS_1, MARKET, cleanPriceReal);
MultipleCurrencyAmount pvPriceReal = BOND_SECURITY_TIPS_1.getSettlement().accept(PVDIIC, MARKET).multipliedBy(cleanPriceReal);
MultipleCurrencyAmount pvAccrued = BOND_SECURITY_TIPS_1.getSettlement().accept(PVDIC, MARKET).
multipliedBy(BOND_SECURITY_TIPS_1.getAccruedInterest());
MultipleCurrencyAmount pvExpected = pvPriceReal.plus(pvAccrued);
assertEquals("Inflation Capital Indexed bond: present value from clean real price",
pvExpected.getAmount(ccy), pv.getAmount(ccy), 1.0E-6);
}
/**
* Tests the present value computation.
*/
public void presentValueFromCleanPriceNominalTips1() {
final double cleanPriceNominal = 1.05;
Currency ccy = BOND_SECURITY_TIPS_1.getCurrency();
final MultipleCurrencyAmount pv = METHOD_BOND_INFLATION.presentValueFromCleanNominalPrice(BOND_SECURITY_TIPS_1, MARKET, cleanPriceNominal);
MultipleCurrencyAmount pvAccrued = BOND_SECURITY_TIPS_1.getSettlement().accept(PVDIC, MARKET).
multipliedBy(BOND_SECURITY_TIPS_1.getAccruedInterest());
double pvPriceNominal = cleanPriceNominal * MARKET.getDiscountFactor(ccy, BOND_SECURITY_TIPS_1.getSettlementTime())
* NOTIONAL_TIPS_1;
double pvExpected = pvPriceNominal + pvAccrued.getAmount(ccy);
assertEquals("Inflation Capital Indexed bond: present value from clean real price", pvExpected,
pv.getAmount(ccy), 1.0E-6);
}
@Test
/**
* Tests the clean real price from the dirty real price.
*/
public void cleanNominalPriceFromDirtyNominalPriceTips1() {
final double dirtyNominal = 1.01;
final double cleanReal = METHOD_BOND_INFLATION.cleanNominalPriceFromDirtyNominalPrice(BOND_SECURITY_TIPS_1, dirtyNominal);
final double indexRatio = BOND_SECURITY_TIPS_1.getIndexRatio();
final double cleanRealExpected = dirtyNominal - BOND_SECURITY_TIPS_1.getAccruedInterest() / NOTIONAL_TIPS_1 * indexRatio;
assertEquals("Inflation Capital Indexed bond: clean from dirty", cleanRealExpected, cleanReal, 1.0E-8);
}
@Test
/**
* Tests the clean real price from the dirty real price.
*/
public void cleanRealFromDirtyRealTips1() {
final double dirtyReal = 1.01;
final double cleanReal = METHOD_BOND_INFLATION.cleanRealPriceFromDirtyRealPrice(BOND_SECURITY_TIPS_1, dirtyReal);
final double cleanRealExpected = dirtyReal - BOND_SECURITY_TIPS_1.getAccruedInterest() / NOTIONAL_TIPS_1;
assertEquals("Inflation Capital Indexed bond: clean from dirty", cleanRealExpected, cleanReal, 1.0E-8);
}
@Test
/**
* Tests the dirty real price computation from the real yield in the "US I/L real" convention.
*/
public void dirtyRealPriceFromRealYieldTips1() {
final double[] yield = new double[] {-0.01, 0.00, 0.01, 0.02, 0.03 };
final int nbCoupon = BOND_SECURITY_TIPS_1.getCoupon().getNumberOfPayments();
final double[] dirtyRealPrice = new double[yield.length];
final double[] dirtyRealPriceExpected = new double[yield.length];
for (int loopyield = 0; loopyield < yield.length; loopyield++) {
dirtyRealPrice[loopyield] = METHOD_BOND_INFLATION.dirtyPriceFromRealYield(BOND_SECURITY_TIPS_1, yield[loopyield]);
final double factorOnPeriod = 1 + yield[loopyield] / BOND_SECURITY_TIPS_1.getCouponPerYear();
double pvAtFirstCoupon = 0;
for (int loopcpn = 0; loopcpn < nbCoupon; loopcpn++) {
pvAtFirstCoupon += REAL_RATE_TIPS_1 / BOND_SECURITY_TIPS_1.getCouponPerYear()
/ Math.pow(factorOnPeriod, loopcpn);
}
pvAtFirstCoupon += 1.0 / Math.pow(factorOnPeriod, nbCoupon - 1);
dirtyRealPriceExpected[loopyield] = pvAtFirstCoupon /
(1 + BOND_SECURITY_TIPS_1.getAccrualFactorToNextCoupon() * yield[loopyield] / BOND_SECURITY_TIPS_1.getCouponPerYear());
assertEquals("Inflation Capital Indexed bond: yield " + loopyield,
dirtyRealPriceExpected[loopyield], dirtyRealPrice[loopyield], TOLERANCE_YIELD);
}
}
@Test
public void yieldRealFromCurves() {
double yield = METHOD_BOND_INFLATION.yieldRealFromCurves(BOND_SECURITY_TIPS_1, MARKET);
double cleanRealPrice = METHOD_BOND_INFLATION.cleanRealPriceFromCurves(BOND_SECURITY_TIPS_1, MARKET);
double dirtyRealPrice = METHOD_BOND_INFLATION.dirtyRealPriceFromCurves(BOND_SECURITY_TIPS_1, MARKET);
double yield2 = METHOD_BOND_INFLATION.yieldRealFromCleanRealPrice(BOND_SECURITY_TIPS_1, cleanRealPrice);
double yield3 = METHOD_BOND_INFLATION.yieldRealFromDirtyRealPrice(BOND_SECURITY_TIPS_1, dirtyRealPrice);
assertEquals("Inflation Capital Indexed bond: yield ", yield, yield2, TOLERANCE_YIELD);
assertEquals("Inflation Capital Indexed bond: yield ", yield, yield3, TOLERANCE_YIELD);
}
@Test
public void yieldRealFromCurvesFirstCouponFixed() {
ZonedDateTime valuationDate = DateUtils.getUTCDate(2012, 1, 2);
BondCapitalIndexedSecurity<Coupon> security = BOND_SECURITY_TIPS_1_DEFINITION.toDerivative(valuationDate, US_CPI);
double yield = METHOD_BOND_INFLATION.yieldRealFromCurves(security, MARKET);
double priceRealDirtyExpected = METHOD_BOND_INFLATION.dirtyPriceFromRealYield(security, yield);
double priceRealDirty = METHOD_BOND_INFLATION.dirtyRealPriceFromCurves(security, MARKET);
assertEquals("Inflation Capital Indexed bond: yield ", priceRealDirtyExpected, priceRealDirty, TOLERANCE_PRICE);
}
@Test
/**
* Tests the clean real price from the dirty real price.
*/
public void yieldRealFromDirtyRealTips1() {
final double[] yield = new double[] {-0.01, 0.00, 0.01, 0.02, 0.03 };
final double[] dirtyRealPrice = new double[yield.length];
final double[] yieldComputed = new double[yield.length];
for (int loopyield = 0; loopyield < yield.length; loopyield++) {
dirtyRealPrice[loopyield] = METHOD_BOND_INFLATION.dirtyPriceFromRealYield(BOND_SECURITY_TIPS_1, yield[loopyield]);
yieldComputed[loopyield] = METHOD_BOND_INFLATION.yieldRealFromDirtyRealPrice(BOND_SECURITY_TIPS_1, dirtyRealPrice[loopyield]);
assertEquals("Inflation Capital Indexed bond: yield " + loopyield, yield[loopyield], yieldComputed[loopyield], 1.0E-8);
}
}
/**
* Tests the clean, dirty and yield vs external hard-coded values.
*/
@Test(enabled = true)
public void priceYieldExternalValues1() {
final double m1 = 1000000; // Notional of the external figures.
final ZonedDateTime pricingDate20110817 = DateUtils.getUTCDate(2011, 8, 17); // Spot 18-Aug-2011
final InflationIssuerProviderDiscount market = MulticurveProviderDiscountDataSets.createMarket1(pricingDate20110817);
final double cleanRealPrice = 1.00;
final BondCapitalIndexedSecurity<Coupon> bond_110817 = BOND_SECURITY_TIPS_1_DEFINITION.toDerivative(pricingDate20110817, US_CPI);
final double referenceIndexExpected = 225.83129; // 18-Aug // 225.83910 17-Aug:
final MultipleCurrencyAmount netAmountSettle = bond_110817.getSettlement().accept(NADIC, market.getInflationProvider());
double df = market.getDiscountFactor(bond_110817.getCurrency(), bond_110817.getSettlement().getPaymentTime());
final double referenceIndexComputed = netAmountSettle.getAmount(bond_110817.getCurrency()) / df
* BOND_SECURITY_TIPS_1_DEFINITION.getIndexStartValue() / bond_110817.getSettlement().getNotional();
assertEquals("Inflation Capital Indexed bond: index", referenceIndexExpected, referenceIndexComputed, 1.0E-5);
final double indexRatioExpected = 1.13782;
final MultipleCurrencyAmount indexRatioCalculated =
bond_110817.getSettlement().accept(NADIC, market.getInflationProvider());
assertEquals("Inflation Capital Indexed bond: indexRatio", indexRatioExpected,
indexRatioCalculated.getAmount(PRICE_INDEX_USCPI.getCurrency()) / NOTIONAL_TIPS_1 / df, 1.0E-5);
final double yieldExpected = 1.999644 / 100.0;
final double dirtyRealPriceComputed = METHOD_BOND_INFLATION.dirtyRealPriceFromCleanRealPrice(bond_110817, cleanRealPrice);
final double yieldComputed = METHOD_BOND_INFLATION.yieldRealFromDirtyRealPrice(bond_110817, dirtyRealPriceComputed);
assertEquals("Inflation Capital Indexed bond: yield ", yieldExpected, yieldComputed, 1.0E-8);
final double accruedExpected = 2102.49;
final double accruedRealExpected = accruedExpected / m1 / indexRatioExpected;
final double accruedReal = bond_110817.getAccruedInterest();
assertEquals("Inflation Capital Indexed bond: accrued", accruedRealExpected, accruedReal / NOTIONAL_TIPS_1, 1.0E-8);
final double netAmountExpected = 1139922.49; // For 1m; uses the rounding rules.
final double netAmount2 = indexRatioExpected * m1 * cleanRealPrice + accruedExpected;
assertEquals("Inflation Capital Indexed bond: net amount", netAmountExpected, netAmount2, 1.0E-2);
final MultipleCurrencyAmount netAmount = METHOD_BOND_INFLATION.netAmount(bond_110817, market, cleanRealPrice);
assertEquals("Inflation Capital Indexed bond: net amount", netAmountExpected,
netAmount.getAmount(PRICE_INDEX_USCPI.getCurrency()) * m1 / df / NOTIONAL_TIPS_1, 2.0E+0); // The difference is due to rounding.
}
@Test(enabled = true)
/**
* Tests the clean, dirty and yield vs external hard-coded values.
*/
public void priceYieldExternalValues2() {
final double m1 = 1000000; // Notional of the external figures.
final ZonedDateTime pricingDate20110817 = DateUtils.getUTCDate(2011, 8, 17); // Spot 18-Aug-2011
final InflationIssuerProviderDiscount market = MulticurveProviderDiscountDataSets.createMarket1(pricingDate20110817);
final double cleanRealPrice = 1.13 + 0.01 / 32;
final BondCapitalIndexedSecurity<Coupon> bond_110817 = BOND_SECURITY_TIPS_1_DEFINITION.toDerivative(pricingDate20110817, US_CPI);
final double referenceIndexExpected = 225.83129;
final MultipleCurrencyAmount netAmountSettle = bond_110817.getSettlement().accept(NADIC, market.getInflationProvider());
double df = market.getDiscountFactor(bond_110817.getCurrency(), bond_110817.getSettlement().getPaymentTime());
final double referenceIndexComputed = netAmountSettle.getAmount(bond_110817.getCurrency()) / df
* BOND_SECURITY_TIPS_1_DEFINITION.getIndexStartValue() / bond_110817.getSettlement().getNotional();
assertEquals("Inflation Capital Indexed bond: index", referenceIndexExpected, referenceIndexComputed, 1.0E-5);
final double indexRatioExpected = 1.13782;
assertEquals("Inflation Capital Indexed bond: indexRatio", indexRatioExpected, referenceIndexComputed / INDEX_START_TIPS_1, 1.0E-5);
final double yieldExpected = -0.892152 / 100.0;
final double dirtyRealPriceComputed = METHOD_BOND_INFLATION.dirtyRealPriceFromCleanRealPrice(bond_110817, cleanRealPrice);
final double yieldComputed = METHOD_BOND_INFLATION.yieldRealFromDirtyRealPrice(bond_110817, dirtyRealPriceComputed);
assertEquals("Inflation Capital Indexed bond: yield ", yieldExpected, yieldComputed, 1.0E-8);
final double accruedExpected = 2102.49;
final double accruedRealExpected = accruedExpected / m1 / indexRatioExpected;
final double accruedReal = bond_110817.getAccruedInterest();
assertEquals("Inflation Capital Indexed bond: accrued", accruedRealExpected, accruedReal / NOTIONAL_TIPS_1, 1.0E-8);
final double netAmountExpected = 1288194.66; // For 1m; uses the rounding rules.
final double netAmount2 = indexRatioExpected * m1 * cleanRealPrice + accruedExpected;
assertEquals("Inflation Capital Indexed bond: net amount", netAmountExpected, netAmount2, 1.0E-2);
final MultipleCurrencyAmount netAmount = METHOD_BOND_INFLATION.netAmount(bond_110817, market, cleanRealPrice);
assertEquals("Inflation Capital Indexed bond: net amount", netAmountExpected,
netAmount.getAmount(PRICE_INDEX_USCPI.getCurrency()) * m1 / df / NOTIONAL_TIPS_1, 2.0E+0); // The difference is due to rounding.
}
@Test(enabled = true)
/**
* Tests the clean, dirty and yield vs external hard-coded values.
*/
public void priceYieldExternalValues3() {
final double m1 = 1000000; // Notional of the external figures.
final ZonedDateTime pricingDate20110817 = DateUtils.getUTCDate(2011, 8, 18); // Spot 19-Aug-2011
final InflationIssuerProviderDiscount market = MulticurveProviderDiscountDataSets.createMarket1(pricingDate20110817);
final double cleanRealPrice = 1.00;
final BondCapitalIndexedSecurity<Coupon> bond_110817 = BOND_SECURITY_TIPS_1_DEFINITION.toDerivative(pricingDate20110817, US_CPI);
final double referenceIndexExpected = 225.82348;
final MultipleCurrencyAmount netAmountSettle = bond_110817.getSettlement().accept(NADIC, market.getInflationProvider());
double df = market.getDiscountFactor(bond_110817.getCurrency(), bond_110817.getSettlement().getPaymentTime());
final double referenceIndexComputed = netAmountSettle.getAmount(bond_110817.getCurrency()) / df
* BOND_SECURITY_TIPS_1_DEFINITION.getIndexStartValue() / bond_110817.getSettlement().getNotional();
assertEquals("Inflation Capital Indexed bond: index", referenceIndexExpected, referenceIndexComputed, 1.0E-5);
final double indexRatioExpected = 1.13778;
final double yieldExpected = 1.999636 / 100.0;
final double dirtyRealPriceComputed = METHOD_BOND_INFLATION.dirtyRealPriceFromCleanRealPrice(bond_110817, cleanRealPrice);
final double yieldComputed = METHOD_BOND_INFLATION.yieldRealFromDirtyRealPrice(bond_110817, dirtyRealPriceComputed);
assertEquals("Inflation Capital Indexed bond: yield ", yieldExpected, yieldComputed, 1.0E-8);
final double accruedExpected = 2164.26;
final double accruedRealExpected = accruedExpected / m1 / indexRatioExpected;
final double accruedReal = bond_110817.getAccruedInterest();
assertEquals("Inflation Capital Indexed bond: accrued", accruedRealExpected, accruedReal / NOTIONAL_TIPS_1, 1.0E-8);
final double netAmountExpected = 1139944.26; // For 1m; uses the rounding rules.
final double netAmount2 = indexRatioExpected * m1 * cleanRealPrice + accruedExpected;
assertEquals("Inflation Capital Indexed bond: net amount", netAmountExpected, netAmount2, 1.0E-2);
final MultipleCurrencyAmount netAmount = METHOD_BOND_INFLATION.netAmount(bond_110817, market, cleanRealPrice);
assertEquals("Inflation Capital Indexed bond: net amount", netAmountExpected,
netAmount.getAmount(PRICE_INDEX_USCPI.getCurrency()) * m1 / df / NOTIONAL_TIPS_1, 2.0E+0); // The difference is due to rounding.
}
@Test(enabled = false)
/**
* Tests of performance. "enabled = false" for the standard testing.
*/
public void performance() {
long startTime, endTime;
final int nbTest = 10000;
final double[] yield = new double[] {-0.01, 0.00, 0.01, 0.02, 0.03 };
final double[] dirtyRealPrice = new double[yield.length];
startTime = System.currentTimeMillis();
for (int looptest = 0; looptest < nbTest; looptest++) {
for (int loopyield = 0; loopyield < yield.length; loopyield++) {
dirtyRealPrice[loopyield] = METHOD_BOND_INFLATION.dirtyPriceFromRealYield(BOND_SECURITY_TIPS_1, yield[loopyield]);
}
}
endTime = System.currentTimeMillis();
System.out.println(nbTest + " price from yield for inflation bonds (TIPS): " + (endTime - startTime) + " ms");
final double[] yieldComputed = new double[yield.length];
startTime = System.currentTimeMillis();
for (int looptest = 0; looptest < nbTest; looptest++) {
for (int loopyield = 0; loopyield < yield.length; loopyield++) {
yieldComputed[loopyield] = METHOD_BOND_INFLATION.yieldRealFromDirtyRealPrice(BOND_SECURITY_TIPS_1, dirtyRealPrice[loopyield]);
}
}
endTime = System.currentTimeMillis();
System.out.println(nbTest + " yield from price for inflation bonds (TIPS): " + (endTime - startTime) + " ms");
}
@Test
/**
* Test the present value parameter curves sensitivity.
*/
public void presentValueParameterCurveSensitivity() {
final MultipleCurrencyParameterSensitivity pvicsFD =
PS_PV_FDC.calculateSensitivity(BOND_SECURITY_GILT_1.getCoupon(), MARKET.getInflationProvider());
final MultipleCurrencyParameterSensitivity pvicsExact =
PSC.calculateSensitivity(BOND_SECURITY_GILT_1.getCoupon(), MARKET.getInflationProvider(), MARKET.getAllNames());
AssertSensitivityObjects.assertEquals("Bond capital indexed security: presentValueParameterCurveSensitivity ",
pvicsExact, pvicsFD, TOLERANCE_PV_DELTA);
}
@Test
/**
* Test the present value curves sensitivity.
*/
public void presentValueCurveSensitivity() {
MulticurveProviderInterface multicurveDecorated = new MulticurveProviderDiscountingDecoratedIssuer(
MARKET.getIssuerProvider(), BOND_SECURITY_GILT_1.getCurrency(), BOND_SECURITY_GILT_1.getIssuerEntity());
InflationProviderInterface inflationDecorated = new InflationProviderDecoratedMulticurve(
MARKET.getInflationProvider(), multicurveDecorated);
final MultipleCurrencyInflationSensitivity sensitivityNominal =
BOND_SECURITY_GILT_1.getNominal().accept(PVCSDC, inflationDecorated);
final MultipleCurrencyInflationSensitivity sensitivityCoupon =
BOND_SECURITY_GILT_1.getCoupon().accept(PVCSDC, inflationDecorated);
final MultipleCurrencyInflationSensitivity pvcisCalculated = sensitivityNominal.plus(sensitivityCoupon);
final MultipleCurrencyInflationSensitivity pvcisMethod =
METHOD_BOND_INFLATION.presentValueCurveSensitivity(BOND_SECURITY_GILT_1, MARKET);
AssertSensitivityObjects.assertEquals("Bond capital indexed security: presentValueCurveSensitivity ",
pvcisCalculated, pvcisMethod, TOLERANCE_PV_DELTA);
}
}