/**
* Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.pricer.swap;
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.BusinessDayConventions.FOLLOWING;
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.date.Tenor.TENOR_10Y;
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.collect.TestHelper.assertThrowsIllegalArg;
import static com.opengamma.strata.collect.TestHelper.date;
import static com.opengamma.strata.pricer.swap.SwapDummyData.FIXED_CMP_FLAT_SWAP_LEG_PAY_GBP;
import static com.opengamma.strata.pricer.swap.SwapDummyData.FIXED_CMP_NONE_SWAP_LEG_PAY_GBP;
import static com.opengamma.strata.pricer.swap.SwapDummyData.FIXED_FX_RESET_SWAP_LEG_PAY_GBP;
import static com.opengamma.strata.pricer.swap.SwapDummyData.FIXED_RATE_ACCRUAL_PERIOD;
import static com.opengamma.strata.pricer.swap.SwapDummyData.FIXED_RATE_ACCRUAL_PERIOD_2;
import static com.opengamma.strata.pricer.swap.SwapDummyData.FIXED_RATE_PAYMENT_PERIOD_CMP_FLAT_REC_GBP;
import static com.opengamma.strata.pricer.swap.SwapDummyData.FIXED_RATE_PAYMENT_PERIOD_PAY_USD;
import static com.opengamma.strata.pricer.swap.SwapDummyData.FIXED_RATE_PAYMENT_PERIOD_PAY_USD_2;
import static com.opengamma.strata.pricer.swap.SwapDummyData.FIXED_SWAP_LEG_PAY_USD;
import static com.opengamma.strata.pricer.swap.SwapDummyData.FIXED_SWAP_LEG_REC_USD;
import static com.opengamma.strata.pricer.swap.SwapDummyData.IBOR_RATE_COMP;
import static com.opengamma.strata.pricer.swap.SwapDummyData.IBOR_RATE_PAYMENT_PERIOD_REC_GBP;
import static com.opengamma.strata.pricer.swap.SwapDummyData.IBOR_RATE_PAYMENT_PERIOD_REC_GBP_2;
import static com.opengamma.strata.pricer.swap.SwapDummyData.IBOR_SWAP_LEG_REC_GBP;
import static com.opengamma.strata.pricer.swap.SwapDummyData.IBOR_SWAP_LEG_REC_GBP_MULTI;
import static com.opengamma.strata.pricer.swap.SwapDummyData.NOTIONAL_EXCHANGE_REC_GBP;
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.type.IborIborSwapConventions.USD_LIBOR_3M_LIBOR_6M;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import java.time.LocalDate;
import java.time.Period;
import java.util.Map;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.opengamma.strata.basics.ReferenceData;
import com.opengamma.strata.basics.currency.Currency;
import com.opengamma.strata.basics.currency.CurrencyAmount;
import com.opengamma.strata.basics.currency.MultiCurrencyAmount;
import com.opengamma.strata.basics.date.BusinessDayAdjustment;
import com.opengamma.strata.basics.date.DaysAdjustment;
import com.opengamma.strata.basics.schedule.Frequency;
import com.opengamma.strata.basics.schedule.PeriodicSchedule;
import com.opengamma.strata.basics.value.ValueDerivatives;
import com.opengamma.strata.basics.value.ValueSchedule;
import com.opengamma.strata.collect.array.DoubleArray;
import com.opengamma.strata.collect.timeseries.LocalDateDoubleTimeSeries;
import com.opengamma.strata.market.amount.CashFlow;
import com.opengamma.strata.market.amount.CashFlows;
import com.opengamma.strata.market.curve.Curve;
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.param.CurrencyParameterSensitivities;
import com.opengamma.strata.market.param.CurrencyParameterSensitivity;
import com.opengamma.strata.market.sensitivity.PointSensitivities;
import com.opengamma.strata.market.sensitivity.PointSensitivityBuilder;
import com.opengamma.strata.pricer.ZeroRateSensitivity;
import com.opengamma.strata.pricer.datasets.RatesProviderDataSets;
import com.opengamma.strata.pricer.impl.MockRatesProvider;
import com.opengamma.strata.pricer.impl.rate.ForwardInflationInterpolatedRateComputationFn;
import com.opengamma.strata.pricer.impl.rate.ForwardInflationMonthlyRateComputationFn;
import com.opengamma.strata.pricer.impl.swap.DispatchingSwapPaymentEventPricer;
import com.opengamma.strata.pricer.rate.IborRateSensitivity;
import com.opengamma.strata.pricer.rate.ImmutableRatesProvider;
import com.opengamma.strata.pricer.rate.RatesProvider;
import com.opengamma.strata.pricer.sensitivity.RatesFiniteDifferenceSensitivityCalculator;
import com.opengamma.strata.product.common.BuySell;
import com.opengamma.strata.product.common.PayReceive;
import com.opengamma.strata.product.rate.InflationInterpolatedRateComputation;
import com.opengamma.strata.product.rate.InflationMonthlyRateComputation;
import com.opengamma.strata.product.swap.FixedRateCalculation;
import com.opengamma.strata.product.swap.InflationRateCalculation;
import com.opengamma.strata.product.swap.NotionalExchange;
import com.opengamma.strata.product.swap.NotionalSchedule;
import com.opengamma.strata.product.swap.SwapPaymentEvent;
import com.opengamma.strata.product.swap.SwapPaymentPeriod;
import com.opengamma.strata.product.swap.PaymentSchedule;
import com.opengamma.strata.product.swap.RateAccrualPeriod;
import com.opengamma.strata.product.swap.RateCalculationSwapLeg;
import com.opengamma.strata.product.swap.RatePaymentPeriod;
import com.opengamma.strata.product.swap.ResolvedSwap;
import com.opengamma.strata.product.swap.ResolvedSwapLeg;
import com.opengamma.strata.product.swap.SwapLeg;
import com.opengamma.strata.product.swap.SwapLegType;
import com.opengamma.strata.product.swap.SwapTrade;
import com.opengamma.strata.product.swap.type.FixedInflationSwapConvention;
import com.opengamma.strata.product.swap.type.FixedInflationSwapConventions;
import com.opengamma.strata.product.swap.type.IborIborSwapConventions;
/**
* Tests {@link DiscountingSwapLegPricer}.
*/
@Test
public class DiscountingSwapLegPricerTest {
private static final RatesProvider MOCK_PROV = new MockRatesProvider(RatesProviderDataSets.VAL_DATE_2014_01_22);
private static final RatesProvider MOCK_PROV_FUTURE = new MockRatesProvider(date(2040, 1, 22));
private static final ReferenceData REF_DATA = ReferenceData.standard();
private static final double TOLERANCE = 1.0e-12;
private static final double TOLERANCE_DELTA = 1.0E+0;
private static final double TOLERANCE_PVBP_FD = 1.0E-4;
private static final DiscountingSwapLegPricer PRICER_LEG = DiscountingSwapLegPricer.DEFAULT;
private static final ImmutableRatesProvider RATES_GBP = RatesProviderDataSets.MULTI_GBP;
private static final ImmutableRatesProvider RATES_USD = RatesProviderDataSets.MULTI_USD;
private static final ImmutableRatesProvider RATES_GBP_USD = RatesProviderDataSets.MULTI_GBP_USD;
private static final double FD_SHIFT = 1.0E-7;
private static final RatesFiniteDifferenceSensitivityCalculator FINITE_DIFFERENCE_CALCULATOR =
new RatesFiniteDifferenceSensitivityCalculator(FD_SHIFT);
//-------------------------------------------------------------------------
public void test_getters() {
assertEquals(DiscountingSwapLegPricer.DEFAULT.getPeriodPricer(), SwapPaymentPeriodPricer.standard());
assertEquals(DiscountingSwapLegPricer.DEFAULT.getEventPricer(), SwapPaymentEventPricer.standard());
}
//-------------------------------------------------------------------------
public void test_couponEquivalent_twoPeriods() {
ResolvedSwapLeg leg = ResolvedSwapLeg.builder()
.type(FIXED)
.payReceive(PAY)
.paymentPeriods(FIXED_RATE_PAYMENT_PERIOD_PAY_USD, FIXED_RATE_PAYMENT_PERIOD_PAY_USD_2)
.build();
RatesProvider mockProv = mock(RatesProvider.class);
double df1 = 0.99d;
when(mockProv.discountFactor(USD, FIXED_RATE_PAYMENT_PERIOD_PAY_USD.getPaymentDate()))
.thenReturn(df1);
double df2 = 0.98d;
when(mockProv.discountFactor(USD, FIXED_RATE_PAYMENT_PERIOD_PAY_USD_2.getPaymentDate()))
.thenReturn(df2);
when(mockProv.getValuationDate()).thenReturn(RatesProviderDataSets.VAL_DATE_2014_01_22);
double pvbp = PRICER_LEG.pvbp(leg, mockProv);
double ceExpected = PRICER_LEG.presentValuePeriodsInternal(leg, mockProv) / pvbp;
double ceComputed = PRICER_LEG.couponEquivalent(leg, mockProv, pvbp);
assertEquals(ceComputed, ceExpected, TOLERANCE);
}
//-------------------------------------------------------------------------
public void test_pvbp_onePeriod() {
RatesProvider mockProv = mock(RatesProvider.class);
double df = 0.99d;
when(mockProv.discountFactor(USD, FIXED_RATE_PAYMENT_PERIOD_PAY_USD.getPaymentDate()))
.thenReturn(df);
double expected = df * FIXED_RATE_PAYMENT_PERIOD_PAY_USD.getNotional() *
FIXED_RATE_PAYMENT_PERIOD_PAY_USD.getAccrualPeriods().get(0).getYearFraction();
DiscountingSwapLegPricer test = DiscountingSwapLegPricer.DEFAULT;
assertEquals(test.pvbp(FIXED_SWAP_LEG_PAY_USD, mockProv), expected, TOLERANCE);
}
public void test_pvbp_twoPeriods() {
ResolvedSwapLeg leg = ResolvedSwapLeg.builder()
.type(FIXED)
.payReceive(PAY)
.paymentPeriods(FIXED_RATE_PAYMENT_PERIOD_PAY_USD, FIXED_RATE_PAYMENT_PERIOD_PAY_USD_2)
.build();
RatesProvider mockProv = mock(RatesProvider.class);
double df1 = 0.99d;
when(mockProv.discountFactor(USD, FIXED_RATE_PAYMENT_PERIOD_PAY_USD.getPaymentDate()))
.thenReturn(df1);
double df2 = 0.98d;
when(mockProv.discountFactor(USD, FIXED_RATE_PAYMENT_PERIOD_PAY_USD_2.getPaymentDate()))
.thenReturn(df2);
double expected = df1 * FIXED_RATE_PAYMENT_PERIOD_PAY_USD.getNotional() *
FIXED_RATE_PAYMENT_PERIOD_PAY_USD.getAccrualPeriods().get(0).getYearFraction();
expected += df2 * FIXED_RATE_PAYMENT_PERIOD_PAY_USD_2.getNotional() *
FIXED_RATE_PAYMENT_PERIOD_PAY_USD_2.getAccrualPeriods().get(0).getYearFraction();
DiscountingSwapLegPricer test = DiscountingSwapLegPricer.DEFAULT;
assertEquals(test.pvbp(leg, mockProv), expected, TOLERANCE);
}
public void test_pvbp_compounding_flat_fixed() {
DiscountingSwapLegPricer test = DiscountingSwapLegPricer.DEFAULT;
SwapPaymentPeriod p = FIXED_CMP_FLAT_SWAP_LEG_PAY_GBP.getPaymentPeriods().get(0);
RatesProvider mockProv = mock(RatesProvider.class);
when(mockProv.getValuationDate()).thenReturn(RatesProviderDataSets.VAL_DATE_2014_01_22);
double df1 = 0.99d;
when(mockProv.discountFactor(GBP, p.getPaymentDate()))
.thenReturn(df1);
double spread = 1.0E-6;
RateAccrualPeriod ap1 = FIXED_RATE_ACCRUAL_PERIOD.toBuilder().spread(spread).build();
RateAccrualPeriod ap2 = FIXED_RATE_ACCRUAL_PERIOD_2.toBuilder().spread(spread).build();
RatePaymentPeriod pp = FIXED_RATE_PAYMENT_PERIOD_CMP_FLAT_REC_GBP.toBuilder().accrualPeriods(ap1, ap2).build();
ResolvedSwapLeg sl = FIXED_CMP_FLAT_SWAP_LEG_PAY_GBP.toBuilder().paymentPeriods(pp).build();
CurrencyAmount pv0 = PRICER_LEG.presentValue(FIXED_CMP_FLAT_SWAP_LEG_PAY_GBP, mockProv);
CurrencyAmount pvP = PRICER_LEG.presentValue(sl, mockProv);
double pvbpExpected = (pvP.getAmount() - pv0.getAmount()) / spread;
double pvbpComputed = test.pvbp(FIXED_CMP_FLAT_SWAP_LEG_PAY_GBP, mockProv);
assertEquals(pvbpComputed, pvbpExpected, TOLERANCE_PVBP_FD);
}
public void test_pvbp_compounding_flat_ibor() {
LocalDate tradeDate = RATES_USD.getValuationDate();
LocalDate effectiveDate = USD_LIBOR_3M_LIBOR_6M.calculateSpotDateFromTradeDate(tradeDate, REF_DATA);
LocalDate endDate = effectiveDate.plus(TENOR_10Y);
double spread = 0.0015;
double shift = 1.0E-6;
RateCalculationSwapLeg leg0 = IborIborSwapConventions.USD_LIBOR_3M_LIBOR_6M.getSpreadLeg()
.toLeg(effectiveDate, endDate, RECEIVE, NOTIONAL, spread);
RateCalculationSwapLeg legP = IborIborSwapConventions.USD_LIBOR_3M_LIBOR_6M.getSpreadLeg()
.toLeg(effectiveDate, endDate, RECEIVE, NOTIONAL, spread + shift);
double parSpread = PRICER_LEG.pvbp(leg0.resolve(REF_DATA), RATES_USD);
double pv0 = PRICER_LEG.presentValue(leg0.resolve(REF_DATA), RATES_USD).getAmount();
double pvP = PRICER_LEG.presentValue(legP.resolve(REF_DATA), RATES_USD).getAmount();
double parSpreadExpected = (pvP - pv0) / shift;
assertEquals(parSpread, parSpreadExpected, TOLERANCE_PVBP_FD);
}
public void test_pvbp_fxReset() {
DiscountingSwapLegPricer test = DiscountingSwapLegPricer.DEFAULT;
assertThrowsIllegalArg(() -> test.pvbp(FIXED_FX_RESET_SWAP_LEG_PAY_GBP, MOCK_PROV));
}
public void test_pvbp_compounding_none() {
DiscountingSwapLegPricer test = DiscountingSwapLegPricer.DEFAULT;
assertThrowsIllegalArg(() -> test.pvbp(FIXED_CMP_NONE_SWAP_LEG_PAY_GBP, MOCK_PROV));
}
//-------------------------------------------------------------------------
public void test_presentValue_withCurrency() {
SwapPaymentPeriodPricer<SwapPaymentPeriod> mockPeriod = mock(SwapPaymentPeriodPricer.class);
when(mockPeriod.presentValue(IBOR_RATE_PAYMENT_PERIOD_REC_GBP, MOCK_PROV))
.thenReturn(1000d);
SwapPaymentEventPricer<SwapPaymentEvent> mockEvent = mock(SwapPaymentEventPricer.class);
when(mockEvent.presentValue(NOTIONAL_EXCHANGE_REC_GBP, MOCK_PROV))
.thenReturn(1000d);
DiscountingSwapLegPricer test = new DiscountingSwapLegPricer(mockPeriod, mockEvent);
CurrencyAmount expected = CurrencyAmount.of(USD, 2000d * 1.6d);
assertEquals(test.presentValue(IBOR_SWAP_LEG_REC_GBP, USD, MOCK_PROV), expected);
}
public void test_presentValue_withCurrency_past() {
SwapPaymentPeriodPricer<SwapPaymentPeriod> mockPeriod = mock(SwapPaymentPeriodPricer.class);
SwapPaymentEventPricer<SwapPaymentEvent> mockEvent = mock(SwapPaymentEventPricer.class);
DiscountingSwapLegPricer test = new DiscountingSwapLegPricer(mockPeriod, mockEvent);
CurrencyAmount expected = CurrencyAmount.of(USD, 0d);
assertEquals(test.presentValue(IBOR_SWAP_LEG_REC_GBP, USD, MOCK_PROV_FUTURE), expected);
}
//-------------------------------------------------------------------------
public void test_presentValue() {
SwapPaymentPeriodPricer<SwapPaymentPeriod> mockPeriod = mock(SwapPaymentPeriodPricer.class);
when(mockPeriod.presentValue(IBOR_RATE_PAYMENT_PERIOD_REC_GBP, MOCK_PROV))
.thenReturn(500d);
SwapPaymentEventPricer<SwapPaymentEvent> mockEvent = mock(SwapPaymentEventPricer.class);
when(mockEvent.presentValue(NOTIONAL_EXCHANGE_REC_GBP, MOCK_PROV))
.thenReturn(1000d);
DiscountingSwapLegPricer test = new DiscountingSwapLegPricer(mockPeriod, mockEvent);
CurrencyAmount expected = CurrencyAmount.of(GBP, 1500d);
assertEquals(test.presentValue(IBOR_SWAP_LEG_REC_GBP, MOCK_PROV), expected);
}
public void test_presentValue_past() {
SwapPaymentPeriodPricer<SwapPaymentPeriod> mockPeriod = mock(SwapPaymentPeriodPricer.class);
SwapPaymentEventPricer<SwapPaymentEvent> mockEvent = mock(SwapPaymentEventPricer.class);
DiscountingSwapLegPricer test = new DiscountingSwapLegPricer(mockPeriod, mockEvent);
CurrencyAmount expected = CurrencyAmount.of(GBP, 0d);
assertEquals(test.presentValue(IBOR_SWAP_LEG_REC_GBP, MOCK_PROV_FUTURE), expected);
}
public void test_presentValue_events() {
SwapPaymentPeriodPricer<SwapPaymentPeriod> mockPeriod = mock(SwapPaymentPeriodPricer.class);
when(mockPeriod.presentValue(IBOR_RATE_PAYMENT_PERIOD_REC_GBP, MOCK_PROV))
.thenReturn(500d);
SwapPaymentEventPricer<SwapPaymentEvent> mockEvent = mock(SwapPaymentEventPricer.class);
when(mockEvent.presentValue(NOTIONAL_EXCHANGE_REC_GBP, MOCK_PROV))
.thenReturn(1000d);
DiscountingSwapLegPricer test = new DiscountingSwapLegPricer(mockPeriod, mockEvent);
assertEquals(test.presentValueEventsInternal(IBOR_SWAP_LEG_REC_GBP, MOCK_PROV), 1000d);
}
public void test_presentValue_periods() {
SwapPaymentPeriodPricer<SwapPaymentPeriod> mockPeriod = mock(SwapPaymentPeriodPricer.class);
when(mockPeriod.presentValue(IBOR_RATE_PAYMENT_PERIOD_REC_GBP, MOCK_PROV))
.thenReturn(500d);
SwapPaymentEventPricer<SwapPaymentEvent> mockEvent = mock(SwapPaymentEventPricer.class);
when(mockEvent.presentValue(NOTIONAL_EXCHANGE_REC_GBP, MOCK_PROV))
.thenReturn(1000d);
DiscountingSwapLegPricer test = new DiscountingSwapLegPricer(mockPeriod, mockEvent);
assertEquals(test.presentValuePeriodsInternal(IBOR_SWAP_LEG_REC_GBP, MOCK_PROV), 500d);
}
//-------------------------------------------------------------------------
public void test_forecastValue() {
SwapPaymentPeriodPricer<SwapPaymentPeriod> mockPeriod = mock(SwapPaymentPeriodPricer.class);
when(mockPeriod.forecastValue(IBOR_RATE_PAYMENT_PERIOD_REC_GBP, MOCK_PROV))
.thenReturn(1000d);
SwapPaymentEventPricer<SwapPaymentEvent> mockEvent = mock(SwapPaymentEventPricer.class);
when(mockEvent.forecastValue(NOTIONAL_EXCHANGE_REC_GBP, MOCK_PROV))
.thenReturn(1000d);
DiscountingSwapLegPricer test = new DiscountingSwapLegPricer(mockPeriod, mockEvent);
CurrencyAmount expected = CurrencyAmount.of(GBP, 2000d);
assertEquals(test.forecastValue(IBOR_SWAP_LEG_REC_GBP, MOCK_PROV), expected);
}
public void test_forecastValue_past() {
SwapPaymentPeriodPricer<SwapPaymentPeriod> mockPeriod = mock(SwapPaymentPeriodPricer.class);
SwapPaymentEventPricer<SwapPaymentEvent> mockEvent = mock(SwapPaymentEventPricer.class);
DiscountingSwapLegPricer test = new DiscountingSwapLegPricer(mockPeriod, mockEvent);
CurrencyAmount expected = CurrencyAmount.of(GBP, 0d);
assertEquals(test.forecastValue(IBOR_SWAP_LEG_REC_GBP, MOCK_PROV_FUTURE), expected);
}
//-------------------------------------------------------------------------
public void test_accruedInterest_firstAccrualPeriod() {
RatesProvider prov = new MockRatesProvider(IBOR_RATE_PAYMENT_PERIOD_REC_GBP.getStartDate().plusDays(7));
SwapPaymentPeriodPricer<SwapPaymentPeriod> mockPeriod = mock(SwapPaymentPeriodPricer.class);
when(mockPeriod.accruedInterest(IBOR_RATE_PAYMENT_PERIOD_REC_GBP, prov))
.thenReturn(1000d);
SwapPaymentEventPricer<SwapPaymentEvent> mockEvent = mock(SwapPaymentEventPricer.class);
DiscountingSwapLegPricer test = new DiscountingSwapLegPricer(mockPeriod, mockEvent);
CurrencyAmount expected = CurrencyAmount.of(GBP, 1000d);
assertEquals(test.accruedInterest(IBOR_SWAP_LEG_REC_GBP, prov), expected);
}
public void test_accruedInterest_valDateBeforePeriod() {
RatesProvider prov = new MockRatesProvider(IBOR_RATE_PAYMENT_PERIOD_REC_GBP.getStartDate());
SwapPaymentPeriodPricer<SwapPaymentPeriod> mockPeriod = mock(SwapPaymentPeriodPricer.class);
when(mockPeriod.accruedInterest(IBOR_RATE_PAYMENT_PERIOD_REC_GBP, prov))
.thenReturn(1000d);
SwapPaymentEventPricer<SwapPaymentEvent> mockEvent = mock(SwapPaymentEventPricer.class);
DiscountingSwapLegPricer test = new DiscountingSwapLegPricer(mockPeriod, mockEvent);
assertEquals(test.accruedInterest(IBOR_SWAP_LEG_REC_GBP, prov), CurrencyAmount.zero(GBP));
}
public void test_accruedInterest_valDateAfterPeriod() {
RatesProvider prov = new MockRatesProvider(IBOR_RATE_PAYMENT_PERIOD_REC_GBP.getEndDate().plusDays(1));
SwapPaymentPeriodPricer<SwapPaymentPeriod> mockPeriod = mock(SwapPaymentPeriodPricer.class);
when(mockPeriod.accruedInterest(IBOR_RATE_PAYMENT_PERIOD_REC_GBP, prov))
.thenReturn(1000d);
SwapPaymentEventPricer<SwapPaymentEvent> mockEvent = mock(SwapPaymentEventPricer.class);
DiscountingSwapLegPricer test = new DiscountingSwapLegPricer(mockPeriod, mockEvent);
assertEquals(test.accruedInterest(IBOR_SWAP_LEG_REC_GBP, prov), CurrencyAmount.zero(GBP));
}
//-------------------------------------------------------------------------
public void test_presentValueSensitivity() {
ResolvedSwapLeg expSwapLeg = IBOR_SWAP_LEG_REC_GBP;
Currency ccy = GBP_LIBOR_3M.getCurrency();
IborRateSensitivity fwdSense = IborRateSensitivity.of(IBOR_RATE_COMP.getObservation(), 140.0);
ZeroRateSensitivity dscSense = ZeroRateSensitivity.of(ccy, 3d, -162.0);
PointSensitivityBuilder sensiPeriod = fwdSense.combinedWith(dscSense);
PointSensitivityBuilder sensiEvent = ZeroRateSensitivity.of(ccy, 4d, -134.0);
PointSensitivities expected = sensiPeriod.build().combinedWith(sensiEvent.build());
SwapPaymentPeriodPricer<SwapPaymentPeriod> mockPeriod = mock(SwapPaymentPeriodPricer.class);
SwapPaymentEventPricer<SwapPaymentEvent> mockEvent = mock(SwapPaymentEventPricer.class);
when(mockPeriod.presentValueSensitivity(expSwapLeg.getPaymentPeriods().get(0), MOCK_PROV))
.thenReturn(sensiPeriod);
when(mockEvent.presentValueSensitivity(expSwapLeg.getPaymentEvents().get(0), MOCK_PROV))
.thenReturn(sensiEvent);
DiscountingSwapLegPricer test = new DiscountingSwapLegPricer(mockPeriod, mockEvent);
PointSensitivities res = test.presentValueSensitivity(expSwapLeg, MOCK_PROV).build();
assertTrue(res.equalWithTolerance(expected, TOLERANCE));
}
public void test_presentValueSensitivity_finiteDifference() {
ResolvedSwapLeg expSwapLeg = IBOR_SWAP_LEG_REC_GBP;
PointSensitivities point = PRICER_LEG.presentValueSensitivity(expSwapLeg, RATES_GBP).build();
CurrencyParameterSensitivities psAd = RATES_GBP.parameterSensitivity(point);
CurrencyParameterSensitivities psFd =
FINITE_DIFFERENCE_CALCULATOR.sensitivity(RATES_GBP, (p) -> PRICER_LEG.presentValue(expSwapLeg, p));
ImmutableList<CurrencyParameterSensitivity> listAd = psAd.getSensitivities();
ImmutableList<CurrencyParameterSensitivity> listFd = psFd.getSensitivities();
assertEquals(listAd.size(), 2); // No Libor 6M sensitivity
assertEquals(listFd.size(), 3); // Libor 6M sensitivity equal to 0 in Finite Difference
assertTrue(psAd.equalWithTolerance(psFd, TOLERANCE_DELTA));
}
public void test_presentValueSensitivity_events() {
ResolvedSwapLeg expSwapLeg = IBOR_SWAP_LEG_REC_GBP;
PointSensitivities point = PRICER_LEG.presentValueSensitivityEventsInternal(expSwapLeg, RATES_GBP).build();
CurrencyParameterSensitivities psAd = RATES_GBP.parameterSensitivity(point);
CurrencyParameterSensitivities psFd = FINITE_DIFFERENCE_CALCULATOR.sensitivity(RATES_GBP,
(p) -> CurrencyAmount.of(GBP, PRICER_LEG.presentValueEventsInternal(expSwapLeg, p)));
assertTrue(psAd.equalWithTolerance(psFd, TOLERANCE_DELTA));
}
public void test_presentValueSensitivity_periods() {
ResolvedSwapLeg expSwapLeg = IBOR_SWAP_LEG_REC_GBP;
PointSensitivities point = PRICER_LEG.presentValueSensitivityPeriodsInternal(expSwapLeg, RATES_GBP).build();
CurrencyParameterSensitivities psAd = RATES_GBP.parameterSensitivity(point);
CurrencyParameterSensitivities psFd = FINITE_DIFFERENCE_CALCULATOR.sensitivity(RATES_GBP,
(p) -> CurrencyAmount.of(GBP, PRICER_LEG.presentValuePeriodsInternal(expSwapLeg, p)));
assertTrue(psAd.equalWithTolerance(psFd, TOLERANCE_DELTA));
}
//-------------------------------------------------------------------------
public void test_pvbpSensitivity() {
ResolvedSwapLeg leg = ResolvedSwapLeg.builder()
.type(FIXED)
.payReceive(PAY)
.paymentPeriods(FIXED_RATE_PAYMENT_PERIOD_PAY_USD, FIXED_RATE_PAYMENT_PERIOD_PAY_USD_2)
.build();
PointSensitivities point = PRICER_LEG.pvbpSensitivity(leg, RATES_USD).build();
CurrencyParameterSensitivities pvbpsAd = RATES_USD.parameterSensitivity(point);
CurrencyParameterSensitivities pvbpsFd = FINITE_DIFFERENCE_CALCULATOR.sensitivity(RATES_USD,
(p) -> CurrencyAmount.of(USD, PRICER_LEG.pvbp(leg, p)));
assertTrue(pvbpsAd.equalWithTolerance(pvbpsFd, TOLERANCE_DELTA));
}
public void test_pvbpSensitivity_FxReset() {
DiscountingSwapLegPricer test = DiscountingSwapLegPricer.DEFAULT;
assertThrowsIllegalArg(() -> test.pvbpSensitivity(FIXED_FX_RESET_SWAP_LEG_PAY_GBP, MOCK_PROV));
}
public void test_pvbpSensitivity_Compounding() {
DiscountingSwapLegPricer test = DiscountingSwapLegPricer.DEFAULT;
assertThrowsIllegalArg(() -> test.pvbpSensitivity(FIXED_CMP_NONE_SWAP_LEG_PAY_GBP, MOCK_PROV));
}
public void test_pvbpSensitivity_compounding_flat_ibor() {
LocalDate tradeDate = RATES_USD.getValuationDate();
LocalDate effectiveDate = USD_LIBOR_3M_LIBOR_6M.calculateSpotDateFromTradeDate(tradeDate, REF_DATA);
LocalDate endDate = effectiveDate.plus(TENOR_10Y);
double spread = 0.0015;
RateCalculationSwapLeg leg = IborIborSwapConventions.USD_LIBOR_3M_LIBOR_6M.getSpreadLeg()
.toLeg(effectiveDate, endDate, RECEIVE, NOTIONAL, spread);
PointSensitivities pvbppts = PRICER_LEG.pvbpSensitivity(leg.resolve(REF_DATA), RATES_USD).build();
CurrencyParameterSensitivities psAd = RATES_USD.parameterSensitivity(pvbppts);
CurrencyParameterSensitivities psFd = FINITE_DIFFERENCE_CALCULATOR.sensitivity(
RATES_USD,
(p) -> CurrencyAmount.of(USD, PRICER_LEG.pvbp(leg.resolve(REF_DATA), p)));
ImmutableList<CurrencyParameterSensitivity> listAd = psAd.getSensitivities();
ImmutableList<CurrencyParameterSensitivity> listFd = psFd.getSensitivities();
assertEquals(listAd.size(), 2); // No Libor 6M sensitivity
assertEquals(listFd.size(), 3); // Libor 6M sensitivity equal to 0 in Finite Difference
assertTrue(psAd.equalWithTolerance(psFd, TOLERANCE_DELTA));
}
//-------------------------------------------------------------------------
public void test_forecastValueSensitivity() {
ResolvedSwapLeg expSwapLeg = IBOR_SWAP_LEG_REC_GBP;
PointSensitivityBuilder sensiPeriod = IborRateSensitivity.of(IBOR_RATE_COMP.getObservation(), 140.0);
PointSensitivities expected = sensiPeriod.build();
SwapPaymentPeriodPricer<SwapPaymentPeriod> mockPeriod = mock(SwapPaymentPeriodPricer.class);
SwapPaymentEventPricer<SwapPaymentEvent> mockEvent = mock(SwapPaymentEventPricer.class);
when(mockPeriod.forecastValueSensitivity(expSwapLeg.getPaymentPeriods().get(0), MOCK_PROV))
.thenReturn(sensiPeriod);
when(mockEvent.forecastValueSensitivity(expSwapLeg.getPaymentEvents().get(0), MOCK_PROV))
.thenReturn(PointSensitivityBuilder.none());
DiscountingSwapLegPricer test = new DiscountingSwapLegPricer(mockPeriod, mockEvent);
PointSensitivities res = test.forecastValueSensitivity(expSwapLeg, MOCK_PROV).build();
assertTrue(res.equalWithTolerance(expected, TOLERANCE));
}
//-------------------------------------------------------------------------
public void test_annuityCash_onePeriod() {
double yield = 0.01;
DiscountingSwapLegPricer test = DiscountingSwapLegPricer.DEFAULT;
double computed = test.annuityCash(FIXED_SWAP_LEG_REC_USD, yield);
double expected = SwapDummyData.NOTIONAL * (1d - 1d / (1d + yield / 4d)) / yield;
assertEquals(computed, expected, SwapDummyData.NOTIONAL * TOLERANCE);
}
public void test_annuityCash_twoPeriods() {
ResolvedSwapLeg leg = ResolvedSwapLeg.builder()
.type(FIXED)
.payReceive(PAY)
.paymentPeriods(FIXED_RATE_PAYMENT_PERIOD_PAY_USD, FIXED_RATE_PAYMENT_PERIOD_PAY_USD_2)
.build();
double yield = 0.01;
DiscountingSwapLegPricer test = DiscountingSwapLegPricer.DEFAULT;
double computed = test.annuityCash(leg, yield);
double expected = SwapDummyData.NOTIONAL * (1d - Math.pow(1d + yield / 4d, -2)) / yield;
assertEquals(computed, expected, SwapDummyData.NOTIONAL * TOLERANCE);
}
public void test_annuityCashDerivative_onePeriod() {
double yield = 0.01;
DiscountingSwapLegPricer test = DiscountingSwapLegPricer.DEFAULT;
double computed = test.annuityCashDerivative(FIXED_SWAP_LEG_REC_USD, yield).getDerivative(0);
double expected = 0.5 * (test.annuityCash(FIXED_SWAP_LEG_REC_USD, yield + FD_SHIFT)
- test.annuityCash(FIXED_SWAP_LEG_REC_USD, yield - FD_SHIFT)) / FD_SHIFT;
assertEquals(computed, expected, SwapDummyData.NOTIONAL * FD_SHIFT);
}
public void test_annuityCashDerivative_twoPeriods() {
ResolvedSwapLeg leg = ResolvedSwapLeg.builder()
.type(FIXED)
.payReceive(PAY)
.paymentPeriods(FIXED_RATE_PAYMENT_PERIOD_PAY_USD, FIXED_RATE_PAYMENT_PERIOD_PAY_USD_2)
.build();
double yield = 0.01;
DiscountingSwapLegPricer test = DiscountingSwapLegPricer.DEFAULT;
double computed = test.annuityCashDerivative(leg, yield).getDerivative(0);
double expected = 0.5 / FD_SHIFT
* (test.annuityCash(leg, yield + FD_SHIFT) - test.annuityCash(leg, yield - FD_SHIFT));
assertEquals(computed, expected, SwapDummyData.NOTIONAL * FD_SHIFT);
}
//-------------------------------------------------------------------------
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 LocalDate DATE_14_03_31 = date(2014, 3, 31);
private static final double START_INDEX = 218.0;
private static final double NOTIONAL = 1000d;
private static final LocalDate VAL_DATE_INFLATION = date(2014, 7, 8);
private static final ImmutableRatesProvider RATES_GBP_INFLATION = RatesProviderDataSets.multiGbp(VAL_DATE_INFLATION);
private static final CurveInterpolator INTERPOLATOR = CurveInterpolators.LINEAR;
private static final double CONSTANT_INDEX = 242.0;
private static final Curve GBPRI_CURVE_FLAT = InterpolatedNodalCurve.of(
Curves.prices("GB_RPI_CURVE"),
DoubleArray.of(1, 200),
DoubleArray.of(CONSTANT_INDEX, CONSTANT_INDEX),
INTERPOLATOR);
private static final CurveInterpolator INTERP_SPLINE = CurveInterpolators.NATURAL_CUBIC_SPLINE;
private static final Curve GBPRI_CURVE = InterpolatedNodalCurve.of(
Curves.prices("GB_RPI_CURVE"),
DoubleArray.of(6, 12, 24, 60, 120),
DoubleArray.of(227.2, 252.6, 289.5, 323.1, 351.1),
INTERP_SPLINE);
private static final double EPS = 1.0e-14;
public void test_inflation_monthly() {
// setup
ResolvedSwapLeg swapLeg = createInflationSwapLeg(false, PAY).resolve(REF_DATA);
DiscountingSwapLegPricer pricer = DiscountingSwapLegPricer.DEFAULT;
Map<Currency, Curve> dscCurve = RATES_GBP_INFLATION.getDiscountCurves();
LocalDateDoubleTimeSeries ts = LocalDateDoubleTimeSeries.of(DATE_14_03_31, START_INDEX);
ImmutableRatesProvider prov = ImmutableRatesProvider.builder(VAL_DATE_INFLATION)
.discountCurves(dscCurve)
.priceIndexCurve(GB_RPI, GBPRI_CURVE_FLAT)
.timeSeries(GB_RPI, ts)
.build();
// test forecastValue and presentValue
CurrencyAmount fvComputed = pricer.forecastValue(swapLeg, prov);
CurrencyAmount pvComputed = pricer.presentValue(swapLeg, prov);
LocalDate paymentDate = swapLeg.getPaymentPeriods().get(0).getPaymentDate();
double dscFactor = prov.discountFactor(GBP, paymentDate);
double fvExpected = (CONSTANT_INDEX / START_INDEX - 1.0) * (-NOTIONAL);
assertEquals(fvComputed.getCurrency(), GBP);
assertEquals(fvComputed.getAmount(), fvExpected, NOTIONAL * EPS);
double pvExpected = dscFactor * fvExpected;
assertEquals(pvComputed.getCurrency(), GBP);
assertEquals(pvComputed.getAmount(), pvExpected, NOTIONAL * EPS);
// test forecastValueSensitivity and presentValueSensitivity
PointSensitivityBuilder fvSensiComputed = pricer.forecastValueSensitivity(swapLeg, prov);
PointSensitivityBuilder pvSensiComputed = pricer.presentValueSensitivity(swapLeg, prov);
ForwardInflationMonthlyRateComputationFn obsFn = ForwardInflationMonthlyRateComputationFn.DEFAULT;
RatePaymentPeriod paymentPeriod = (RatePaymentPeriod) swapLeg.getPaymentPeriods().get(0);
InflationMonthlyRateComputation obs =
(InflationMonthlyRateComputation) paymentPeriod.getAccrualPeriods().get(0).getRateComputation();
PointSensitivityBuilder pvSensiExpected = obsFn.rateSensitivity(obs, DATE_14_06_09, DATE_19_06_09, prov);
pvSensiExpected = pvSensiExpected.multipliedBy(-NOTIONAL);
assertTrue(fvSensiComputed.build().normalized()
.equalWithTolerance(pvSensiExpected.build().normalized(), EPS * NOTIONAL));
pvSensiExpected = pvSensiExpected.multipliedBy(dscFactor);
PointSensitivityBuilder dscSensiExpected = prov.discountFactors(GBP).zeroRatePointSensitivity(paymentDate);
dscSensiExpected = dscSensiExpected.multipliedBy(fvExpected);
pvSensiExpected = pvSensiExpected.combinedWith(dscSensiExpected);
assertTrue(pvSensiComputed.build().normalized()
.equalWithTolerance(pvSensiExpected.build().normalized(), EPS * NOTIONAL));
}
public void test_inflation_interpolated() {
// setup
ResolvedSwapLeg swapLeg = createInflationSwapLeg(true, RECEIVE).resolve(REF_DATA);
DiscountingSwapLegPricer pricer = DiscountingSwapLegPricer.DEFAULT;
Map<Currency, Curve> dscCurve = RATES_GBP_INFLATION.getDiscountCurves();
LocalDateDoubleTimeSeries ts = LocalDateDoubleTimeSeries.of(DATE_14_03_31, START_INDEX);
ImmutableRatesProvider prov = ImmutableRatesProvider.builder(VAL_DATE_INFLATION)
.discountCurves(dscCurve)
.priceIndexCurve(GB_RPI, GBPRI_CURVE)
.timeSeries(GB_RPI, ts)
.build();
// test forecastValue and presentValue
CurrencyAmount fvComputed = pricer.forecastValue(swapLeg, prov);
CurrencyAmount pvComputed = pricer.presentValue(swapLeg, prov);
LocalDate paymentDate = swapLeg.getPaymentPeriods().get(0).getPaymentDate();
double dscFactor = prov.discountFactor(GBP, paymentDate);
ForwardInflationInterpolatedRateComputationFn obsFn = ForwardInflationInterpolatedRateComputationFn.DEFAULT;
RatePaymentPeriod paymentPeriod = (RatePaymentPeriod) swapLeg.getPaymentPeriods().get(0);
InflationInterpolatedRateComputation obs =
(InflationInterpolatedRateComputation) paymentPeriod.getAccrualPeriods().get(0).getRateComputation();
double indexRate = obsFn.rate(obs, DATE_14_06_09, DATE_19_06_09, prov);
double fvExpected = indexRate * (NOTIONAL);
assertEquals(fvComputed.getCurrency(), GBP);
assertEquals(fvComputed.getAmount(), fvExpected, NOTIONAL * EPS);
double pvExpected = dscFactor * fvExpected;
assertEquals(pvComputed.getCurrency(), GBP);
assertEquals(pvComputed.getAmount(), pvExpected, NOTIONAL * EPS);
// test forecastValueSensitivity and presentValueSensitivity
PointSensitivityBuilder fvSensiComputed = pricer.forecastValueSensitivity(swapLeg, prov);
PointSensitivityBuilder pvSensiComputed = pricer.presentValueSensitivity(swapLeg, prov);
PointSensitivityBuilder pvSensiExpected = obsFn.rateSensitivity(obs, DATE_14_06_09, DATE_19_06_09, prov);
pvSensiExpected = pvSensiExpected.multipliedBy(NOTIONAL);
assertTrue(fvSensiComputed.build().normalized()
.equalWithTolerance(pvSensiExpected.build().normalized(), EPS * NOTIONAL));
pvSensiExpected = pvSensiExpected.multipliedBy(dscFactor);
PointSensitivityBuilder dscSensiExpected = prov.discountFactors(GBP).zeroRatePointSensitivity(paymentDate);
dscSensiExpected = dscSensiExpected.multipliedBy(fvExpected);
pvSensiExpected = pvSensiExpected.combinedWith(dscSensiExpected);
assertTrue(pvSensiComputed.build().normalized()
.equalWithTolerance(pvSensiExpected.build().normalized(), EPS * NOTIONAL));
}
private SwapLeg createInflationSwapLeg(boolean interpolated, PayReceive pay) {
BusinessDayAdjustment adj = BusinessDayAdjustment.of(FOLLOWING, GBLO);
PeriodicSchedule accrualSchedule = PeriodicSchedule.builder()
.startDate(DATE_14_06_09)
.endDate(DATE_19_06_09)
.frequency(Frequency.ofYears(5))
.businessDayAdjustment(adj)
.build();
PaymentSchedule paymentSchedule = PaymentSchedule.builder()
.paymentFrequency(Frequency.ofYears(5))
.paymentDateOffset(DaysAdjustment.ofBusinessDays(2, GBLO))
.build();
InflationRateCalculation rateCalc = InflationRateCalculation.builder()
.index(GB_RPI)
.indexCalculationMethod(interpolated ? INTERPOLATED : MONTHLY)
.lag(Period.ofMonths(3))
.build();
NotionalSchedule notionalSchedule = NotionalSchedule.of(GBP, NOTIONAL);
SwapLeg swapLeg = RateCalculationSwapLeg.builder()
.payReceive(pay)
.accrualSchedule(accrualSchedule)
.paymentSchedule(paymentSchedule)
.notionalSchedule(notionalSchedule)
.calculation(rateCalc)
.build();
return swapLeg;
}
public void test_inflation_fixed() {
// setup
double fixedRate = 0.05;
BusinessDayAdjustment adj = BusinessDayAdjustment.of(FOLLOWING, GBLO);
PeriodicSchedule accrualSchedule = PeriodicSchedule.builder()
.startDate(DATE_14_06_09)
.endDate(DATE_19_06_09)
.frequency(P12M)
.businessDayAdjustment(adj)
.build();
PaymentSchedule paymentSchedule = PaymentSchedule.builder()
.paymentFrequency(Frequency.ofYears(5))
.paymentDateOffset(DaysAdjustment.ofBusinessDays(2, GBLO))
.compoundingMethod(STRAIGHT)
.build();
FixedRateCalculation rateCalc = FixedRateCalculation.builder()
.rate(ValueSchedule.of(fixedRate))
.dayCount(ONE_ONE) // year fraction is always 1.
.build();
NotionalSchedule notionalSchedule = NotionalSchedule.of(GBP, 1000d);
ResolvedSwapLeg swapLeg = RateCalculationSwapLeg.builder()
.payReceive(RECEIVE)
.accrualSchedule(accrualSchedule)
.paymentSchedule(paymentSchedule)
.notionalSchedule(notionalSchedule)
.calculation(rateCalc)
.build()
.resolve(REF_DATA);
DiscountingSwapLegPricer pricer = DiscountingSwapLegPricer.DEFAULT;
Map<Currency, Curve> dscCurve = RATES_GBP_INFLATION.getDiscountCurves();
ImmutableRatesProvider prov = ImmutableRatesProvider.builder(VAL_DATE_INFLATION)
.discountCurves(dscCurve)
.build();
// test forecastValue and presentValue
CurrencyAmount fvComputed = pricer.forecastValue(swapLeg, prov);
CurrencyAmount pvComputed = pricer.presentValue(swapLeg, prov);
LocalDate paymentDate = swapLeg.getPaymentPeriods().get(0).getPaymentDate();
double dscFactor = prov.discountFactor(GBP, paymentDate);
double fvExpected = (Math.pow(1.0 + fixedRate, 5) - 1.0) * NOTIONAL;
assertEquals(fvComputed.getCurrency(), GBP);
assertEquals(fvComputed.getAmount(), fvExpected, NOTIONAL * EPS);
double pvExpected = fvExpected * dscFactor;
assertEquals(pvComputed.getCurrency(), GBP);
assertEquals(pvComputed.getAmount(), pvExpected, NOTIONAL * EPS);
// test forecastValueSensitivity and presentValueSensitivity
PointSensitivityBuilder fvSensiComputed = pricer.forecastValueSensitivity(swapLeg, prov);
PointSensitivityBuilder pvSensiComputed = pricer.presentValueSensitivity(swapLeg, prov);
assertEquals(fvSensiComputed, PointSensitivityBuilder.none());
PointSensitivityBuilder pvSensiExpected = prov.discountFactors(GBP).zeroRatePointSensitivity(paymentDate);
pvSensiExpected = pvSensiExpected.multipliedBy(fvExpected);
assertTrue(pvSensiComputed.build().normalized()
.equalWithTolerance(pvSensiExpected.build().normalized(), EPS * NOTIONAL));
}
//-------------------------------------------------------------------------
public void test_cashFlows() {
RatesProvider mockProv = mock(RatesProvider.class);
SwapPaymentPeriodPricer<SwapPaymentPeriod> mockPeriod = mock(SwapPaymentPeriodPricer.class);
DispatchingSwapPaymentEventPricer eventPricer = DispatchingSwapPaymentEventPricer.DEFAULT;
ResolvedSwapLeg expSwapLeg = IBOR_SWAP_LEG_REC_GBP_MULTI;
SwapPaymentPeriod period1 = IBOR_RATE_PAYMENT_PERIOD_REC_GBP;
SwapPaymentPeriod period2 = IBOR_RATE_PAYMENT_PERIOD_REC_GBP_2;
NotionalExchange event = NOTIONAL_EXCHANGE_REC_GBP;
double fv1 = 520d;
double fv2 = 450d;
double df = 1.0d;
double df1 = 0.98;
double df2 = 0.93;
when(mockPeriod.forecastValue(period1, mockProv)).thenReturn(fv1);
when(mockPeriod.forecastValue(period2, mockProv)).thenReturn(fv2);
when(mockProv.getValuationDate()).thenReturn(LocalDate.of(2014, 7, 1));
when(mockProv.discountFactor(expSwapLeg.getCurrency(), period1.getPaymentDate())).thenReturn(df1);
when(mockProv.discountFactor(expSwapLeg.getCurrency(), period2.getPaymentDate())).thenReturn(df2);
when(mockProv.discountFactor(expSwapLeg.getCurrency(), event.getPaymentDate())).thenReturn(df);
DiscountingSwapLegPricer pricer = new DiscountingSwapLegPricer(mockPeriod, eventPricer);
CashFlows computed = pricer.cashFlows(expSwapLeg, mockProv);
CashFlow flow1 = CashFlow.ofForecastValue(period1.getPaymentDate(), GBP, fv1, df1);
CashFlow flow2 = CashFlow.ofForecastValue(period2.getPaymentDate(), GBP, fv2, df2);
CashFlow flow3 = CashFlow.ofForecastValue(event.getPaymentDate(), GBP, event.getPaymentAmount().getAmount(), df);
CashFlows expected = CashFlows.of(ImmutableList.of(flow1, flow2, flow3));
assertEquals(computed, expected);
}
//-------------------------------------------------------------------------
public void test_currencyExposure() {
ResolvedSwapLeg expSwapLeg = IBOR_SWAP_LEG_REC_GBP;
PointSensitivities point = PRICER_LEG.presentValueSensitivity(expSwapLeg, RATES_GBP).build();
MultiCurrencyAmount expected = RATES_GBP.currencyExposure(point).plus(PRICER_LEG.presentValue(expSwapLeg, RATES_GBP));
MultiCurrencyAmount computed = PRICER_LEG.currencyExposure(expSwapLeg, RATES_GBP);
assertEquals(computed, expected);
}
public void test_currencyExposure_fx() {
ResolvedSwapLeg expSwapLeg = FIXED_FX_RESET_SWAP_LEG_PAY_GBP;
PointSensitivities point = PRICER_LEG.presentValueSensitivity(expSwapLeg, RATES_GBP_USD).build();
MultiCurrencyAmount expected = RATES_GBP_USD.currencyExposure(point.convertedTo(USD, RATES_GBP_USD))
.plus(PRICER_LEG.presentValue(expSwapLeg, RATES_GBP_USD));
MultiCurrencyAmount computed = PRICER_LEG.currencyExposure(expSwapLeg, RATES_GBP_USD);
assertEquals(computed.getAmount(USD).getAmount(), expected.getAmount(USD).getAmount(), EPS * NOTIONAL);
assertFalse(computed.contains(GBP)); // 0 GBP
}
//-------------------------------------------------------------------------
public void test_currentCash_zero() {
ResolvedSwapLeg expSwapLeg = IBOR_SWAP_LEG_REC_GBP;
CurrencyAmount computed = PRICER_LEG.currentCash(expSwapLeg, RATES_GBP);
assertEquals(computed, CurrencyAmount.zero(expSwapLeg.getCurrency()));
}
public void test_currentCash_payEvent() {
ResolvedSwapLeg expSwapLeg = FIXED_SWAP_LEG_PAY_USD;
LocalDate paymentDate = expSwapLeg.getPaymentEvents().get(0).getPaymentDate();
RatesProvider prov = new MockRatesProvider(paymentDate);
SwapPaymentEventPricer<SwapPaymentEvent> mockEvent = mock(SwapPaymentEventPricer.class);
double expected = 1234d;
when(mockEvent.currentCash(expSwapLeg.getPaymentEvents().get(0), prov)).thenReturn(expected);
DiscountingSwapLegPricer pricer = new DiscountingSwapLegPricer(SwapPaymentPeriodPricer.standard(), mockEvent);
CurrencyAmount computed = pricer.currentCash(expSwapLeg, prov);
assertEquals(computed, CurrencyAmount.of(expSwapLeg.getCurrency(), expected));
}
public void test_currentCash_payPeriod() {
ResolvedSwapLeg expSwapLeg = FIXED_SWAP_LEG_PAY_USD;
LocalDate paymentDate = expSwapLeg.getPaymentPeriods().get(0).getPaymentDate();
RatesProvider prov = new MockRatesProvider(paymentDate);
SwapPaymentPeriodPricer<SwapPaymentPeriod> mockPeriod = mock(SwapPaymentPeriodPricer.class);
double expected = 1234d;
when(mockPeriod.currentCash(expSwapLeg.getPaymentPeriods().get(0), prov)).thenReturn(expected);
DiscountingSwapLegPricer pricer = new DiscountingSwapLegPricer(mockPeriod, SwapPaymentEventPricer.standard());
CurrencyAmount computed = pricer.currentCash(expSwapLeg, prov);
assertEquals(computed, CurrencyAmount.of(expSwapLeg.getCurrency(), expected));
}
public void test_currentCash_convention() { // Check that standard conventions return a compounded ZC fixed leg
FixedInflationSwapConvention US_CPI = FixedInflationSwapConventions.USD_FIXED_ZC_US_CPI;
double rate = 0.10;
int nbYears = 5;
LocalDate endDate = VAL_DATE_INFLATION.plusYears(nbYears);
SwapTrade swap = US_CPI.toTrade(VAL_DATE_INFLATION, VAL_DATE_INFLATION, endDate, BuySell.BUY, NOTIONAL, rate);
ResolvedSwap resolved = swap.getProduct().resolve(REF_DATA);
DiscountingSwapLegPricer pricer = DiscountingSwapLegPricer.DEFAULT;
RatesProvider providerEndDate = new MockRatesProvider(endDate);
CurrencyAmount c = pricer.currentCash(resolved.getLegs(SwapLegType.FIXED).get(0), providerEndDate);
assertEquals(c.getAmount(), -(Math.pow(1 + rate, nbYears) - 1.0) * NOTIONAL, NOTIONAL * EPS);
}
private static final int NB_PERIODS = 10;
private static final int NB_PERIODS_PER_YEAR = 2;
private static final double[] RATES = {0.01, 0.10, -0.01, 0.0, 1.0E-6 };
private static final double TOLERANCE_ANNUITY = 1.0E-10;
private static final double TOLERANCE_ANNUITY_1 = 1.0E-6;
private static final double TOLERANCE_ANNUITY_2 = 1.0E-4;
private static final double TOLERANCE_ANNUITY_3 = 1.0E-2;
public void annuity_cash() {
for (int looprate = 0; looprate < RATES.length; looprate++) {
double annuityExpected = 0.0d;
for (int loopperiod = 0; loopperiod < NB_PERIODS; loopperiod++) {
annuityExpected += 1.0d / NB_PERIODS_PER_YEAR / Math.pow(1.0d + RATES[looprate] / NB_PERIODS_PER_YEAR, loopperiod + 1);
}
double annuityComputed = PRICER_LEG.annuityCash(NB_PERIODS_PER_YEAR, NB_PERIODS, RATES[looprate]);
assertEquals(annuityComputed, annuityExpected, TOLERANCE_ANNUITY, "Rate: " + looprate);
}
}
public void annuity_cash_1() {
double shift = 1.0E-7;
for (int looprate = 0; looprate < RATES.length; looprate++) {
double annuityExpected = PRICER_LEG.annuityCash(NB_PERIODS_PER_YEAR, NB_PERIODS, RATES[looprate]);
ValueDerivatives annuityComputed = PRICER_LEG.annuityCash1(NB_PERIODS_PER_YEAR, NB_PERIODS, RATES[looprate]);
assertEquals(annuityComputed.getValue(), annuityExpected, TOLERANCE_ANNUITY);
double annuityP = PRICER_LEG.annuityCash(NB_PERIODS_PER_YEAR, NB_PERIODS, RATES[looprate] + shift);
double annuityM = PRICER_LEG.annuityCash(NB_PERIODS_PER_YEAR, NB_PERIODS, RATES[looprate] - shift);
double derivative1Expected = (annuityP - annuityM) / (2.0d * shift);
assertEquals(annuityComputed.getDerivative(0), derivative1Expected, TOLERANCE_ANNUITY_1, "Rate: " + looprate);
}
}
public void annuity_cash_2() {
double shift = 1.0E-7;
for (int looprate = 0; looprate < RATES.length; looprate++) {
ValueDerivatives annuityExpected = PRICER_LEG.annuityCash1(NB_PERIODS_PER_YEAR, NB_PERIODS, RATES[looprate]);
ValueDerivatives annuityComputed = PRICER_LEG.annuityCash2(NB_PERIODS_PER_YEAR, NB_PERIODS, RATES[looprate]);
ValueDerivatives annuityP = PRICER_LEG.annuityCash1(NB_PERIODS_PER_YEAR, NB_PERIODS, RATES[looprate] + shift);
ValueDerivatives annuityM = PRICER_LEG.annuityCash1(NB_PERIODS_PER_YEAR, NB_PERIODS, RATES[looprate] - shift);
double derivative2Expected = (annuityP.getDerivative(0) - annuityM.getDerivative(0)) / (2.0d * shift);
assertEquals(annuityComputed.getValue(), annuityExpected.getValue(), TOLERANCE_ANNUITY_1);
assertEquals(annuityComputed.getDerivative(0), annuityExpected.getDerivative(0), TOLERANCE_ANNUITY_1);
assertEquals(annuityComputed.getDerivative(1), derivative2Expected, TOLERANCE_ANNUITY_2);
}
}
public void annuity_cash_3() {
double shift = 1.0E-7;
for (int looprate = 0; looprate < RATES.length; looprate++) {
ValueDerivatives annuityExpected = PRICER_LEG.annuityCash2(NB_PERIODS_PER_YEAR, NB_PERIODS, RATES[looprate]);
ValueDerivatives annuityComputed = PRICER_LEG.annuityCash3(NB_PERIODS_PER_YEAR, NB_PERIODS, RATES[looprate]);
ValueDerivatives annuityP = PRICER_LEG.annuityCash2(NB_PERIODS_PER_YEAR, NB_PERIODS, RATES[looprate] + shift);
ValueDerivatives annuityM = PRICER_LEG.annuityCash2(NB_PERIODS_PER_YEAR, NB_PERIODS, RATES[looprate] - shift);
double derivative3Expected = (annuityP.getDerivative(1) - annuityM.getDerivative(1)) / (2.0d * shift);
assertEquals(annuityComputed.getValue(), annuityExpected.getValue(), TOLERANCE_ANNUITY_1);
assertEquals(annuityComputed.getDerivative(0), annuityExpected.getDerivative(0), TOLERANCE_ANNUITY_1);
assertEquals(annuityComputed.getDerivative(1), annuityExpected.getDerivative(1), TOLERANCE_ANNUITY_2);
assertEquals(annuityComputed.getDerivative(2), derivative3Expected, TOLERANCE_ANNUITY_3, "rate: " + looprate);
}
}
}