com.opengamma.strata.pricer.cms.SabrExtrapolationReplicationCmsProductPricer Maven / Gradle / Ivy
/*
* Copyright (C) 2016 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.pricer.cms;
import java.util.ArrayList;
import java.util.List;
import com.opengamma.strata.basics.currency.CurrencyAmount;
import com.opengamma.strata.basics.currency.MultiCurrencyAmount;
import com.opengamma.strata.collect.ArgChecker;
import com.opengamma.strata.market.explain.ExplainKey;
import com.opengamma.strata.market.explain.ExplainMap;
import com.opengamma.strata.market.explain.ExplainMapBuilder;
import com.opengamma.strata.market.sensitivity.PointSensitivityBuilder;
import com.opengamma.strata.pricer.rate.RatesProvider;
import com.opengamma.strata.pricer.swap.DiscountingSwapLegPricer;
import com.opengamma.strata.pricer.swaption.SabrSwaptionVolatilities;
import com.opengamma.strata.product.cms.CmsLeg;
import com.opengamma.strata.product.cms.ResolvedCms;
import com.opengamma.strata.product.swap.SwapLeg;
/**
* Pricer for CMS products by swaption replication on a SABR formula with extrapolation.
*
* This function provides the ability to price {@link ResolvedCms}.
*/
public class SabrExtrapolationReplicationCmsProductPricer {
/**
* The pricer for {@link CmsLeg}.
*/
private final SabrExtrapolationReplicationCmsLegPricer cmsLegPricer;
/**
* The pricer for {@link SwapLeg}.
*/
private final DiscountingSwapLegPricer payLegPricer;
/**
* Creates an instance using the default pay leg pricer.
*
* @param cmsLegPricer the pricer for {@link CmsLeg}
*/
public SabrExtrapolationReplicationCmsProductPricer(
SabrExtrapolationReplicationCmsLegPricer cmsLegPricer) {
this(cmsLegPricer, DiscountingSwapLegPricer.DEFAULT);
}
/**
* Creates an instance.
*
* @param cmsLegPricer the pricer for {@link CmsLeg}
* @param payLegPricer the pricer for {@link SwapLeg}
*/
public SabrExtrapolationReplicationCmsProductPricer(
SabrExtrapolationReplicationCmsLegPricer cmsLegPricer,
DiscountingSwapLegPricer payLegPricer) {
this.cmsLegPricer = ArgChecker.notNull(cmsLegPricer, "cmsLegPricer");
this.payLegPricer = ArgChecker.notNull(payLegPricer, "payLegPricer");
}
//-------------------------------------------------------------------------
/**
* Calculates the present value of the CMS product.
*
* The present value of the product is the value on the valuation date.
*
* CMS leg and pay leg are typically in the same currency. Thus the present value is expressed as a
* single currency amount in most cases.
*
* @param cms the CMS product
* @param ratesProvider the rates provider
* @param swaptionVolatilities the swaption volatilities
* @return the present value
*/
public MultiCurrencyAmount presentValue(
ResolvedCms cms,
RatesProvider ratesProvider,
SabrSwaptionVolatilities swaptionVolatilities) {
CurrencyAmount pvCmsLeg = cmsLegPricer.presentValue(cms.getCmsLeg(), ratesProvider, swaptionVolatilities);
if (!cms.getPayLeg().isPresent()) {
return MultiCurrencyAmount.of(pvCmsLeg);
}
CurrencyAmount pvPayLeg = payLegPricer.presentValue(cms.getPayLeg().get(), ratesProvider);
return MultiCurrencyAmount.of(pvCmsLeg).plus(pvPayLeg);
}
//-------------------------------------------------------------------------
/**
* Explains the present value of the CMS product.
*
* This returns explanatory information about the calculation.
*
* @param cms the CMS product
* @param ratesProvider the rates provider
* @param swaptionVolatilities the swaption volatilities
* @return the explain PV map
*/
public ExplainMap explainPresentValue(
ResolvedCms cms,
RatesProvider ratesProvider,
SabrSwaptionVolatilities swaptionVolatilities) {
ExplainMapBuilder builder = ExplainMap.builder();
builder.put(ExplainKey.ENTRY_TYPE, "CmsSwap");
List legsExplain = new ArrayList<>();
legsExplain.add(cmsLegPricer.explainPresentValue(cms.getCmsLeg(), ratesProvider, swaptionVolatilities));
if (cms.getPayLeg().isPresent()) {
legsExplain.add(payLegPricer.explainPresentValue(cms.getPayLeg().get(), ratesProvider));
}
builder.put(ExplainKey.LEGS, legsExplain);
return builder.build();
}
//-------------------------------------------------------------------------
/**
* Calculates the present value curve sensitivity of the CMS product.
*
* The present value sensitivity of the product is the sensitivity of the present value to the underlying curves.
*
* @param cms the CMS product
* @param ratesProvider the rates provider
* @param swaptionVolatilities the swaption volatilities
* @return the present value sensitivity
*/
public PointSensitivityBuilder presentValueSensitivityRates(
ResolvedCms cms,
RatesProvider ratesProvider,
SabrSwaptionVolatilities swaptionVolatilities) {
PointSensitivityBuilder pvSensiCmsLeg =
cmsLegPricer.presentValueSensitivityRates(cms.getCmsLeg(), ratesProvider, swaptionVolatilities);
if (!cms.getPayLeg().isPresent()) {
return pvSensiCmsLeg;
}
PointSensitivityBuilder pvSensiPayLeg = payLegPricer.presentValueSensitivity(cms.getPayLeg().get(), ratesProvider);
return pvSensiCmsLeg.combinedWith(pvSensiPayLeg);
}
/**
* Calculates the present value sensitivity to the SABR model parameters.
*
* The present value sensitivity of the product is the sensitivity of the present value
* to the SABR model parameters, alpha, beta, rho and nu.
*
* @param cms the CMS product
* @param ratesProvider the rates provider
* @param swaptionVolatilities the swaption volatilities
* @return the present value sensitivity
*/
public PointSensitivityBuilder presentValueSensitivityModelParamsSabr(
ResolvedCms cms,
RatesProvider ratesProvider,
SabrSwaptionVolatilities swaptionVolatilities) {
return cmsLegPricer.presentValueSensitivityModelParamsSabr(cms.getCmsLeg(), ratesProvider, swaptionVolatilities);
}
/**
* Calculates the present value sensitivity to the strike value.
*
* The present value sensitivity of the product is the sensitivity of the present value to the strike value.
* This is not relevant for CMS coupons and an exception is thrown in the underlying pricer.
*
* @param cms the CMS product
* @param ratesProvider the rates provider
* @param swaptionVolatilities the swaption volatilities
* @return the present value sensitivity
*/
public double presentValueSensitivityStrike(
ResolvedCms cms,
RatesProvider ratesProvider,
SabrSwaptionVolatilities swaptionVolatilities) {
return cmsLegPricer.presentValueSensitivityStrike(cms.getCmsLeg(), ratesProvider, swaptionVolatilities);
}
//-------------------------------------------------------------------------
/**
* Calculates the currency exposure of the product.
*
* @param cms the CMS product
* @param ratesProvider the rates provider
* @param swaptionVolatilities the swaption volatilities
* @return the currency exposure
*/
public MultiCurrencyAmount currencyExposure(
ResolvedCms cms,
RatesProvider ratesProvider,
SabrSwaptionVolatilities swaptionVolatilities) {
CurrencyAmount ceCmsLeg = cmsLegPricer.presentValue(cms.getCmsLeg(), ratesProvider, swaptionVolatilities);
if (!cms.getPayLeg().isPresent()) {
return MultiCurrencyAmount.of(ceCmsLeg);
}
MultiCurrencyAmount cePayLeg = payLegPricer.currencyExposure(cms.getPayLeg().get(), ratesProvider);
return cePayLeg.plus(ceCmsLeg);
}
/**
* Calculates the current cash of the product.
*
* @param cms the CMS product
* @param ratesProvider the rates provider
* @param swaptionVolatilities the swaption volatilities
* @return the current cash
*/
public MultiCurrencyAmount currentCash(
ResolvedCms cms,
RatesProvider ratesProvider,
SabrSwaptionVolatilities swaptionVolatilities) {
CurrencyAmount ccCmsLeg = cmsLegPricer.currentCash(cms.getCmsLeg(), ratesProvider, swaptionVolatilities);
if (!cms.getPayLeg().isPresent()) {
return MultiCurrencyAmount.of(ccCmsLeg);
}
CurrencyAmount ccPayLeg = payLegPricer.currentCash(cms.getPayLeg().get(), ratesProvider);
return MultiCurrencyAmount.of(ccPayLeg).plus(ccCmsLeg);
}
}