/**
* 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 org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
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.basics.date.Tenor;
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.rate.ImmutableRatesProvider;
import com.opengamma.strata.product.common.BuySell;
import com.opengamma.strata.product.common.LongShort;
import com.opengamma.strata.product.swap.Swap;
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 SabrSwaptionTradePricer} for physical.
*/
@Test
public class SabrSwaptionPhysicalTradePricerTest {
private static final ReferenceData REF_DATA = ReferenceData.standard();
private static final LocalDate VAL_DATE = LocalDate.of(2014, 1, 22);
// swaption trades
private static final double NOTIONAL = 100000000; //100m
private static final double RATE = 0.0350;
private static final int TENOR_YEAR = 7;
private static final Tenor TENOR = Tenor.ofYears(TENOR_YEAR);
private static final ZonedDateTime MATURITY_DATE = LocalDate.of(2016, 1, 22).atStartOfDay(ZoneOffset.UTC); // 2Y
private static final Swap SWAP_REC = SwaptionSabrRateVolatilityDataSet.SWAP_CONVENTION_USD.createTrade(
MATURITY_DATE.toLocalDate(), TENOR, BuySell.SELL, NOTIONAL, RATE, REF_DATA).getProduct();
private static final SwaptionSettlement PHYSICAL_SETTLE = PhysicalSwaptionSettlement.DEFAULT;
private static final ResolvedSwaption SWAPTION_LONG_REC = Swaption.builder()
.expiryDate(AdjustableDate.of(MATURITY_DATE.toLocalDate()))
.expiryTime(MATURITY_DATE.toLocalTime())
.expiryZone(MATURITY_DATE.getZone())
.longShort(LongShort.LONG)
.swaptionSettlement(PHYSICAL_SETTLE)
.underlying(SWAP_REC)
.build()
.resolve(REF_DATA);
private static final double PREMIUM_AMOUNT = 100_000;
private static final Payment PREMIUM_FWD_PAY = Payment.of(
CurrencyAmount.of(USD, -PREMIUM_AMOUNT), MATURITY_DATE.toLocalDate());
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();
// providers
private static final ImmutableRatesProvider RATE_PROVIDER =
SwaptionSabrRateVolatilityDataSet.getRatesProviderUsd(VAL_DATE);
private static final SabrSwaptionVolatilities VOLS =
SwaptionSabrRateVolatilityDataSet.getVolatilitiesUsd(VAL_DATE, true);
private static final double TOL = 1.0e-12;
private static final VolatilitySwaptionTradePricer PRICER_COMMON = VolatilitySwaptionTradePricer.DEFAULT;
private static final SabrSwaptionTradePricer PRICER_TRADE = SabrSwaptionTradePricer.DEFAULT;
private static final SabrSwaptionPhysicalProductPricer PRICER_PRODUCT = SabrSwaptionPhysicalProductPricer.DEFAULT;
private static final DiscountingPaymentPricer PRICER_PAYMENT = DiscountingPaymentPricer.DEFAULT;
//-------------------------------------------------------------------------
public void present_value_premium_forward() {
CurrencyAmount pvTrade =
PRICER_TRADE.presentValue(SWAPTION_PREFWD_LONG_REC, RATE_PROVIDER, VOLS);
CurrencyAmount pvProduct =
PRICER_PRODUCT.presentValue(SWAPTION_LONG_REC, RATE_PROVIDER, VOLS);
CurrencyAmount pvPremium = PRICER_PAYMENT.presentValue(PREMIUM_FWD_PAY, RATE_PROVIDER);
assertEquals(pvTrade.getAmount(), pvProduct.getAmount() + pvPremium.getAmount(), NOTIONAL * TOL);
// test via VolatilitySwaptionTradePricer
CurrencyAmount pv = PRICER_COMMON.presentValue(SWAPTION_PREFWD_LONG_REC, RATE_PROVIDER, VOLS);
assertEquals(pv, pvTrade);
}
public void present_value_premium_valuedate() {
CurrencyAmount pvTrade =
PRICER_TRADE.presentValue(SWAPTION_PRETOD_LONG_REC, RATE_PROVIDER, VOLS);
CurrencyAmount pvProduct =
PRICER_PRODUCT.presentValue(SWAPTION_LONG_REC, RATE_PROVIDER, VOLS);
CurrencyAmount pvPremium = PRICER_PAYMENT.presentValue(PREMIUM_TRA_PAY, RATE_PROVIDER);
assertEquals(pvTrade.getAmount(), pvProduct.getAmount() + pvPremium.getAmount(), NOTIONAL * TOL);
}
public void present_value_premium_past() {
CurrencyAmount pvTrade =
PRICER_TRADE.presentValue(SWAPTION_PREPAST_LONG_REC, RATE_PROVIDER, VOLS);
CurrencyAmount pvProduct =
PRICER_PRODUCT.presentValue(SWAPTION_LONG_REC, RATE_PROVIDER, VOLS);
assertEquals(pvTrade.getAmount(), pvProduct.getAmount(), NOTIONAL * TOL);
}
//-------------------------------------------------------------------------
public void currency_exposure_premium_forward() {
CurrencyAmount pv = PRICER_TRADE
.presentValue(SWAPTION_PREFWD_LONG_REC, RATE_PROVIDER, VOLS);
MultiCurrencyAmount ce = PRICER_TRADE
.currencyExposure(SWAPTION_PREFWD_LONG_REC, RATE_PROVIDER, VOLS);
assertEquals(pv.getAmount(), ce.getAmount(USD).getAmount(), NOTIONAL * TOL);
}
//-------------------------------------------------------------------------
public void current_cash_forward() {
CurrencyAmount ccTrade = PRICER_TRADE.currentCash(SWAPTION_PREFWD_LONG_REC, VAL_DATE);
assertEquals(ccTrade.getAmount(), 0, NOTIONAL * TOL);
}
public void current_cash_vd() {
CurrencyAmount ccTrade = PRICER_TRADE.currentCash(SWAPTION_PRETOD_LONG_REC, VAL_DATE);
assertEquals(ccTrade.getAmount(), -PREMIUM_AMOUNT, NOTIONAL * TOL);
}
public void current_cash_past() {
CurrencyAmount ccTrade = PRICER_TRADE.currentCash(SWAPTION_PREPAST_LONG_REC, VAL_DATE);
assertEquals(ccTrade.getAmount(), 0, NOTIONAL * TOL);
}
//-------------------------------------------------------------------------
public void present_value_sensitivity_premium_forward() {
PointSensitivities pvcsTrade = PRICER_TRADE
.presentValueSensitivityRatesStickyModel(SWAPTION_PREFWD_LONG_REC, RATE_PROVIDER, VOLS);
PointSensitivityBuilder pvcsProduct = PRICER_PRODUCT
.presentValueSensitivityRatesStickyModel(SWAPTION_LONG_REC, RATE_PROVIDER, VOLS);
PointSensitivityBuilder pvcsPremium = PRICER_PAYMENT.presentValueSensitivity(PREMIUM_FWD_PAY, RATE_PROVIDER);
CurrencyParameterSensitivities pvpsTrade = RATE_PROVIDER.parameterSensitivity(pvcsTrade);
CurrencyParameterSensitivities pvpsProduct =
RATE_PROVIDER.parameterSensitivity(pvcsProduct.combinedWith(pvcsPremium).build());
assertTrue(pvpsTrade.equalWithTolerance(pvpsProduct, NOTIONAL * NOTIONAL * TOL));
}
public void present_value_sensitivity_premium_valuedate() {
PointSensitivities pvcsTrade = PRICER_TRADE
.presentValueSensitivityRatesStickyModel(SWAPTION_PRETOD_LONG_REC, RATE_PROVIDER, VOLS);
PointSensitivityBuilder pvcsProduct = PRICER_PRODUCT
.presentValueSensitivityRatesStickyModel(SWAPTION_LONG_REC, RATE_PROVIDER, VOLS);
CurrencyParameterSensitivities pvpsTrade = RATE_PROVIDER.parameterSensitivity(pvcsTrade);
CurrencyParameterSensitivities pvpsProduct = RATE_PROVIDER.parameterSensitivity(pvcsProduct.build());
assertTrue(pvpsTrade.equalWithTolerance(pvpsProduct, NOTIONAL * NOTIONAL * TOL));
}
public void present_value_sensitivity_premium_past() {
PointSensitivities pvcsTrade = PRICER_TRADE
.presentValueSensitivityRatesStickyModel(SWAPTION_PREPAST_LONG_REC, RATE_PROVIDER, VOLS);
PointSensitivityBuilder pvcsProduct = PRICER_PRODUCT
.presentValueSensitivityRatesStickyModel(SWAPTION_LONG_REC, RATE_PROVIDER, VOLS);
CurrencyParameterSensitivities pvpsTrade = RATE_PROVIDER.parameterSensitivity(pvcsTrade);
CurrencyParameterSensitivities pvpsProduct = RATE_PROVIDER.parameterSensitivity(pvcsProduct.build());
assertTrue(pvpsTrade.equalWithTolerance(pvpsProduct, NOTIONAL * NOTIONAL * TOL));
}
//-------------------------------------------------------------------------
public void present_value_vol_sensitivity_premium_forward() {
PointSensitivities vegaTrade = PRICER_TRADE
.presentValueSensitivityModelParamsSabr(SWAPTION_PREFWD_LONG_REC, RATE_PROVIDER, VOLS);
PointSensitivities vegaProduct = PRICER_PRODUCT
.presentValueSensitivityModelParamsSabr(SWAPTION_LONG_REC, RATE_PROVIDER, VOLS).build();
assertEquals(vegaTrade, vegaProduct);
}
}