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

Java tutorial

Introduction

Here is the source code for com.opengamma.analytics.financial.model.volatility.smile.fitting.sabr.ForexSmileDeltaSurfaceDataBundle.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.ObjectUtils;

import com.opengamma.analytics.financial.model.interestrate.curve.ForwardCurve;
import com.opengamma.analytics.financial.model.option.definition.SmileDeltaParameters;
import com.opengamma.analytics.math.curve.InterpolatedDoublesCurve;
import com.opengamma.analytics.math.interpolation.CombinedInterpolatorExtrapolator;
import com.opengamma.util.ArgumentChecker;

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

    private final boolean _isCallData;

    public ForexSmileDeltaSurfaceDataBundle(final double[] forwards, final double[] expiries, final double[] deltas,
            final double[] atms, final double[][] riskReversals, final double[][] strangle,
            final boolean isCallData, final CombinedInterpolatorExtrapolator interpolator) {
        ArgumentChecker.notNull(deltas, "delta");
        ArgumentChecker.notNull(forwards, "forwards");
        ArgumentChecker.notNull(expiries, "expiries");
        ArgumentChecker.notNull(atms, "at-the-money");
        ArgumentChecker.notNull(riskReversals, "risk reversal");
        ArgumentChecker.notNull(strangle, "strangle");
        _nExpiries = expiries.length;
        ArgumentChecker.isTrue(_nExpiries == forwards.length, "forwards wrong length; have {}, need {}",
                forwards.length, _nExpiries);
        ArgumentChecker.isTrue(_nExpiries == atms.length, "atms wrong length; have {}, need {}", atms.length,
                _nExpiries);
        final int n = deltas.length;
        ArgumentChecker.isTrue(n > 0, "need at least one delta");
        ArgumentChecker.isTrue(n == riskReversals.length, "wrong number of rr sets; have {}, need {}",
                riskReversals.length, n);
        ArgumentChecker.isTrue(n == strangle.length, "wrong number of strangle sets; have {}, need {}",
                strangle.length, n);
        for (int i = 0; i < n; i++) {
            ArgumentChecker.isTrue(_nExpiries == riskReversals[i].length, "wrong number of rr; have {}, need {}",
                    riskReversals[i].length, _nExpiries);
            ArgumentChecker.isTrue(_nExpiries == strangle[i].length, "wrong number of strangles; have {}, need {}",
                    strangle[i].length, _nExpiries);
        }
        _forwards = forwards;
        _expiries = expiries;
        _forwardCurve = new ForwardCurve(InterpolatedDoublesCurve.from(_expiries, _forwards, interpolator));
        _strikes = new double[_nExpiries][];
        _vols = new double[_nExpiries][];
        for (int i = 0; i < _nExpiries; i++) {
            final double[] rr = new double[n];
            final double[] s = new double[n];
            for (int j = 0; j < n; j++) {
                rr[j] = riskReversals[j][i];
                s[j] = strangle[j][i];
            }
            final SmileDeltaParameters cal = new SmileDeltaParameters(_expiries[i], atms[i], deltas, rr, s);
            _strikes[i] = cal.getStrike(_forwards[i]);
            _vols[i] = cal.getVolatility();
        }
        _isCallData = isCallData;
        checkVolatilities(expiries, _vols);
    }

    public ForexSmileDeltaSurfaceDataBundle(final ForwardCurve forwardCurve, final double[] expiries,
            final double[] deltas, final double[] atms, final double[][] riskReversals, final double[][] strangle,
            final boolean isCallData) {
        ArgumentChecker.notNull(deltas, "delta");
        ArgumentChecker.notNull(forwardCurve, "forward curve");
        ArgumentChecker.notNull(expiries, "expiries");
        ArgumentChecker.notNull(atms, "atms");
        ArgumentChecker.notNull(riskReversals, "risk reversals");
        ArgumentChecker.notNull(strangle, "strangle");
        _nExpiries = expiries.length;
        ArgumentChecker.isTrue(_nExpiries == atms.length, "atms wrong length; have {}, need {}", atms.length,
                _nExpiries);
        final int n = deltas.length;
        ArgumentChecker.isTrue(n > 0, "need at least one delta");
        ArgumentChecker.isTrue(n == riskReversals.length, "wrong number of rr sets; have {}, need {}",
                riskReversals.length, n);
        ArgumentChecker.isTrue(n == strangle.length, "wrong number of strangle sets; have {}, need {}",
                strangle.length, n);
        for (int i = 0; i < n; i++) {
            ArgumentChecker.isTrue(_nExpiries == riskReversals[i].length, "wrong number of rr; have {}, need {}",
                    riskReversals[i].length, _nExpiries);
            ArgumentChecker.isTrue(_nExpiries == strangle[i].length, "wrong number of strangles; have {}, need {}",
                    strangle[i].length, _nExpiries);
        }
        _forwards = new double[_nExpiries];
        _expiries = expiries;
        _forwardCurve = forwardCurve;
        _strikes = new double[_nExpiries][];
        _vols = new double[_nExpiries][];
        for (int i = 0; i < _nExpiries; i++) {
            _forwards[i] = forwardCurve.getForward(_expiries[i]);
            final double[] rr = new double[n];
            final double[] s = new double[n];
            for (int j = 0; j < n; j++) {
                rr[j] = riskReversals[j][i];
                s[j] = strangle[j][i];
            }
            final SmileDeltaParameters cal = new SmileDeltaParameters(_expiries[i], atms[i], deltas, rr, s);
            _strikes[i] = cal.getStrike(_forwards[i]);
            _vols[i] = cal.getVolatility();
        }
        _isCallData = isCallData;
        checkVolatilities(expiries, _vols);
    }

    public ForexSmileDeltaSurfaceDataBundle(final ForwardCurve forwardCurve, final double[] expiries,
            final double[][] strikes, final double[][] vols, final boolean isCallData) {
        ArgumentChecker.notNull(forwardCurve, "forward curve");
        ArgumentChecker.notNull(expiries, "expiries");
        ArgumentChecker.notNull(strikes, "strikes");
        ArgumentChecker.notNull(vols, "vols");
        _nExpiries = expiries.length;
        ArgumentChecker.isTrue(_nExpiries == strikes.length, "strikes wrong length; have {}, need {}",
                strikes.length, _nExpiries);
        ArgumentChecker.isTrue(_nExpiries == vols.length, "implied vols wrong length; have {}, need {}",
                vols.length, _nExpiries);
        for (int i = 0; i < _nExpiries; i++) {
            ArgumentChecker.isTrue(strikes[i].length == vols[i].length,
                    "wrong number of volatilities; have {}, need {}", strikes[i].length, vols[i].length);
        }
        _forwardCurve = forwardCurve;
        _expiries = expiries;
        _strikes = strikes;
        _vols = vols;
        _forwards = new double[_nExpiries];
        for (int i = 0; i < _nExpiries; i++) {
            _forwards[i] = forwardCurve.getForward(expiries[i]);
        }
        _isCallData = isCallData;
    }

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

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

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

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

    @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 int nStrikes = strikes[expiryIndex].length;
        final double[][] vols = new double[_nExpiries][];
        for (int i = 0; i < _nExpiries; i++) {
            vols[i] = new double[nStrikes];
            System.arraycopy(_vols[i], 0, vols[i], 0, nStrikes);
        }
        vols[expiryIndex][strikeIndex] += amount;
        return new ForexSmileDeltaSurfaceDataBundle(getForwardCurve(), getExpiries(), getStrikes(), vols,
                _isCallData);
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + _forwardCurve.hashCode();
        result = prime * result + Arrays.deepHashCode(_vols);
        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 ForexSmileDeltaSurfaceDataBundle other = (ForexSmileDeltaSurfaceDataBundle) 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(_vols[i], other._vols[i])) {
                return false;
            }
        }

        return true;
    }
}