/** * 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.function; import static org.testng.Assert.assertEquals; import java.util.ArrayList; import java.util.List; import org.testng.annotations.Test; import com.opengamma.analytics.financial.model.option.pricing.analytic.formula.EuropeanVanillaOption; import com.opengamma.analytics.math.function.Function1D; import com.opengamma.util.test.TestGroup; /** * Test. */ @Test(groups = TestGroup.UNIT) public class HestonVolatilityFunctionTest { private static final double KAPPA = 0.1; private static final double THETA = 0.05; private static final double VOL0 = 0.1; private static final double OMEGA = 0.7; private static final double RHO = -0.8; private static final HestonModelData DATA = new HestonModelData(KAPPA, THETA, VOL0, OMEGA, RHO); private static final double FORWARD = 0.012; private static final double TIME = 2.4; private static final double[] STRIKES; private static final VolatilityFunctionProvider<HestonModelData> VOL_FUNC_PROVIDER = new HestonVolatilityFunction(); private static final List<Function1D<HestonModelData, Double>> VOL_FUNC_LIST; private static final Function1D<HestonModelData, double[]> VOL_FUNC_SET; private static final VolatilityFunctionProvider<HestonModelData> VOL_FUNC_PROVIDER_FD = new VolatilityFunctionProvider<HestonModelData>() { @Override @SuppressWarnings("synthetic-access") public Function1D<HestonModelData, Double> getVolatilityFunction(final EuropeanVanillaOption option, final double forward) { return VOL_FUNC_PROVIDER.getVolatilityFunction(option, forward); } }; static { final int n = 11; VOL_FUNC_LIST = new ArrayList<>(n); STRIKES = new double[n]; for (int i = 0; i < n; i++) { final double m = -1 + 2.0 * i / (n - 1); STRIKES[i] = FORWARD * Math.exp(m); final EuropeanVanillaOption option = new EuropeanVanillaOption(STRIKES[i], TIME, false); VOL_FUNC_LIST.add(VOL_FUNC_PROVIDER.getVolatilityFunction(option, FORWARD)); } VOL_FUNC_SET = VOL_FUNC_PROVIDER.getVolatilityFunction(FORWARD, STRIKES, TIME); } @Test public void testVolFunction() { final int n = STRIKES.length; final double[] vols = VOL_FUNC_SET.evaluate(DATA); for (int i = 0; i < n; i++) { assertEquals(vols[i], VOL_FUNC_LIST.get(i).evaluate(DATA), 1e-4, "Strike: " + STRIKES[i]); } } @Test public void tesVolFunctionAdjoint() { final int n = STRIKES.length; final Function1D<HestonModelData, double[][]> adjointSetFunc = VOL_FUNC_PROVIDER.getVolatilityAdjointFunction(FORWARD, STRIKES, TIME); final Function1D<HestonModelData, double[][]> adjointSetFuncFD = VOL_FUNC_PROVIDER_FD.getVolatilityAdjointFunction(FORWARD, STRIKES, TIME); final double[][] adjointSet = adjointSetFunc.evaluate(DATA); final double[][] adjointSetFD = adjointSetFuncFD.evaluate(DATA); assertEquals(adjointSet.length, n, "#strikes"); assertEquals(adjointSetFD.length, n, "#strikes FD"); assertEquals(adjointSet[0].length, 8, "#parameters"); assertEquals(adjointSetFD[0].length, 8, "#parameters FD"); for (int i = 0; i < n; i++) { for (int pIndex = 3; pIndex < 8; pIndex++) { assertEquals(adjointSetFD[i][pIndex], adjointSet[i][pIndex], 5e-3, "parameter: " + pIndex + ". strike: " + i); } } } }