/**
* 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_6M;
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.currency.Payment;
import com.opengamma.strata.basics.value.ValueSchedule;
import com.opengamma.strata.collect.timeseries.LocalDateDoubleTimeSeries;
import com.opengamma.strata.market.sensitivity.PointSensitivities;
import com.opengamma.strata.pricer.DiscountingPaymentPricer;
import com.opengamma.strata.pricer.rate.ImmutableRatesProvider;
import com.opengamma.strata.product.TradeInfo;
import com.opengamma.strata.product.capfloor.ResolvedIborCapFloor;
import com.opengamma.strata.product.capfloor.ResolvedIborCapFloorLeg;
import com.opengamma.strata.product.capfloor.ResolvedIborCapFloorTrade;
import com.opengamma.strata.product.swap.ResolvedSwapLeg;
/**
* Test {@link SabrIborCapFloorTradePricer}.
*/
@Test
public class SabrIborCapFloorTradePricerTest {
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_6M, START, END, STRIKE, NOTIONAL, CALL, RECEIVE);
private static final ResolvedSwapLeg PAY_LEG =
IborCapFloorDataSet.createFixedPayLeg(EUR_EURIBOR_6M, START, END, 0.0395, 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 = IborCapletFloorletSabrRateVolatilityDataSet.getRatesProvider(
VALUATION.toLocalDate(), EUR_EURIBOR_6M, LocalDateDoubleTimeSeries.empty());
private static final SabrIborCapletFloorletVolatilities VOLS = IborCapletFloorletSabrRateVolatilityDataSet
.getVolatilities(VALUATION, EUR_EURIBOR_6M);
private static final TradeInfo TRADE_INFO = TradeInfo.builder().tradeDate(VALUATION.toLocalDate()).build();
private static final Payment PREMIUM = Payment.of(EUR, -NOTIONAL_VALUE * 0.19, VALUATION.toLocalDate());
private static final ResolvedIborCapFloorTrade TRADE_PAYLEG = ResolvedIborCapFloorTrade.builder()
.product(CAP_TWO_LEGS)
.info(TRADE_INFO)
.build();
private static final ResolvedIborCapFloorTrade TRADE_PREMIUM = ResolvedIborCapFloorTrade.builder()
.product(CAP_ONE_LEG)
.premium(PREMIUM)
.info(TradeInfo.empty())
.build();
// valuation at payment of 1st period
private static final double OBS_INDEX_1 = 0.013;
private static final double OBS_INDEX_2 = 0.0135;
private static final LocalDateDoubleTimeSeries TIME_SERIES = LocalDateDoubleTimeSeries.builder()
.put(date(2015, 10, 19), OBS_INDEX_1)
.put(date(2016, 4, 19), OBS_INDEX_2)
.build();
private static final ZonedDateTime VALUATION_PAY = dateUtc(2016, 4, 21);
private static final ImmutableRatesProvider RATES_PAY =
IborCapletFloorletSabrRateVolatilityDataSet.getRatesProvider(VALUATION_PAY.toLocalDate(), EUR_EURIBOR_6M, TIME_SERIES);
private static final SabrIborCapletFloorletVolatilities VOLS_PAY = IborCapletFloorletSabrRateVolatilityDataSet
.getVolatilities(VALUATION_PAY, EUR_EURIBOR_6M);
private static final double TOL = 1.0e-13;
private static final SabrIborCapFloorTradePricer PRICER = SabrIborCapFloorTradePricer.DEFAULT;
private static final SabrIborCapFloorProductPricer PRICER_PRODUCT = SabrIborCapFloorProductPricer.DEFAULT;
private static final DiscountingPaymentPricer PRICER_PREMIUM = DiscountingPaymentPricer.DEFAULT;
public void test_presentValue() {
MultiCurrencyAmount computedWithPayLeg = PRICER.presentValue(TRADE_PAYLEG, RATES, VOLS);
MultiCurrencyAmount computedWithPremium = PRICER.presentValue(TRADE_PREMIUM, RATES, VOLS);
MultiCurrencyAmount pvOneLeg = PRICER_PRODUCT.presentValue(CAP_ONE_LEG, RATES, VOLS);
MultiCurrencyAmount pvTwoLegs = PRICER_PRODUCT.presentValue(CAP_TWO_LEGS, RATES, VOLS);
CurrencyAmount pvPrem = PRICER_PREMIUM.presentValue(PREMIUM, RATES);
assertEquals(computedWithPayLeg, pvTwoLegs);
assertEquals(computedWithPremium, pvOneLeg.plus(pvPrem));
}
public void test_presentValueSensitivity() {
PointSensitivities computedWithPayLeg = PRICER.presentValueSensitivityRates(TRADE_PAYLEG, RATES, VOLS);
PointSensitivities computedWithPremium = PRICER.presentValueSensitivityRates(TRADE_PREMIUM, RATES, VOLS);
PointSensitivities pvOneLeg = PRICER_PRODUCT.presentValueSensitivityRates(CAP_ONE_LEG, RATES, VOLS).build();
PointSensitivities pvTwoLegs = PRICER_PRODUCT.presentValueSensitivityRates(CAP_TWO_LEGS, RATES, VOLS).build();
PointSensitivities pvPrem = PRICER_PREMIUM.presentValueSensitivity(PREMIUM, RATES).build();
assertEquals(computedWithPayLeg, pvTwoLegs);
assertEquals(computedWithPremium, pvOneLeg.combinedWith(pvPrem));
}
public void test_presentValueSensitivityRatesStickyModel() {
PointSensitivities computedWithPayLeg = PRICER.presentValueSensitivityRatesStickyModel(TRADE_PAYLEG, RATES, VOLS);
PointSensitivities computedWithPremium = PRICER.presentValueSensitivityRatesStickyModel(TRADE_PREMIUM, RATES, VOLS);
PointSensitivities pvOneLeg = PRICER_PRODUCT.presentValueSensitivityRatesStickyModel(CAP_ONE_LEG, RATES, VOLS).build();
PointSensitivities pvTwoLegs = PRICER_PRODUCT.presentValueSensitivityRatesStickyModel(CAP_TWO_LEGS, RATES, VOLS).build();
PointSensitivities pvPrem = PRICER_PREMIUM.presentValueSensitivity(PREMIUM, RATES).build();
assertEquals(computedWithPayLeg, pvTwoLegs);
assertEquals(computedWithPremium, pvOneLeg.combinedWith(pvPrem));
}
public void test_presentValueSensitivityModelParamsVolatility() {
PointSensitivities computedWithPayLeg =
PRICER.presentValueSensitivityModelParamsVolatility(TRADE_PAYLEG, RATES, VOLS).build();
PointSensitivities computedWithPremium =
PRICER.presentValueSensitivityModelParamsVolatility(TRADE_PREMIUM, RATES, VOLS).build();
PointSensitivities pvOneLeg = PRICER_PRODUCT.presentValueSensitivityModelParamsVolatility(CAP_ONE_LEG, RATES, VOLS).build();
PointSensitivities pvTwoLegs = PRICER_PRODUCT.presentValueSensitivityModelParamsVolatility(CAP_TWO_LEGS, RATES, VOLS).build();
assertEquals(computedWithPayLeg, pvTwoLegs);
assertEquals(computedWithPremium, pvOneLeg);
}
public void test_presentValueSensitivityModelParamsSabr() {
PointSensitivities computedWithPayLeg = PRICER.presentValueSensitivityModelParamsSabr(TRADE_PAYLEG, RATES, VOLS).build();
PointSensitivities computedWithPremium = PRICER.presentValueSensitivityModelParamsSabr(TRADE_PREMIUM, RATES, VOLS).build();
PointSensitivities pvOneLeg = PRICER_PRODUCT.presentValueSensitivityModelParamsSabr(CAP_ONE_LEG, RATES, VOLS).build();
PointSensitivities pvTwoLegs = PRICER_PRODUCT.presentValueSensitivityModelParamsSabr(CAP_TWO_LEGS, RATES, VOLS).build();
assertEquals(computedWithPayLeg, pvTwoLegs);
assertEquals(computedWithPremium, pvOneLeg);
}
public void test_currencyExposure() {
MultiCurrencyAmount computedWithPayLeg = PRICER.currencyExposure(TRADE_PAYLEG, RATES, VOLS);
MultiCurrencyAmount computedWithPremium = PRICER.currencyExposure(TRADE_PREMIUM, RATES, VOLS);
MultiCurrencyAmount pvWithPayLeg = PRICER.presentValue(TRADE_PAYLEG, RATES, VOLS);
MultiCurrencyAmount pvWithPremium = PRICER.presentValue(TRADE_PREMIUM, RATES, VOLS);
PointSensitivities pointWithPayLeg = PRICER.presentValueSensitivityRates(TRADE_PAYLEG, RATES, VOLS);
PointSensitivities pointWithPremium = PRICER.presentValueSensitivityRates(TRADE_PREMIUM, RATES, VOLS);
MultiCurrencyAmount expectedWithPayLeg = RATES.currencyExposure(pointWithPayLeg).plus(pvWithPayLeg);
MultiCurrencyAmount expectedWithPremium = RATES.currencyExposure(pointWithPremium).plus(pvWithPremium);
assertEquals(computedWithPayLeg.getAmount(EUR).getAmount(),
expectedWithPayLeg.getAmount(EUR).getAmount(), NOTIONAL_VALUE * TOL);
assertEquals(computedWithPremium.getAmount(EUR).getAmount(),
expectedWithPremium.getAmount(EUR).getAmount(), NOTIONAL_VALUE * TOL);
}
public void test_currentCash() {
MultiCurrencyAmount computedWithPayLeg = PRICER.currentCash(TRADE_PAYLEG, RATES, VOLS);
MultiCurrencyAmount computedWithPremium = PRICER.currentCash(TRADE_PREMIUM, RATES, VOLS);
assertEquals(computedWithPayLeg, MultiCurrencyAmount.of(CurrencyAmount.zero(EUR)));
assertEquals(computedWithPremium, MultiCurrencyAmount.of(PREMIUM.getValue()));
}
public void test_currentCash_onPay() {
MultiCurrencyAmount computedWithPayLeg = PRICER.currentCash(TRADE_PAYLEG, RATES_PAY, VOLS_PAY);
MultiCurrencyAmount computedWithPremium = PRICER.currentCash(TRADE_PREMIUM, RATES_PAY, VOLS_PAY);
MultiCurrencyAmount expectedWithPayLeg = PRICER_PRODUCT.currentCash(CAP_TWO_LEGS, RATES_PAY, VOLS_PAY);
MultiCurrencyAmount expectedWithPremium = PRICER_PRODUCT.currentCash(CAP_ONE_LEG, RATES_PAY, VOLS_PAY);
assertEquals(computedWithPayLeg, expectedWithPayLeg);
assertEquals(computedWithPremium, expectedWithPremium);
}
}