/**
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.pricer.swaption;
import static com.opengamma.strata.basics.currency.Currency.USD;
import static com.opengamma.strata.basics.index.IborIndices.USD_LIBOR_3M;
import static com.opengamma.strata.product.common.BuySell.SELL;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.Period;
import java.time.ZoneId;
import org.testng.annotations.Test;
import com.opengamma.strata.basics.ReferenceData;
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.date.AdjustableDate;
import com.opengamma.strata.collect.DoubleArrayMath;
import com.opengamma.strata.collect.array.DoubleArray;
import com.opengamma.strata.market.param.CurrencyParameterSensitivities;
import com.opengamma.strata.market.sensitivity.PointSensitivities;
import com.opengamma.strata.market.sensitivity.PointSensitivityBuilder;
import com.opengamma.strata.pricer.DiscountingPaymentPricer;
import com.opengamma.strata.pricer.datasets.RatesProviderDataSets;
import com.opengamma.strata.pricer.index.HullWhiteIborFutureDataSet;
import com.opengamma.strata.pricer.model.HullWhiteOneFactorPiecewiseConstantParametersProvider;
import com.opengamma.strata.pricer.rate.ImmutableRatesProvider;
import com.opengamma.strata.product.common.LongShort;
import com.opengamma.strata.product.swap.Swap;
import com.opengamma.strata.product.swap.type.FixedIborSwapConventions;
import com.opengamma.strata.product.swaption.PhysicalSwaptionSettlement;
import com.opengamma.strata.product.swaption.ResolvedSwaption;
import com.opengamma.strata.product.swaption.ResolvedSwaptionTrade;
import com.opengamma.strata.product.swaption.Swaption;
import com.opengamma.strata.product.swaption.SwaptionSettlement;
/**
* Test {@link HullWhiteSwaptionPhysicalTradePricer}.
*/
@Test
public class HullWhiteSwaptionPhysicalTradePricerTest {
private static final ReferenceData REF_DATA = ReferenceData.standard();
private static final LocalDate VAL_DATE = RatesProviderDataSets.VAL_DATE_2014_01_22;
private static final LocalDate SWAPTION_EXERCISE_DATE = VAL_DATE.plusYears(5);
private static final LocalTime SWAPTION_EXPIRY_TIME = LocalTime.of(11, 0);
private static final ZoneId SWAPTION_EXPIRY_ZONE = ZoneId.of("America/New_York");
private static final LocalDate SWAP_EFFECTIVE_DATE =
USD_LIBOR_3M.calculateEffectiveFromFixing(SWAPTION_EXERCISE_DATE, REF_DATA);
private static final int SWAP_TENOR_YEAR = 5;
private static final Period SWAP_TENOR = Period.ofYears(SWAP_TENOR_YEAR);
private static final LocalDate SWAP_MATURITY_DATE = SWAP_EFFECTIVE_DATE.plus(SWAP_TENOR);
private static final double STRIKE = 0.01;
private static final double NOTIONAL = 100_000_000;
private static final Swap SWAP_REC = FixedIborSwapConventions.USD_FIXED_6M_LIBOR_3M
.toTrade(VAL_DATE, SWAP_EFFECTIVE_DATE, SWAP_MATURITY_DATE, SELL, NOTIONAL, STRIKE).getProduct();
private static final SwaptionSettlement PHYSICAL_SETTLE = PhysicalSwaptionSettlement.DEFAULT;
private static final double PREMIUM_AMOUNT = 100_000;
private static final ResolvedSwaption SWAPTION_LONG_REC = Swaption.builder()
.swaptionSettlement(PHYSICAL_SETTLE)
.expiryDate(AdjustableDate.of(SWAPTION_EXERCISE_DATE))
.expiryTime(SWAPTION_EXPIRY_TIME)
.expiryZone(SWAPTION_EXPIRY_ZONE)
.longShort(LongShort.LONG)
.underlying(SWAP_REC)
.build()
.resolve(REF_DATA);
private static final Payment PREMIUM_FWD_PAY = Payment.of(CurrencyAmount.of(USD, -PREMIUM_AMOUNT),
SWAP_EFFECTIVE_DATE);
private static final ResolvedSwaptionTrade SWAPTION_PREFWD_LONG_REC = ResolvedSwaptionTrade.builder()
.product(SWAPTION_LONG_REC)
.premium(PREMIUM_FWD_PAY)
.build();
private static final Payment PREMIUM_TRA_PAY = Payment.of(CurrencyAmount.of(USD, -PREMIUM_AMOUNT), VAL_DATE);
private static final ResolvedSwaptionTrade SWAPTION_PRETOD_LONG_REC = ResolvedSwaptionTrade.builder()
.product(SWAPTION_LONG_REC)
.premium(PREMIUM_TRA_PAY)
.build();
private static final Payment PREMIUM_PAST_PAY =
Payment.of(CurrencyAmount.of(USD, -PREMIUM_AMOUNT), VAL_DATE.minusDays(1));
private static final ResolvedSwaptionTrade SWAPTION_PREPAST_LONG_REC = ResolvedSwaptionTrade.builder()
.product(SWAPTION_LONG_REC)
.premium(PREMIUM_PAST_PAY)
.build();
private static final HullWhiteSwaptionPhysicalProductPricer PRICER_PRODUCT =
HullWhiteSwaptionPhysicalProductPricer.DEFAULT;
private static final HullWhiteSwaptionPhysicalTradePricer PRICER_TRADE =
HullWhiteSwaptionPhysicalTradePricer.DEFAULT;
private static final DiscountingPaymentPricer PRICER_PAYMENT = DiscountingPaymentPricer.DEFAULT;
private static final ImmutableRatesProvider MULTI_USD = RatesProviderDataSets.multiUsd(VAL_DATE);
private static final HullWhiteOneFactorPiecewiseConstantParametersProvider HW_PROVIDER =
HullWhiteIborFutureDataSet.createHullWhiteProvider(VAL_DATE);
private static final double TOL = 1.0E-12;
//-------------------------------------------------------------------------
public void present_value_premium_forward() {
CurrencyAmount pvTrade = PRICER_TRADE.presentValue(SWAPTION_PREFWD_LONG_REC, MULTI_USD, HW_PROVIDER);
CurrencyAmount pvProduct = PRICER_PRODUCT.presentValue(SWAPTION_LONG_REC, MULTI_USD, HW_PROVIDER);
CurrencyAmount pvPremium = PRICER_PAYMENT.presentValue(PREMIUM_FWD_PAY, MULTI_USD);
assertEquals(pvTrade.getAmount(), pvProduct.getAmount() + pvPremium.getAmount(), TOL * NOTIONAL);
}
public void present_value_premium_valuedate() {
CurrencyAmount pvTrade = PRICER_TRADE.presentValue(SWAPTION_PRETOD_LONG_REC, MULTI_USD, HW_PROVIDER);
CurrencyAmount pvProduct = PRICER_PRODUCT.presentValue(SWAPTION_LONG_REC, MULTI_USD, HW_PROVIDER);
CurrencyAmount pvPremium = PRICER_PAYMENT.presentValue(PREMIUM_TRA_PAY, MULTI_USD);
assertEquals(pvTrade.getAmount(), pvProduct.getAmount() + pvPremium.getAmount(), TOL * NOTIONAL);
}
public void present_value_premium_past() {
CurrencyAmount pvTrade = PRICER_TRADE.presentValue(SWAPTION_PREPAST_LONG_REC, MULTI_USD, HW_PROVIDER);
CurrencyAmount pvProduct = PRICER_PRODUCT.presentValue(SWAPTION_LONG_REC, MULTI_USD, HW_PROVIDER);
assertEquals(pvTrade.getAmount(), pvProduct.getAmount(), TOL * NOTIONAL);
}
//-------------------------------------------------------------------------
public void currency_exposure_premium_forward() {
CurrencyAmount pv = PRICER_TRADE.presentValue(SWAPTION_PREFWD_LONG_REC, MULTI_USD, HW_PROVIDER);
MultiCurrencyAmount ce = PRICER_TRADE.currencyExposure(SWAPTION_PREFWD_LONG_REC, MULTI_USD, HW_PROVIDER);
assertEquals(pv.getAmount(), ce.getAmount(USD).getAmount(), TOL * NOTIONAL);
}
//-------------------------------------------------------------------------
public void current_cash_forward() {
CurrencyAmount ccTrade = PRICER_TRADE.currentCash(SWAPTION_PREFWD_LONG_REC, VAL_DATE);
assertEquals(ccTrade.getAmount(), 0, TOL * NOTIONAL);
}
public void current_cash_vd() {
CurrencyAmount ccTrade = PRICER_TRADE.currentCash(SWAPTION_PRETOD_LONG_REC, VAL_DATE);
assertEquals(ccTrade.getAmount(), -PREMIUM_AMOUNT, TOL * NOTIONAL);
}
public void current_cash_past() {
CurrencyAmount ccTrade = PRICER_TRADE.currentCash(SWAPTION_PREPAST_LONG_REC, VAL_DATE);
assertEquals(ccTrade.getAmount(), 0, TOL * NOTIONAL);
}
//-------------------------------------------------------------------------
public void present_value_sensitivity_premium_forward() {
PointSensitivities pvcsTrade = PRICER_TRADE
.presentValueSensitivityRates(SWAPTION_PREFWD_LONG_REC, MULTI_USD, HW_PROVIDER);
PointSensitivityBuilder pvcsProduct = PRICER_PRODUCT
.presentValueSensitivityRates(SWAPTION_LONG_REC, MULTI_USD, HW_PROVIDER);
PointSensitivityBuilder pvcsPremium = PRICER_PAYMENT.presentValueSensitivity(PREMIUM_FWD_PAY, MULTI_USD);
CurrencyParameterSensitivities pvpsTrade = MULTI_USD.parameterSensitivity(pvcsTrade);
CurrencyParameterSensitivities pvpsProduct =
MULTI_USD.parameterSensitivity(pvcsProduct.combinedWith(pvcsPremium).build());
assertTrue(pvpsTrade.equalWithTolerance(pvpsProduct, TOL * NOTIONAL));
}
public void present_value_sensitivity_premium_valuedate() {
PointSensitivities pvcsTrade = PRICER_TRADE
.presentValueSensitivityRates(SWAPTION_PRETOD_LONG_REC, MULTI_USD, HW_PROVIDER);
PointSensitivityBuilder pvcsProduct = PRICER_PRODUCT
.presentValueSensitivityRates(SWAPTION_LONG_REC, MULTI_USD, HW_PROVIDER);
CurrencyParameterSensitivities pvpsTrade = MULTI_USD.parameterSensitivity(pvcsTrade);
CurrencyParameterSensitivities pvpsProduct = MULTI_USD.parameterSensitivity(pvcsProduct.build());
assertTrue(pvpsTrade.equalWithTolerance(pvpsProduct, TOL * NOTIONAL));
}
public void present_value_sensitivity_premium_past() {
PointSensitivities pvcsTrade = PRICER_TRADE
.presentValueSensitivityRates(SWAPTION_PREPAST_LONG_REC, MULTI_USD, HW_PROVIDER);
PointSensitivityBuilder pvcsProduct = PRICER_PRODUCT
.presentValueSensitivityRates(SWAPTION_LONG_REC, MULTI_USD, HW_PROVIDER);
CurrencyParameterSensitivities pvpsTrade = MULTI_USD.parameterSensitivity(pvcsTrade);
CurrencyParameterSensitivities pvpsProduct = MULTI_USD.parameterSensitivity(pvcsProduct.build());
assertTrue(pvpsTrade.equalWithTolerance(pvpsProduct, TOL * NOTIONAL));
}
//-------------------------------------------------------------------------
public void present_value_hw_param_sensitivity_premium_forward() {
DoubleArray hwTrade = PRICER_TRADE
.presentValueSensitivityModelParamsHullWhite(SWAPTION_PREFWD_LONG_REC, MULTI_USD, HW_PROVIDER);
DoubleArray hwProduct = PRICER_PRODUCT
.presentValueSensitivityModelParamsHullWhite(SWAPTION_LONG_REC, MULTI_USD, HW_PROVIDER);
assertTrue(DoubleArrayMath.fuzzyEquals(hwTrade.toArray(), hwProduct.toArray(), TOL * NOTIONAL));
}
}