com.opengamma.analytics.financial.interestrate.MultipleYieldCurveFinderDataBundle.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.analytics.financial.interestrate.MultipleYieldCurveFinderDataBundle.java

Source

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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;

import org.apache.commons.lang.ObjectUtils;

import com.opengamma.analytics.financial.forex.method.FXMatrix;
import com.opengamma.analytics.math.interpolation.Interpolator1D;
import com.opengamma.util.ArgumentChecker;

/**
 * @deprecated {@link YieldCurveBundle} is deprecated
 */
@Deprecated
public class MultipleYieldCurveFinderDataBundle {

    private final List<InstrumentDerivative> _derivatives;
    private final double[] _marketValues;
    private final YieldCurveBundle _knownCurves;
    private final LinkedHashMap<String, double[]> _unknownCurveNodePoints;
    private final LinkedHashMap<String, Interpolator1D> _unknownCurveInterpolators;
    private final int _totalNodes;
    private final List<String> _names;
    private final boolean _useFiniteDifferenceByDefault;
    private final FXMatrix _fxMatrix;

    /**
     * Private constructor from all the stored data. No check is performed; they are done in the public methods.
     * @param derivatives The list of instruments used in the calibration.
     * @param marketValues The market value of the instruments.
     * @param knownCurves The curves already calibrated.
     * @param unknownCurveNodePoints The node points of the new curves to calibrate.
     * @param unknownCurveInterpolators The interpolators of the new curves to calibrate.
     * @param useFiniteDifferenceByDefault Flag for using the finite difference computation of the Jacobian.
     * @param fxMatrix The FX Matrix with the required exchange rates.
     * @param totalNodes The total number of nodes.
     * @param names The names of the curves used for matrix evaluation.
     */
    private MultipleYieldCurveFinderDataBundle(final List<InstrumentDerivative> derivatives,
            final double[] marketValues, final YieldCurveBundle knownCurves,
            final LinkedHashMap<String, double[]> unknownCurveNodePoints,
            final LinkedHashMap<String, Interpolator1D> unknownCurveInterpolators,
            final boolean useFiniteDifferenceByDefault, final FXMatrix fxMatrix, final int totalNodes,
            final List<String> names) {
        _derivatives = derivatives;
        _marketValues = marketValues;
        _knownCurves = knownCurves;
        _unknownCurveNodePoints = unknownCurveNodePoints;
        _unknownCurveInterpolators = unknownCurveInterpolators;
        _useFiniteDifferenceByDefault = useFiniteDifferenceByDefault;
        _fxMatrix = fxMatrix;
        _totalNodes = totalNodes;
        _names = names;
    }

    public MultipleYieldCurveFinderDataBundle(final List<InstrumentDerivative> derivatives,
            final double[] marketValues, final YieldCurveBundle knownCurves,
            final LinkedHashMap<String, double[]> unknownCurveNodePoints,
            final LinkedHashMap<String, Interpolator1D> unknownCurveInterpolators,
            final boolean useFiniteDifferenceByDefault, final FXMatrix fxMatrix) {
        ArgumentChecker.notNull(derivatives, "derivatives");
        ArgumentChecker.noNulls(derivatives, "derivatives");
        ArgumentChecker.notNull(marketValues, "market values null");
        ArgumentChecker.notNull(unknownCurveNodePoints, "unknown curve node points");
        ArgumentChecker.notNull(unknownCurveInterpolators, "unknown curve interpolators");
        ArgumentChecker.notEmpty(unknownCurveNodePoints, "unknown curve node points");
        ArgumentChecker.notEmpty(unknownCurveInterpolators, "unknown curve interpolators");
        ArgumentChecker.isTrue(derivatives.size() == marketValues.length,
                "marketValues wrong length; must be one par rate per derivative (have {} values for {} derivatives",
                marketValues.length, derivatives.size());
        ArgumentChecker.notNull(fxMatrix, "FX matrix");
        if (knownCurves != null) {
            for (final String name : knownCurves.getAllNames()) {
                if (unknownCurveInterpolators.containsKey(name)) {
                    throw new IllegalArgumentException("Curve name in known set matches one to be solved for");
                }
            }
            _knownCurves = knownCurves;
        } else {
            _knownCurves = null;
        }
        _derivatives = derivatives;
        _marketValues = marketValues;
        if (unknownCurveNodePoints.size() != unknownCurveInterpolators.size()) {
            throw new IllegalArgumentException("Number of unknown curves not the same as curve interpolators");
        }
        final Iterator<Entry<String, double[]>> nodePointsIterator = unknownCurveNodePoints.entrySet().iterator();
        final Iterator<Entry<String, Interpolator1D>> unknownCurvesIterator = unknownCurveInterpolators.entrySet()
                .iterator();
        _names = new ArrayList<>();
        while (nodePointsIterator.hasNext()) {
            final Entry<String, double[]> entry1 = nodePointsIterator.next();
            final Entry<String, Interpolator1D> entry2 = unknownCurvesIterator.next();
            final String name1 = entry1.getKey();
            if (!name1.equals(entry2.getKey())) {
                throw new IllegalArgumentException("Names must be the same");
            }
            ArgumentChecker.notNull(entry1.getValue(), "curve node points for " + name1);
            ArgumentChecker.notNull(entry2.getValue(), "interpolator for " + name1);
            _names.add(name1);
        }
        int nNodes = 0;
        for (final double[] nodes : unknownCurveNodePoints.values()) {
            nNodes += nodes.length;
        }
        if (nNodes > derivatives.size()) {
            throw new IllegalArgumentException("Total number of nodes (" + nNodes
                    + ") is greater than the number of instruments (" + derivatives.size() + ")");
        }
        _totalNodes = nNodes;
        _unknownCurveNodePoints = unknownCurveNodePoints;
        _unknownCurveInterpolators = unknownCurveInterpolators;
        _useFiniteDifferenceByDefault = useFiniteDifferenceByDefault;
        _fxMatrix = fxMatrix;
    }

    /**
     * Create a MultipleYieldCurveFinderDataBundle where the number of nodes and the list of curve names correspond to all the curves (known curves and curves still to be calibrated).
     * This constructor is used to compute the extended Jacobian matrix when curves are calibrated in several blocks.
     * @param derivatives The list of instruments used in the calibration.
     * @param marketValues The market value of the instruments.
     * @param knownCurves The curves already calibrated.
     * @param unknownCurveNodePoints The node points of the new curves to calibrate.
     * @param unknownCurveInterpolators The interpolators of the new curves to calibrate.
     * @param useFiniteDifferenceByDefault Flag for using the finite difference computation of the Jacobian.
     * @param fxMatrix The FX Matrix with the required exchange rates.
     * @return The data bundle.
     */
    public static MultipleYieldCurveFinderDataBundle withAllCurves(final List<InstrumentDerivative> derivatives,
            final double[] marketValues, final YieldCurveBundle knownCurves,
            final LinkedHashMap<String, double[]> unknownCurveNodePoints,
            final LinkedHashMap<String, Interpolator1D> unknownCurveInterpolators,
            final boolean useFiniteDifferenceByDefault, final FXMatrix fxMatrix) {
        // Argument checker: start
        ArgumentChecker.notNull(derivatives, "derivatives");
        ArgumentChecker.noNulls(derivatives, "derivatives");
        ArgumentChecker.notNull(marketValues, "market values null");
        ArgumentChecker.notNull(unknownCurveNodePoints, "unknown curve node points");
        ArgumentChecker.notNull(unknownCurveInterpolators, "unknown curve interpolators");
        ArgumentChecker.notEmpty(unknownCurveNodePoints, "unknown curve node points");
        ArgumentChecker.notEmpty(unknownCurveInterpolators, "unknown curve interpolators");
        ArgumentChecker.isTrue(derivatives.size() == marketValues.length,
                "marketValues wrong length; must be one par rate per derivative (have {} values for {} derivatives",
                marketValues.length, derivatives.size());
        ArgumentChecker.notNull(fxMatrix, "FX matrix");
        if (knownCurves != null) {
            for (final String name : knownCurves.getAllNames()) {
                if (unknownCurveInterpolators.containsKey(name)) {
                    throw new IllegalArgumentException("Curve name in known set matches one to be solved for");
                }
            }
        }
        if (unknownCurveNodePoints.size() != unknownCurveInterpolators.size()) {
            throw new IllegalArgumentException("Number of unknown curves not the same as curve interpolators");
        }
        // Argument checker: end
        int nbNodes = 0;
        if (knownCurves != null) {
            for (final String name : knownCurves.getAllNames()) {
                nbNodes += knownCurves.getCurve(name).getNumberOfParameters();
            }
        }
        for (final double[] nodes : unknownCurveNodePoints.values()) { // Nodes from new curves
            nbNodes += nodes.length;
        }
        final List<String> names = new ArrayList<>();
        if (knownCurves != null) {
            names.addAll(knownCurves.getAllNames()); // Names from existing curves
        }
        final Iterator<Entry<String, double[]>> nodePointsIterator = unknownCurveNodePoints.entrySet().iterator();
        final Iterator<Entry<String, Interpolator1D>> unknownCurvesIterator = unknownCurveInterpolators.entrySet()
                .iterator();
        while (nodePointsIterator.hasNext()) { // Names from new curves
            final Entry<String, double[]> entry1 = nodePointsIterator.next();
            final Entry<String, Interpolator1D> entry2 = unknownCurvesIterator.next();
            final String name1 = entry1.getKey();
            if (!name1.equals(entry2.getKey())) {
                throw new IllegalArgumentException("Names must be the same");
            }
            ArgumentChecker.notNull(entry1.getValue(), "curve node points for " + name1);
            ArgumentChecker.notNull(entry2.getValue(), "interpolator for " + name1);
            names.add(name1);
        }
        return new MultipleYieldCurveFinderDataBundle(derivatives, marketValues, knownCurves,
                unknownCurveNodePoints, unknownCurveInterpolators, useFiniteDifferenceByDefault, fxMatrix, nbNodes,
                names);
    }

    public List<InstrumentDerivative> getDerivatives() {
        return _derivatives;
    }

    public YieldCurveBundle getKnownCurves() {
        return _knownCurves;
    }

    public LinkedHashMap<String, double[]> getUnknownCurveNodePoints() {
        return _unknownCurveNodePoints;
    }

    public LinkedHashMap<String, Interpolator1D> getUnknownCurveInterpolators() {
        return _unknownCurveInterpolators;
    }

    public int getNumInstruments() {
        return _derivatives.size();
    }

    public int getTotalNodes() {
        return _totalNodes;
    }

    public InstrumentDerivative getDerivative(final int i) {
        return _derivatives.get(i);
    }

    public double getMarketValue(final int i) {
        return _marketValues[i];
    }

    public boolean useFiniteDifferenceForNodeSensitivities() {
        return _useFiniteDifferenceByDefault;
    }

    public FXMatrix getFXMatrix() {
        return _fxMatrix;
    }

    public double[] getCurveNodePointsForCurve(final String name) {
        ArgumentChecker.notNull(name, "name");
        final double[] result = _unknownCurveNodePoints.get(name);
        if (result == null) {
            throw new IllegalArgumentException("Data for name " + name + " not found");
        }
        return result;
    }

    public int getNumberOfPointsForCurve(final String name) {
        ArgumentChecker.notNull(name, "name");
        if (_unknownCurveNodePoints.containsKey(name)) {
            return _unknownCurveNodePoints.get(name).length;
        }
        if (_knownCurves != null) {
            if (_knownCurves.containsName(name)) {
                return _knownCurves.getCurve(name).getNumberOfParameters();
            }
        }
        throw new IllegalArgumentException("Data for name " + name + " not found");
    }

    public Interpolator1D getInterpolatorForCurve(final String name) {
        ArgumentChecker.notNull(name, "name");
        final Interpolator1D result = _unknownCurveInterpolators.get(name);
        if (result == null) {
            throw new IllegalArgumentException("Data for name " + name + " not found");
        }
        return result;
    }

    public List<String> getCurveNames() {
        return _names;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + _derivatives.hashCode();
        result = prime * result + ((_knownCurves == null) ? 0 : _knownCurves.hashCode());
        result = prime * result + Arrays.hashCode(_marketValues);
        result = prime * result + _unknownCurveInterpolators.hashCode();
        result = prime * result + _unknownCurveNodePoints.hashCode();
        result = prime * result + (_useFiniteDifferenceByDefault ? 1231 : 1237);
        result = prime * result + _fxMatrix.hashCode();
        return result;
    }

    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final MultipleYieldCurveFinderDataBundle other = (MultipleYieldCurveFinderDataBundle) obj;

        if (!Arrays.equals(_marketValues, other._marketValues)) {
            return false;
        }
        if (!ObjectUtils.equals(_derivatives, other._derivatives)) {
            return false;
        }
        if (!ObjectUtils.equals(_knownCurves, other._knownCurves)) {
            return false;
        }
        if (!ObjectUtils.equals(_unknownCurveInterpolators, other._unknownCurveInterpolators)) {
            return false;
        }
        if (!ObjectUtils.equals(_unknownCurveNodePoints, other._unknownCurveNodePoints)) {
            return false;
        }
        if (_useFiniteDifferenceByDefault != other._useFiniteDifferenceByDefault) {
            return false;
        }
        if (!ObjectUtils.equals(_fxMatrix, other._fxMatrix)) {
            return false;
        }
        return true;
    }
}