/**
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.pricer.deposit;
import static com.opengamma.strata.basics.currency.Currency.EUR;
import static com.opengamma.strata.basics.date.BusinessDayConventions.MODIFIED_FOLLOWING;
import static com.opengamma.strata.basics.date.HolidayCalendarIds.EUTA;
import static com.opengamma.strata.basics.index.IborIndices.EUR_EURIBOR_6M;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.time.LocalDate;
import org.testng.annotations.Test;
import com.opengamma.strata.basics.ReferenceData;
import com.opengamma.strata.basics.currency.CurrencyAmount;
import com.opengamma.strata.basics.date.BusinessDayAdjustment;
import com.opengamma.strata.market.param.CurrencyParameterSensitivities;
import com.opengamma.strata.market.sensitivity.PointSensitivities;
import com.opengamma.strata.pricer.datasets.ImmutableRatesProviderSimpleData;
import com.opengamma.strata.pricer.rate.ImmutableRatesProvider;
import com.opengamma.strata.pricer.sensitivity.RatesFiniteDifferenceSensitivityCalculator;
import com.opengamma.strata.product.common.BuySell;
import com.opengamma.strata.product.deposit.IborFixingDeposit;
import com.opengamma.strata.product.deposit.ResolvedIborFixingDeposit;
/**
* Test {@link DiscountingIborFixingDepositProductPricer}.
*/
@Test
public class DiscountingIborFixingDepositProductPricerTest {
private static final ReferenceData REF_DATA = ReferenceData.standard();
private static final LocalDate VAL_DATE = ImmutableRatesProviderSimpleData.VAL_DATE;
private static final LocalDate START_DATE = EUR_EURIBOR_6M.calculateEffectiveFromFixing(VAL_DATE, REF_DATA);
private static final LocalDate END_DATE = EUR_EURIBOR_6M.calculateMaturityFromEffective(START_DATE, REF_DATA);
private static final double NOTIONAL = 100000000d;
private static final double RATE = 0.0150;
private static final BusinessDayAdjustment BD_ADJ = BusinessDayAdjustment.of(MODIFIED_FOLLOWING, EUTA);
private static final IborFixingDeposit DEPOSIT = IborFixingDeposit.builder()
.buySell(BuySell.BUY)
.notional(NOTIONAL)
.startDate(START_DATE)
.endDate(END_DATE)
.businessDayAdjustment(BD_ADJ)
.index(EUR_EURIBOR_6M)
.fixedRate(RATE)
.build();
private static final ResolvedIborFixingDeposit RDEPOSIT = DEPOSIT.resolve(REF_DATA);
private static final double TOLERANCE_PV = 1E-2;
private static final double TOLERANCE_PV_DELTA = 1E-2;
private static final double TOLERANCE_RATE = 1E-8;
private static final double TOLERANCE_RATE_DELTA = 1E-6;
private static final double EPS_FD = 1E-7;
private static final RatesFiniteDifferenceSensitivityCalculator CAL_FD =
new RatesFiniteDifferenceSensitivityCalculator(EPS_FD);
private static final ImmutableRatesProvider IMM_PROV_NOFIX = ImmutableRatesProviderSimpleData.IMM_PROV_EUR_NOFIX;
private static final ImmutableRatesProvider IMM_PROV_FIX = ImmutableRatesProviderSimpleData.IMM_PROV_EUR_FIX;
private static final DiscountingIborFixingDepositProductPricer PRICER =
DiscountingIborFixingDepositProductPricer.DEFAULT;
//-------------------------------------------------------------------------
public void test_presentValue_noFixing() {
double discountFactor = IMM_PROV_NOFIX.discountFactor(EUR, END_DATE);
double forwardRate = IMM_PROV_NOFIX.iborIndexRates(EUR_EURIBOR_6M).rate(RDEPOSIT.getFloatingRate().getObservation());
CurrencyAmount computed = PRICER.presentValue(RDEPOSIT, IMM_PROV_NOFIX);
double expected = NOTIONAL * discountFactor * (RATE - forwardRate) * RDEPOSIT.getYearFraction();
assertEquals(computed.getCurrency(), EUR);
assertEquals(computed.getAmount(), expected, TOLERANCE_PV);
}
public void test_presentValue_fixing() {
CurrencyAmount computedNoFix = PRICER.presentValue(RDEPOSIT, IMM_PROV_NOFIX);
CurrencyAmount computedFix = PRICER.presentValue(RDEPOSIT, IMM_PROV_FIX); // Fixing should not be taken into account
assertEquals(computedFix.getCurrency(), EUR);
assertEquals(computedFix.getAmount(), computedNoFix.getAmount(), TOLERANCE_PV);
}
//-------------------------------------------------------------------------
public void test_presentValueSensitivity_noFixing() {
PointSensitivities computed = PRICER.presentValueSensitivity(RDEPOSIT, IMM_PROV_NOFIX);
CurrencyParameterSensitivities sensiComputed = IMM_PROV_NOFIX.parameterSensitivity(computed);
CurrencyParameterSensitivities sensiExpected =
CAL_FD.sensitivity(IMM_PROV_NOFIX, (p) -> PRICER.presentValue(RDEPOSIT, (p)));
assertTrue(sensiComputed.equalWithTolerance(sensiExpected, NOTIONAL * EPS_FD));
}
//-------------------------------------------------------------------------
public void test_presentValueSensitivity_fixing() {
PointSensitivities computedNoFix = PRICER.presentValueSensitivity(RDEPOSIT, IMM_PROV_NOFIX);
CurrencyParameterSensitivities sensiComputedNoFix = IMM_PROV_NOFIX.parameterSensitivity(computedNoFix);
PointSensitivities computedFix = PRICER.presentValueSensitivity(RDEPOSIT, IMM_PROV_FIX);
CurrencyParameterSensitivities sensiComputedFix = IMM_PROV_NOFIX.parameterSensitivity(computedFix);
assertTrue(sensiComputedNoFix.equalWithTolerance(sensiComputedFix, TOLERANCE_PV_DELTA));
}
//-------------------------------------------------------------------------
public void test_parRate() {
double parRate = PRICER.parRate(RDEPOSIT, IMM_PROV_NOFIX);
IborFixingDeposit deposit0 = DEPOSIT.toBuilder().fixedRate(parRate).build();
CurrencyAmount pv0 = PRICER.presentValue(deposit0.resolve(REF_DATA), IMM_PROV_NOFIX);
assertEquals(pv0.getAmount(), 0, TOLERANCE_RATE);
double parRate2 = PRICER.parRate(RDEPOSIT, IMM_PROV_NOFIX);
assertEquals(parRate, parRate2, TOLERANCE_RATE);
}
//-------------------------------------------------------------------------
public void test_parSpread_noFixing() {
double parSpread = PRICER.parSpread(RDEPOSIT, IMM_PROV_NOFIX);
IborFixingDeposit deposit0 = DEPOSIT.toBuilder().fixedRate(RATE + parSpread).build();
CurrencyAmount pv0 = PRICER.presentValue(deposit0.resolve(REF_DATA), IMM_PROV_NOFIX);
assertEquals(pv0.getAmount(), 0, TOLERANCE_RATE);
double parSpread2 = PRICER.parSpread(RDEPOSIT, IMM_PROV_NOFIX);
assertEquals(parSpread, parSpread2, TOLERANCE_RATE);
}
public void test_parSpread_fixing() {
double parSpread1 = PRICER.parSpread(RDEPOSIT, IMM_PROV_FIX);
double parSpread2 = PRICER.parSpread(RDEPOSIT, IMM_PROV_NOFIX);
assertEquals(parSpread1, parSpread2, TOLERANCE_RATE);
}
//-------------------------------------------------------------------------
public void test_parSpreadSensitivity_noFixing() {
PointSensitivities computedNoFix = PRICER.parSpreadSensitivity(RDEPOSIT, IMM_PROV_NOFIX);
CurrencyParameterSensitivities sensiComputedNoFix = IMM_PROV_NOFIX.parameterSensitivity(computedNoFix);
CurrencyParameterSensitivities sensiExpected =
CAL_FD.sensitivity(IMM_PROV_NOFIX, (p) -> CurrencyAmount.of(EUR, PRICER.parSpread(RDEPOSIT, (p))));
assertTrue(sensiComputedNoFix.equalWithTolerance(sensiExpected, TOLERANCE_RATE_DELTA));
// Par rate and par spread sensitivities are equal
PointSensitivities computedParRateNoFix = PRICER.parRateSensitivity(RDEPOSIT, IMM_PROV_NOFIX);
CurrencyParameterSensitivities sensiComputedParRateNoFix = IMM_PROV_NOFIX.parameterSensitivity(computedParRateNoFix);
assertTrue(sensiComputedNoFix.equalWithTolerance(sensiComputedParRateNoFix, TOLERANCE_RATE_DELTA));
PointSensitivities computedFix = PRICER.parSpreadSensitivity(RDEPOSIT, IMM_PROV_FIX);
CurrencyParameterSensitivities sensiComputedFix = IMM_PROV_NOFIX.parameterSensitivity(computedFix);
assertTrue(sensiComputedFix.equalWithTolerance(sensiExpected, TOLERANCE_RATE_DELTA));
}
public void test_parSpreadSensitivity_fixing() {
PointSensitivities computedNoFix = PRICER.parSpreadSensitivity(RDEPOSIT, IMM_PROV_NOFIX);
PointSensitivities computedFix = PRICER.parSpreadSensitivity(RDEPOSIT, IMM_PROV_FIX);
assertTrue(computedNoFix.equalWithTolerance(computedFix, TOLERANCE_PV_DELTA));
PointSensitivities computedParRateFix = PRICER.parRateSensitivity(RDEPOSIT, IMM_PROV_FIX);
assertTrue(computedParRateFix.equalWithTolerance(computedFix, TOLERANCE_PV_DELTA));
}
}