All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.opengamma.strata.pricer.swaption.SabrSwaptionCashParYieldProductPricer Maven / Gradle / Ivy

The newest version!
/*
 * 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.market.model.SabrParameterType.ALPHA;
import static com.opengamma.strata.market.model.SabrParameterType.BETA;
import static com.opengamma.strata.market.model.SabrParameterType.NU;
import static com.opengamma.strata.market.model.SabrParameterType.RHO;

import java.time.LocalDate;
import java.time.ZonedDateTime;

import com.opengamma.strata.basics.currency.Currency;
import com.opengamma.strata.basics.value.ValueDerivatives;
import com.opengamma.strata.collect.array.DoubleArray;
import com.opengamma.strata.market.sensitivity.PointSensitivityBuilder;
import com.opengamma.strata.pricer.impl.option.BlackFormulaRepository;
import com.opengamma.strata.pricer.rate.RatesProvider;
import com.opengamma.strata.pricer.swap.DiscountingSwapProductPricer;
import com.opengamma.strata.product.swap.ResolvedSwap;
import com.opengamma.strata.product.swap.ResolvedSwapLeg;
import com.opengamma.strata.product.swap.Swap;
import com.opengamma.strata.product.swaption.CashSwaptionSettlement;
import com.opengamma.strata.product.swaption.ResolvedSwaption;

/**
 * Pricer for swaption with par yield curve method of cash settlement in SABR model.
 * 

* The swap underlying the swaption must have a fixed leg on which the forward rate is computed. * The underlying swap must be single currency. *

* The volatility parameters are not adjusted for the underlying swap convention. * The volatilities from the provider are taken as such. *

* The value of the swaption after expiry is 0. For a swaption which already expired, negative number is returned by * the method, {@link SabrSwaptionVolatilities#relativeTime(ZonedDateTime)}. */ public class SabrSwaptionCashParYieldProductPricer extends VolatilitySwaptionCashParYieldProductPricer { /** * Default implementation. */ public static final SabrSwaptionCashParYieldProductPricer DEFAULT = new SabrSwaptionCashParYieldProductPricer(DiscountingSwapProductPricer.DEFAULT); /** * Creates an instance. * * @param swapPricer the pricer for {@link Swap} */ public SabrSwaptionCashParYieldProductPricer(DiscountingSwapProductPricer swapPricer) { super(swapPricer); } //------------------------------------------------------------------------- /** * Calculates the present value sensitivity of the swaption product to the rate curves. *

* The present value sensitivity is computed in a "sticky model parameter" style, i.e. the sensitivity to the * curve nodes with the SABR model parameters unchanged. This sensitivity does not include a potential * re-calibration of the model parameters to the raw market data. * * @param swaption the swaption product * @param ratesProvider the rates provider * @param swaptionVolatilities the volatilities * @return the point sensitivity to the rate curves */ public PointSensitivityBuilder presentValueSensitivityRatesStickyModel( ResolvedSwaption swaption, RatesProvider ratesProvider, SabrSwaptionVolatilities swaptionVolatilities) { validate(swaption, ratesProvider, swaptionVolatilities); ZonedDateTime expiryDateTime = swaption.getExpiry(); double expiry = swaptionVolatilities.relativeTime(expiryDateTime); ResolvedSwap underlying = swaption.getUnderlying(); ResolvedSwapLeg fixedLeg = fixedLeg(underlying); if (expiry < 0d) { // Option has expired already return PointSensitivityBuilder.none(); } double forward = forwardRate(swaption, ratesProvider); ValueDerivatives annuityDerivative = getSwapPricer().getLegPricer().annuityCashDerivative(fixedLeg, forward); double annuityCash = annuityDerivative.getValue(); double annuityCashDr = annuityDerivative.getDerivative(0); LocalDate settlementDate = ((CashSwaptionSettlement) swaption.getSwaptionSettlement()).getSettlementDate(); double discountSettle = ratesProvider.discountFactor(fixedLeg.getCurrency(), settlementDate); double strike = calculateStrike(fixedLeg); double tenor = swaptionVolatilities.tenor(fixedLeg.getStartDate(), fixedLeg.getEndDate()); double shift = swaptionVolatilities.shift(expiry, tenor); ValueDerivatives volatilityAdj = swaptionVolatilities.volatilityAdjoint(expiry, tenor, strike, forward); boolean isCall = fixedLeg.getPayReceive().isPay(); double shiftedForward = forward + shift; double shiftedStrike = strike + shift; double price = BlackFormulaRepository.price(shiftedForward, shiftedStrike, expiry, volatilityAdj.getValue(), isCall); double delta = BlackFormulaRepository.delta(shiftedForward, shiftedStrike, expiry, volatilityAdj.getValue(), isCall); double vega = BlackFormulaRepository.vega(shiftedForward, shiftedStrike, expiry, volatilityAdj.getValue()); PointSensitivityBuilder forwardSensi = getSwapPricer().parRateSensitivity(underlying, ratesProvider); PointSensitivityBuilder discountSettleSensi = ratesProvider.discountFactors(fixedLeg.getCurrency()).zeroRatePointSensitivity(settlementDate); double sign = swaption.getLongShort().sign(); return forwardSensi.multipliedBy( sign * discountSettle * (annuityCash * (delta + vega * volatilityAdj.getDerivative(0)) + annuityCashDr * price)) .combinedWith(discountSettleSensi.multipliedBy(sign * annuityCash * price)); } //------------------------------------------------------------------------- /** * Calculates the present value sensitivity to the SABR model parameters of the swaption product. *

* The sensitivity of the present value to the SABR model parameters, alpha, beta, rho and nu. * * @param swaption the swaption product * @param ratesProvider the rates provider * @param swaptionVolatilities the volatilities * @return the point sensitivity to the SABR model parameters */ public PointSensitivityBuilder presentValueSensitivityModelParamsSabr( ResolvedSwaption swaption, RatesProvider ratesProvider, SabrSwaptionVolatilities swaptionVolatilities) { validate(swaption, ratesProvider, swaptionVolatilities); double expiry = swaptionVolatilities.relativeTime(swaption.getExpiry()); ResolvedSwap underlying = swaption.getUnderlying(); ResolvedSwapLeg fixedLeg = fixedLeg(underlying); double tenor = swaptionVolatilities.tenor(fixedLeg.getStartDate(), fixedLeg.getEndDate()); double shift = swaptionVolatilities.shift(expiry, tenor); double strike = calculateStrike(fixedLeg); if (expiry < 0d) { // Option has expired already return PointSensitivityBuilder.none(); } double forward = forwardRate(swaption, ratesProvider); double volatility = swaptionVolatilities.volatility(expiry, tenor, strike, forward); double numeraire = calculateNumeraire(swaption, fixedLeg, forward, ratesProvider); DoubleArray derivative = swaptionVolatilities.volatilityAdjoint(expiry, tenor, strike, forward).getDerivatives(); double vega = numeraire * swaption.getLongShort().sign() * BlackFormulaRepository.vega(forward + shift, strike + shift, expiry, volatility); // sensitivities Currency ccy = fixedLeg.getCurrency(); SwaptionVolatilitiesName name = swaptionVolatilities.getName(); return PointSensitivityBuilder.of( SwaptionSabrSensitivity.of(name, expiry, tenor, ALPHA, ccy, vega * derivative.get(2)), SwaptionSabrSensitivity.of(name, expiry, tenor, BETA, ccy, vega * derivative.get(3)), SwaptionSabrSensitivity.of(name, expiry, tenor, RHO, ccy, vega * derivative.get(4)), SwaptionSabrSensitivity.of(name, expiry, tenor, NU, ccy, vega * derivative.get(5))); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy