/**
* 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.interpolation;
import static org.testng.AssertJUnit.assertEquals;
import java.util.Arrays;
import org.testng.annotations.Test;
import com.opengamma.analytics.math.function.Function1D;
import com.opengamma.util.test.TestGroup;
/**
* Test.
*/
@Test(groups = TestGroup.UNIT)
public abstract class SmileInterpolatorTestCase {
private static final double FORWARD = 1172.011012;
private static final double EXPIRY = 1.5;
private static final double[] STRIKES = new double[] {782.9777301, 982.3904005, 1242.99164, 1547.184937, 1854.305534};
private static final double[] VOLS = new double[] {0.311, 0.288, 0.267, 0.271, 0.276};
public abstract GeneralSmileInterpolator getSmileInterpolator();
protected double[] getStrikes() {
return STRIKES;
}
protected double[] getVols() {
return VOLS;
}
protected double getForward() {
return FORWARD;
}
protected double getExpiry() {
return EXPIRY;
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testNullStrikes() {
getSmileInterpolator().getVolatilityFunction(FORWARD, null, EXPIRY, VOLS);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testNullVols() {
getSmileInterpolator().getVolatilityFunction(FORWARD, STRIKES, EXPIRY, null);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testWrongLengthVols() {
getSmileInterpolator().getVolatilityFunction(FORWARD, STRIKES, EXPIRY, Arrays.copyOfRange(VOLS, 0, VOLS.length - 1));
}
@Test
public void smileTest() {
// final long startTime = System.nanoTime();
final GeneralSmileInterpolator interpolator = getSmileInterpolator();
final Function1D<Double, Double> smile = interpolator.getVolatilityFunction(FORWARD, STRIKES, EXPIRY, VOLS);
final int n = STRIKES.length;
for (int i = 0; i < n; i++) {
final double k = STRIKES[i];
final double vol = smile.evaluate(k);
assertEquals(VOLS[i], vol, 1e-6);
}
// final long endTime = System.nanoTime();
// System.out.println("smileTest time: " + (endTime - startTime) / 1e6 + "ms");
}
@Test
public void flatTest() {
final int n = STRIKES.length;
final double flatVol = 0.11;
final double[] vols = new double[n];
Arrays.fill(vols, flatVol);
// final long startTime = System.nanoTime();
final GeneralSmileInterpolator interpolator = getSmileInterpolator();
final Function1D<Double, Double> smile = interpolator.getVolatilityFunction(FORWARD, STRIKES, EXPIRY, vols);
for (int i = 0; i < 200; i++) {
final double k = 700 + 1300 * i / 199.;
final double vol = smile.evaluate(k);
assertEquals(flatVol, vol, 1e-8);
}
// final long endTime = System.nanoTime();
// System.out.println("flat time: " + (endTime - startTime) / 1e6 + "ms");
}
@Test
public void smallBumpTest() {
final GeneralSmileInterpolator interpolator = getSmileInterpolator();
final double bump = 1e-3;
final int n = STRIKES.length;
for (int index = 0; index < n; index++) {
final double[] vols = Arrays.copyOf(VOLS, VOLS.length);
vols[index] += bump;
final Function1D<Double, Double> smile = interpolator.getVolatilityFunction(FORWARD, STRIKES, EXPIRY, vols);
for (int i = 0; i < n; i++) {
final double k = STRIKES[i];
final double vol = smile.evaluate(k);
assertEquals(vols[i], vol, 1e-6);
}
}
}
//**********************************************************************************************
// The following are debug tests that print output. Ensure enabled = false before committing
//**********************************************************************************************
@Test(enabled = false)
public void printSmileTest() {
final GeneralSmileInterpolator interpolator = getSmileInterpolator();
final Function1D<Double, Double> smile = interpolator.getVolatilityFunction(FORWARD, STRIKES, EXPIRY, VOLS);
for (int i = 0; i < 200; i++) {
final double k = 700 + 1300 * i / 199.;
final double vol = smile.evaluate(k);
System.out.println(k + "\t" + vol);
}
}
@Test(enabled = false)
public void bumpTest() {
final GeneralSmileInterpolator interpolator = getSmileInterpolator();
final double bump = 1e-3;
final int index = 1;
final double[] vols = Arrays.copyOf(VOLS, VOLS.length);
vols[index] += bump;
final Function1D<Double, Double> smile = interpolator.getVolatilityFunction(FORWARD, STRIKES, EXPIRY, vols);
for (int i = 0; i < 200; i++) {
final double k = 700 + 1300 * i / 199.;
final double vol = smile.evaluate(k);
System.out.println(k + "\t" + vol);
}
}
@Test(enabled = false)
public void flatBumpTest() {
final GeneralSmileInterpolator interpolator = getSmileInterpolator();
final int n = STRIKES.length;
final double[] vols = new double[n];
Arrays.fill(vols, 0.2);
final double bump = 1e-3;
final int index = 0;
vols[index] += bump;
final Function1D<Double, Double> smile = interpolator.getVolatilityFunction(FORWARD, STRIKES, EXPIRY, vols);
for (int i = 0; i < 200; i++) {
final double k = 700 + 1300 * i / 199.;
final double vol = smile.evaluate(k);
System.out.println(k + "\t" + vol);
}
}
@Test(enabled = false)
public void badFitTest() {
final GeneralSmileInterpolator interpolator = getSmileInterpolator();
final double forward = 1.30276013603506;
final double[] strikes = new double[] {1.080256504787705, 1.161299691076151, 1.329077636516407, 1.5210230159922162, 1.635211041136184};
final double expiry = 1.0;
final double[] impVols = new double[] {0.2, 0.2, 0.2, 0.2, 0.2};
final double bump = 1e-3;
final int index = 2;
impVols[index] += bump;
final Function1D<Double, Double> smile = interpolator.getVolatilityFunction(forward, strikes, expiry, impVols);
for (int i = 0; i < 200; i++) {
final double k = 0.8 + 1.2 * i / 199.;
final double vol = smile.evaluate(k);
System.out.println(k + "\t" + vol);
}
}
}