/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.model.finitedifference.applications;
import static org.testng.AssertJUnit.assertEquals;
import org.testng.annotations.Test;
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.local.LocalVolatilitySurfaceStrike;
import com.opengamma.analytics.financial.model.volatility.smile.function.MultiHorizonMixedLogNormalModelData;
import com.opengamma.analytics.financial.model.volatility.surface.MixedLogNormalVolatilitySurface;
import com.opengamma.analytics.math.curve.ConstantDoublesCurve;
import com.opengamma.analytics.math.surface.ConstantDoublesSurface;
/**
* @deprecated This class tests deprecated functionality
*/
@Deprecated
public class LocalVolPDEPricerTest {
LocalVolPDEPricer PRICER = new LocalVolPDEPricer();
@Test
public void testFlat() {
//generate a local volatility surface using a mixed log-normal density as this allows us to have an analytical option price that we can compare with the numerical value
final double t = 1.5;
final double spot = 100.0;
final double r = 0.05;
final double q = 0;
final double b = r - q;
final double k = 120.0;
final double sigma = 0.4;
final boolean isCall = true;
final ForwardCurve fc = new ForwardCurve(spot, r);
final LocalVolatilitySurfaceStrike lv = new LocalVolatilitySurfaceStrike(ConstantDoublesSurface.from(sigma));
final int tN = 60;
final int sN = 80 * tN;
final double pdePrice = PRICER.price(spot, k, r, b, t, lv, true, false, sN, tN);
final double price = Math.exp(-r * t) * BlackFormulaRepository.price(fc.getForward(t), k, t, sigma, isCall);
// System.out.println(price + "\t" + pdePrice);
assertEquals(price, pdePrice, 1e-5 * price);
}
@Test
//(enabled = false)
public void test() {
//generate a local volatility surface using a mixed log-normal density as this allows us to have an analytical option price that we can compare with the numerical value
final double t = 1.5;
final double spot = 100.0;
final double r = 0.1;
final double q = 0.07;
final double b = r - q;
final double k = 120.0;
final boolean isCall = true;
final ForwardCurve fc = new ForwardCurve(spot, b);
final YieldAndDiscountCurve discountCurve = new YieldCurve("test", ConstantDoublesCurve.from(r));
final double[] w = new double[] {0.7, 0.25, 0.05 };
final double[] sigma = new double[] {0.3, 0.6, 1.0 };
final double[] mu = new double[] {0.0, 0.3, -0.5 };
final MultiHorizonMixedLogNormalModelData data = new MultiHorizonMixedLogNormalModelData(w, sigma, mu);
final LocalVolatilitySurfaceStrike lv = MixedLogNormalVolatilitySurface.getLocalVolatilitySurface(fc, data);
//TODO relatively large grid needed for moderate accuracy
final int tN = 400;
final int sN = 2 * tN;
final double pdePrice = PRICER.price(spot, k, r, b, t, lv, true, false, sN, tN);
final double price = MixedLogNormalVolatilitySurface.getPriceSurface(fc, discountCurve, data).getPrice(t, k);
final double vol = MixedLogNormalVolatilitySurface.getImpliedVolatilitySurface(fc, data).getVolatility(t, k);
final double price2 = Math.exp(-r * t) * BlackFormulaRepository.price(spot * Math.exp(b * t), k, t, vol, isCall);
//System.out.println(price + "\t" + price2 + "\t" + pdePrice);
assertEquals(price, pdePrice, 1e-3 * price);
}
}