Package com.opengamma.analytics.financial.provider.method

Source Code of com.opengamma.analytics.financial.provider.method.SuccessiveLeastSquareLMMDDCalibrationEngine

/**
* Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.provider.method;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.opengamma.analytics.financial.interestrate.InstrumentDerivative;
import com.opengamma.analytics.financial.interestrate.InstrumentDerivativeVisitor;
import com.opengamma.analytics.financial.interestrate.swaption.derivative.SwaptionPhysicalFixedIbor;
import com.opengamma.analytics.financial.provider.description.interestrate.ParameterProviderInterface;
import com.opengamma.analytics.math.linearalgebra.DecompositionFactory;
import com.opengamma.analytics.math.matrix.DoubleMatrix1D;
import com.opengamma.analytics.math.matrix.MatrixAlgebraFactory;
import com.opengamma.analytics.math.statistics.leastsquare.LeastSquareResults;
import com.opengamma.analytics.math.statistics.leastsquare.NonLinearLeastSquare;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.money.MultipleCurrencyAmount;

/**
* Specific calibration engine for the LMM model with swaption.
* @param <DATA_TYPE>  The type of the data for the base calculator.
*/
public class SuccessiveLeastSquareLMMDDCalibrationEngine<DATA_TYPE extends ParameterProviderInterface> extends CalibrationEngineWithCalculators<DATA_TYPE> {

  /**
   * The precision used in least-square search.
   */
  private static final double DEFAULT_PRECISION = 1.0E-15;
  /**
   * The list of the last index in the Ibor date for each instrument.
   */
  private final List<Integer> _instrumentIndex = new ArrayList<>();
  /**
   * The number of instruments in a calibration block. The total number of instruments should be a multiple of that number.
   */
  private final int _nbInstrumentsBlock;

  /**
   * The calibration objective.
   */
  private final SuccessiveLeastSquareCalibrationObjectiveWithMultiCurves _calibrationObjective;

  /**
   * Constructor of the calibration engine.
   * @param calibrationObjective The calibration objective.
   * @param nbInstrumentsBlock The number of instruments in a calibration block.
   */
  public SuccessiveLeastSquareLMMDDCalibrationEngine(final SuccessiveLeastSquareLMMDDCalibrationObjective calibrationObjective, final int nbInstrumentsBlock) {
    super(calibrationObjective.getFXMatrix(), calibrationObjective.getCcy());
    _instrumentIndex.add(0);
    _nbInstrumentsBlock = nbInstrumentsBlock;
    _calibrationObjective = calibrationObjective;
  }

  /**
   * Gets the instrument index.
   * @return The instrument index.
   */
  public List<Integer> getInstrumentIndex() {
    return _instrumentIndex;
  }

  /**
   * Returns the number of instruments in a calibration block.
   * @return The number.
   */
  public int getNbInstrumentsBlock() {
    return _nbInstrumentsBlock;
  }

  @Override
  public void addInstrument(final InstrumentDerivative instrument, final InstrumentDerivativeVisitor<DATA_TYPE, MultipleCurrencyAmount> calculator) {
    ArgumentChecker.isTrue(instrument instanceof SwaptionPhysicalFixedIbor, "Calibration instruments should be swaptions");
    final SwaptionPhysicalFixedIbor swaption = (SwaptionPhysicalFixedIbor) instrument;
    getBasket().add(instrument);
    getMethod().add(calculator);
    getCalibrationPrices().add(0.0);
    _instrumentIndex.add(Arrays.binarySearch(((SuccessiveLeastSquareLMMDDCalibrationObjective) _calibrationObjective).getLMMParameters().getIborTime(), swaption.getUnderlyingSwap().getSecondLeg()
        .getNthPayment(swaption.getUnderlyingSwap().getSecondLeg().getNumberOfPayments() - 1).getPaymentTime()));
  }

  @Override
  public void calibrate(final DATA_TYPE data) {
    final int nbInstruments = getBasket().size();
    ArgumentChecker.isTrue(nbInstruments % _nbInstrumentsBlock == 0, "Number of instruments incompatible with block size");
    final int nbBlocks = nbInstruments / _nbInstrumentsBlock;
    computeCalibrationPrice(data);
    _calibrationObjective.setMulticurves(data.getMulticurveProvider());
    final SuccessiveLeastSquareLMMDDCalibrationObjective objective = (SuccessiveLeastSquareLMMDDCalibrationObjective) _calibrationObjective;
    final NonLinearLeastSquare ls = new NonLinearLeastSquare(DecompositionFactory.SV_COMMONS, MatrixAlgebraFactory.OG_ALGEBRA, DEFAULT_PRECISION);
    //    final NonLinearLeastSquare ls = new NonLinearLeastSquare();
    for (int loopblock = 0; loopblock < nbBlocks; loopblock++) {
      final InstrumentDerivative[] instruments = new InstrumentDerivative[_nbInstrumentsBlock];
      final double[] prices = new double[_nbInstrumentsBlock];
      for (int loopins = 0; loopins < _nbInstrumentsBlock; loopins++) {
        instruments[loopins] = getBasket().get(loopblock * _nbInstrumentsBlock + loopins);
        prices[loopins] = getCalibrationPrices().get(loopblock * _nbInstrumentsBlock + loopins);
      }
      _calibrationObjective.setInstruments(instruments);
      _calibrationObjective.setPrice(prices);
      objective.setStartIndex(_instrumentIndex.get(loopblock * _nbInstrumentsBlock));
      objective.setEndIndex(_instrumentIndex.get((loopblock + 1) * _nbInstrumentsBlock) - 1);
      // Implementation note: the index start is from the first instrument of the block and the index end is from the last instrument of the block.
      final DoubleMatrix1D observedValues = new DoubleMatrix1D(_nbInstrumentsBlock, 0.0);
      @SuppressWarnings("unused")
      final
      LeastSquareResults result = ls.solve(observedValues, _calibrationObjective, new DoubleMatrix1D(1.0, 0.0));
      // Implementation note: the start value is a multiplicative factor of one and an additive term of 0 (parameters unchanged).
      //   The observed values are 0 as the function returns the difference between the calculated prices and the targets.
    }
  }

}
TOP

Related Classes of com.opengamma.analytics.financial.provider.method.SuccessiveLeastSquareLMMDDCalibrationEngine

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.