/** * Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.interestrate.swaption.method; import com.opengamma.analytics.financial.interestrate.YieldCurveBundle; import com.opengamma.analytics.financial.interestrate.method.SuccessiveLeastSquareCalibrationObjective; import com.opengamma.analytics.financial.interestrate.swaption.derivative.SwaptionPhysicalFixedIbor; import com.opengamma.analytics.financial.model.interestrate.definition.LiborMarketModelDisplacedDiffusionDataBundle; import com.opengamma.analytics.financial.model.interestrate.definition.LiborMarketModelDisplacedDiffusionParameters; import com.opengamma.analytics.math.matrix.DoubleMatrix1D; import com.opengamma.util.ArgumentChecker; /** * Specific objective function for LMM calibration with swaptions. The calibration is done on the volatilities and the displacements (skews). * @deprecated {@link YieldCurveBundle} is deprecated */ @Deprecated public class SwaptionPhysicalLMMDDSuccessiveLeastSquareCalibrationObjective extends SuccessiveLeastSquareCalibrationObjective { /** * The pricing method used to price the swaptions. */ private static final SwaptionPhysicalFixedIborLMMDDMethod METHOD_LMM_SWAPTION = SwaptionPhysicalFixedIborLMMDDMethod.getInstance(); /** * The LMM parameters. The calibration is done on the block of parameters between _startIndex and _endIndex. */ private final LiborMarketModelDisplacedDiffusionParameters _lmmParameters; /** * The LMM parameters and curves bundle. */ private LiborMarketModelDisplacedDiffusionDataBundle _lmmBundle; /** * The start index for the calibration. */ private int _startIndex; /** * The end index for the calibration. */ private int _endIndex; /** * The initial LMM volatilities before calibration. */ private final double[][] _volatilityInit; /** * The initial displacement parameters before calibration. */ private final double[] _displacementInit; /** * Constructor of the objective function with the LMM parameters. The parameters range and accuracy are set at some default value * (minimum: 1.0E-1; maximum: 1.0E+1, function value accuracy: 1.0E-4; parameter absolute accuracy: 1.0E-9). * @param parameters The Hull-White parameters. */ public SwaptionPhysicalLMMDDSuccessiveLeastSquareCalibrationObjective(final LiborMarketModelDisplacedDiffusionParameters parameters) { ArgumentChecker.notNull(parameters, "parameters"); _lmmParameters = parameters; _volatilityInit = new double[_lmmParameters.getNbPeriod()][_lmmParameters.getNbFactor()]; for (int loopperiod = 0; loopperiod < _lmmParameters.getNbPeriod(); loopperiod++) { for (int loopfact = 0; loopfact < _lmmParameters.getNbFactor(); loopfact++) { _volatilityInit[loopperiod][loopfact] = parameters.getVolatility()[loopperiod][loopfact]; } } _displacementInit = new double[_lmmParameters.getNbPeriod()]; for (int loopperiod = 0; loopperiod < _lmmParameters.getNbPeriod(); loopperiod++) { _displacementInit[loopperiod] = parameters.getDisplacement()[loopperiod]; } } /** * Gets the LMM data. * @return The LMM data. */ public LiborMarketModelDisplacedDiffusionParameters getLMMParameters() { return _lmmParameters; } /** * Gets the LMM curve bundle. * @return The LMM curve bundle. */ public LiborMarketModelDisplacedDiffusionDataBundle getLMMBundle() { return _lmmBundle; } @Override public void setCurves(final YieldCurveBundle curves) { _lmmBundle = new LiborMarketModelDisplacedDiffusionDataBundle(_lmmParameters, curves); } /** * Gets the start index. * @return The start index. */ public int getStartIndex() { return _startIndex; } /** * Sets the start index. * @param startIndex The start index. */ public void setStartIndex(final int startIndex) { _startIndex = startIndex; } /** * Gets the end index. * @return The end index. */ public int getEndIndex() { return _endIndex; } /** * Sets the end index. * @param endIndex The end index. */ public void setEndIndex(final int endIndex) { _endIndex = endIndex; } /** * Gets the initial volatility array. * @return The initial volatility array. */ public double[][] getVolatilityInit() { return _volatilityInit; } @Override /** * The inputs are the multiplicative factor on the volatilities and the additive term on the displacement. */ public DoubleMatrix1D evaluate(final DoubleMatrix1D x) { final int nbVol = _endIndex - _startIndex + 1; final double[][] volChanged = new double[nbVol][_lmmParameters.getNbFactor()]; for (int loopperiod = 0; loopperiod < nbVol; loopperiod++) { for (int loopfact = 0; loopfact < _lmmParameters.getNbFactor(); loopfact++) { volChanged[loopperiod][loopfact] = _volatilityInit[loopperiod + _startIndex][loopfact] * x.getEntry(0); } } _lmmParameters.setVolatility(volChanged, _startIndex); final double[] disChanged = new double[nbVol]; for (int loopperiod = 0; loopperiod < nbVol; loopperiod++) { disChanged[loopperiod] = _displacementInit[loopperiod + _startIndex] + x.getEntry(1); } _lmmParameters.setDisplacement(disChanged, _startIndex); final int nbInstruments = getInstruments().length; final Double[] result = new Double[nbInstruments]; // Implementation note: The pv error for each instrument for (int loopins = 0; loopins < nbInstruments; loopins++) { result[loopins] = METHOD_LMM_SWAPTION.presentValue((SwaptionPhysicalFixedIbor) getInstruments()[loopins], _lmmBundle).getAmount() - getPrices()[loopins]; } return new DoubleMatrix1D(result); } }