/**
* Copyright (C) 2012 - 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.option.definition.Barrier;
import com.opengamma.analytics.financial.model.option.definition.Barrier.BarrierType;
import com.opengamma.analytics.financial.model.option.definition.Barrier.KnockType;
import com.opengamma.analytics.financial.model.option.definition.Barrier.ObservationType;
import com.opengamma.analytics.financial.model.option.pricing.analytic.formula.BlackBarrierPriceFunction;
import com.opengamma.analytics.financial.model.option.pricing.analytic.formula.EuropeanVanillaOption;
import com.opengamma.util.test.TestGroup;
/**
* Test.
*/
@Test(groups = TestGroup.UNIT)
public class BarrierOptionPricerTest {
private static final boolean PRINT = false;
private static final double SPOT = 100;
private static final double REBATE = 3.0;
// private static final double REBATE = 0.0;
private static final double EXPIRY = 0.5;
private static final double R = 0.08;
private static final double B = 0.04;
private static final double SIGMA = 0.3;
private static final BarrierOptionPricer PRICER = new BarrierOptionPricer(100, 50, 0.5, 0.1);
// private static final BarrierOptionPricer PRICER = new BarrierOptionPricer(100, 50, 100, 0.1);
private static final BlackBarrierPriceFunction ANAL_PRICER = BlackBarrierPriceFunction.getInstance();
@Test
public void outBarrierTest() {
if (PRINT) {
System.out.println("BarrierOptionPricerTest");
}
for (int i = 0; i < 5; i++) {
final double strike = SPOT * (0.8 + i * 0.1);
for (int j = 0; j < 5; j++) {
final double h = SPOT * (0.9 + j * 0.05);
for (int k = 0; k < 2; k++) {
final boolean isCall = k == 0;
final BarrierType bt = SPOT > h ? BarrierType.DOWN : BarrierType.UP;
final double anPrice = ANAL_PRICER.getPrice(new EuropeanVanillaOption(strike, EXPIRY, isCall),
new Barrier(KnockType.OUT, bt, ObservationType.CONTINUOUS, h), REBATE, SPOT, B, R, SIGMA);
final double fdPrice = PRICER.outBarrier(SPOT, h, strike, EXPIRY, R, B, SIGMA, isCall, REBATE);
if (PRINT) {
final String call = isCall ? "call" : "put ";
System.out.format(call + " x = %.0f h = %.0f\tprice = %.4f\tfdPrice = %.4f\n", strike, h, anPrice, fdPrice);
}
//TODO not splendid accuracy here - need to use discrete versions of r,b and sigma on the fd-grid to improve things
assertEquals(anPrice, fdPrice, 5e-2);
}
}
}
}
@Test
public void inBarrierTest() {
if (PRINT) {
System.out.println("BarrierOptionPricerTest");
}
for (int i = 0; i < 5; i++) {
final double strike = SPOT * (0.9 + i * 0.1);
for (int j = 0; j < 5; j++) {
final double h = SPOT * (0.9 + j * 0.05);
for (int k = 0; k < 2; k++) {
final boolean isCall = k == 0;
final BarrierType bt = SPOT > h ? BarrierType.DOWN : BarrierType.UP;
final double anPrice = ANAL_PRICER.getPrice(new EuropeanVanillaOption(strike, EXPIRY, isCall), new Barrier(KnockType.IN, bt, ObservationType.CONTINUOUS, h), REBATE, SPOT, B, R, SIGMA);
final double fdPrice = PRICER.inBarrier(SPOT, h, strike, EXPIRY, R, B, SIGMA, isCall, REBATE);
if (PRINT) {
final String call = isCall ? "call" : "put ";
System.out.format(call + " x = %.0f h = %.0f\tprice = %.4f\tfdPrice = %.4f\n", strike, h, anPrice, fdPrice);
}
//TODO not splendid accuracy here - need to use discrete versions of r,b and sigma on the fd-grid to improve things
assertEquals(anPrice, fdPrice, 5e-2);
}
}
}
}
@Test
public void barrierTest() {
final double spot = 100.0;
final double expiry = 2.0;
final boolean isCall = true;
final double strike = 100.0;
final double barrerLevel = 95.0;
final double rebate = 3.0;
final double r = 0.08;
final double b = 0.04;
final double sigma = 0.3;
final EuropeanVanillaOption option = new EuropeanVanillaOption(strike, expiry, isCall);
final Barrier barrierIn = new Barrier(KnockType.IN, BarrierType.DOWN, ObservationType.CONTINUOUS, barrerLevel);
final double p1In = PRICER.getPrice(option, barrierIn, rebate, spot, b, r, sigma);
final double p2In = PRICER.inBarrier(spot, barrerLevel, strike, expiry, r, b, sigma, isCall, rebate);
assertEquals(p1In, p2In, 1e-20);
final Barrier barrierOut = new Barrier(KnockType.OUT, BarrierType.DOWN, ObservationType.CONTINUOUS, barrerLevel);
final double p1Out = PRICER.getPrice(option, barrierOut, rebate, spot, b, r, sigma);
final double p2Out = PRICER.outBarrier(spot, barrerLevel, strike, expiry, r, b, sigma, isCall, rebate);
assertEquals(p1Out, p2Out, 1e-20);
}
@Test
public void debugTest() {
final double spot = 10.0;
final double expiry = 2.0;
final boolean isCall = true;
final double strike = 13.0;
final double barrerLevel = 17.0;
final double rebate = 1.0;
final double r = 0.0;
final double b = 0.0;
final double sigma = 0.3;
final EuropeanVanillaOption option = new EuropeanVanillaOption(strike, expiry, isCall);
final Barrier barrier = new Barrier(KnockType.OUT, BarrierType.UP, ObservationType.CONTINUOUS, barrerLevel);
final BarrierOptionPricer pricer = new BarrierOptionPricer(100, 50, 0.5, 0.1);
if (PRINT) {
final double p1 = ANAL_PRICER.getPrice(option, barrier, rebate, spot, b, r, sigma);
final double p2 = pricer.getPrice(option, barrier, rebate, spot, b, r, sigma);
final double error = 1e6 * (p1 - p2) / p1;
System.out.println(p1 + "\t" + p2 + "\t" + error);
}
}
}