LinearSmileInterpolater.java
package net.finmath.marketdata.model.volatility.caplet.smile;
/**
* This class implements the smile linearly and extrapolates piecewise constant.
*
* @author Daniel Willhalm
*/
public class LinearSmileInterpolater implements SmileInterpolationExtrapolationMethod {
private final double[][] volatilityMatrix;
private final double[] strikeVector;
public LinearSmileInterpolater(final double[][] volatilityMatrix, final double[] strikeVector) {
this.volatilityMatrix = volatilityMatrix;
this.strikeVector = strikeVector;
}
/**
* Method that returns the linearly interpolated or constantly extrapolated volatility for a given strike and row index.
*
* @param strike The desired strike.
* @param rowIndex The desired row index.
* @return The inter/extrapolated volatility.
*/
@Override
public double calculateInterpolatedExtrapolatedSmileVolatility(final double strike, final int rowIndex) {
if (strike < strikeVector[0]) {
//return ((strike-strikeVector[0])*(volatilityMatrix[rowIndex][1]-volatilityMatrix[rowIndex][0])/(strikeVector[1]-strikeVector[0])+volatilityMatrix[rowIndex][0]);
return volatilityMatrix[rowIndex][0];
}
if (strike >= strikeVector[strikeVector.length-1]) {
//return ((strike-strikeVector[strikeVector.length-1])*(volatilityMatrix[rowIndex][strikeVector.length-1]-volatilityMatrix[rowIndex][strikeVector.length-2])/(strikeVector[strikeVector.length-1]-strikeVector[strikeVector.length-2])+volatilityMatrix[rowIndex][strikeVector.length-1]);
return volatilityMatrix[rowIndex][strikeVector.length-1];
}
int indexLargestStrikeLeftOfInterpolationStrike = 0;
int i = 0;
while (strike >= strikeVector[i]) {
indexLargestStrikeLeftOfInterpolationStrike = i;
i++;
}
if ((volatilityMatrix[rowIndex][indexLargestStrikeLeftOfInterpolationStrike+1] == 0.0) || (strike == strikeVector[indexLargestStrikeLeftOfInterpolationStrike])) {
return volatilityMatrix[rowIndex][indexLargestStrikeLeftOfInterpolationStrike];
}
return ((strike - strikeVector[indexLargestStrikeLeftOfInterpolationStrike])
* (volatilityMatrix[rowIndex][indexLargestStrikeLeftOfInterpolationStrike + 1]
- volatilityMatrix[rowIndex][indexLargestStrikeLeftOfInterpolationStrike])
/ (strikeVector[indexLargestStrikeLeftOfInterpolationStrike + 1]
- strikeVector[indexLargestStrikeLeftOfInterpolationStrike])
+ volatilityMatrix[rowIndex][indexLargestStrikeLeftOfInterpolationStrike]);
}
}