/**
* 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.smile.fitting;
import org.testng.annotations.Test;
import com.opengamma.analytics.financial.model.option.DistributionFromImpliedVolatility;
import com.opengamma.analytics.financial.model.option.pricing.analytic.formula.EuropeanVanillaOption;
import com.opengamma.analytics.financial.model.volatility.smile.function.SABRBerestyckiVolatilityFunction;
import com.opengamma.analytics.financial.model.volatility.smile.function.SABRFormulaData;
import com.opengamma.analytics.financial.model.volatility.smile.function.SABRHaganAlternativeVolatilityFunction;
import com.opengamma.analytics.financial.model.volatility.smile.function.SABRHaganVolatilityFunction;
import com.opengamma.analytics.financial.model.volatility.smile.function.SABRJohnsonVolatilityFunction;
import com.opengamma.analytics.financial.model.volatility.smile.function.SABRPaulotVolatilityFunction;
import com.opengamma.analytics.financial.model.volatility.smile.function.VolatilityFunctionProvider;
import com.opengamma.analytics.math.function.Function1D;
import com.opengamma.analytics.math.statistics.distribution.ProbabilityDistribution;
import com.opengamma.util.test.TestGroup;
/**
* Test.
*/
@Test(groups = TestGroup.UNIT)
public class SABRPDFTest {
private static final double F = 5;
private static final double BETA = 0.99;
private static final double NU = 0.4;
private static final double RHO = -0.5;
private static final double T = 25;
private static final double ATM_VOL = 0.3;
private static final double ALPHA = ATM_VOL * Math.pow(F, 1 - BETA);
private static ProbabilityDistribution<Double> SABR_DIST;
private static ProbabilityDistribution<Double> HAGAN_DIST;
private static ProbabilityDistribution<Double> BERESTYCKI_DIST;
private static ProbabilityDistribution<Double> PAULOT_DIST;
private static ProbabilityDistribution<Double> JOHNSON_DIST;
private static final SABRFormulaData DATA = new SABRFormulaData( ALPHA, BETA, RHO, NU);
private final static Function1D<Double, Double> SABR = new MyFunction(new SABRHaganVolatilityFunction());
private final static Function1D<Double, Double> SABR_HAGAN = new MyFunction(new SABRHaganAlternativeVolatilityFunction());
private final static Function1D<Double, Double> SABR_BERESTYCKI = new MyFunction(new SABRBerestyckiVolatilityFunction());
private final static Function1D<Double, Double> SABR_PAULOT = new MyFunction(new SABRPaulotVolatilityFunction());
private final static Function1D<Double, Double> SABR_JOHNSON = new MyFunction(new SABRJohnsonVolatilityFunction());
static {
SABR_DIST = new DistributionFromImpliedVolatility(F, T, SABR);
HAGAN_DIST = new DistributionFromImpliedVolatility(F, T, SABR_HAGAN);
BERESTYCKI_DIST = new DistributionFromImpliedVolatility(F, T, SABR_BERESTYCKI);
PAULOT_DIST = new DistributionFromImpliedVolatility(F, T, SABR_PAULOT);
JOHNSON_DIST = new DistributionFromImpliedVolatility(F, T, SABR_JOHNSON);
}
@Test
public void test() {
final int n = 800;
final double[] strike = new double[n];
final double[] impliedVol = new double[n];
final double[] impliedVol2 = new double[n];
final double[] impliedVol3 = new double[n];
final double[] impliedVol4 = new double[n];
final double[] impliedVol5 = new double[n];
final double[] pdf1 = new double[n];
final double[] pdf2 = new double[n];
final double[] pdf3 = new double[n];
final double[] pdf4 = new double[n];
final double[] pdf5 = new double[n];
//final double sigmaRootT = ATM_VOL * Math.sqrt(T);
//final double sigmaRootT = ALPHA * Math.sqrt(T);
final double step = 20.0 / (n);
//System.out.println("Strike \t SABR Vol \t Hagan Vol \t Berestycki vol \t Paulot vol \t Johnson vol \t SABR PDF \t Hagan PDF \t Berestycki PDF \t Paulot PDF \t Johnson");
for (int i = 0; i < n; i++) {
//double z = (i - 3 * n) * step;
// double k = F * Math.exp(sigmaRootT * z) * 1.2;
final double k = 0.0 + (i + 1) * step;
strike[i] = k;
impliedVol[i] = SABR.evaluate(k);
impliedVol2[i] = SABR_HAGAN.evaluate(k);
impliedVol3[i] = SABR_BERESTYCKI.evaluate(k);
impliedVol4[i] = SABR_PAULOT.evaluate(k);
impliedVol5[i] = SABR_JOHNSON.evaluate(k);
//price[i] = BLACK.callPrice(F, k, 1.0, impliedVol[i], T);
pdf1[i] = SABR_DIST.getPDF(k);
pdf2[i] = HAGAN_DIST.getPDF(k);
pdf3[i] = BERESTYCKI_DIST.getPDF(k);
pdf4[i] = PAULOT_DIST.getPDF(k);
pdf5[i] = JOHNSON_DIST.getPDF(k);
//System.out.println(strike[i] + "\t" + impliedVol[i] + "\t" + impliedVol2[i] + "\t" + impliedVol3[i] + "\t" + impliedVol4[i] + "\t" + impliedVol5[i] + "\t" + pdf1[i] + "\t" + pdf2[i] + "\t"
// + pdf3[i] + "\t" + pdf4[i] + "\t" + pdf5[i]);
}
}
private static class MyFunction extends Function1D<Double, Double> {
private final VolatilityFunctionProvider<SABRFormulaData> _sabr;
public MyFunction(final VolatilityFunctionProvider<SABRFormulaData> sabr) {
_sabr = sabr;
}
@SuppressWarnings("synthetic-access")
@Override
public Double evaluate(final Double k) {
final EuropeanVanillaOption option = new EuropeanVanillaOption(k, T, true);
return _sabr.getVolatilityFunction(option,F).evaluate(DATA);
}
}
}