/**
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.product.swap;
import static com.opengamma.strata.basics.index.PriceIndices.CH_CPI;
import static com.opengamma.strata.basics.index.PriceIndices.GB_HICP;
import static com.opengamma.strata.basics.index.PriceIndices.JP_CPI_EXF;
import static com.opengamma.strata.collect.TestHelper.assertSerialization;
import static com.opengamma.strata.collect.TestHelper.assertThrows;
import static com.opengamma.strata.collect.TestHelper.assertThrowsIllegalArg;
import static com.opengamma.strata.collect.TestHelper.coverBeanEquals;
import static com.opengamma.strata.collect.TestHelper.coverImmutableBean;
import static com.opengamma.strata.collect.TestHelper.date;
import static com.opengamma.strata.product.swap.PriceIndexCalculationMethod.INTERPOLATED;
import static com.opengamma.strata.product.swap.PriceIndexCalculationMethod.INTERPOLATED_JAPAN;
import static com.opengamma.strata.product.swap.PriceIndexCalculationMethod.MONTHLY;
import static org.testng.Assert.assertEquals;
import java.time.LocalDate;
import java.time.Period;
import java.time.YearMonth;
import java.util.Optional;
import java.util.OptionalDouble;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.opengamma.strata.basics.ReferenceData;
import com.opengamma.strata.basics.index.Index;
import com.opengamma.strata.basics.schedule.Frequency;
import com.opengamma.strata.basics.schedule.RollConventions;
import com.opengamma.strata.basics.schedule.Schedule;
import com.opengamma.strata.basics.schedule.SchedulePeriod;
import com.opengamma.strata.basics.value.ValueAdjustment;
import com.opengamma.strata.basics.value.ValueSchedule;
import com.opengamma.strata.basics.value.ValueStep;
import com.opengamma.strata.product.rate.InflationEndInterpolatedRateComputation;
import com.opengamma.strata.product.rate.InflationEndMonthRateComputation;
import com.opengamma.strata.product.rate.InflationInterpolatedRateComputation;
import com.opengamma.strata.product.rate.InflationMonthlyRateComputation;
/**
* Test {@link InflationRateCalculation}.
*/
@Test
public class InflationRateCalculationTest {
private static final ReferenceData REF_DATA = ReferenceData.standard();
private static final LocalDate DATE_2015_01_05 = date(2015, 1, 5);
private static final LocalDate DATE_2015_02_05 = date(2015, 2, 5);
private static final LocalDate DATE_2015_03_05 = date(2015, 3, 5);
private static final LocalDate DATE_2015_03_07 = date(2015, 3, 7);
private static final LocalDate DATE_2015_04_05 = date(2015, 4, 5);
private static final SchedulePeriod ACCRUAL1 =
SchedulePeriod.of(DATE_2015_01_05, DATE_2015_02_05, DATE_2015_01_05, DATE_2015_02_05);
private static final SchedulePeriod ACCRUAL2 =
SchedulePeriod.of(DATE_2015_02_05, DATE_2015_03_07, DATE_2015_02_05, DATE_2015_03_05);
private static final SchedulePeriod ACCRUAL3 =
SchedulePeriod.of(DATE_2015_03_07, DATE_2015_04_05, DATE_2015_03_05, DATE_2015_04_05);
private static final Schedule ACCRUAL_SCHEDULE = Schedule.builder()
.periods(ACCRUAL1, ACCRUAL2, ACCRUAL3)
.frequency(Frequency.P1M)
.rollConvention(RollConventions.DAY_5)
.build();
private static final double START_INDEX = 325d;
private static final ValueSchedule GEARING =
ValueSchedule.of(1d, ValueStep.of(2, ValueAdjustment.ofReplace(2d)));
//-------------------------------------------------------------------------
public void test_of() {
InflationRateCalculation test1 = InflationRateCalculation.of(CH_CPI, 3, MONTHLY);
assertEquals(test1.getIndex(), CH_CPI);
assertEquals(test1.getLag(), Period.ofMonths(3));
assertEquals(test1.getIndexCalculationMethod(), MONTHLY);
assertEquals(test1.getFirstIndexValue(), OptionalDouble.empty());
assertEquals(test1.getGearing(), Optional.empty());
assertEquals(test1.getType(), SwapLegType.INFLATION);
}
public void test_of_firstIndexValue() {
InflationRateCalculation test1 = InflationRateCalculation.of(CH_CPI, 3, MONTHLY, 123d);
assertEquals(test1.getIndex(), CH_CPI);
assertEquals(test1.getLag(), Period.ofMonths(3));
assertEquals(test1.getIndexCalculationMethod(), MONTHLY);
assertEquals(test1.getFirstIndexValue(), OptionalDouble.of(123d));
assertEquals(test1.getGearing(), Optional.empty());
assertEquals(test1.getType(), SwapLegType.INFLATION);
}
//-------------------------------------------------------------------------
public void test_builder() {
InflationRateCalculation test1 = InflationRateCalculation.builder()
.index(CH_CPI)
.lag(Period.ofMonths(3))
.indexCalculationMethod(MONTHLY)
.firstIndexValue(123d)
.build();
assertEquals(test1.getIndex(), CH_CPI);
assertEquals(test1.getLag(), Period.ofMonths(3));
assertEquals(test1.getIndexCalculationMethod(), MONTHLY);
assertEquals(test1.getGearing(), Optional.empty());
assertEquals(test1.getFirstIndexValue(), OptionalDouble.of(123d));
assertEquals(test1.getType(), SwapLegType.INFLATION);
InflationRateCalculation test2 = InflationRateCalculation.builder()
.index(GB_HICP)
.lag(Period.ofMonths(4))
.indexCalculationMethod(INTERPOLATED)
.gearing(GEARING)
.build();
assertEquals(test2.getIndex(), GB_HICP);
assertEquals(test2.getLag(), Period.ofMonths(4));
assertEquals(test2.getIndexCalculationMethod(), INTERPOLATED);
assertEquals(test2.getFirstIndexValue(), OptionalDouble.empty());
assertEquals(test2.getGearing().get(), GEARING);
assertEquals(test2.getType(), SwapLegType.INFLATION);
}
public void test_builder_missing_index() {
assertThrowsIllegalArg(() -> InflationRateCalculation.builder().build());
}
public void test_builder_badLag() {
assertThrowsIllegalArg(() -> InflationRateCalculation.builder()
.index(GB_HICP)
.lag(Period.ZERO)
.build());
assertThrowsIllegalArg(() -> InflationRateCalculation.builder()
.index(GB_HICP)
.lag(Period.ofMonths(-1))
.build());
}
//-------------------------------------------------------------------------
public void test_collectIndices() {
InflationRateCalculation test = InflationRateCalculation.builder()
.index(GB_HICP)
.lag(Period.ofMonths(3))
.indexCalculationMethod(MONTHLY)
.build();
ImmutableSet.Builder<Index> builder = ImmutableSet.builder();
test.collectIndices(builder);
assertEquals(builder.build(), ImmutableSet.of(GB_HICP));
}
//-------------------------------------------------------------------------
public void test_createAccrualPeriods_Monthly() {
InflationRateCalculation test = InflationRateCalculation.builder()
.index(GB_HICP)
.lag(Period.ofMonths(3))
.indexCalculationMethod(MONTHLY)
.build();
RateAccrualPeriod rap1 = RateAccrualPeriod.builder(ACCRUAL1)
.yearFraction(1.0)
.rateComputation(
InflationMonthlyRateComputation.of(
GB_HICP,
YearMonth.from(DATE_2015_01_05).minusMonths(3),
YearMonth.from(DATE_2015_02_05).minusMonths(3)))
.build();
RateAccrualPeriod rap2 = RateAccrualPeriod.builder(ACCRUAL2)
.yearFraction(1.0)
.rateComputation(
InflationMonthlyRateComputation.of(
GB_HICP,
YearMonth.from(DATE_2015_02_05).minusMonths(3),
YearMonth.from(DATE_2015_03_07).minusMonths(3)))
.build();
RateAccrualPeriod rap3 = RateAccrualPeriod.builder(ACCRUAL3)
.yearFraction(1.0)
.rateComputation(
InflationMonthlyRateComputation.of(
GB_HICP,
YearMonth.from(DATE_2015_03_07).minusMonths(3),
YearMonth.from(DATE_2015_04_05).minusMonths(3)))
.build();
ImmutableList<RateAccrualPeriod> periods = test.createAccrualPeriods(ACCRUAL_SCHEDULE, ACCRUAL_SCHEDULE, REF_DATA);
assertEquals(periods, ImmutableList.of(rap1, rap2, rap3));
}
public void test_createAccrualPeriods_Interpolated() {
InflationRateCalculation test = InflationRateCalculation.builder()
.index(CH_CPI)
.lag(Period.ofMonths(3))
.indexCalculationMethod(INTERPOLATED)
.build();
double weight1 = 1.0 - 4.0 / 28.0;
double weight2 = 1.0 - 6.0 / 31.0;
double weight3 = 1.0 - 4.0 / 30.0;
RateAccrualPeriod rap1 = RateAccrualPeriod
.builder(ACCRUAL1)
.yearFraction(1.0)
.rateComputation(InflationInterpolatedRateComputation.of(
CH_CPI,
YearMonth.from(DATE_2015_01_05).minusMonths(3),
YearMonth.from(DATE_2015_02_05).minusMonths(3),
weight1))
.build();
RateAccrualPeriod rap2 = RateAccrualPeriod
.builder(ACCRUAL2)
.yearFraction(1.0)
.rateComputation(InflationInterpolatedRateComputation.of(
CH_CPI,
YearMonth.from(DATE_2015_02_05).minusMonths(3),
YearMonth.from(DATE_2015_03_07).minusMonths(3),
weight2))
.build();
RateAccrualPeriod rap3 = RateAccrualPeriod
.builder(ACCRUAL3)
.yearFraction(1.0)
.rateComputation(InflationInterpolatedRateComputation.of(
CH_CPI,
YearMonth.from(DATE_2015_03_07).minusMonths(3),
YearMonth.from(DATE_2015_04_05).minusMonths(3),
weight3))
.build();
ImmutableList<RateAccrualPeriod> periods = test.createAccrualPeriods(ACCRUAL_SCHEDULE, ACCRUAL_SCHEDULE, REF_DATA);
assertEquals(periods, ImmutableList.of(rap1, rap2, rap3));
}
public void test_createRateComputation_InterpolatedJapan() {
LocalDate date1 = LocalDate.of(2013, 3, 9);
LocalDate date2 = LocalDate.of(2013, 3, 10);
LocalDate date3 = LocalDate.of(2013, 3, 11);
InflationRateCalculation test = InflationRateCalculation.builder()
.index(JP_CPI_EXF)
.lag(Period.ofMonths(3))
.indexCalculationMethod(INTERPOLATED_JAPAN)
.firstIndexValue(START_INDEX)
.build();
double weight1 = 1.0 - (9.0 + 28.0 - 10.0) / 28.0;
double weight2 = 1.0;
double weight3 = 1.0 - 1.0 / 31.0;
InflationEndInterpolatedRateComputation obs1 = InflationEndInterpolatedRateComputation.of(
JP_CPI_EXF, START_INDEX, YearMonth.from(date1).minusMonths(4), weight1);
InflationEndInterpolatedRateComputation obs2 = InflationEndInterpolatedRateComputation.of(
JP_CPI_EXF, START_INDEX, YearMonth.from(date2).minusMonths(3), weight2);
InflationEndInterpolatedRateComputation obs3 = InflationEndInterpolatedRateComputation.of(
JP_CPI_EXF, START_INDEX, YearMonth.from(date3).minusMonths(3), weight3);
assertEquals(test.createRateComputation(date1), obs1);
assertEquals(test.createRateComputation(date2), obs2);
assertEquals(test.createRateComputation(date3), obs3);
}
public void test_createAccrualPeriods_Monthly_firstKnown() {
InflationRateCalculation test = InflationRateCalculation.builder()
.index(GB_HICP)
.lag(Period.ofMonths(3))
.indexCalculationMethod(MONTHLY)
.firstIndexValue(123d)
.build();
RateAccrualPeriod rap1 = RateAccrualPeriod.builder(ACCRUAL1)
.yearFraction(1.0)
.rateComputation(
InflationEndMonthRateComputation.of(
GB_HICP,
123d,
YearMonth.from(DATE_2015_02_05).minusMonths(3)))
.build();
RateAccrualPeriod rap2 = RateAccrualPeriod.builder(ACCRUAL2)
.yearFraction(1.0)
.rateComputation(
InflationMonthlyRateComputation.of(
GB_HICP,
YearMonth.from(DATE_2015_02_05).minusMonths(3),
YearMonth.from(DATE_2015_03_07).minusMonths(3)))
.build();
RateAccrualPeriod rap3 = RateAccrualPeriod.builder(ACCRUAL3)
.yearFraction(1.0)
.rateComputation(
InflationMonthlyRateComputation.of(
GB_HICP,
YearMonth.from(DATE_2015_03_07).minusMonths(3),
YearMonth.from(DATE_2015_04_05).minusMonths(3)))
.build();
ImmutableList<RateAccrualPeriod> periods = test.createAccrualPeriods(ACCRUAL_SCHEDULE, ACCRUAL_SCHEDULE, REF_DATA);
assertEquals(periods, ImmutableList.of(rap1, rap2, rap3));
}
//-------------------------------------------------------------------------
public void test_createRateComputation_Monthly() {
InflationRateCalculation test = InflationRateCalculation.builder()
.index(GB_HICP)
.lag(Period.ofMonths(3))
.indexCalculationMethod(MONTHLY)
.firstIndexValue(START_INDEX)
.build();
InflationEndMonthRateComputation obs1 = InflationEndMonthRateComputation.of(
GB_HICP, START_INDEX, YearMonth.from(DATE_2015_02_05).minusMonths(3));
InflationEndMonthRateComputation obs2 = InflationEndMonthRateComputation.of(
GB_HICP, START_INDEX, YearMonth.from(DATE_2015_03_07).minusMonths(3));
InflationEndMonthRateComputation obs3 = InflationEndMonthRateComputation.of(
GB_HICP, START_INDEX, YearMonth.from(DATE_2015_04_05).minusMonths(3));
assertEquals(test.createRateComputation(DATE_2015_02_05), obs1);
assertEquals(test.createRateComputation(DATE_2015_03_07), obs2);
assertEquals(test.createRateComputation(DATE_2015_04_05), obs3);
}
public void test_createRateComputation_Interpolated() {
InflationRateCalculation test = InflationRateCalculation.builder()
.index(CH_CPI)
.lag(Period.ofMonths(3))
.indexCalculationMethod(INTERPOLATED)
.firstIndexValue(START_INDEX)
.build();
double weight1 = 1.0 - 4.0 / 28.0;
double weight2 = 1.0 - 6.0 / 31.0;
double weight3 = 1.0 - 4.0 / 30.0;
InflationEndInterpolatedRateComputation obs1 = InflationEndInterpolatedRateComputation.of(
CH_CPI, START_INDEX, YearMonth.from(DATE_2015_02_05).minusMonths(3), weight1);
InflationEndInterpolatedRateComputation obs2 = InflationEndInterpolatedRateComputation.of(
CH_CPI, START_INDEX, YearMonth.from(DATE_2015_03_07).minusMonths(3), weight2);
InflationEndInterpolatedRateComputation obs3 = InflationEndInterpolatedRateComputation.of(
CH_CPI, START_INDEX, YearMonth.from(DATE_2015_04_05).minusMonths(3), weight3);
assertEquals(test.createRateComputation(DATE_2015_02_05), obs1);
assertEquals(test.createRateComputation(DATE_2015_03_07), obs2);
assertEquals(test.createRateComputation(DATE_2015_04_05), obs3);
}
public void test_createRateComputation_noFirstIndexValue() {
InflationRateCalculation test = InflationRateCalculation.builder()
.index(CH_CPI)
.lag(Period.ofMonths(3))
.indexCalculationMethod(INTERPOLATED)
.build();
assertThrows(() -> test.createRateComputation(DATE_2015_04_05), IllegalStateException.class);
}
//-------------------------------------------------------------------------
public void coverage() {
InflationRateCalculation test1 = InflationRateCalculation.builder()
.index(CH_CPI)
.lag(Period.ofMonths(3))
.indexCalculationMethod(MONTHLY)
.build();
coverImmutableBean(test1);
InflationRateCalculation test2 = InflationRateCalculation.builder()
.index(GB_HICP)
.lag(Period.ofMonths(4))
.indexCalculationMethod(INTERPOLATED)
.gearing(GEARING)
.build();
coverBeanEquals(test1, test2);
}
public void test_serialization() {
InflationRateCalculation test1 = InflationRateCalculation.builder()
.index(CH_CPI)
.lag(Period.ofMonths(3))
.indexCalculationMethod(MONTHLY)
.build();
assertSerialization(test1);
}
}