/** * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.model.volatility.surface; import org.apache.commons.lang.ObjectUtils; import com.opengamma.analytics.financial.model.option.definition.SmileDeltaParameters; import com.opengamma.analytics.financial.model.volatility.SmileAndBucketedSensitivities; import com.opengamma.analytics.financial.model.volatility.VolatilityAndBucketedSensitivities; 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.data.Interpolator1DDataBundle; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.tuple.Triple; /** * Class describing the data required to describe a delta and expiration dependent smile from ATM, risk reversal and strangle as used in Forex market. * The delta used is the delta with respect to forward. */ public class SmileDeltaTermStructureParametersStrikeInterpolation extends SmileDeltaTermStructureParameters { /** * The interpolator/extrapolator used in the strike dimension. */ private final Interpolator1D _strikeInterpolator; /** * The default interpolator: linear with flat extrapolation. */ private static final Interpolator1D DEFAULT_INTERPOLATOR_STRIKE = CombinedInterpolatorExtrapolatorFactory.getInterpolator(Interpolator1DFactory.LINEAR, Interpolator1DFactory.FLAT_EXTRAPOLATOR, Interpolator1DFactory.FLAT_EXTRAPOLATOR); /** * Constructor from volatility term structure. The default interpolator is used to interpolate in the strike dimension. The default interpolator is linear with flat extrapolation. * @param volatilityTerm The volatility description at the different expiration. */ public SmileDeltaTermStructureParametersStrikeInterpolation(final SmileDeltaParameters[] volatilityTerm) { this(volatilityTerm, DEFAULT_INTERPOLATOR_STRIKE); } /** * Constructor from volatility term structure. * @param volatilityTerm The volatility description at the different expiration. * @param strikeInterpolator The interpolator used in the strike dimension. */ public SmileDeltaTermStructureParametersStrikeInterpolation(final SmileDeltaParameters[] volatilityTerm, final Interpolator1D strikeInterpolator) { super(volatilityTerm); _strikeInterpolator = strikeInterpolator; } /** * Constructor from volatility term structure. * @param volatilityTerm The volatility description at the different expiration. * @param strikeInterpolator The interpolator used in the strike dimension. * @param timeInterpolator The interpolator used in the time dimension. */ public SmileDeltaTermStructureParametersStrikeInterpolation(final SmileDeltaParameters[] volatilityTerm, final Interpolator1D strikeInterpolator, final Interpolator1D timeInterpolator) { super(volatilityTerm, timeInterpolator); ArgumentChecker.notNull(strikeInterpolator, "strike interpolator"); _strikeInterpolator = strikeInterpolator; } /** * Constructor from market data. The default interpolator is used to interpolate in the strike dimension. The default interpolator is linear with flat extrapolation. * @param timeToExpiration The time to expiration of each volatility smile. * @param delta The delta at which the volatilities are given. Must be positive and sorted in ascending order. The put will have as delta the opposite of the numbers. * Common to all time to expiration. * @param volatility The volatilities at each delta. */ public SmileDeltaTermStructureParametersStrikeInterpolation(final double[] timeToExpiration, final double[] delta, final double[][] volatility) { this(timeToExpiration, delta, volatility, DEFAULT_INTERPOLATOR_STRIKE); } /** * Constructor from market data. * @param timeToExpiration The time to expiration of each volatility smile. * @param delta The delta at which the volatilities are given. Must be positive and sorted in ascending order. The put will have as delta the opposite of the numbers. * Common to all time to expiration. * @param volatility The volatilities at each delta. * @param strikeInterpolator The interpolator used in the strike dimension. */ public SmileDeltaTermStructureParametersStrikeInterpolation(final double[] timeToExpiration, final double[] delta, final double[][] volatility, final Interpolator1D strikeInterpolator) { super(timeToExpiration, delta, volatility); ArgumentChecker.notNull(strikeInterpolator, "strike interpolator"); _strikeInterpolator = strikeInterpolator; } /** * Constructor from market data. The default interpolator is used to interpolate in the strike dimension. The default interpolator is linear with flat extrapolation. * @param timeToExpiration The time to expiration of each volatility smile. * @param delta The delta at which the volatilities are given. Common to all time to expiration. * @param atm The ATM volatilities for each time to expiration. The length should be equal to the length of timeToExpiration. * @param riskReversal The risk reversal figures. * @param strangle The strangle figures. */ public SmileDeltaTermStructureParametersStrikeInterpolation(final double[] timeToExpiration, final double[] delta, final double[] atm, final double[][] riskReversal, final double[][] strangle) { this(timeToExpiration, delta, atm, riskReversal, strangle, DEFAULT_INTERPOLATOR_STRIKE); } /** * Constructor from market data. * @param timeToExpiration The time to expiration of each volatility smile. * @param delta The delta at which the volatilities are given. Common to all time to expiration. * @param atm The ATM volatilities for each time to expiration. The length should be equal to the length of timeToExpiration. * @param riskReversal The risk reversal figures. * @param strangle The strangle figures. * @param strikeInterpolator The interpolator used in the strike dimension. */ public SmileDeltaTermStructureParametersStrikeInterpolation(final double[] timeToExpiration, final double[] delta, final double[] atm, final double[][] riskReversal, final double[][] strangle, final Interpolator1D strikeInterpolator) { super(timeToExpiration, delta, atm, riskReversal, strangle); ArgumentChecker.notNull(strikeInterpolator, "strike interpolator"); _strikeInterpolator = strikeInterpolator; } /** * Constructor from market data. * @param timeToExpiration The time to expiration of each volatility smile. * @param delta The delta at which the volatilities are given. Common to all time to expiration. * @param atm The ATM volatilities for each time to expiration. The length should be equal to the length of timeToExpiration. * @param riskReversal The risk reversal figures. * @param strangle The strangle figures. * @param strikeInterpolator The interpolator used in the strike dimension. * @param timeInterpolator The interpolator used in the time dimension. */ public SmileDeltaTermStructureParametersStrikeInterpolation(final double[] timeToExpiration, final double[] delta, final double[] atm, final double[][] riskReversal, final double[][] strangle, final Interpolator1D strikeInterpolator, final Interpolator1D timeInterpolator) { super(timeToExpiration, delta, atm, riskReversal, strangle, timeInterpolator); ArgumentChecker.notNull(strikeInterpolator, "strike interpolator"); _strikeInterpolator = strikeInterpolator; } /** * Create a copy of the bundle * @return A copy of the bundle */ @Override public SmileDeltaTermStructureParametersStrikeInterpolation copy() { return new SmileDeltaTermStructureParametersStrikeInterpolation(getVolatilityTerm(), getStrikeInterpolator(), getTimeInterpolator()); } /** * Get the volatility at a given time/strike/forward from the term structure. The volatility at a given delta are interpolated linearly on the total variance (s^2*t) and extrapolated flat. * The volatility are then linearly interpolated in the strike dimension and extrapolated flat. * @param time The time to expiry. * @param strike The strike. * @param forward The forward. * @return The volatility. */ public double getVolatility(final double time, final double strike, final double forward) { ArgumentChecker.isTrue(time >= 0, "Positive time"); final SmileDeltaParameters smile = getSmileForTime(time); final double[] strikes = smile.getStrike(forward); final Interpolator1DDataBundle volatilityInterpolation = _strikeInterpolator.getDataBundle(strikes, smile.getVolatility()); final double volatility = _strikeInterpolator.interpolate(volatilityInterpolation, strike); return volatility; } /** * Computes the volatility and the volatility sensitivity with respect to the volatility data points. * @param time The time to expiration. * @param strike The strike. * @param forward The forward. * After the methods, it contains the volatility sensitivity to the data points. * Only the lines of impacted dates are changed. The input data on the other lines will not be changed. * @return The volatility. */ public VolatilityAndBucketedSensitivities getVolatilityAndSensitivities(final double time, final double strike, final double forward) { ArgumentChecker.isTrue(time >= 0, "Positive time"); final SmileDeltaParameters smile = getSmileForTime(time); final double[] strikes = smile.getStrike(forward); final Interpolator1DDataBundle volatilityInterpolation = _strikeInterpolator.getDataBundle(strikes, smile.getVolatility()); final double volatility = _strikeInterpolator.interpolate(volatilityInterpolation, strike); // Backward sweep final double[] smileVolatilityBar = _strikeInterpolator.getNodeSensitivitiesForValue(volatilityInterpolation, strike); final SmileAndBucketedSensitivities smileAndSensitivities = getSmileAndSensitivitiesForTime(time, smileVolatilityBar); return new VolatilityAndBucketedSensitivities(volatility, smileAndSensitivities.getBucketedSensitivities()); } /** * Get the volatility from a triple. * @param tsf The Time, Strike, Forward triple, not null * @return The volatility. */ @Override public Double getVolatility(final Triple<Double, Double, Double> tsf) { ArgumentChecker.notNull(tsf, "time/strike/forward triple"); return getVolatility(tsf.getFirst(), tsf.getSecond(), tsf.getThird()); } @Override public VolatilityAndBucketedSensitivities getVolatilityAndSensitivities(final Triple<Double, Double, Double> tsf) { ArgumentChecker.notNull(tsf, "time/strike/forward triple"); return getVolatilityAndSensitivities(tsf.getFirst(), tsf.getSecond(), tsf.getThird()); } /** * Gets the interpolator * @return The interpolator */ public Interpolator1D getStrikeInterpolator() { return _strikeInterpolator; } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + _strikeInterpolator.hashCode(); return result; } @Override public boolean equals(final Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } final SmileDeltaTermStructureParametersStrikeInterpolation other = (SmileDeltaTermStructureParametersStrikeInterpolation) obj; if (!ObjectUtils.equals(_strikeInterpolator, other._strikeInterpolator)) { return false; } return true; } }