/** * 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 com.opengamma.strata.product.swap.type.FixedIborSwapConventions.USD_FIXED_6M_LIBOR_3M; 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.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.rate.ImmutableRatesProvider; 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; /** * Tests {@link NormalSwaptionTradePricer} for physical. */ @Test public class NormalSwaptionTradePricerPhysicalTest { 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 = 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 VolatilitySwaptionTradePricer PRICER_COMMON = VolatilitySwaptionTradePricer.DEFAULT; private static final NormalSwaptionTradePricer PRICER_TRADE = NormalSwaptionTradePricer.DEFAULT; private static final NormalSwaptionPhysicalProductPricer PRICER_PRODUCT = NormalSwaptionPhysicalProductPricer.DEFAULT; private static final DiscountingPaymentPricer PRICER_PAYMENT = DiscountingPaymentPricer.DEFAULT; private static final ImmutableRatesProvider MULTI_USD = RatesProviderDataSets.multiUsd(VAL_DATE); private static final NormalSwaptionExpiryTenorVolatilities NORMAL_VOLS_USD = SwaptionNormalVolatilityDataSets.NORMAL_SWAPTION_VOLS_USD_STD; private static final double TOLERANCE_PV = 1.0E-2; private static final double TOLERANCE_PV_DELTA = 1.0E+2; private static final double TOLERANCE_PV_VEGA = 1.0E+4; //------------------------------------------------------------------------- public void present_value_premium_forward() { CurrencyAmount pvTrade = PRICER_TRADE.presentValue(SWAPTION_PREFWD_LONG_REC, MULTI_USD, NORMAL_VOLS_USD); CurrencyAmount pvProduct = PRICER_PRODUCT.presentValue(SWAPTION_LONG_REC, MULTI_USD, NORMAL_VOLS_USD); CurrencyAmount pvPremium = PRICER_PAYMENT.presentValue(PREMIUM_FWD_PAY, MULTI_USD); assertEquals(pvTrade.getAmount(), pvProduct.getAmount() + pvPremium.getAmount(), TOLERANCE_PV); // test via VolatilitySwaptionTradePricer CurrencyAmount pv = PRICER_COMMON.presentValue(SWAPTION_PREFWD_LONG_REC, MULTI_USD, NORMAL_VOLS_USD); assertEquals(pv, pvTrade); } public void present_value_premium_valuedate() { CurrencyAmount pvTrade = PRICER_TRADE.presentValue(SWAPTION_PRETOD_LONG_REC, MULTI_USD, NORMAL_VOLS_USD); CurrencyAmount pvProduct = PRICER_PRODUCT.presentValue(SWAPTION_LONG_REC, MULTI_USD, NORMAL_VOLS_USD); CurrencyAmount pvPremium = PRICER_PAYMENT.presentValue(PREMIUM_TRA_PAY, MULTI_USD); assertEquals(pvTrade.getAmount(), pvProduct.getAmount() + pvPremium.getAmount(), TOLERANCE_PV); } public void present_value_premium_past() { CurrencyAmount pvTrade = PRICER_TRADE.presentValue(SWAPTION_PREPAST_LONG_REC, MULTI_USD, NORMAL_VOLS_USD); CurrencyAmount pvProduct = PRICER_PRODUCT.presentValue(SWAPTION_LONG_REC, MULTI_USD, NORMAL_VOLS_USD); assertEquals(pvTrade.getAmount(), pvProduct.getAmount(), TOLERANCE_PV); } //------------------------------------------------------------------------- public void currency_exposure_premium_forward() { CurrencyAmount pv = PRICER_TRADE .presentValue(SWAPTION_PREFWD_LONG_REC, MULTI_USD, NORMAL_VOLS_USD); MultiCurrencyAmount ce = PRICER_TRADE .currencyExposure(SWAPTION_PREFWD_LONG_REC, MULTI_USD, NORMAL_VOLS_USD); assertEquals(pv.getAmount(), ce.getAmount(USD).getAmount(), TOLERANCE_PV); } //------------------------------------------------------------------------- public void current_cash_forward() { CurrencyAmount ccTrade = PRICER_TRADE.currentCash(SWAPTION_PREFWD_LONG_REC, VAL_DATE); assertEquals(ccTrade.getAmount(), 0, TOLERANCE_PV); } public void current_cash_vd() { CurrencyAmount ccTrade = PRICER_TRADE.currentCash(SWAPTION_PRETOD_LONG_REC, VAL_DATE); assertEquals(ccTrade.getAmount(), -PREMIUM_AMOUNT, TOLERANCE_PV); } public void current_cash_past() { CurrencyAmount ccTrade = PRICER_TRADE.currentCash(SWAPTION_PREPAST_LONG_REC, VAL_DATE); assertEquals(ccTrade.getAmount(), 0, TOLERANCE_PV); } //------------------------------------------------------------------------- public void present_value_sensitivity_premium_forward() { PointSensitivities pvcsTrade = PRICER_TRADE .presentValueSensitivityRatesStickyStrike(SWAPTION_PREFWD_LONG_REC, MULTI_USD, NORMAL_VOLS_USD); PointSensitivityBuilder pvcsProduct = PRICER_PRODUCT .presentValueSensitivityRatesStickyStrike(SWAPTION_LONG_REC, MULTI_USD, NORMAL_VOLS_USD); 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, TOLERANCE_PV_DELTA)); } public void present_value_sensitivity_premium_valuedate() { PointSensitivities pvcsTrade = PRICER_TRADE .presentValueSensitivityRatesStickyStrike(SWAPTION_PRETOD_LONG_REC, MULTI_USD, NORMAL_VOLS_USD); PointSensitivityBuilder pvcsProduct = PRICER_PRODUCT .presentValueSensitivityRatesStickyStrike(SWAPTION_LONG_REC, MULTI_USD, NORMAL_VOLS_USD); CurrencyParameterSensitivities pvpsTrade = MULTI_USD.parameterSensitivity(pvcsTrade); CurrencyParameterSensitivities pvpsProduct = MULTI_USD.parameterSensitivity(pvcsProduct.build()); assertTrue(pvpsTrade.equalWithTolerance(pvpsProduct, TOLERANCE_PV_DELTA)); } public void present_value_sensitivity_premium_past() { PointSensitivities pvcsTrade = PRICER_TRADE .presentValueSensitivityRatesStickyStrike(SWAPTION_PREPAST_LONG_REC, MULTI_USD, NORMAL_VOLS_USD); PointSensitivityBuilder pvcsProduct = PRICER_PRODUCT .presentValueSensitivityRatesStickyStrike(SWAPTION_LONG_REC, MULTI_USD, NORMAL_VOLS_USD); CurrencyParameterSensitivities pvpsTrade = MULTI_USD.parameterSensitivity(pvcsTrade); CurrencyParameterSensitivities pvpsProduct = MULTI_USD.parameterSensitivity(pvcsProduct.build()); assertTrue(pvpsTrade.equalWithTolerance(pvpsProduct, TOLERANCE_PV_DELTA)); } //------------------------------------------------------------------------- public void present_value_normal_vol_sensitivity_premium_forward() { PointSensitivities vegaTrade = PRICER_TRADE .presentValueSensitivityModelParamsVolatility(SWAPTION_PREFWD_LONG_REC, MULTI_USD, NORMAL_VOLS_USD); SwaptionSensitivity vegaProduct = PRICER_PRODUCT .presentValueSensitivityModelParamsVolatility(SWAPTION_LONG_REC, MULTI_USD, NORMAL_VOLS_USD); assertEquals(vegaTrade.getSensitivities().get(0).getSensitivity(), vegaProduct.getSensitivity(), TOLERANCE_PV_VEGA); } }