/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.equity.variance;
import org.testng.annotations.Test;
import com.opengamma.analytics.financial.equity.variance.pricing.AffineDividends;
import com.opengamma.analytics.financial.equity.variance.pricing.EquityDividendsCurvesBundle;
import com.opengamma.analytics.financial.equity.variance.pricing.EquityVarianceSwapStaticReplicationPricer;
import com.opengamma.analytics.financial.model.interestrate.curve.ForwardCurve;
import com.opengamma.analytics.financial.model.interestrate.curve.YieldAndDiscountCurve;
import com.opengamma.analytics.financial.model.interestrate.curve.YieldCurve;
import com.opengamma.analytics.financial.model.volatility.BlackFormulaRepository;
import com.opengamma.analytics.financial.model.volatility.smile.fitting.sabr.SmileSurfaceDataBundle;
import com.opengamma.analytics.financial.model.volatility.smile.fitting.sabr.StandardSmileSurfaceDataBundle;
import com.opengamma.analytics.financial.model.volatility.smile.function.MultiHorizonMixedLogNormalModelData;
import com.opengamma.analytics.financial.model.volatility.surface.BlackVolatilitySurfaceStrike;
import com.opengamma.analytics.financial.model.volatility.surface.MixedLogNormalVolatilitySurface;
import com.opengamma.analytics.financial.model.volatility.surface.PureImpliedVolatilitySurface;
import com.opengamma.analytics.financial.varianceswap.VarianceSwap;
import com.opengamma.analytics.math.curve.ConstantDoublesCurve;
import com.opengamma.analytics.math.interpolation.Interpolator1DFactory;
import com.opengamma.analytics.math.surface.ConstantDoublesSurface;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.money.Currency;
/**
*
*/
public class EquityVarianceSwapStaticReplicationPricerTest {
private static final boolean PRINT = false;
private static final double SPOT = 65.4;
private static final String[] EXPIRY_LABELS = new String[] {"1W", "2W", "1M", "3M", "6M", "1Y", "2Y" };
private static final double[] EXPIRIES = new double[] {1. / 52, 2. / 52, 1. / 12, 3. / 12, 6. / 12, 1.0, 2.0 };
private static final double[][] STRIKES = new double[][] { {50, 55, 60, 65, 70, 75, 80 }, {50, 55, 60, 65, 70, 75, 80 }, {50, 55, 60, 65, 70, 75, 80 },
{40, 50, 60, 70, 80, 90 }, {40, 50, 60, 70, 80, 90, 100 }, {30, 50, 60, 70, 80, 90, 100 }, {20, 40, 55, 65, 75, 90, 105, 125 } };
private static final double PURE_VOL = 0.45;
private static final PureImpliedVolatilitySurface PURE_VOL_SURFACE;
private static final double[] TAU = new double[] {5. / 12, 11. / 12, 17. / 12, 23. / 12, 29. / 12 };
private static final double[] ALPHA = new double[] {3.0, 2.0, 1.0, 0.0, 0.0 };
private static final double[] BETA = new double[] {0.0, 0.02, 0.03, 0.04, 0.05 };
private static final AffineDividends NULL_DIVIDENDS = AffineDividends.noDividends();
private static final AffineDividends DIVIDENDS = new AffineDividends(TAU, ALPHA, BETA);
private static final double R = 0.07;
private static final YieldAndDiscountCurve DISCOUNT_CURVE = new YieldCurve("Discount", ConstantDoublesCurve.from(R));
private static final VarianceSwap VS = new VarianceSwap(0, 0.75, 0.75, 0.0, 1.0, Currency.USD, 252, 252, 0, new double[0], new double[0]);
private static final EquityVarianceSwap EVS_COR_FRO_DIVS = new EquityVarianceSwap(VS, true);
private static final EquityVarianceSwap EVS = new EquityVarianceSwap(VS, false);
private static final EquityVarianceSwapStaticReplicationPricer PRICER = EquityVarianceSwapStaticReplicationPricer.builder().create();
static {
final double[] weights = new double[] {0.15, 0.8, 0.05 };
final double[] sigma = new double[] {0.15, 0.3, 0.8 };
final double[] mu = new double[] {0.04, 0.02, -0.2 };
final MultiHorizonMixedLogNormalModelData data = new MultiHorizonMixedLogNormalModelData(weights, sigma, mu);
final BlackVolatilitySurfaceStrike temp = MixedLogNormalVolatilitySurface.getImpliedVolatilitySurface(new ForwardCurve(1.0), data);
PURE_VOL_SURFACE = new PureImpliedVolatilitySurface(temp.getSurface());
}
@Test
public void bucketedVegaTest() {
if (PRINT) {
final PureImpliedVolatilitySurface flat = new PureImpliedVolatilitySurface(ConstantDoublesSurface.from(PURE_VOL));
final SmileSurfaceDataBundle v1 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, NULL_DIVIDENDS, flat);
final SmileSurfaceDataBundle v2 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, DIVIDENDS, flat);
final SmileSurfaceDataBundle v3 = v2;
final SmileSurfaceDataBundle v4 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, NULL_DIVIDENDS, PURE_VOL_SURFACE);
final SmileSurfaceDataBundle v5 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, DIVIDENDS, PURE_VOL_SURFACE);
final SmileSurfaceDataBundle v6 = v5;
final double[][] res1 = PRICER.bucketedVega(EVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v1);
final double[][] res2 = PRICER.bucketedVega(EVS_COR_FRO_DIVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v2);
final double[][] res3 = PRICER.bucketedVega(EVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v3);
final double[][] res4 = PRICER.bucketedVega(EVS, SPOT, DISCOUNT_CURVE, NULL_DIVIDENDS, v4);
final double[][] res5 = PRICER.bucketedVega(EVS_COR_FRO_DIVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v5);
final double[][] res6 = PRICER.bucketedVega(EVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v6);
printBucketedVega("Flat surface - no dividends", res1);
printBucketedVega("Flat surface - dividends corrected", res2);
printBucketedVega("Flat surface - dividends not corrected", res3);
printBucketedVega("Non-flat surface - no dividends", res4);
printBucketedVega("Non-flat surface - dividends corrected", res5);
printBucketedVega("Non-flat surface - dividends not corrected", res6);
}
}
private void printBucketedVega(final String label, final double[][] data) {
final int n = data.length;
ArgumentChecker.isTrue(n == EXPIRY_LABELS.length, "data wrong length");
System.out.println(label);
for (int i = 0; i < n; i++) {
System.out.print(EXPIRY_LABELS[i] + "\t");
final int m = data[i].length;
for (int j = 0; j < m; j++) {
System.out.print(data[i][j] + "\t");
}
System.out.print("\n");
}
}
@Test
public void dividendSensitivityWithStickyImpVolTest() {
if (PRINT) {
//make all the implied volatility scenarios with the spot fixed
final PureImpliedVolatilitySurface flat = new PureImpliedVolatilitySurface(ConstantDoublesSurface.from(PURE_VOL));
final SmileSurfaceDataBundle v1 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, NULL_DIVIDENDS, flat);
final SmileSurfaceDataBundle v2 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, DIVIDENDS, flat);
final SmileSurfaceDataBundle v3 = v2;
final SmileSurfaceDataBundle v4 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, NULL_DIVIDENDS, PURE_VOL_SURFACE);
final SmileSurfaceDataBundle v5 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, DIVIDENDS, PURE_VOL_SURFACE);
final SmileSurfaceDataBundle v6 = v5;
//now assume that the implied volatilities remain fixed as the spot moves
// double[][] d1 = pricer.dividendSensitivityWithStickyImpliedVol(EVS_COR_FRO_DIVS, SPOT, DISCOUNT_CURVE, ZERO_DIVIDENDS, v1);
final double[][] d2 = PRICER.dividendSensitivityWithStickyImpliedVol(EVS_COR_FRO_DIVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v2);
final double[][] d3 = PRICER.dividendSensitivityWithStickyImpliedVol(EVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v3);
// double[][] d4 = pricer.dividendSensitivityWithStickyImpliedVol(EVS, SPOT, DISCOUNT_CURVE, ZERO_DIVIDENDS, v4);
final double[][] d5 = PRICER.dividendSensitivityWithStickyImpliedVol(EVS_COR_FRO_DIVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v5);
final double[][] d6 = PRICER.dividendSensitivityWithStickyImpliedVol(EVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v6);
//printDividendSense("Flat surface - no dividends:", d1);
printDividendSense("Flat, divs corr:", d2);
printDividendSense("Flat, divs not corr:", d3);
// printDividendSense(" Non-flat surface - no dividends:", d4);
printDividendSense("Non-flat, divs corr:", d5);
printDividendSense("Non-flat, divs not corr:", d6);
}
}
private void printDividendSense(final String label, final double[][] data) {
System.out.print(label + "\t");
final int n = data.length;
for (int i = 0; i < n; i++) {
final int m = data[i].length;
for (int j = 0; j < m; j++) {
System.out.print(data[i][j] + "\t");
}
}
System.out.print("\n");
}
@Test
public void deltaWithDtickyStikeTest() {
if (PRINT) {
//make all the implied volatility scenarios with the spot fixed
final PureImpliedVolatilitySurface flat = new PureImpliedVolatilitySurface(ConstantDoublesSurface.from(PURE_VOL));
final SmileSurfaceDataBundle v1 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, NULL_DIVIDENDS, flat);
final SmileSurfaceDataBundle v2 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, DIVIDENDS, flat);
final SmileSurfaceDataBundle v3 = v2;
final SmileSurfaceDataBundle v4 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, NULL_DIVIDENDS, PURE_VOL_SURFACE);
final SmileSurfaceDataBundle v5 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, DIVIDENDS, PURE_VOL_SURFACE);
final SmileSurfaceDataBundle v6 = v5;
//now assume that the implied volatilities remain fixed as the spot moves
final double d1 = PRICER.deltaWithStickyStrike(EVS, SPOT, DISCOUNT_CURVE, NULL_DIVIDENDS, v1);
final double d2 = PRICER.deltaWithStickyStrike(EVS_COR_FRO_DIVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v2);
final double d3 = PRICER.deltaWithStickyStrike(EVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v3);
final double d4 = PRICER.deltaWithStickyStrike(EVS, SPOT, DISCOUNT_CURVE, NULL_DIVIDENDS, v4);
final double d5 = PRICER.deltaWithStickyStrike(EVS_COR_FRO_DIVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v5);
final double d6 = PRICER.deltaWithStickyStrike(EVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v6);
System.out.println("Flat, no divs: " + d1);
System.out.println("Flat, divs corr: " + d2);
System.out.println("Flat, divs not corr: " + d3);
System.out.println("Non-flat, no divs: " + d4);
System.out.println("Non-flat, divs corr: " + d5);
System.out.println("Non-flat, divs not corr: " + d6);
}
}
@Test
public void deltaWithStickyPureStrikeTest() {
if (PRINT) {
//make all the implied volatility scenarios with the spot fixed
final PureImpliedVolatilitySurface flat = new PureImpliedVolatilitySurface(ConstantDoublesSurface.from(PURE_VOL));
final SmileSurfaceDataBundle v1 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, NULL_DIVIDENDS, flat);
final SmileSurfaceDataBundle v2 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, DIVIDENDS, flat);
final SmileSurfaceDataBundle v3 = v2;
final SmileSurfaceDataBundle v4 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, NULL_DIVIDENDS, PURE_VOL_SURFACE);
final SmileSurfaceDataBundle v5 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, DIVIDENDS, PURE_VOL_SURFACE);
final SmileSurfaceDataBundle v6 = v5;
//now assume that the implied volatilities remain fixed as the spot moves
final double d1 = PRICER.deltaWithStickyPureStrike(EVS, SPOT, DISCOUNT_CURVE, NULL_DIVIDENDS, v1);
final double d2 = PRICER.deltaWithStickyPureStrike(EVS_COR_FRO_DIVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v2);
final double d3 = PRICER.deltaWithStickyPureStrike(EVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v3);
final double d4 = PRICER.deltaWithStickyPureStrike(EVS, SPOT, DISCOUNT_CURVE, NULL_DIVIDENDS, v4);
final double d5 = PRICER.deltaWithStickyPureStrike(EVS_COR_FRO_DIVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v5);
final double d6 = PRICER.deltaWithStickyPureStrike(EVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v6);
System.out.println("Flat, no divs: " + d1);
System.out.println("Flat, divs corr: " + d2);
System.out.println("Flat, divs not corr: " + d3);
System.out.println("Non-flat, no divs: " + d4);
System.out.println("Non-flat, divs corr: " + d5);
System.out.println("Non-flat, divs not corr: " + d6);
}
}
@Test
public void gammaStickyStikeTest() {
if (PRINT) {
//make all the implied volatility scenarios with the spot fixed
final PureImpliedVolatilitySurface flat = new PureImpliedVolatilitySurface(ConstantDoublesSurface.from(PURE_VOL));
final SmileSurfaceDataBundle v1 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, NULL_DIVIDENDS, flat);
final SmileSurfaceDataBundle v2 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, DIVIDENDS, flat);
final SmileSurfaceDataBundle v3 = v2;
final SmileSurfaceDataBundle v4 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, NULL_DIVIDENDS, PURE_VOL_SURFACE);
final SmileSurfaceDataBundle v5 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, DIVIDENDS, PURE_VOL_SURFACE);
final SmileSurfaceDataBundle v6 = v5;
//now assume that the implied volatilities remain fixed as the spot moves
final double d1 = PRICER.gammaWithStickyStrike(EVS, SPOT, DISCOUNT_CURVE, NULL_DIVIDENDS, v1);
final double d2 = PRICER.gammaWithStickyStrike(EVS_COR_FRO_DIVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v2);
final double d3 = PRICER.gammaWithStickyStrike(EVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v3);
final double d4 = PRICER.gammaWithStickyStrike(EVS, SPOT, DISCOUNT_CURVE, NULL_DIVIDENDS, v4);
final double d5 = PRICER.gammaWithStickyStrike(EVS_COR_FRO_DIVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v5);
final double d6 = PRICER.gammaWithStickyStrike(EVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v6);
System.out.println("Flat, no divs:\t" + d1);
System.out.println("Flat, divs corr:\t" + d2);
System.out.println("Flat, divs not corr:\t" + d3);
System.out.println("Non-flat, no divs:\t" + d4);
System.out.println("Non-flat, divs corr:\t" + d5);
System.out.println("Non-flat, divs not corr:\t" + d6);
}
}
@Test
public void gammaWithStickyPureStrikeTest() {
if (PRINT) {
//make all the implied volatility scenarios with the spot fixed
final PureImpliedVolatilitySurface flat = new PureImpliedVolatilitySurface(ConstantDoublesSurface.from(PURE_VOL));
final SmileSurfaceDataBundle v1 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, NULL_DIVIDENDS, flat);
final SmileSurfaceDataBundle v2 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, DIVIDENDS, flat);
final SmileSurfaceDataBundle v3 = v2;
final SmileSurfaceDataBundle v4 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, NULL_DIVIDENDS, PURE_VOL_SURFACE);
final SmileSurfaceDataBundle v5 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, DIVIDENDS, PURE_VOL_SURFACE);
final SmileSurfaceDataBundle v6 = v5;
//now assume that the implied volatilities remain fixed as the spot moves
final double d1 = PRICER.deltaWithStickyPureStrike(EVS, SPOT, DISCOUNT_CURVE, NULL_DIVIDENDS, v1);
final double d2 = PRICER.deltaWithStickyPureStrike(EVS_COR_FRO_DIVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v2);
final double d3 = PRICER.deltaWithStickyPureStrike(EVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v3);
final double d4 = PRICER.deltaWithStickyPureStrike(EVS, SPOT, DISCOUNT_CURVE, NULL_DIVIDENDS, v4);
final double d5 = PRICER.deltaWithStickyPureStrike(EVS_COR_FRO_DIVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v5);
final double d6 = PRICER.deltaWithStickyPureStrike(EVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v6);
System.out.println("Flat, no divs:\t" + d1);
System.out.println("Flat, divs corr:\t" + d2);
System.out.println("Flat, divs not corr:\t" + d3);
System.out.println("Non-flat, no divs:\t" + d4);
System.out.println("Non-flat, divs corr:\t" + d5);
System.out.println("Non-flat, divs not corr:\t" + d6);
}
}
@Test
public void vegaImpVolTest() {
if (PRINT) {
//make all the implied volatility scenarios with the spot fixed
final PureImpliedVolatilitySurface flat = new PureImpliedVolatilitySurface(ConstantDoublesSurface.from(PURE_VOL));
final SmileSurfaceDataBundle v1 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, NULL_DIVIDENDS, flat);
final SmileSurfaceDataBundle v2 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, DIVIDENDS, flat);
final SmileSurfaceDataBundle v3 = v2;
final SmileSurfaceDataBundle v4 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, NULL_DIVIDENDS, PURE_VOL_SURFACE);
final SmileSurfaceDataBundle v5 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, DIVIDENDS, PURE_VOL_SURFACE);
final SmileSurfaceDataBundle v6 = v5;
//now assume that the implied volatilities remain fixed as the spot moves
final double d1 = PRICER.vegaImpVol(EVS, SPOT, DISCOUNT_CURVE, NULL_DIVIDENDS, v1);
final double d2 = PRICER.vegaImpVol(EVS_COR_FRO_DIVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v2);
final double d3 = PRICER.vegaImpVol(EVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v3);
final double d4 = PRICER.vegaImpVol(EVS, SPOT, DISCOUNT_CURVE, NULL_DIVIDENDS, v4);
final double d5 = PRICER.vegaImpVol(EVS_COR_FRO_DIVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v5);
final double d6 = PRICER.vegaImpVol(EVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v6);
System.out.println("Flat, no divs: " + d1);
System.out.println("Flat, divs corr: " + d2);
System.out.println("Flat, divs not corr: " + d3);
System.out.println("Non-flat, no divs: " + d4);
System.out.println("Non-flat, divs corr: " + d5);
System.out.println("Non-flat, divs not corr: " + d6);
}
}
@Test
public void vegaPureImpVolTest() {
if (PRINT) {
//make all the implied volatility scenarios with the spot fixed
final PureImpliedVolatilitySurface flat = new PureImpliedVolatilitySurface(ConstantDoublesSurface.from(PURE_VOL));
final SmileSurfaceDataBundle v1 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, NULL_DIVIDENDS, flat);
final SmileSurfaceDataBundle v2 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, DIVIDENDS, flat);
final SmileSurfaceDataBundle v3 = v2;
final SmileSurfaceDataBundle v4 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, NULL_DIVIDENDS, PURE_VOL_SURFACE);
final SmileSurfaceDataBundle v5 = getMarketVols(SPOT, EXPIRIES, STRIKES, DISCOUNT_CURVE, DIVIDENDS, PURE_VOL_SURFACE);
final SmileSurfaceDataBundle v6 = v5;
//now assume that the implied volatilities remain fixed as the spot moves
final double d1 = PRICER.vegaPureImpVol(EVS, SPOT, DISCOUNT_CURVE, NULL_DIVIDENDS, v1);
final double d2 = PRICER.vegaPureImpVol(EVS_COR_FRO_DIVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v2);
final double d3 = PRICER.vegaPureImpVol(EVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v3);
final double d4 = PRICER.vegaPureImpVol(EVS, SPOT, DISCOUNT_CURVE, NULL_DIVIDENDS, v4);
final double d5 = PRICER.vegaPureImpVol(EVS_COR_FRO_DIVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v5);
final double d6 = PRICER.vegaPureImpVol(EVS, SPOT, DISCOUNT_CURVE, DIVIDENDS, v6);
System.out.println("Flat, no divs: " + d1);
System.out.println("Flat, divs corr: " + d2);
System.out.println("Flat, divs not corr: " + d3);
System.out.println("Non-flat, no divs: " + d4);
System.out.println("Non-flat, divs corr: " + d5);
System.out.println("Non-flat, divs not corr: " + d6);
}
}
private static SmileSurfaceDataBundle getMarketVols(final double spot, final double[] expiries, final double[][] strikes, final YieldAndDiscountCurve discountCurve,
final AffineDividends dividends, final PureImpliedVolatilitySurface surf) {
final int nExp = expiries.length;
final double[] f = new double[nExp];
final double[][] vols = new double[nExp][];
final EquityDividendsCurvesBundle divCurves = new EquityDividendsCurvesBundle(spot, discountCurve, dividends);
for (int i = 0; i < nExp; i++) {
final int n = strikes[i].length;
vols[i] = new double[n];
final double t = expiries[i];
f[i] = divCurves.getF(t);
final double d = divCurves.getD(t);
for (int j = 0; j < n; j++) {
final double x = (strikes[i][j] - d) / (f[i] - d);
final boolean isCall = x >= 1.0;
final double pVol = surf.getVolatility(t, x);
final double p = (f[i] - d) * BlackFormulaRepository.price(1.0, x, t, pVol, isCall);
vols[i][j] = BlackFormulaRepository.impliedVolatility(p, f[i], strikes[i][j], t, pVol);
}
}
return new StandardSmileSurfaceDataBundle(spot, f, expiries, strikes, vols, Interpolator1DFactory.DOUBLE_QUADRATIC_INSTANCE);
}
}