/** * Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.strata.pricer.bond; import static com.opengamma.strata.basics.currency.Currency.GBP; import static com.opengamma.strata.basics.currency.Currency.USD; import static com.opengamma.strata.basics.date.DayCounts.ACT_365F; import static com.opengamma.strata.collect.TestHelper.date; import static com.opengamma.strata.pricer.CompoundedRateType.PERIODIC; import static java.time.temporal.ChronoUnit.DAYS; import static org.testng.Assert.assertEquals; import java.time.LocalDate; import org.testng.annotations.Test; import com.opengamma.strata.collect.array.DoubleArray; import com.opengamma.strata.market.curve.CurveMetadata; import com.opengamma.strata.market.curve.CurveName; import com.opengamma.strata.market.curve.Curves; import com.opengamma.strata.market.curve.InterpolatedNodalCurve; import com.opengamma.strata.market.curve.interpolator.CurveInterpolator; import com.opengamma.strata.market.curve.interpolator.CurveInterpolators; import com.opengamma.strata.market.explain.ExplainKey; import com.opengamma.strata.market.explain.ExplainMap; import com.opengamma.strata.market.explain.ExplainMapBuilder; import com.opengamma.strata.market.sensitivity.PointSensitivityBuilder; import com.opengamma.strata.pricer.DiscountFactors; import com.opengamma.strata.pricer.ZeroRateDiscountFactors; import com.opengamma.strata.product.bond.FixedCouponBondPaymentPeriod; /** * Test {@link DiscountingFixedCouponBondPaymentPeriodPricer}. */ @Test public class DiscountingFixedCouponBondPaymentPeriodPricerTest { // issuer curves private static final LocalDate VAL_DATE = date(2015, 1, 28); private static final LocalDate VAL_DATE_AFTER = date(2015, 8, 28); private static final CurveInterpolator INTERPOLATOR = CurveInterpolators.LINEAR; private static final CurveName NAME = CurveName.of("TestCurve"); private static final CurveMetadata METADATA = Curves.zeroRates(NAME, ACT_365F); private static final InterpolatedNodalCurve CURVE = InterpolatedNodalCurve.of(METADATA, DoubleArray.of(0, 10), DoubleArray.of(0.1, 0.18), INTERPOLATOR); private static final DiscountFactors DSC_FACTORS = ZeroRateDiscountFactors.of(GBP, VAL_DATE, CURVE); private static final DiscountFactors DSC_FACTORS_AFTER = ZeroRateDiscountFactors.of(GBP, VAL_DATE_AFTER, CURVE); private static final LegalEntityGroup GROUP = LegalEntityGroup.of("ISSUER1"); private static final IssuerCurveDiscountFactors ISSUER_CURVE = IssuerCurveDiscountFactors.of(DSC_FACTORS, GROUP); private static final IssuerCurveDiscountFactors ISSUER_CURVE_AFTER = IssuerCurveDiscountFactors.of(DSC_FACTORS_AFTER, GROUP); // coupon payment private static final LocalDate START = LocalDate.of(2015, 2, 2); private static final LocalDate END = LocalDate.of(2015, 8, 2); private static final LocalDate START_ADJUSTED = LocalDate.of(2015, 2, 2); private static final LocalDate END_ADJUSTED = LocalDate.of(2015, 8, 3); private static final double FIXED_RATE = 0.025; private static final double NOTIONAL = 1.0e7; private static final double YEAR_FRACTION = 0.51; private static final FixedCouponBondPaymentPeriod PAYMENT_PERIOD = FixedCouponBondPaymentPeriod.builder() .currency(USD) .startDate(START_ADJUSTED) .unadjustedStartDate(START) .endDate(END_ADJUSTED) .unadjustedEndDate(END) .notional(NOTIONAL) .fixedRate(FIXED_RATE) .yearFraction(YEAR_FRACTION) .build(); /// z-spread private static final double Z_SPREAD = 0.02; private static final int PERIOD_PER_YEAR = 4; private static final DiscountingFixedCouponBondPaymentPeriodPricer PRICER = DiscountingFixedCouponBondPaymentPeriodPricer.DEFAULT; private static final double TOL = 1.0e-12; //------------------------------------------------------------------------- public void test_presentValue() { double computed = PRICER.presentValue(PAYMENT_PERIOD, ISSUER_CURVE); double expected = FIXED_RATE * NOTIONAL * YEAR_FRACTION * DSC_FACTORS.discountFactor(END_ADJUSTED); assertEquals(computed, expected); } public void test_presentValueWithSpread() { double computed = PRICER.presentValueWithSpread( PAYMENT_PERIOD, ISSUER_CURVE, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR); double expected = FIXED_RATE * NOTIONAL * YEAR_FRACTION * DSC_FACTORS.discountFactorWithSpread(END_ADJUSTED, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR); assertEquals(computed, expected); } public void test_forecastValue() { double computed = PRICER.forecastValue(PAYMENT_PERIOD, ISSUER_CURVE); double expected = FIXED_RATE * NOTIONAL * YEAR_FRACTION; assertEquals(computed, expected); } public void test_presentValue_past() { double computed = PRICER.presentValue(PAYMENT_PERIOD, ISSUER_CURVE_AFTER); assertEquals(computed, 0d); } public void test_presentValueWithSpread_past() { double computed = PRICER.presentValueWithSpread( PAYMENT_PERIOD, ISSUER_CURVE_AFTER, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR); assertEquals(computed, 0d); } public void test_forecastValue_past() { double computed = PRICER.forecastValue(PAYMENT_PERIOD, ISSUER_CURVE_AFTER); assertEquals(computed, 0d); } //------------------------------------------------------------------------- public void test_presentValueSensitivity() { PointSensitivityBuilder computed = PRICER.presentValueSensitivity(PAYMENT_PERIOD, ISSUER_CURVE); PointSensitivityBuilder expected = IssuerCurveZeroRateSensitivity.of( DSC_FACTORS.zeroRatePointSensitivity(END_ADJUSTED).multipliedBy(FIXED_RATE * NOTIONAL * YEAR_FRACTION), GROUP); assertEquals(computed, expected); } public void test_presentValueSensitivityWithSpread() { PointSensitivityBuilder computed = PRICER.presentValueSensitivityWithSpread( PAYMENT_PERIOD, ISSUER_CURVE, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR); PointSensitivityBuilder expected = IssuerCurveZeroRateSensitivity.of( DSC_FACTORS.zeroRatePointSensitivityWithSpread(END_ADJUSTED, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR) .multipliedBy(FIXED_RATE * NOTIONAL * YEAR_FRACTION), GROUP); assertEquals(computed, expected); } public void test_forecastValueSensitivity() { PointSensitivityBuilder computed = PRICER.forecastValueSensitivity(PAYMENT_PERIOD, ISSUER_CURVE); assertEquals(computed, PointSensitivityBuilder.none()); } public void test_presentValueSensitivity_past() { PointSensitivityBuilder computed = PRICER.presentValueSensitivity(PAYMENT_PERIOD, ISSUER_CURVE_AFTER); assertEquals(computed, PointSensitivityBuilder.none()); } public void test_presentValueSensitivityWithSpread_past() { PointSensitivityBuilder computed = PRICER.presentValueSensitivityWithSpread( PAYMENT_PERIOD, ISSUER_CURVE_AFTER, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR); assertEquals(computed, PointSensitivityBuilder.none()); } //------------------------------------------------------------------------- public void test_explainPresentValue() { ExplainMapBuilder builder = ExplainMap.builder(); PRICER.explainPresentValue(PAYMENT_PERIOD, ISSUER_CURVE, builder); ExplainMap explain = builder.build(); assertEquals(explain.get(ExplainKey.ENTRY_TYPE).get(), "FixedCouponBondPaymentPeriod"); assertEquals(explain.get(ExplainKey.PAYMENT_DATE).get(), PAYMENT_PERIOD.getPaymentDate()); assertEquals(explain.get(ExplainKey.PAYMENT_CURRENCY).get(), PAYMENT_PERIOD.getCurrency()); assertEquals(explain.get(ExplainKey.START_DATE).get(), START_ADJUSTED); assertEquals(explain.get(ExplainKey.UNADJUSTED_START_DATE).get(), START); assertEquals(explain.get(ExplainKey.END_DATE).get(), END_ADJUSTED); assertEquals(explain.get(ExplainKey.UNADJUSTED_END_DATE).get(), END); assertEquals(explain.get(ExplainKey.DAYS).get().intValue(), (int) DAYS.between(START_ADJUSTED, END_ADJUSTED)); assertEquals(explain.get(ExplainKey.DISCOUNT_FACTOR).get(), DSC_FACTORS.discountFactor(END_ADJUSTED)); assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().getAmount(), FIXED_RATE * NOTIONAL * YEAR_FRACTION, NOTIONAL * TOL); assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().getAmount(), FIXED_RATE * NOTIONAL * YEAR_FRACTION * DSC_FACTORS.discountFactor(END_ADJUSTED), NOTIONAL * TOL); } public void test_explainPresentValue_past() { ExplainMapBuilder builder = ExplainMap.builder(); PRICER.explainPresentValue(PAYMENT_PERIOD, ISSUER_CURVE_AFTER, builder); ExplainMap explain = builder.build(); assertEquals(explain.get(ExplainKey.ENTRY_TYPE).get(), "FixedCouponBondPaymentPeriod"); assertEquals(explain.get(ExplainKey.PAYMENT_DATE).get(), PAYMENT_PERIOD.getPaymentDate()); assertEquals(explain.get(ExplainKey.PAYMENT_CURRENCY).get(), PAYMENT_PERIOD.getCurrency()); assertEquals(explain.get(ExplainKey.START_DATE).get(), START_ADJUSTED); assertEquals(explain.get(ExplainKey.UNADJUSTED_START_DATE).get(), START); assertEquals(explain.get(ExplainKey.END_DATE).get(), END_ADJUSTED); assertEquals(explain.get(ExplainKey.UNADJUSTED_END_DATE).get(), END); assertEquals(explain.get(ExplainKey.DAYS).get().intValue(), (int) DAYS.between(START_ADJUSTED, END_ADJUSTED)); assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().getAmount(), 0d, NOTIONAL * TOL); assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().getAmount(), 0d, NOTIONAL * TOL); } public void test_explainPresentValueWithSpread() { ExplainMapBuilder builder = ExplainMap.builder(); PRICER.explainPresentValueWithSpread( PAYMENT_PERIOD, ISSUER_CURVE, builder, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR); ExplainMap explain = builder.build(); assertEquals(explain.get(ExplainKey.ENTRY_TYPE).get(), "FixedCouponBondPaymentPeriod"); assertEquals(explain.get(ExplainKey.PAYMENT_DATE).get(), PAYMENT_PERIOD.getPaymentDate()); assertEquals(explain.get(ExplainKey.PAYMENT_CURRENCY).get(), PAYMENT_PERIOD.getCurrency()); assertEquals(explain.get(ExplainKey.START_DATE).get(), START_ADJUSTED); assertEquals(explain.get(ExplainKey.UNADJUSTED_START_DATE).get(), START); assertEquals(explain.get(ExplainKey.END_DATE).get(), END_ADJUSTED); assertEquals(explain.get(ExplainKey.UNADJUSTED_END_DATE).get(), END); assertEquals(explain.get(ExplainKey.DAYS).get().intValue(), (int) DAYS.between(START_ADJUSTED, END_ADJUSTED)); assertEquals(explain.get(ExplainKey.DISCOUNT_FACTOR).get(), DSC_FACTORS.discountFactorWithSpread(END_ADJUSTED, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR)); assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().getAmount(), FIXED_RATE * NOTIONAL * YEAR_FRACTION, NOTIONAL * TOL); assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().getAmount(), FIXED_RATE * NOTIONAL * YEAR_FRACTION * DSC_FACTORS.discountFactorWithSpread(END_ADJUSTED, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR), NOTIONAL * TOL); } public void test_explainPresentValueWithSpread_past() { ExplainMapBuilder builder = ExplainMap.builder(); PRICER.explainPresentValueWithSpread( PAYMENT_PERIOD, ISSUER_CURVE_AFTER, builder, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR); ExplainMap explain = builder.build(); assertEquals(explain.get(ExplainKey.ENTRY_TYPE).get(), "FixedCouponBondPaymentPeriod"); assertEquals(explain.get(ExplainKey.PAYMENT_DATE).get(), PAYMENT_PERIOD.getPaymentDate()); assertEquals(explain.get(ExplainKey.PAYMENT_CURRENCY).get(), PAYMENT_PERIOD.getCurrency()); assertEquals(explain.get(ExplainKey.START_DATE).get(), START_ADJUSTED); assertEquals(explain.get(ExplainKey.UNADJUSTED_START_DATE).get(), START); assertEquals(explain.get(ExplainKey.END_DATE).get(), END_ADJUSTED); assertEquals(explain.get(ExplainKey.UNADJUSTED_END_DATE).get(), END); assertEquals(explain.get(ExplainKey.DAYS).get().intValue(), (int) DAYS.between(START_ADJUSTED, END_ADJUSTED)); assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().getAmount(), 0d, NOTIONAL * TOL); assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().getAmount(), 0d, NOTIONAL * TOL); } }