/** * 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 java.util.Arrays; import org.apache.commons.lang.NotImplementedException; import com.opengamma.analytics.financial.model.volatility.discrete.ParameterizedSmileModelDiscreteVolatilityFunctionProvider; import com.opengamma.analytics.financial.model.volatility.smile.function.SmileModelData; import com.opengamma.analytics.math.function.VectorFunctionProvider; import com.opengamma.analytics.math.matrix.DoubleMatrix1D; import com.opengamma.util.ArgumentChecker; /** * Smile model based caplet stripper. The parameters of the smile model (e.g. SABR, Heston, SVI) are themselves * represented as parameterised term structures (one for each smile model parameter), 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 smile model) 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-5) parameters, it is generally not * possible to recover exactly market values using this method. * @param <T> The type of smile model data */ public class CapletStripperSmileModel<T extends SmileModelData> implements CapletStripper { private final CapletStrippingCore _imp; /** * Set up the stripper. * @param pricer The pricer (which contained the details of the market values of the caps/floors) * @param volFuncProvider A {@link VectorFunctionProvider} backed by a smile model */ public CapletStripperSmileModel(MultiCapFloorPricer pricer, ParameterizedSmileModelDiscreteVolatilityFunctionProvider<T> volFuncProvider) { ArgumentChecker.notNull(pricer, "pricer"); ArgumentChecker.notNull(volFuncProvider, "volFuncProvider"); _imp = new CapletStrippingCore(pricer, volFuncProvider); } @Override public CapletStrippingResult solve(double[] marketValues, MarketDataType type) { throw new NotImplementedException("must provide a guess"); } @Override public CapletStrippingResult solve(double[] marketValues, MarketDataType type, double[] errors) { throw new NotImplementedException("must provide a guess"); } @Override public CapletStrippingResult solve(double[] marketValues, MarketDataType type, DoubleMatrix1D guess) { ArgumentChecker.notNull(marketValues, "marketValues"); int n = marketValues.length; double[] errors = new double[n]; Arrays.fill(errors, 1.0); return solve(marketValues, type, errors, guess); } @Override public CapletStrippingResult solve(double[] marketValues, MarketDataType type, double[] errors, DoubleMatrix1D guess) { if (type == MarketDataType.PRICE) { return _imp.solveForCapPrices(marketValues, errors, guess); } else if (type == MarketDataType.VOL) { return _imp.solveForCapVols(marketValues, errors, guess); } throw new IllegalArgumentException("Unknown MarketDataType " + type.toString()); } }