/**
* Copyright (C) 2016 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.pricer.capfloor;
import static com.opengamma.strata.basics.currency.Currency.EUR;
import static com.opengamma.strata.basics.index.IborIndices.EUR_EURIBOR_3M;
import static com.opengamma.strata.collect.TestHelper.date;
import static com.opengamma.strata.collect.TestHelper.dateUtc;
import static com.opengamma.strata.product.common.PayReceive.PAY;
import static com.opengamma.strata.product.common.PayReceive.RECEIVE;
import static com.opengamma.strata.product.common.PutCall.CALL;
import static org.testng.Assert.assertEquals;
import java.time.LocalDate;
import java.time.ZonedDateTime;
import org.testng.annotations.Test;
import com.opengamma.strata.basics.currency.CurrencyAmount;
import com.opengamma.strata.basics.currency.MultiCurrencyAmount;
import com.opengamma.strata.basics.value.ValueSchedule;
import com.opengamma.strata.collect.timeseries.LocalDateDoubleTimeSeries;
import com.opengamma.strata.market.sensitivity.PointSensitivityBuilder;
import com.opengamma.strata.pricer.rate.ImmutableRatesProvider;
import com.opengamma.strata.pricer.swap.DiscountingSwapLegPricer;
import com.opengamma.strata.product.capfloor.ResolvedIborCapFloor;
import com.opengamma.strata.product.capfloor.ResolvedIborCapFloorLeg;
import com.opengamma.strata.product.swap.ResolvedSwapLeg;
/**
* Test {@link BlackIborCapFloorProductPricer}.
*/
@Test
public class BlackIborCapFloorProductPricerTest {
private static final double NOTIONAL_VALUE = 1.0e6;
private static final ValueSchedule NOTIONAL = ValueSchedule.of(NOTIONAL_VALUE);
private static final LocalDate START = LocalDate.of(2015, 10, 21);
private static final LocalDate END = LocalDate.of(2020, 10, 21);
private static final double STRIKE_VALUE = 0.0105;
private static final ValueSchedule STRIKE = ValueSchedule.of(STRIKE_VALUE);
private static final ResolvedIborCapFloorLeg CAP_LEG =
IborCapFloorDataSet.createCapFloorLeg(EUR_EURIBOR_3M, START, END, STRIKE, NOTIONAL, CALL, RECEIVE);
private static final ResolvedSwapLeg PAY_LEG =
IborCapFloorDataSet.createFixedPayLeg(EUR_EURIBOR_3M, START, END, 0.0015, NOTIONAL_VALUE, PAY);
private static final ResolvedIborCapFloor CAP_TWO_LEGS = ResolvedIborCapFloor.of(CAP_LEG, PAY_LEG);
private static final ResolvedIborCapFloor CAP_ONE_LEG = ResolvedIborCapFloor.of(CAP_LEG);
// valuation before start
private static final ZonedDateTime VALUATION = dateUtc(2015, 8, 20);
private static final ImmutableRatesProvider RATES =
IborCapletFloorletDataSet.createRatesProvider(VALUATION.toLocalDate());
private static final BlackIborCapletFloorletExpiryStrikeVolatilities VOLS = IborCapletFloorletDataSet
.createBlackVolatilities(VALUATION, EUR_EURIBOR_3M);
// valuation at payment of 1st period
private static final double OBS_INDEX_1 = 0.012;
private static final double OBS_INDEX_2 = 0.0125;
private static final LocalDateDoubleTimeSeries TIME_SERIES = LocalDateDoubleTimeSeries.builder()
.put(date(2015, 10, 19), OBS_INDEX_1)
.put(date(2016, 1, 19), OBS_INDEX_2)
.build();
private static final ZonedDateTime VALUATION_PAY = dateUtc(2016, 1, 21);
private static final ImmutableRatesProvider RATES_PAY =
IborCapletFloorletDataSet.createRatesProvider(VALUATION_PAY.toLocalDate(), EUR_EURIBOR_3M, TIME_SERIES);
private static final BlackIborCapletFloorletExpiryStrikeVolatilities VOLS_PAY = IborCapletFloorletDataSet
.createBlackVolatilities(VALUATION_PAY, EUR_EURIBOR_3M);
private static final double TOL = 1.0e-13;
private static final BlackIborCapFloorProductPricer PRICER = BlackIborCapFloorProductPricer.DEFAULT;
private static final BlackIborCapFloorLegPricer PRICER_CAP_LEG = BlackIborCapFloorLegPricer.DEFAULT;
private static final DiscountingSwapLegPricer PRICER_PAY_LEG = DiscountingSwapLegPricer.DEFAULT;
public void test_presentValue() {
MultiCurrencyAmount computed1 = PRICER.presentValue(CAP_ONE_LEG, RATES, VOLS);
MultiCurrencyAmount computed2 = PRICER.presentValue(CAP_TWO_LEGS, RATES, VOLS);
CurrencyAmount cap = PRICER_CAP_LEG.presentValue(CAP_LEG, RATES, VOLS);
CurrencyAmount pay = PRICER_PAY_LEG.presentValue(PAY_LEG, RATES);
assertEquals(computed1, MultiCurrencyAmount.of(cap));
assertEquals(computed2, MultiCurrencyAmount.of(cap.plus(pay)));
}
public void test_presentValueDelta() {
MultiCurrencyAmount computed1 = PRICER.presentValueDelta(CAP_ONE_LEG, RATES, VOLS);
MultiCurrencyAmount computed2 = PRICER.presentValueDelta(CAP_TWO_LEGS, RATES, VOLS);
CurrencyAmount cap = PRICER_CAP_LEG.presentValueDelta(CAP_LEG, RATES, VOLS);
assertEquals(computed1, MultiCurrencyAmount.of(cap));
assertEquals(computed2, MultiCurrencyAmount.of(cap));
}
public void test_presentValueGamma() {
MultiCurrencyAmount computed1 = PRICER.presentValueGamma(CAP_ONE_LEG, RATES, VOLS);
MultiCurrencyAmount computed2 = PRICER.presentValueGamma(CAP_TWO_LEGS, RATES, VOLS);
CurrencyAmount cap = PRICER_CAP_LEG.presentValueGamma(CAP_LEG, RATES, VOLS);
assertEquals(computed1, MultiCurrencyAmount.of(cap));
assertEquals(computed2, MultiCurrencyAmount.of(cap));
}
public void test_presentValueTheta() {
MultiCurrencyAmount computed1 = PRICER.presentValueTheta(CAP_ONE_LEG, RATES, VOLS);
MultiCurrencyAmount computed2 = PRICER.presentValueTheta(CAP_TWO_LEGS, RATES, VOLS);
CurrencyAmount cap = PRICER_CAP_LEG.presentValueTheta(CAP_LEG, RATES, VOLS);
assertEquals(computed1, MultiCurrencyAmount.of(cap));
assertEquals(computed2, MultiCurrencyAmount.of(cap));
}
public void test_presentValueSensitivity() {
PointSensitivityBuilder computed1 = PRICER.presentValueSensitivityRates(CAP_ONE_LEG, RATES, VOLS);
PointSensitivityBuilder computed2 = PRICER.presentValueSensitivityRates(CAP_TWO_LEGS, RATES, VOLS);
PointSensitivityBuilder cap = PRICER_CAP_LEG.presentValueSensitivityRates(CAP_LEG, RATES, VOLS);
PointSensitivityBuilder pay = PRICER_PAY_LEG.presentValueSensitivity(PAY_LEG, RATES);
assertEquals(computed1, cap);
assertEquals(computed2, cap.combinedWith(pay));
}
public void test_presentValueSensitivityVolatility() {
PointSensitivityBuilder computed1 = PRICER.presentValueSensitivityModelParamsVolatility(CAP_ONE_LEG, RATES, VOLS);
PointSensitivityBuilder computed2 = PRICER.presentValueSensitivityModelParamsVolatility(CAP_TWO_LEGS, RATES, VOLS);
PointSensitivityBuilder cap = PRICER_CAP_LEG.presentValueSensitivityModelParamsVolatility(CAP_LEG, RATES, VOLS);
assertEquals(computed1, cap);
assertEquals(computed2, cap);
}
public void test_currencyExposure() {
MultiCurrencyAmount computed1 = PRICER.currencyExposure(CAP_ONE_LEG, RATES, VOLS);
MultiCurrencyAmount computed2 = PRICER.currencyExposure(CAP_TWO_LEGS, RATES, VOLS);
MultiCurrencyAmount pv1 = PRICER.presentValue(CAP_ONE_LEG, RATES, VOLS);
MultiCurrencyAmount pv2 = PRICER.presentValue(CAP_TWO_LEGS, RATES, VOLS);
PointSensitivityBuilder point1 = PRICER.presentValueSensitivityRates(CAP_ONE_LEG, RATES, VOLS);
PointSensitivityBuilder point2 = PRICER.presentValueSensitivityRates(CAP_TWO_LEGS, RATES, VOLS);
MultiCurrencyAmount expected1 = RATES.currencyExposure(point1.build()).plus(pv1);
MultiCurrencyAmount expected2 = RATES.currencyExposure(point2.build()).plus(pv2);
assertEquals(computed1.getAmount(EUR).getAmount(), expected1.getAmount(EUR).getAmount(), NOTIONAL_VALUE * TOL);
assertEquals(computed2.getAmount(EUR).getAmount(), expected2.getAmount(EUR).getAmount(), NOTIONAL_VALUE * TOL);
}
public void test_currentCash() {
MultiCurrencyAmount cc1 = PRICER.currentCash(CAP_ONE_LEG, RATES, VOLS);
MultiCurrencyAmount cc2 = PRICER.currentCash(CAP_TWO_LEGS, RATES, VOLS);
assertEquals(cc1, MultiCurrencyAmount.of(CurrencyAmount.zero(EUR)));
assertEquals(cc2, MultiCurrencyAmount.of(CurrencyAmount.zero(EUR)));
}
public void test_currentCash_onPay() {
MultiCurrencyAmount cc1 = PRICER.currentCash(CAP_ONE_LEG, RATES_PAY, VOLS_PAY);
MultiCurrencyAmount cc2 = PRICER.currentCash(CAP_TWO_LEGS, RATES_PAY, VOLS_PAY);
CurrencyAmount ccCap = PRICER_CAP_LEG.currentCash(CAP_LEG, RATES_PAY, VOLS_PAY);
CurrencyAmount ccPay = PRICER_PAY_LEG.currentCash(PAY_LEG, RATES_PAY);
assertEquals(cc1, MultiCurrencyAmount.of(ccCap));
assertEquals(cc2, MultiCurrencyAmount.of(ccCap).plus(ccPay));
}
}