/**
* 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.smile.fitting;
import static org.testng.AssertJUnit.assertEquals;
import java.util.Arrays;
import org.testng.annotations.Test;
import com.opengamma.analytics.financial.model.option.pricing.analytic.formula.EuropeanVanillaOption;
import com.opengamma.analytics.financial.model.volatility.smile.fitting.sabr.PiecewiseMixedLogNormalFitter;
import com.opengamma.analytics.financial.model.volatility.smile.function.MixedLogNormalModelData;
import com.opengamma.analytics.financial.model.volatility.smile.function.MixedLogNormalVolatilityFunction;
import com.opengamma.analytics.math.function.Function1D;
import com.opengamma.analytics.math.matrix.DoubleMatrix1D;
import com.opengamma.analytics.math.statistics.leastsquare.LeastSquareResultsWithTransform;
import com.opengamma.util.test.TestGroup;
/**
* Test.
*/
@Test(groups = TestGroup.UNIT)
public class PiecewiseMixLogNormalFitterTest {
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 };
private static final PiecewiseMixedLogNormalFitter FITTER = new PiecewiseMixedLogNormalFitter();
private static final MixedLogNormalVolatilityFunction MODEL = MixedLogNormalVolatilityFunction.getInstance();
@Test
(enabled = false)
public void test() {
final MixedLogNormalModelData[] modelParms = FITTER.getFittedfModelParameters(FORWARD, STRIKES, EXPIRY, VOLS);
final int n = modelParms.length;
for (int i = 0; i < n; i++) {
System.out.println(modelParms[i].toString());
}
final Function1D<Double, Double> smile = FITTER.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 double bump = 1e-2;
final int index = 1;
final double[] vols = Arrays.copyOf(VOLS, VOLS.length);
vols[index] += bump;
final MixedLogNormalModelData[] parms = FITTER.getFittedfModelParameters(FORWARD, STRIKES, EXPIRY, vols);
for (final MixedLogNormalModelData parm : parms) {
System.out.println(parm.toString());
}
final Function1D<Double, Double> smile = FITTER.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 flatTest() {
final int n = STRIKES.length;
final double[] vols = new double[n];
Arrays.fill(vols, 0.2);
final Function1D<Double, Double> smile = FITTER.getVolatilityFunction(FORWARD, STRIKES, EXPIRY, vols);
//double vol = fitter.getVol(1550);
for (int i = 0; i < 200; i++) {
final double k = 700 + 1300 * i / 199.;
final double vol = smile.evaluate(k);
assertEquals(0.2, vol, 1e-9);
}
}
@Test(enabled = false)
public void badFitTest() {
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 = FITTER.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);
}
}
@Test(enabled = false)
public void badFitTest2() {
final double forward = 1172.011012;
final double[] strikes = new double[] {782.9777301, 982.3904005, 1242.99164, 1547.184937, 1854.305534 };
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 = 1;
impVols[index] += bump;
final double[] errors = new double[5];
Arrays.fill(errors, 1e-4);
errors[0] = 1e-1;
errors[1] = 1e-1;
final SmileModelFitter<MixedLogNormalModelData> fitter = new MixedLogNormalModelFitter(forward, strikes, expiry, impVols, errors, MODEL, 2, true);
final DoubleMatrix1D start = new DoubleMatrix1D(0.15, 0.1, 0.5, 0.5);
final LeastSquareResultsWithTransform lsres = fitter.solve(start);
System.out.println(lsres.toString());
final MixedLogNormalModelData data = new MixedLogNormalModelData(lsres.getModelParameters().getData());
System.out.println(data.toString());
for (int i = 0; i < 200; i++) {
final double k = 700 + 1300 * i / 199.;
final double vol = MODEL.getVolatility(new EuropeanVanillaOption(k, expiry, true), forward, data);
System.out.println(k + "\t" + vol);
}
}
}