/**
* Copyright (C) 2014 - 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.currency.Currency.EUR;
import static com.opengamma.strata.basics.currency.Currency.GBP;
import static com.opengamma.strata.basics.date.BusinessDayConventions.FOLLOWING;
import static com.opengamma.strata.basics.date.DayCounts.ACT_360;
import static com.opengamma.strata.basics.date.DayCounts.ACT_365F;
import static com.opengamma.strata.basics.date.DayCounts.ONE_ONE;
import static com.opengamma.strata.basics.date.HolidayCalendarIds.GBLO;
import static com.opengamma.strata.basics.index.FxIndices.EUR_GBP_ECB;
import static com.opengamma.strata.basics.index.IborIndices.GBP_LIBOR_1M;
import static com.opengamma.strata.basics.index.IborIndices.GBP_LIBOR_3M;
import static com.opengamma.strata.basics.index.PriceIndices.GB_RPI;
import static com.opengamma.strata.basics.schedule.Frequency.P12M;
import static com.opengamma.strata.basics.schedule.Frequency.P1M;
import static com.opengamma.strata.basics.schedule.Frequency.P2M;
import static com.opengamma.strata.basics.schedule.Frequency.P3M;
import static com.opengamma.strata.collect.TestHelper.assertSerialization;
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.common.PayReceive.PAY;
import static com.opengamma.strata.product.common.PayReceive.RECEIVE;
import static com.opengamma.strata.product.swap.CompoundingMethod.STRAIGHT;
import static com.opengamma.strata.product.swap.PriceIndexCalculationMethod.INTERPOLATED;
import static com.opengamma.strata.product.swap.PriceIndexCalculationMethod.MONTHLY;
import static com.opengamma.strata.product.swap.SwapLegType.FIXED;
import static com.opengamma.strata.product.swap.SwapLegType.IBOR;
import static org.testng.Assert.assertEquals;
import java.time.LocalDate;
import java.time.Period;
import java.time.YearMonth;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.opengamma.strata.basics.ReferenceData;
import com.opengamma.strata.basics.currency.CurrencyAmount;
import com.opengamma.strata.basics.currency.Payment;
import com.opengamma.strata.basics.date.AdjustableDate;
import com.opengamma.strata.basics.date.BusinessDayAdjustment;
import com.opengamma.strata.basics.date.DayCounts;
import com.opengamma.strata.basics.date.DaysAdjustment;
import com.opengamma.strata.basics.index.FxIndexObservation;
import com.opengamma.strata.basics.index.Index;
import com.opengamma.strata.basics.schedule.Frequency;
import com.opengamma.strata.basics.schedule.PeriodicSchedule;
import com.opengamma.strata.basics.schedule.StubConvention;
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.FixedRateComputation;
import com.opengamma.strata.product.rate.IborRateComputation;
import com.opengamma.strata.product.rate.InflationInterpolatedRateComputation;
import com.opengamma.strata.product.rate.InflationMonthlyRateComputation;
/**
* Test.
*/
@Test
public class RateCalculationSwapLegTest {
private static final ReferenceData REF_DATA = ReferenceData.standard();
private static final LocalDate DATE_01_02 = date(2014, 1, 2);
private static final LocalDate DATE_01_05 = date(2014, 1, 5);
private static final LocalDate DATE_01_06 = date(2014, 1, 6);
private static final LocalDate DATE_02_03 = date(2014, 2, 3);
private static final LocalDate DATE_02_05 = date(2014, 2, 5);
private static final LocalDate DATE_02_07 = date(2014, 2, 7);
private static final LocalDate DATE_03_03 = date(2014, 3, 3);
private static final LocalDate DATE_03_05 = date(2014, 3, 5);
private static final LocalDate DATE_03_07 = date(2014, 3, 7);
private static final LocalDate DATE_04_03 = date(2014, 4, 3);
private static final LocalDate DATE_04_05 = date(2014, 4, 5);
private static final LocalDate DATE_04_07 = date(2014, 4, 7);
private static final LocalDate DATE_04_09 = date(2014, 4, 9);
private static final LocalDate DATE_05_01 = date(2014, 5, 1);
private static final LocalDate DATE_05_05 = date(2014, 5, 5);
private static final LocalDate DATE_05_06 = date(2014, 5, 6);
private static final LocalDate DATE_05_08 = date(2014, 5, 8);
private static final LocalDate DATE_06_05 = date(2014, 6, 5);
private static final LocalDate DATE_06_09 = date(2014, 6, 9);
private static final LocalDate DATE_14_06_09 = date(2014, 6, 9);
private static final LocalDate DATE_19_06_09 = date(2019, 6, 9);
private static final DaysAdjustment PLUS_THREE_DAYS = DaysAdjustment.ofBusinessDays(3, GBLO);
private static final DaysAdjustment PLUS_TWO_DAYS = DaysAdjustment.ofBusinessDays(2, GBLO);
private static final DaysAdjustment MINUS_TWO_DAYS = DaysAdjustment.ofBusinessDays(-2, GBLO);
//-------------------------------------------------------------------------
public void test_builder() {
BusinessDayAdjustment bda = BusinessDayAdjustment.of(FOLLOWING, GBLO);
PeriodicSchedule accrualSchedule = PeriodicSchedule.builder()
.startDate(DATE_01_05)
.endDate(DATE_04_05)
.frequency(P1M)
.businessDayAdjustment(bda)
.build();
PaymentSchedule paymentSchedule = PaymentSchedule.builder()
.paymentFrequency(P1M)
.paymentDateOffset(DaysAdjustment.ofBusinessDays(2, GBLO))
.build();
FixedRateCalculation rateCalc = FixedRateCalculation.builder()
.dayCount(DayCounts.ACT_365F)
.rate(ValueSchedule.of(0.025d))
.build();
NotionalSchedule notionalSchedule = NotionalSchedule.of(GBP, 1000d);
RateCalculationSwapLeg test = RateCalculationSwapLeg.builder()
.payReceive(PAY)
.accrualSchedule(accrualSchedule)
.paymentSchedule(paymentSchedule)
.notionalSchedule(notionalSchedule)
.calculation(rateCalc)
.build();
assertEquals(test.getStartDate(), AdjustableDate.of(DATE_01_05, bda));
assertEquals(test.getEndDate(), AdjustableDate.of(DATE_04_05, bda));
assertEquals(test.getCurrency(), GBP);
assertEquals(test.getPayReceive(), PAY);
assertEquals(test.getAccrualSchedule(), accrualSchedule);
assertEquals(test.getPaymentSchedule(), paymentSchedule);
assertEquals(test.getNotionalSchedule(), notionalSchedule);
assertEquals(test.getCalculation(), rateCalc);
}
//-------------------------------------------------------------------------
public void test_collectIndices_simple() {
RateCalculationSwapLeg test = RateCalculationSwapLeg.builder()
.payReceive(PAY)
.accrualSchedule(PeriodicSchedule.builder()
.startDate(DATE_01_05)
.endDate(DATE_04_05)
.frequency(P1M)
.businessDayAdjustment(BusinessDayAdjustment.of(FOLLOWING, GBLO))
.build())
.paymentSchedule(PaymentSchedule.builder()
.paymentFrequency(P1M)
.paymentDateOffset(PLUS_TWO_DAYS)
.build())
.notionalSchedule(NotionalSchedule.of(GBP, 1000d))
.calculation(IborRateCalculation.builder()
.dayCount(DayCounts.ACT_365F)
.index(GBP_LIBOR_3M)
.fixingDateOffset(MINUS_TWO_DAYS)
.build())
.build();
ImmutableSet.Builder<Index> builder = ImmutableSet.builder();
test.collectIndices(builder);
assertEquals(builder.build(), ImmutableSet.of(GBP_LIBOR_3M));
assertEquals(test.allIndices(), ImmutableSet.of(GBP_LIBOR_3M));
}
public void test_collectIndices_fxReset() {
RateCalculationSwapLeg test = RateCalculationSwapLeg.builder()
.payReceive(PAY)
.accrualSchedule(PeriodicSchedule.builder()
.startDate(DATE_01_05)
.endDate(DATE_04_05)
.frequency(P1M)
.businessDayAdjustment(BusinessDayAdjustment.of(FOLLOWING, GBLO))
.build())
.paymentSchedule(PaymentSchedule.builder()
.paymentFrequency(P1M)
.paymentDateOffset(PLUS_TWO_DAYS)
.build())
.notionalSchedule(NotionalSchedule.builder()
.currency(GBP)
.amount(ValueSchedule.of(1000d))
.fxReset(FxResetCalculation.builder()
.referenceCurrency(EUR)
.index(EUR_GBP_ECB)
.fixingDateOffset(MINUS_TWO_DAYS)
.build())
.build())
.calculation(IborRateCalculation.builder()
.dayCount(DayCounts.ACT_365F)
.index(GBP_LIBOR_3M)
.fixingDateOffset(MINUS_TWO_DAYS)
.build())
.build();
ImmutableSet.Builder<Index> builder = ImmutableSet.builder();
test.collectIndices(builder);
assertEquals(builder.build(), ImmutableSet.of(GBP_LIBOR_3M, EUR_GBP_ECB));
assertEquals(test.allIndices(), ImmutableSet.of(GBP_LIBOR_3M, EUR_GBP_ECB));
}
//-------------------------------------------------------------------------
public void test_resolve_oneAccrualPerPayment_fixedRate() {
// test case
RateCalculationSwapLeg test = RateCalculationSwapLeg.builder()
.payReceive(PAY)
.accrualSchedule(PeriodicSchedule.builder()
.startDate(DATE_01_05)
.endDate(DATE_04_05)
.frequency(P1M)
.businessDayAdjustment(BusinessDayAdjustment.of(FOLLOWING, GBLO))
.build())
.paymentSchedule(PaymentSchedule.builder()
.paymentFrequency(P1M)
.paymentDateOffset(PLUS_TWO_DAYS)
.build())
.notionalSchedule(NotionalSchedule.of(GBP, 1000d))
.calculation(FixedRateCalculation.builder()
.dayCount(ACT_365F)
.rate(ValueSchedule.of(0.025d))
.build())
.build();
// expected
RatePaymentPeriod rpp1 = RatePaymentPeriod.builder()
.paymentDate(DATE_02_07)
.accrualPeriods(RateAccrualPeriod.builder()
.startDate(DATE_01_06)
.endDate(DATE_02_05)
.unadjustedStartDate(DATE_01_05)
.yearFraction(ACT_365F.yearFraction(DATE_01_06, DATE_02_05))
.rateComputation(FixedRateComputation.of(0.025d))
.build())
.dayCount(ACT_365F)
.currency(GBP)
.notional(-1000d)
.build();
RatePaymentPeriod rpp2 = RatePaymentPeriod.builder()
.paymentDate(DATE_03_07)
.accrualPeriods(RateAccrualPeriod.builder()
.startDate(DATE_02_05)
.endDate(DATE_03_05)
.yearFraction(ACT_365F.yearFraction(DATE_02_05, DATE_03_05))
.rateComputation(FixedRateComputation.of(0.025d))
.build())
.dayCount(ACT_365F)
.currency(GBP)
.notional(-1000d)
.build();
RatePaymentPeriod rpp3 = RatePaymentPeriod.builder()
.paymentDate(DATE_04_09)
.accrualPeriods(RateAccrualPeriod.builder()
.startDate(DATE_03_05)
.endDate(DATE_04_07)
.unadjustedEndDate(DATE_04_05)
.yearFraction(ACT_365F.yearFraction(DATE_03_05, DATE_04_07))
.rateComputation(FixedRateComputation.of(0.025d))
.build())
.dayCount(ACT_365F)
.currency(GBP)
.notional(-1000d)
.build();
// assertion
assertEquals(test.resolve(REF_DATA), ResolvedSwapLeg.builder()
.type(FIXED)
.payReceive(PAY)
.paymentPeriods(rpp1, rpp2, rpp3)
.build());
}
public void test_resolve_knownAmountStub() {
// test case
CurrencyAmount knownAmount = CurrencyAmount.of(GBP, 150d);
RateCalculationSwapLeg test = RateCalculationSwapLeg.builder()
.payReceive(PAY)
.accrualSchedule(PeriodicSchedule.builder()
.startDate(DATE_02_03)
.endDate(DATE_04_03)
.firstRegularStartDate(DATE_02_05)
.lastRegularEndDate(DATE_03_05)
.frequency(P1M)
.stubConvention(StubConvention.BOTH)
.businessDayAdjustment(BusinessDayAdjustment.of(FOLLOWING, GBLO))
.build())
.paymentSchedule(PaymentSchedule.builder()
.paymentFrequency(P1M)
.paymentDateOffset(PLUS_TWO_DAYS)
.build())
.notionalSchedule(NotionalSchedule.of(GBP, 1000d))
.calculation(FixedRateCalculation.builder()
.dayCount(ACT_365F)
.rate(ValueSchedule.of(0.025d))
.initialStub(FixedRateStubCalculation.ofKnownAmount(knownAmount))
.finalStub(FixedRateStubCalculation.ofFixedRate(0.1d))
.build())
.build();
// expected
KnownAmountNotionalSwapPaymentPeriod pp1 = KnownAmountNotionalSwapPaymentPeriod.builder()
.payment(Payment.of(knownAmount, DATE_02_07))
.startDate(DATE_02_03)
.endDate(DATE_02_05)
.unadjustedStartDate(DATE_02_03)
.notionalAmount(CurrencyAmount.of(GBP, -1000d))
.build();
RatePaymentPeriod rpp2 = RatePaymentPeriod.builder()
.paymentDate(DATE_03_07)
.accrualPeriods(RateAccrualPeriod.builder()
.startDate(DATE_02_05)
.endDate(DATE_03_05)
.yearFraction(ACT_365F.yearFraction(DATE_02_05, DATE_03_05))
.rateComputation(FixedRateComputation.of(0.025d))
.build())
.dayCount(ACT_365F)
.currency(GBP)
.notional(-1000d)
.build();
RatePaymentPeriod rpp3 = RatePaymentPeriod.builder()
.paymentDate(DATE_04_07)
.accrualPeriods(RateAccrualPeriod.builder()
.startDate(DATE_03_05)
.endDate(DATE_04_03)
.unadjustedEndDate(DATE_04_03)
.yearFraction(ACT_365F.yearFraction(DATE_03_05, DATE_04_03))
.rateComputation(FixedRateComputation.of(0.1d))
.build())
.dayCount(ACT_365F)
.currency(GBP)
.notional(-1000d)
.build();
// assertion
assertEquals(test.resolve(REF_DATA), ResolvedSwapLeg.builder()
.type(FIXED)
.payReceive(PAY)
.paymentPeriods(pp1, rpp2, rpp3)
.build());
}
public void test_resolve_twoAccrualsPerPayment_iborRate_varyingNotional_notionalExchange() {
// test case
RateCalculationSwapLeg test = RateCalculationSwapLeg.builder()
.payReceive(PAY)
.accrualSchedule(PeriodicSchedule.builder()
.startDate(DATE_01_05)
.endDate(DATE_06_05)
.frequency(P1M)
.businessDayAdjustment(BusinessDayAdjustment.of(FOLLOWING, GBLO))
.build())
.paymentSchedule(PaymentSchedule.builder()
.paymentFrequency(P2M)
.paymentDateOffset(PLUS_TWO_DAYS)
.compoundingMethod(STRAIGHT)
.build())
.notionalSchedule(NotionalSchedule.builder()
.currency(GBP)
.amount(ValueSchedule.of(1000d, ValueStep.of(1, ValueAdjustment.ofReplace(1500d))))
.initialExchange(true)
.intermediateExchange(true)
.finalExchange(true)
.build())
.calculation(IborRateCalculation.builder()
.dayCount(ACT_365F)
.index(GBP_LIBOR_1M)
.fixingDateOffset(DaysAdjustment.ofBusinessDays(-2, GBLO))
.build())
.build();
// expected
RatePaymentPeriod rpp1 = RatePaymentPeriod.builder()
.paymentDate(DATE_03_07)
.accrualPeriods(
RateAccrualPeriod.builder()
.startDate(DATE_01_06)
.endDate(DATE_02_05)
.unadjustedStartDate(DATE_01_05)
.yearFraction(ACT_365F.yearFraction(DATE_01_06, DATE_02_05))
.rateComputation(IborRateComputation.of(GBP_LIBOR_1M, DATE_01_02, REF_DATA))
.build(),
RateAccrualPeriod.builder()
.startDate(DATE_02_05)
.endDate(DATE_03_05)
.yearFraction(ACT_365F.yearFraction(DATE_02_05, DATE_03_05))
.rateComputation(IborRateComputation.of(GBP_LIBOR_1M, DATE_02_03, REF_DATA))
.build())
.dayCount(ACT_365F)
.currency(GBP)
.notional(-1000d)
.compoundingMethod(STRAIGHT)
.build();
RatePaymentPeriod rpp2 = RatePaymentPeriod.builder()
.paymentDate(DATE_05_08)
.accrualPeriods(
RateAccrualPeriod.builder()
.startDate(DATE_03_05)
.endDate(DATE_04_07)
.unadjustedEndDate(DATE_04_05)
.yearFraction(ACT_365F.yearFraction(DATE_03_05, DATE_04_07))
.rateComputation(IborRateComputation.of(GBP_LIBOR_1M, DATE_03_03, REF_DATA))
.build(),
RateAccrualPeriod.builder()
.startDate(DATE_04_07)
.endDate(DATE_05_06)
.unadjustedStartDate(DATE_04_05)
.unadjustedEndDate(DATE_05_05)
.yearFraction(ACT_365F.yearFraction(DATE_04_07, DATE_05_06))
.rateComputation(IborRateComputation.of(GBP_LIBOR_1M, DATE_04_03, REF_DATA))
.build())
.dayCount(ACT_365F)
.currency(GBP)
.notional(-1500d)
.compoundingMethod(STRAIGHT)
.build();
RatePaymentPeriod rpp3 = RatePaymentPeriod.builder()
.paymentDate(DATE_06_09)
.accrualPeriods(RateAccrualPeriod.builder()
.startDate(DATE_05_06)
.endDate(DATE_06_05)
.unadjustedStartDate(DATE_05_05)
.yearFraction(ACT_365F.yearFraction(DATE_05_06, DATE_06_05))
.rateComputation(IborRateComputation.of(GBP_LIBOR_1M, DATE_05_01, REF_DATA))
.build())
.dayCount(ACT_365F)
.currency(GBP)
.notional(-1500d)
.compoundingMethod(STRAIGHT)
.build();
// events (only one intermediate exchange)
NotionalExchange nexInitial = NotionalExchange.of(CurrencyAmount.of(GBP, 1000d), DATE_01_06);
NotionalExchange nexIntermediate = NotionalExchange.of(CurrencyAmount.of(GBP, 500d), DATE_03_07);
NotionalExchange nexFinal = NotionalExchange.of(CurrencyAmount.of(GBP, -1500d), DATE_06_09);
// assertion
assertEquals(test.resolve(REF_DATA), ResolvedSwapLeg.builder()
.type(IBOR)
.payReceive(PAY)
.paymentPeriods(rpp1, rpp2, rpp3)
.paymentEvents(nexInitial, nexIntermediate, nexFinal)
.build());
}
public void test_resolve_threeAccrualsPerPayment() {
// test case
RateCalculationSwapLeg test = RateCalculationSwapLeg.builder()
.payReceive(PAY)
.accrualSchedule(PeriodicSchedule.builder()
.startDate(DATE_01_05)
.endDate(DATE_04_05)
.frequency(P1M)
.businessDayAdjustment(BusinessDayAdjustment.of(FOLLOWING, GBLO))
.build())
.paymentSchedule(PaymentSchedule.builder()
.paymentFrequency(P3M)
.paymentDateOffset(PLUS_TWO_DAYS)
.compoundingMethod(STRAIGHT)
.build())
.notionalSchedule(NotionalSchedule.of(GBP, 1000d))
.calculation(FixedRateCalculation.builder()
.dayCount(ACT_365F)
.rate(ValueSchedule.of(0.025d))
.build())
.build();
// expected
RatePaymentPeriod rpp1 = RatePaymentPeriod.builder()
.paymentDate(DATE_04_09)
.accrualPeriods(
RateAccrualPeriod.builder()
.startDate(DATE_01_06)
.endDate(DATE_02_05)
.unadjustedStartDate(DATE_01_05)
.yearFraction(ACT_365F.yearFraction(DATE_01_06, DATE_02_05))
.rateComputation(FixedRateComputation.of(0.025d))
.build(),
RateAccrualPeriod.builder()
.startDate(DATE_02_05)
.endDate(DATE_03_05)
.yearFraction(ACT_365F.yearFraction(DATE_02_05, DATE_03_05))
.rateComputation(FixedRateComputation.of(0.025d))
.build(),
RateAccrualPeriod.builder()
.startDate(DATE_03_05)
.endDate(DATE_04_07)
.unadjustedEndDate(DATE_04_05)
.yearFraction(ACT_365F.yearFraction(DATE_03_05, DATE_04_07))
.rateComputation(FixedRateComputation.of(0.025d))
.build())
.dayCount(ACT_365F)
.currency(GBP)
.notional(-1000d)
.compoundingMethod(STRAIGHT)
.build();
// assertion
assertEquals(test.resolve(REF_DATA), ResolvedSwapLeg.builder()
.type(FIXED)
.payReceive(PAY)
.paymentPeriods(rpp1)
.build());
}
//-------------------------------------------------------------------------
public void test_resolve_oneAccrualPerPayment_fxReset() {
// test case
RateCalculationSwapLeg test = RateCalculationSwapLeg.builder()
.payReceive(PAY)
.accrualSchedule(PeriodicSchedule.builder()
.startDate(DATE_01_05)
.endDate(DATE_04_05)
.frequency(P1M)
.businessDayAdjustment(BusinessDayAdjustment.of(FOLLOWING, GBLO))
.build())
.paymentSchedule(PaymentSchedule.builder()
.paymentFrequency(P1M)
.paymentDateOffset(PLUS_TWO_DAYS)
.build())
.notionalSchedule(NotionalSchedule.builder()
.currency(GBP)
.amount(ValueSchedule.of(1000d))
.fxReset(FxResetCalculation.builder()
.referenceCurrency(EUR)
.index(EUR_GBP_ECB)
.fixingDateOffset(MINUS_TWO_DAYS)
.build())
.build())
.calculation(FixedRateCalculation.builder()
.dayCount(ACT_365F)
.rate(ValueSchedule.of(0.025d))
.build())
.build();
// expected
RatePaymentPeriod rpp1 = RatePaymentPeriod.builder()
.paymentDate(DATE_02_07)
.accrualPeriods(RateAccrualPeriod.builder()
.startDate(DATE_01_06)
.endDate(DATE_02_05)
.unadjustedStartDate(DATE_01_05)
.yearFraction(ACT_365F.yearFraction(DATE_01_06, DATE_02_05))
.rateComputation(FixedRateComputation.of(0.025d))
.build())
.dayCount(ACT_365F)
.currency(GBP)
.notional(-1000d)
.fxReset(FxReset.of(FxIndexObservation.of(EUR_GBP_ECB, DATE_01_02, REF_DATA), EUR))
.build();
RatePaymentPeriod rpp2 = RatePaymentPeriod.builder()
.paymentDate(DATE_03_07)
.accrualPeriods(RateAccrualPeriod.builder()
.startDate(DATE_02_05)
.endDate(DATE_03_05)
.yearFraction(ACT_365F.yearFraction(DATE_02_05, DATE_03_05))
.rateComputation(FixedRateComputation.of(0.025d))
.build())
.dayCount(ACT_365F)
.currency(GBP)
.notional(-1000d)
.fxReset(FxReset.of(FxIndexObservation.of(EUR_GBP_ECB, DATE_02_03, REF_DATA), EUR))
.build();
RatePaymentPeriod rpp3 = RatePaymentPeriod.builder()
.paymentDate(DATE_04_09)
.accrualPeriods(RateAccrualPeriod.builder()
.startDate(DATE_03_05)
.endDate(DATE_04_07)
.unadjustedEndDate(DATE_04_05)
.yearFraction(ACT_365F.yearFraction(DATE_03_05, DATE_04_07))
.rateComputation(FixedRateComputation.of(0.025d))
.build())
.dayCount(ACT_365F)
.currency(GBP)
.notional(-1000d)
.fxReset(FxReset.of(FxIndexObservation.of(EUR_GBP_ECB, DATE_03_03, REF_DATA), EUR))
.build();
FxResetNotionalExchange ne1a = FxResetNotionalExchange.of(
CurrencyAmount.of(EUR, 1000d), DATE_01_06, FxIndexObservation.of(EUR_GBP_ECB, DATE_01_02, REF_DATA));
FxResetNotionalExchange ne1b = FxResetNotionalExchange.of(
CurrencyAmount.of(EUR, -1000d), DATE_02_07, FxIndexObservation.of(EUR_GBP_ECB, DATE_01_02, REF_DATA));
FxResetNotionalExchange ne2a = FxResetNotionalExchange.of(
CurrencyAmount.of(EUR, 1000d), DATE_02_07, FxIndexObservation.of(EUR_GBP_ECB, DATE_02_03, REF_DATA));
FxResetNotionalExchange ne2b = FxResetNotionalExchange.of(
CurrencyAmount.of(EUR, -1000d), DATE_03_07, FxIndexObservation.of(EUR_GBP_ECB, DATE_02_03, REF_DATA));
FxResetNotionalExchange ne3a = FxResetNotionalExchange.of(
CurrencyAmount.of(EUR, 1000d), DATE_03_07, FxIndexObservation.of(EUR_GBP_ECB, DATE_03_03, REF_DATA));
FxResetNotionalExchange ne3b = FxResetNotionalExchange.of(
CurrencyAmount.of(EUR, -1000d), DATE_04_09, FxIndexObservation.of(EUR_GBP_ECB, DATE_03_03, REF_DATA));
// assertion
assertEquals(test.resolve(REF_DATA), ResolvedSwapLeg.builder()
.type(FIXED)
.payReceive(PAY)
.paymentPeriods(rpp1, rpp2, rpp3)
.paymentEvents(ne1a, ne1b, ne2a, ne2b, ne3a, ne3b)
.build());
}
//-------------------------------------------------------------------------
public void test_inflation_monthly() {
BusinessDayAdjustment bda = BusinessDayAdjustment.of(FOLLOWING, GBLO);
PeriodicSchedule accrualSchedule = PeriodicSchedule.builder()
.startDate(DATE_14_06_09)
.endDate(DATE_19_06_09)
.frequency(Frequency.ofYears(5))
.businessDayAdjustment(bda)
.build();
PaymentSchedule paymentSchedule = PaymentSchedule.builder()
.paymentFrequency(Frequency.ofYears(5))
.paymentDateOffset(DaysAdjustment.ofBusinessDays(2, GBLO))
.build();
InflationRateCalculation rateCalc = InflationRateCalculation.builder()
.index(GB_RPI)
.indexCalculationMethod(MONTHLY)
.lag(Period.ofMonths(3))
.build();
NotionalSchedule notionalSchedule = NotionalSchedule.of(GBP, 1000d);
RateCalculationSwapLeg test = RateCalculationSwapLeg.builder()
.payReceive(PAY)
.accrualSchedule(accrualSchedule)
.paymentSchedule(paymentSchedule)
.notionalSchedule(notionalSchedule)
.calculation(rateCalc)
.build();
assertEquals(test.getStartDate(), AdjustableDate.of(DATE_14_06_09, bda));
assertEquals(test.getEndDate(), AdjustableDate.of(DATE_19_06_09, bda));
assertEquals(test.getCurrency(), GBP);
assertEquals(test.getPayReceive(), PAY);
assertEquals(test.getAccrualSchedule(), accrualSchedule);
assertEquals(test.getPaymentSchedule(), paymentSchedule);
assertEquals(test.getNotionalSchedule(), notionalSchedule);
assertEquals(test.getCalculation(), rateCalc);
RatePaymentPeriod rpp = RatePaymentPeriod.builder()
.paymentDate(DaysAdjustment.ofBusinessDays(2, GBLO).adjust(bda.adjust(DATE_19_06_09, REF_DATA), REF_DATA))
.accrualPeriods(RateAccrualPeriod.builder()
.startDate(BusinessDayAdjustment.of(FOLLOWING, GBLO).adjust(DATE_14_06_09, REF_DATA))
.endDate(BusinessDayAdjustment.of(FOLLOWING, GBLO).adjust(DATE_19_06_09, REF_DATA))
.unadjustedStartDate(DATE_14_06_09)
.unadjustedEndDate(DATE_19_06_09)
.yearFraction(1.0)
.rateComputation(
InflationMonthlyRateComputation.of(
GB_RPI,
YearMonth.from(bda.adjust(DATE_14_06_09, REF_DATA)).minusMonths(3),
YearMonth.from(bda.adjust(DATE_19_06_09, REF_DATA)).minusMonths(3)))
.build())
.dayCount(ONE_ONE)
.currency(GBP)
.notional(-1000d)
.build();
ResolvedSwapLeg expected = ResolvedSwapLeg.builder()
.paymentPeriods(rpp)
.payReceive(PAY)
.type(SwapLegType.INFLATION)
.build();
ResolvedSwapLeg testResolved = test.resolve(REF_DATA);
assertEquals(testResolved, expected);
}
public void test_inflation_interpolated() {
BusinessDayAdjustment bda = BusinessDayAdjustment.of(FOLLOWING, GBLO);
PeriodicSchedule accrualSchedule = PeriodicSchedule.builder()
.startDate(DATE_14_06_09)
.endDate(DATE_19_06_09)
.frequency(Frequency.ofYears(5))
.businessDayAdjustment(bda)
.build();
PaymentSchedule paymentSchedule = PaymentSchedule.builder()
.paymentFrequency(Frequency.ofYears(5))
.paymentDateOffset(DaysAdjustment.ofBusinessDays(2, GBLO))
.build();
InflationRateCalculation rateCalc = InflationRateCalculation.builder()
.index(GB_RPI)
.indexCalculationMethod(INTERPOLATED)
.lag(Period.ofMonths(3))
.build();
NotionalSchedule notionalSchedule = NotionalSchedule.of(GBP, 1000d);
RateCalculationSwapLeg test = RateCalculationSwapLeg.builder()
.payReceive(RECEIVE)
.accrualSchedule(accrualSchedule)
.paymentSchedule(paymentSchedule)
.notionalSchedule(notionalSchedule)
.calculation(rateCalc)
.build();
assertEquals(test.getStartDate(), AdjustableDate.of(DATE_14_06_09, bda));
assertEquals(test.getEndDate(), AdjustableDate.of(DATE_19_06_09, bda));
assertEquals(test.getCurrency(), GBP);
assertEquals(test.getPayReceive(), RECEIVE);
assertEquals(test.getAccrualSchedule(), accrualSchedule);
assertEquals(test.getPaymentSchedule(), paymentSchedule);
assertEquals(test.getNotionalSchedule(), notionalSchedule);
assertEquals(test.getCalculation(), rateCalc);
double weight = 1. - 9.0 / 30.0;
RatePaymentPeriod rpp0 = RatePaymentPeriod.builder()
.paymentDate(DaysAdjustment.ofBusinessDays(2, GBLO).adjust(bda.adjust(DATE_19_06_09, REF_DATA), REF_DATA))
.accrualPeriods(RateAccrualPeriod.builder()
.startDate(bda.adjust(DATE_14_06_09, REF_DATA))
.endDate(bda.adjust(DATE_19_06_09, REF_DATA))
.unadjustedStartDate(DATE_14_06_09)
.unadjustedEndDate(DATE_19_06_09)
.yearFraction(1.0)
.rateComputation(
InflationInterpolatedRateComputation.of(
GB_RPI,
YearMonth.from(bda.adjust(DATE_14_06_09, REF_DATA)).minusMonths(3),
YearMonth.from(bda.adjust(DATE_19_06_09, REF_DATA)).minusMonths(3),
weight))
.build())
.dayCount(ONE_ONE)
.currency(GBP)
.notional(1000d)
.build();
ResolvedSwapLeg expected = ResolvedSwapLeg.builder()
.paymentPeriods(rpp0)
.payReceive(RECEIVE)
.type(SwapLegType.INFLATION)
.build();
ResolvedSwapLeg testExpand = test.resolve(REF_DATA);
assertEquals(testExpand, expected);
}
public void test_inflation_fixed() {
BusinessDayAdjustment bda = BusinessDayAdjustment.of(FOLLOWING, GBLO);
PeriodicSchedule accrualSchedule = PeriodicSchedule.builder()
.startDate(DATE_14_06_09)
.endDate(DATE_19_06_09)
.frequency(P12M)
.businessDayAdjustment(bda)
.build();
PaymentSchedule paymentSchedule = PaymentSchedule.builder()
.paymentFrequency(Frequency.ofYears(5))
.paymentDateOffset(DaysAdjustment.ofBusinessDays(2, GBLO))
.compoundingMethod(STRAIGHT)
.build();
FixedRateCalculation rateCalc = FixedRateCalculation.builder()
.rate(ValueSchedule.of(0.05))
.dayCount(ONE_ONE) // year fraction is always 1.
.build();
NotionalSchedule notionalSchedule = NotionalSchedule.of(GBP, 1000d);
RateCalculationSwapLeg test = RateCalculationSwapLeg.builder()
.payReceive(RECEIVE)
.accrualSchedule(accrualSchedule)
.paymentSchedule(paymentSchedule)
.notionalSchedule(notionalSchedule)
.calculation(rateCalc)
.build();
assertEquals(test.getStartDate(), AdjustableDate.of(DATE_14_06_09, bda));
assertEquals(test.getEndDate(), AdjustableDate.of(DATE_19_06_09, bda));
assertEquals(test.getCurrency(), GBP);
assertEquals(test.getPayReceive(), RECEIVE);
assertEquals(test.getAccrualSchedule(), accrualSchedule);
assertEquals(test.getPaymentSchedule(), paymentSchedule);
assertEquals(test.getNotionalSchedule(), notionalSchedule);
assertEquals(test.getCalculation(), rateCalc);
RateAccrualPeriod rap0 = RateAccrualPeriod.builder()
.startDate(bda.adjust(DATE_14_06_09, REF_DATA))
.endDate(bda.adjust(DATE_14_06_09.plusYears(1), REF_DATA))
.unadjustedStartDate(DATE_14_06_09)
.unadjustedEndDate(DATE_14_06_09.plusYears(1))
.yearFraction(1.0)
.rateComputation(FixedRateComputation.of(0.05))
.build();
RateAccrualPeriod rap1 = RateAccrualPeriod.builder()
.startDate(bda.adjust(DATE_14_06_09.plusYears(1), REF_DATA))
.endDate(bda.adjust(DATE_14_06_09.plusYears(2), REF_DATA))
.unadjustedStartDate(DATE_14_06_09.plusYears(1))
.unadjustedEndDate(DATE_14_06_09.plusYears(2))
.yearFraction(1.0)
.rateComputation(FixedRateComputation.of(0.05))
.build();
RateAccrualPeriod rap2 = RateAccrualPeriod.builder()
.startDate(bda.adjust(DATE_14_06_09.plusYears(2), REF_DATA))
.endDate(bda.adjust(DATE_14_06_09.plusYears(3), REF_DATA))
.unadjustedStartDate(DATE_14_06_09.plusYears(2))
.unadjustedEndDate(DATE_14_06_09.plusYears(3))
.yearFraction(1.0)
.rateComputation(FixedRateComputation.of(0.05))
.build();
RateAccrualPeriod rap3 = RateAccrualPeriod.builder()
.startDate(bda.adjust(DATE_14_06_09.plusYears(3), REF_DATA))
.endDate(bda.adjust(DATE_14_06_09.plusYears(4), REF_DATA))
.unadjustedStartDate(DATE_14_06_09.plusYears(3))
.unadjustedEndDate(DATE_14_06_09.plusYears(4))
.yearFraction(1.0)
.rateComputation(FixedRateComputation.of(0.05))
.build();
RateAccrualPeriod rap4 = RateAccrualPeriod.builder()
.startDate(bda.adjust(DATE_14_06_09.plusYears(4), REF_DATA))
.endDate(bda.adjust(DATE_19_06_09, REF_DATA))
.unadjustedStartDate(DATE_14_06_09.plusYears(4))
.unadjustedEndDate(DATE_19_06_09)
.yearFraction(1.0)
.rateComputation(FixedRateComputation.of(0.05))
.build();
RatePaymentPeriod rpp = RatePaymentPeriod.builder()
.paymentDate(DaysAdjustment.ofBusinessDays(2, GBLO).adjust(bda.adjust(DATE_19_06_09, REF_DATA), REF_DATA))
.accrualPeriods(rap0, rap1, rap2, rap3, rap4)
.compoundingMethod(STRAIGHT)
.dayCount(ONE_ONE)
.currency(GBP)
.notional(1000d)
.build();
ResolvedSwapLeg expected = ResolvedSwapLeg.builder()
.paymentPeriods(rpp)
.payReceive(RECEIVE)
.type(SwapLegType.FIXED)
.build();
ResolvedSwapLeg testExpand = test.resolve(REF_DATA);
assertEquals(testExpand, expected);
}
//-------------------------------------------------------------------------
public void coverage() {
RateCalculationSwapLeg test = RateCalculationSwapLeg.builder()
.payReceive(PAY)
.accrualSchedule(PeriodicSchedule.builder()
.startDate(DATE_01_05)
.endDate(DATE_04_05)
.frequency(P1M)
.businessDayAdjustment(BusinessDayAdjustment.of(FOLLOWING, GBLO))
.build())
.paymentSchedule(PaymentSchedule.builder()
.paymentFrequency(P1M)
.paymentDateOffset(PLUS_TWO_DAYS)
.build())
.notionalSchedule(NotionalSchedule.of(GBP, 1000d))
.calculation(FixedRateCalculation.builder()
.dayCount(ACT_365F)
.rate(ValueSchedule.of(0.025d))
.build())
.build();
coverImmutableBean(test);
RateCalculationSwapLeg test2 = RateCalculationSwapLeg.builder()
.payReceive(RECEIVE)
.accrualSchedule(PeriodicSchedule.builder()
.startDate(DATE_02_05)
.endDate(DATE_03_05)
.frequency(P1M)
.businessDayAdjustment(BusinessDayAdjustment.of(FOLLOWING, GBLO))
.build())
.paymentSchedule(PaymentSchedule.builder()
.paymentFrequency(P1M)
.paymentDateOffset(PLUS_THREE_DAYS)
.build())
.notionalSchedule(NotionalSchedule.of(GBP, 2000d))
.calculation(FixedRateCalculation.builder()
.dayCount(ACT_360)
.rate(ValueSchedule.of(0.025d))
.build())
.build();
coverBeanEquals(test, test2);
}
public void test_serialization() {
RateCalculationSwapLeg test = RateCalculationSwapLeg.builder()
.payReceive(PAY)
.accrualSchedule(PeriodicSchedule.builder()
.startDate(DATE_01_05)
.endDate(DATE_04_05)
.frequency(P1M)
.businessDayAdjustment(BusinessDayAdjustment.of(FOLLOWING, GBLO))
.build())
.paymentSchedule(PaymentSchedule.builder()
.paymentFrequency(P1M)
.paymentDateOffset(PLUS_TWO_DAYS)
.build())
.notionalSchedule(NotionalSchedule.of(GBP, 1000d))
.calculation(FixedRateCalculation.builder()
.dayCount(DayCounts.ACT_365F)
.rate(ValueSchedule.of(0.025d))
.build())
.build();
assertSerialization(test);
}
}