/** * Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.interestrate.capletstripping; import com.opengamma.analytics.financial.model.interestrate.curve.ForwardCurve; import com.opengamma.analytics.financial.model.volatility.discrete.DiscreteVolatilityFunction; import com.opengamma.analytics.financial.model.volatility.discrete.ParameterizedSABRModelDiscreteVolatilityFunctionProvider; import com.opengamma.analytics.financial.model.volatility.discrete.ParameterizedSmileModelDiscreteVolatilityFunctionProvider; import com.opengamma.analytics.financial.model.volatility.smile.function.SABRFormulaData; import com.opengamma.analytics.math.curve.InterpolatedDoublesCurve; import com.opengamma.analytics.math.function.DoublesVectorFunctionProvider; import com.opengamma.analytics.math.function.VectorFunction; import com.opengamma.analytics.math.interpolation.CombinedInterpolatorExtrapolatorFactory; import com.opengamma.analytics.math.interpolation.Interpolator1DFactory; import com.opengamma.util.ArgumentChecker; /** * Caplet stripper using Hagan's SABR formula. The SABR parameters (alpha, beta, rho & nu) are themselves represented as * parameterised term structures, and this collection of parameters are the <i>model parameters</i>. For a particular * caplet, we can find the smile model parameters at its expiry, then (using the SABR formula) find the (Black) * volatility at its strike; hence the model parameters describe a caplet volatility surface. * <p> * For a set of market cap values, we can find, in a least-square sense, the optimal set of model parameters to reproduce the market values. Since the smiles are smooth functions of a few (4) * parameters, it is generally not possible to recover exactly market values using this method. */ public class CapletStripperSABRModel extends CapletStripperSmileModel<SABRFormulaData> { private static final int NUM_MODEL_PARMS = 4; /** * Set up the stripper. * @param pricer The pricer (which contained the details of the market values of the caps/floors) * @param volFuncProvider This will 'provide' a {@link DiscreteVolatilityFunction} that maps from a set of model * parameters (describing the term structures of SABR parameters) to the volatilities of the requested caplets. */ public CapletStripperSABRModel(MultiCapFloorPricer pricer, ParameterizedSmileModelDiscreteVolatilityFunctionProvider<SABRFormulaData> volFuncProvider) { super(pricer, volFuncProvider); } /** * Set up the stripper. * @param pricer The pricer (which contained the details of the market values of the caps/floors) * @param smileModelParameterProviders each of these providers represents a different smile parameter - <b>there * must be one for each smile model parameter</b>. Given a (common) set of expiries, each one provides a {@link VectorFunction} that gives the corresponding smile model parameter at each expiry for * a set of model * parameters. This gives a lot of flexibility as to how the (smile model) parameter term structures are * represented. */ public CapletStripperSABRModel(MultiCapFloorPricer pricer, DoublesVectorFunctionProvider[] smileModelParameterProviders) { super(pricer, getDiscreteVolatilityFunctionProvider(pricer, smileModelParameterProviders)); } private static ParameterizedSABRModelDiscreteVolatilityFunctionProvider getDiscreteVolatilityFunctionProvider(MultiCapFloorPricer pricer, DoublesVectorFunctionProvider[] smileModelParameterProviders) { ArgumentChecker.notNull(pricer, "pricer"); ArgumentChecker.noNulls(smileModelParameterProviders, "smileModelParameterProviders"); ArgumentChecker.isTrue(NUM_MODEL_PARMS == smileModelParameterProviders.length, "Require {} smileModelParameterProviders", NUM_MODEL_PARMS); // this interpolated forward curve that will only be hit at the knots, so don't need anything more than linear ForwardCurve fwdCurve = new ForwardCurve(InterpolatedDoublesCurve.from(pricer.getCapletExpiries(), pricer.getCapletForwardRates(), CombinedInterpolatorExtrapolatorFactory.getInterpolator(Interpolator1DFactory.LINEAR, Interpolator1DFactory.LINEAR_EXTRAPOLATOR))); return new ParameterizedSABRModelDiscreteVolatilityFunctionProvider(fwdCurve, smileModelParameterProviders); } }