Package com.opengamma.analytics.financial.interestrate.capletstripping

Source Code of com.opengamma.analytics.financial.interestrate.capletstripping.CapletStrippingSingleStrikeDirect

/**
* Copyright (C) 2013 - 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 java.util.List;

import com.opengamma.analytics.financial.interestrate.YieldCurveBundle;
import com.opengamma.analytics.financial.model.volatility.VolatilityTermStructure;
import com.opengamma.analytics.financial.model.volatility.curve.VolatilityCurve;
import com.opengamma.analytics.math.curve.InterpolatedDoublesCurve;
import com.opengamma.analytics.math.function.Function1D;
import com.opengamma.analytics.math.interpolation.CombinedInterpolatorExtrapolatorFactory;
import com.opengamma.analytics.math.interpolation.Interpolator1D;
import com.opengamma.analytics.math.interpolation.Interpolator1DFactory;
import com.opengamma.analytics.math.interpolation.PSplineFitter;
import com.opengamma.analytics.math.matrix.ColtMatrixAlgebra;
import com.opengamma.analytics.math.matrix.DoubleMatrix1D;
import com.opengamma.analytics.math.matrix.DoubleMatrix2D;
import com.opengamma.analytics.math.matrix.MatrixAlgebra;
import com.opengamma.analytics.math.statistics.leastsquare.LeastSquareResults;
import com.opengamma.analytics.math.statistics.leastsquare.NonLinearLeastSquareWithPenalty;

/**
* @deprecated {@link YieldCurveBundle} is deprecated
*/
@Deprecated
public class CapletStrippingSingleStrikeDirect extends CapletStrippingAbsoluteStrike {

  private static final MatrixAlgebra MA = new ColtMatrixAlgebra();
  private static final Interpolator1D DEFAULT_INTERPOLATOR = CombinedInterpolatorExtrapolatorFactory.getInterpolator(Interpolator1DFactory.DOUBLE_QUADRATIC, Interpolator1DFactory.FLAT_EXTRAPOLATOR);
  private static final NonLinearLeastSquareWithPenalty NLLSWP = new NonLinearLeastSquareWithPenalty();
  private static final int DIFFERENCE_ORDER = 2;
  private static final double LAMBDA = 1000;

  private final Interpolator1D _interpolator;
  private final DoubleMatrix2D _penalty;

  public CapletStrippingSingleStrikeDirect(final List<CapFloor> caps, final YieldCurveBundle yieldCurves) {
    super(caps, yieldCurves);

    final PSplineFitter psf = new PSplineFitter();
    _penalty = (DoubleMatrix2D) MA.scale(psf.getPenaltyMatrix(getnCaplets(), DIFFERENCE_ORDER), LAMBDA);
    _interpolator = DEFAULT_INTERPOLATOR;
    // _altCapletStripper = new CapletStrippingAbsoluteStrikeInterpolation(caps, yieldCurves);
  }

  @Override
  public CapletStrippingSingleStrikeResult solveForPrices(final double[] capPrices) {
    checkPrices(capPrices);

    final MultiCapFloorPricer pricer = getPricer();
    final double[] capVols = pricer.impliedVols(capPrices);
    final double[] vega = pricer.vega(capVols);
    final double[] start = new double[getnCaplets()];
    Arrays.fill(start, capVols[capVols.length - 1]);

    final LeastSquareResults lsRes = solveForPrice(new DoubleMatrix1D(capPrices), new DoubleMatrix1D(vega), new DoubleMatrix1D(start));

    final double[] mPrices = pricer.priceFromCapletVols(lsRes.getFitParameters().getData());
    final double chiSqr = chiSqr(capPrices, mPrices);
    final VolatilityTermStructure vc = getVolCurve(lsRes.getFitParameters().getData());
    return new CapletStrippingSingleStrikeResult(chiSqr, lsRes.getFitParameters(), vc, new DoubleMatrix1D(mPrices));
  }

  private VolatilityTermStructure getVolCurve(final double[] capletVols) {
    return new VolatilityCurve(InterpolatedDoublesCurve.from(getPricer().getCapletExpiries(), capletVols, _interpolator));
  }

  @Override
  public CapletStrippingSingleStrikeResult solveForPrices(final double[] capPrices, final double[] errors, final boolean scaleByVega) {
    checkPrices(capPrices);
    checkErrors(errors);

    final MultiCapFloorPricer pricer = getPricer();
    final double[] capVols = pricer.impliedVols(capPrices);

    DoubleMatrix1D sigma = null;
    if (scaleByVega) {
      final double[] capVega = pricer.vega(capVols);
      final int n = getnCaps();
      for (int i = 0; i < n; i++) {
        capVega[i] *= errors[i];
      }
      sigma = new DoubleMatrix1D(capVega);
    } else {
      sigma = new DoubleMatrix1D(errors);
    }

    final double[] start = new double[getnCaplets()];
    Arrays.fill(start, capVols[capVols.length - 1]);
    final LeastSquareResults lsRes = solveForPrice(new DoubleMatrix1D(capPrices), sigma, new DoubleMatrix1D(start));

    final double[] mPrices = pricer.priceFromCapletVols(lsRes.getFitParameters().getData());
    final double chiSqr = chiSqr(capPrices, mPrices, errors);
    final VolatilityTermStructure vc = getVolCurve(lsRes.getFitParameters().getData());
    return new CapletStrippingSingleStrikeResult(chiSqr, lsRes.getFitParameters(), vc, new DoubleMatrix1D(mPrices));
  }

  @Override
  public CapletStrippingSingleStrikeResult solveForVol(final double[] capVols) {
    final double err = 0.001; // 10bps
    final double[] errors = new double[getnCaps()];
    Arrays.fill(errors, err);
    return solveForVol(capVols, errors, true);
  }

  @Override
  public CapletStrippingSingleStrikeResult solveForVol(final double[] capVols, final double[] errors, final boolean solveByPrice) {
    checkVols(capVols);
    checkErrors(errors);

    final MultiCapFloorPricer pricer = getPricer();

    final double[] start = new double[getnCaplets()];
    Arrays.fill(start, capVols[capVols.length - 1]);

    // we are using CapletStrippingAbsoluteStrikeInterpolation to give use a starting position
    // CapletStrippingSingleStrikeResult altRes = _altCapletStripper.solveForVol(capVols);
    // VolatilityTermStructure altVC = altRes.getVolatilityCurve();
    // double[] t = pricer.getCapletExpiries();
    // final int nCaplets = getnCaplets();
    // for (int i = 0; i < nCaplets; i++) {
    // start[i] = altVC.getVolatility(t[i]);
    // }

    final int n = getnCaps();
    LeastSquareResults lsRes;
    if (solveByPrice) {
      final double[] capPrices = pricer.price(capVols);
      final double[] capVega = pricer.vega(capVols);
      for (int i = 0; i < n; i++) {
        capVega[i] *= errors[i];
      }
      final DoubleMatrix1D sigma = new DoubleMatrix1D(capVega);
      lsRes = solveForPrice(new DoubleMatrix1D(capPrices), sigma, new DoubleMatrix1D(start));
    } else {
      lsRes = solveForVol(new DoubleMatrix1D(capVols), new DoubleMatrix1D(errors), new DoubleMatrix1D(start));
    }

    final double[] mVols = pricer.impliedVols(pricer.priceFromCapletVols(lsRes.getFitParameters().getData()));
    final double chiSqr = chiSqr(capVols, mVols, errors);
    final VolatilityTermStructure vc = getVolCurve(lsRes.getFitParameters().getData());
    return new CapletStrippingSingleStrikeResult(chiSqr, lsRes.getFitParameters(), vc, new DoubleMatrix1D(mVols));
  }

  private LeastSquareResults solveForPrice(final DoubleMatrix1D capPrices, final DoubleMatrix1D sigma, final DoubleMatrix1D start) {

    final Function1D<DoubleMatrix1D, Boolean> allowed = new Function1D<DoubleMatrix1D, Boolean>() {
      @Override
      public Boolean evaluate(final DoubleMatrix1D x) {
        final double[] temp = x.getData();
        final int n = temp.length;
        for (int i = 0; i < n; i++) {
          if (temp[i] < 0) {
            return false;
          }
        }
        return true;
      }
    };

    final Function1D<DoubleMatrix1D, DoubleMatrix1D> modelPriceFunc = new Function1D<DoubleMatrix1D, DoubleMatrix1D>() {
      @Override
      public DoubleMatrix1D evaluate(final DoubleMatrix1D x) {
        final double[] modelPrices = getPricer().priceFromCapletVols(x.getData());
        return new DoubleMatrix1D(modelPrices);
      }
    };

    final Function1D<DoubleMatrix1D, DoubleMatrix2D> modelPriceJac = new Function1D<DoubleMatrix1D, DoubleMatrix2D>() {
      @Override
      public DoubleMatrix2D evaluate(final DoubleMatrix1D x) {
        return getPricer().vegaFromCapletVols(x.getData());
      }
    };

    return NLLSWP.solve(capPrices, sigma, modelPriceFunc, modelPriceJac, start, _penalty, allowed);
  }

  private LeastSquareResults solveForVol(final DoubleMatrix1D capVols, final DoubleMatrix1D sigma, final DoubleMatrix1D start) {
    final int n = getnCaps();
    final int m = getnCaplets();
    final MultiCapFloorPricer pricer = getPricer();

    final Function1D<DoubleMatrix1D, DoubleMatrix1D> modelVolFunc = new Function1D<DoubleMatrix1D, DoubleMatrix1D>() {
      @Override
      public DoubleMatrix1D evaluate(final DoubleMatrix1D x) {
        final double[] modelPrices = pricer.priceFromCapletVols(x.getData());
        final double[] modelVols = pricer.impliedVols(modelPrices);
        return new DoubleMatrix1D(modelVols);
      }
    };

    final Function1D<DoubleMatrix1D, DoubleMatrix2D> modelVolJac = new Function1D<DoubleMatrix1D, DoubleMatrix2D>() {
      @Override
      public DoubleMatrix2D evaluate(final DoubleMatrix1D x) {
        final double[] modelPrices = pricer.priceFromCapletVols(x.getData());
        final double[] modelVols = pricer.impliedVols(modelPrices);
        final double[] vega = pricer.vega(modelVols);

        final DoubleMatrix2D vegaMatrix = pricer.vegaFromCapletVols(x.getData());
        // scale by inverse of cap vega
        for (int i = 0; i < n; i++) {
          for (int j = 0; j < m; j++) {
            if (vegaMatrix.getData()[i][j] != 0.0) {
              vegaMatrix.getData()[i][j] /= vega[i]; //CSIGNORE
            }
          }
        }
        return vegaMatrix;
      }
    };

    return NLLSWP.solve(capVols, sigma, modelVolFunc, modelVolJac, start, _penalty);
  }

}
TOP

Related Classes of com.opengamma.analytics.financial.interestrate.capletstripping.CapletStrippingSingleStrikeDirect

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.