com.opengamma.analytics.financial.model.volatility.smile.fitting.sabr.StandardSmileSurfaceDataBundle.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.analytics.financial.model.volatility.smile.fitting.sabr.StandardSmileSurfaceDataBundle.java

Source

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

import java.util.Arrays;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.ObjectUtils;

import com.opengamma.analytics.financial.model.interestrate.curve.ForwardCurve;
import com.opengamma.analytics.math.curve.InterpolatedDoublesCurve;
import com.opengamma.analytics.math.interpolation.Interpolator1D;
import com.opengamma.util.ArgumentChecker;

/**
 * 
 */
public class StandardSmileSurfaceDataBundle extends SmileSurfaceDataBundle {
    private final double[] _forwards;
    private final double[] _expiries;
    private final double[][] _strikes;
    private final double[][] _impliedVols;
    private final ForwardCurve _forwardCurve;
    private final int _nExpiries;

    public StandardSmileSurfaceDataBundle(final double spot, final double[] forwards, final double[] expiries,
            final double[][] strikes, final double[][] impliedVols, final Interpolator1D forwardCurveInterpolator) {
        ArgumentChecker.notNull(forwards, "forwards");
        ArgumentChecker.notNull(expiries, "expiries");
        ArgumentChecker.notNull(strikes, "strikes");
        ArgumentChecker.notNull(impliedVols, "implied volatilities");
        ArgumentChecker.notNull(forwardCurveInterpolator, "forward curve interpolator");
        _nExpiries = expiries.length;
        ArgumentChecker.isTrue(_nExpiries == forwards.length, "forwards wrong length; have {}, need {}",
                forwards.length, _nExpiries);
        ArgumentChecker.isTrue(_nExpiries == strikes.length, "strikes wrong length; have {}, need {}",
                strikes.length, _nExpiries);
        ArgumentChecker.isTrue(_nExpiries == impliedVols.length,
                "implied volatilities wrong length; have {}, need {}", impliedVols.length, _nExpiries);
        for (int i = 0; i < strikes.length; i++) {
            ArgumentChecker.isTrue(strikes[i].length == impliedVols[i].length,
                    "implied volatilities for expiry {} not the same length as strikes; have {}, need {}",
                    strikes[i].length, impliedVols[i].length);
        }
        // checkVolatilities(expiries, strikes, impliedVols); // Put this check in place, if desired, after construction.
        _expiries = expiries;
        _forwards = forwards;

        final double[] t = ArrayUtils.add(expiries, 0, 0.0);
        final double[] f = ArrayUtils.add(forwards, 0, spot);
        _forwardCurve = new ForwardCurve(InterpolatedDoublesCurve.from(t, f, forwardCurveInterpolator));
        _strikes = strikes;
        _impliedVols = impliedVols;
    }

    public StandardSmileSurfaceDataBundle(final ForwardCurve forwardCurve, final double[] expiries,
            final double[][] strikes, final double[][] impliedVols) {
        ArgumentChecker.notNull(forwardCurve, "forward curve");
        ArgumentChecker.notNull(expiries, "expiries");
        ArgumentChecker.notNull(strikes, "strikes");
        ArgumentChecker.notNull(impliedVols, "implied volatilities");
        _nExpiries = expiries.length;
        ArgumentChecker.isTrue(_nExpiries == strikes.length, "strikes wrong length; have {}, need {}", _nExpiries,
                strikes.length);
        ArgumentChecker.isTrue(_nExpiries == impliedVols.length,
                "implied volatilities wrong length; have {}, need {}", _nExpiries, impliedVols.length);
        _forwards = new double[_nExpiries];
        for (int i = 0; i < _nExpiries; i++) {
            ArgumentChecker.isTrue(strikes[i].length == impliedVols[i].length,
                    "implied volatilities for expiry {} not the same length as strikes; have {}, need {}",
                    strikes[i].length, impliedVols[i].length);
            _forwards[i] = forwardCurve.getForward(expiries[i]);
        }
        // checkVolatilities(expiries, strikes, impliedVols); // Put this check in place, if desired, after construction.
        _expiries = expiries;
        _strikes = strikes;
        _impliedVols = impliedVols;
        _forwardCurve = forwardCurve;
    }

    @Override
    public int getNumExpiries() {
        return _nExpiries;
    }

    @Override
    public double[] getExpiries() {
        return _expiries;
    }

    @Override
    public double[][] getStrikes() {
        return _strikes;
    }

    @Override
    public double[][] getVolatilities() {
        return _impliedVols;
    }

    @Override
    public double[] getForwards() {
        return _forwards;
    }

    @Override
    public ForwardCurve getForwardCurve() {
        return _forwardCurve;
    }

    @Override
    public SmileSurfaceDataBundle withBumpedPoint(final int expiryIndex, final int strikeIndex,
            final double amount) {
        ArgumentChecker.isTrue(ArgumentChecker.isInRangeExcludingHigh(0, _nExpiries, expiryIndex),
                "Invalid index for expiry; {}", expiryIndex);
        final double[][] strikes = getStrikes();
        ArgumentChecker.isTrue(ArgumentChecker.isInRangeExcludingHigh(0, strikes[expiryIndex].length, strikeIndex),
                "Invalid index for strike; {}", strikeIndex);
        final double[][] vols = new double[_nExpiries][];
        for (int i = 0; i < _nExpiries; i++) {
            final int nStrikes = strikes[i].length;
            vols[i] = new double[nStrikes];
            System.arraycopy(_impliedVols[i], 0, vols[i], 0, nStrikes);
        }
        vols[expiryIndex][strikeIndex] += amount;
        return new StandardSmileSurfaceDataBundle(getForwardCurve(), getExpiries(), getStrikes(), vols);
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + _forwardCurve.hashCode();
        result = prime * result + Arrays.deepHashCode(_impliedVols);

        result = prime * result + Arrays.deepHashCode(_strikes);
        result = prime * result + Arrays.hashCode(_expiries);
        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 StandardSmileSurfaceDataBundle other = (StandardSmileSurfaceDataBundle) obj;
        if (!ObjectUtils.equals(_forwardCurve, other._forwardCurve)) {
            return false;
        }
        if (!Arrays.equals(_expiries, other._expiries)) {
            return false;
        }
        for (int i = 0; i < _nExpiries; i++) {
            if (!Arrays.equals(_strikes[i], other._strikes[i])) {
                return false;
            }
            if (!Arrays.equals(_impliedVols[i], other._impliedVols[i])) {
                return false;
            }
        }

        return true;
    }
}