/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.model.volatility.cube;
import org.apache.commons.lang.ObjectUtils;
import com.opengamma.analytics.financial.model.volatility.VolatilityModel;
import com.opengamma.analytics.financial.model.volatility.surface.VolatilitySurface;
import com.opengamma.analytics.math.Axis;
import com.opengamma.analytics.math.Plane;
import com.opengamma.analytics.math.cube.Cube;
import com.opengamma.analytics.math.cube.CubeShiftFunctionFactory;
import com.opengamma.analytics.math.cube.CubeSliceFunction;
import com.opengamma.analytics.math.interpolation.Interpolator2D;
import com.opengamma.analytics.math.surface.Surface;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.tuple.Triple;
/**
*
*/
public class VolatilityCube implements VolatilityModel<Triple<Double, Double, Double>> {
private final Cube<Double, Double, Double, Double> _cube;
/** x-axis */
public static final Axis EXPIRY_AXIS = Axis.X; // TODO Review
/** y-axis */
public static final Axis STRIKE_AXIS = Axis.Y;
/** z-axis */
public static final Axis MATURITY_AXIS = Axis.Z;
public VolatilityCube(final Cube<Double, Double, Double, Double> cube) {
ArgumentChecker.notNull(cube, "cube");
_cube = cube;
}
@Override
public Double getVolatility(final Triple<Double, Double, Double> xyz) {
ArgumentChecker.notNull(xyz, "xyz triple");
return _cube.getValue(xyz);
}
/**
* Return a volatility for the expiry, strike, maturity triple provided.
* Interpolation/extrapolation behaviour depends on underlying cube
* @param t time to maturity
* @param k strike
* @param m maturity //TODO review it !
* @return The Black (implied) volatility //TODO review it !
*/
public double getVolatility(final double t, final double k, final double m) {
final Triple<Double, Double, Double> temp = Triple.of(t, k, m);
return getVolatility(temp);
}
public VolatilitySurface getSlice(final Plane plane, final double here, final Interpolator2D interpolator) {
final Surface<Double, Double, Double> surface = CubeSliceFunction.cut(_cube, plane, here, interpolator);
return new VolatilitySurface(surface);
}
public Cube<Double, Double, Double, Double> getCube() {
return _cube;
}
public VolatilityCube withParallelShift(final double shift) {
return new VolatilityCube(CubeShiftFunctionFactory.getShiftedCube(_cube, shift, true));
}
public VolatilityCube withSingleAdditiveShift(final double x, final double y, final double z, final double shift) {
return new VolatilityCube(CubeShiftFunctionFactory.getShiftedCube(_cube, x, y, z, shift, true));
}
public VolatilityCube withMultipleAdditiveShifts(final double[] x, final double[] y, final double[] z, final double[] shifts) {
return new VolatilityCube(CubeShiftFunctionFactory.getShiftedCube(_cube, x, y, z, shifts, true));
}
public VolatilityCube withConstantMultiplicativeShift(final double shift) {
return new VolatilityCube(CubeShiftFunctionFactory.getShiftedCube(_cube, shift, false));
}
public VolatilityCube withSingleMultiplicativeShift(final double x, final double y, final double z, final double shift) {
return new VolatilityCube(CubeShiftFunctionFactory.getShiftedCube(_cube, x, y, z, shift, false));
}
public VolatilityCube withMultipleMultiplicativeShifts(final double[] x, final double[] y, final double[] z, final double[] shifts) {
return new VolatilityCube(CubeShiftFunctionFactory.getShiftedCube(_cube, x, y, z, shifts, false));
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + _cube.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 VolatilityCube other = (VolatilityCube) obj;
return ObjectUtils.equals(_cube, other._cube);
}
}