/**
* Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.pricer.impl.option;
import static com.opengamma.strata.product.common.PutCall.CALL;
import static com.opengamma.strata.product.common.PutCall.PUT;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.util.function.Function;
import org.testng.annotations.Test;
import com.opengamma.strata.basics.value.ValueDerivatives;
import com.opengamma.strata.collect.tuple.Pair;
import com.opengamma.strata.math.impl.integration.GaussHermiteQuadratureIntegrator1D;
import com.opengamma.strata.math.impl.integration.RungeKuttaIntegrator1D;
import com.opengamma.strata.math.impl.statistics.distribution.NormalDistribution;
import com.opengamma.strata.math.impl.statistics.distribution.ProbabilityDistribution;
import com.opengamma.strata.product.common.PutCall;
/**
* Test {@link BlackFormulaRepository}.
*/
@Test
public class BlackFormulaRepositoryTest {
private static final double EPS = 1.e-10;
private static final double DELTA = 1.e-6;
private static final ProbabilityDistribution<Double> NORMAL = new NormalDistribution(0, 1);
private static final double TIME_TO_EXPIRY = 4.5;
private static final double FORWARD = 104;
private static final double[] STRIKES_INPUT = new double[] {
85.0, 90.0, 95.0, 100.0, 103.0, 108.0, 120.0, 150.0, 250.0};
private static final double[] VOLS = new double[] {0.1, 0.12, 0.15, 0.2, 0.3, 0.5, 0.8};
private static final double[][] PRE_COMPUTER_PRICES = new double[][] {
{20.816241352493662, 21.901361401145017, 23.739999392248883, 27.103751052550102, 34.22506482807403,
48.312929458905, 66.87809290575849},
{17.01547107842069, 18.355904456594594, 20.492964568435653, 24.216799858954104, 31.81781516125381,
46.52941355755593, 65.73985671517116},
{13.655000481751557, 15.203913570037663, 17.57850003037605, 21.58860329455819, 29.58397731664536,
44.842632571211, 64.65045683512315},
{10.76221357246159, 12.452317171280882, 14.990716295389468, 19.207654124402573, 27.51258894693435,
43.24555444486169, 63.606185385322505},
{9.251680464551534, 10.990050517334176, 13.589326615797177, 17.892024398947207, 26.343236303647927,
42.327678792768694, 62.99989771948578},
{7.094602606393259, 8.852863501660629, 11.492701186228047, 15.876921735149438, 24.50948746286295,
40.86105495729011, 62.02112426294542},
{3.523029591534474, 5.0769317175689395, 7.551079210499658, 11.857770325364342, 20.641589813250427,
37.63447312094027, 59.81944968154744},
{0.4521972353043875, 1.0637022636084144, 2.442608010436077, 5.613178543779881, 13.579915684294491,
31.040979917191127, 55.062112340600244},
{1.328198130230618E-4, 0.0029567128738985232, 0.04468941116428932, 0.47558224046532205, 3.8091577630027356,
18.03481967011267, 43.99634090899799}};
public void zeroVolTest() {
boolean isCall = true;
int n = STRIKES_INPUT.length;
for (int i = 0; i < n; i++) {
double intrinic = Math.max(0, FORWARD - STRIKES_INPUT[i]);
double price = BlackFormulaRepository.price(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, 0.0, isCall);
assertEquals(intrinic, price, 1e-15);
}
}
public void zeroExpiryTest() {
boolean isCall = false;
int n = STRIKES_INPUT.length;
for (int i = 0; i < n; i++) {
double intrinic = Math.max(0, STRIKES_INPUT[i] - FORWARD);
double price = BlackFormulaRepository.price(FORWARD, STRIKES_INPUT[i], 0.0, 0.3, isCall);
assertEquals(intrinic, price, 1e-15);
}
}
public void tinyVolTest() {
double vol = 1e-4;
boolean isCall = true;
int n = STRIKES_INPUT.length;
for (int i = 0; i < n; i++) {
double intrinic = Math.max(0, FORWARD - STRIKES_INPUT[i]);
double price = BlackFormulaRepository.price(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, vol, isCall);
assertEquals(intrinic, price, 1e-15);
}
}
public void shortExpiryTest() {
double t = 1e-5;
double vol = 0.4;
boolean isCall = false;
int n = STRIKES_INPUT.length;
for (int i = 0; i < n; i++) {
double intrinic = Math.max(0, STRIKES_INPUT[i] - FORWARD);
double price = BlackFormulaRepository.price(FORWARD, STRIKES_INPUT[i], t, vol, isCall);
assertEquals(intrinic, price, 1e-15);
}
}
public void massiveVolTest() {
double vol = 8.0; // 800% vol
boolean isCall = true;
int n = STRIKES_INPUT.length;
for (int i = 0; i < n; i++) {
double price = BlackFormulaRepository.price(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, vol, isCall);
assertEquals(FORWARD, price, 1e-15);
}
}
public void zeroStikeTest() {
boolean isCall = true;
int n = VOLS.length;
for (int i = 0; i < n; i++) {
double price = BlackFormulaRepository.price(FORWARD, 0.0, TIME_TO_EXPIRY, VOLS[i], isCall);
assertEquals(FORWARD, price, 1e-15);
}
}
public void putCallParityTest() {
int n = VOLS.length;
int m = STRIKES_INPUT.length;
for (int i = 0; i < m; i++) {
double fk = FORWARD - STRIKES_INPUT[i];
for (int j = 0; j < n; j++) {
double call = BlackFormulaRepository.price(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, VOLS[j], true);
double put = BlackFormulaRepository.price(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, VOLS[j], false);
assertEquals(fk, call - put, 1e-13);
}
}
}
public void nonEdgeCaseTest() {
boolean isCall = true;
int n = VOLS.length;
int m = STRIKES_INPUT.length;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
double price = BlackFormulaRepository.price(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, VOLS[j], isCall);
assertEquals(PRE_COMPUTER_PRICES[i][j], price, 1e-13 * price);
}
}
}
/**
* Tests the strikes in a range of strikes, volatilities and call/put.
*/
public void impliedStrike() {
int nbStrike = STRIKES_INPUT.length;
int nbVols = VOLS.length;
boolean callput = false;
for (int loopcall = 0; loopcall < 2; loopcall++) {
callput = !callput;
for (int loopstrike = 0; loopstrike < nbStrike; loopstrike++) {
for (int loopVols = 0; loopVols < nbVols; loopVols++) {
ValueDerivatives d = BlackFormulaRepository
.priceAdjoint(FORWARD, STRIKES_INPUT[loopstrike], TIME_TO_EXPIRY, VOLS[loopVols], callput);
double delta = d.getDerivative(0);
double strikeOutput =
BlackFormulaRepository.impliedStrike(delta, callput, FORWARD, TIME_TO_EXPIRY, VOLS[loopVols]);
assertEquals(STRIKES_INPUT[loopstrike], strikeOutput, 1.0E-8,
"Implied strike: (data " + loopstrike + " / " + callput + ")");
}
}
}
}
/**
* Tests the strikes in a range of strikes, volatilities and call/put.
*/
public void impliedStrikeDerivatives() {
double[] delta = new double[] {0.25, -0.25, 0.49};
boolean[] cap = new boolean[] {true, false, true};
double[] forward = new double[] {104, 100, 10};
double[] time = new double[] {2.5, 5.0, 0.5};
double[] vol = new double[] {0.25, 0.10, 0.50};
double shift = 0.000001;
double shiftF = 0.001;
double[] derivatives = new double[4];
for (int loop = 0; loop < delta.length; loop++) {
double strike = BlackFormulaRepository.impliedStrike(delta[loop], cap[loop], forward[loop], time[loop],
vol[loop], derivatives);
double strikeD = BlackFormulaRepository.impliedStrike(delta[loop] + shift, cap[loop], forward[loop],
time[loop], vol[loop]);
assertEquals((strikeD - strike) / shift, derivatives[0], 1.0E-3, "Implied strike: derivative delta");
double strikeF = BlackFormulaRepository.impliedStrike(delta[loop], cap[loop], forward[loop] + shiftF,
time[loop], vol[loop]);
assertEquals((strikeF - strike) / shiftF, derivatives[1], 1.0E-5, "Implied strike: derivative forward");
double strikeT = BlackFormulaRepository.impliedStrike(delta[loop], cap[loop], forward[loop], time[loop] +
shift, vol[loop]);
assertEquals((strikeT - strike) / shift, derivatives[2], 1.0E-4, "Implied strike: derivative time");
double strikeV = BlackFormulaRepository.impliedStrike(delta[loop], cap[loop], forward[loop], time[loop],
vol[loop] + shift);
assertEquals((strikeV - strike) / shift, derivatives[3], 1.0E-3, "Implied strike: derivative volatility");
}
}
/**
* finite difference vs greek methods
*/
public void greeksTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
double[] upStrikes = new double[nStrikes];
double[] dwStrikes = new double[nStrikes];
double upFwd = FORWARD * (1. + DELTA);
double dwFwd = FORWARD * (1. - DELTA);
double upTime = TIME_TO_EXPIRY * (1. + DELTA);
double dwTime = TIME_TO_EXPIRY * (1. - DELTA);
double[] upVOLS = new double[nVols];
double[] dwVOLS = new double[nVols];
for (int i = 0; i < nStrikes; ++i) {
upStrikes[i] = STRIKES_INPUT[i] * (1. + DELTA);
dwStrikes[i] = STRIKES_INPUT[i] * (1. - DELTA);
}
for (int i = 0; i < nVols; ++i) {
upVOLS[i] = VOLS[i] * (1. + DELTA);
dwVOLS[i] = VOLS[i] * (1. - DELTA);
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double finDeltaC =
(BlackFormulaRepository.price(upFwd, STRIKES_INPUT[i], TIME_TO_EXPIRY, VOLS[j], true) - BlackFormulaRepository
.price(dwFwd, STRIKES_INPUT[i], TIME_TO_EXPIRY, VOLS[j], true)) / 2. / FORWARD / DELTA;
double finDeltaP =
(BlackFormulaRepository.price(upFwd, STRIKES_INPUT[i], TIME_TO_EXPIRY, VOLS[j], false) - BlackFormulaRepository
.price(dwFwd, STRIKES_INPUT[i], TIME_TO_EXPIRY, VOLS[j], false)) / 2. / FORWARD / DELTA;
assertEquals(finDeltaC, BlackFormulaRepository.delta(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, VOLS[j], true),
Math.abs(finDeltaC) * DELTA);
assertEquals(finDeltaP,
BlackFormulaRepository.delta(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, VOLS[j], false),
Math.abs(finDeltaP) * DELTA);
double finDualDeltaC = (BlackFormulaRepository
.price(FORWARD, upStrikes[i], TIME_TO_EXPIRY, VOLS[j], true) - BlackFormulaRepository.price(FORWARD,
dwStrikes[i], TIME_TO_EXPIRY, VOLS[j], true)) /
2. / STRIKES_INPUT[i] / DELTA;
double finDualDeltaP = (BlackFormulaRepository.price(FORWARD, upStrikes[i], TIME_TO_EXPIRY, VOLS[j],
false) - BlackFormulaRepository.price(FORWARD, dwStrikes[i], TIME_TO_EXPIRY, VOLS[j], false)) /
2. /
STRIKES_INPUT[i] / DELTA;
assertEquals(finDualDeltaC,
BlackFormulaRepository.dualDelta(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, VOLS[j], true),
Math.abs(finDualDeltaC) * DELTA);
assertEquals(finDualDeltaP,
BlackFormulaRepository.dualDelta(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, VOLS[j], false),
Math.abs(finDualDeltaP) * DELTA);
double finGamma =
(BlackFormulaRepository.delta(upFwd, STRIKES_INPUT[i], TIME_TO_EXPIRY, VOLS[j], true) - BlackFormulaRepository
.delta(dwFwd, STRIKES_INPUT[i], TIME_TO_EXPIRY, VOLS[j], true)) / 2. / FORWARD / DELTA;
assertEquals(finGamma, BlackFormulaRepository.gamma(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, VOLS[j]),
Math.abs(finGamma) * DELTA);
double finDualGamma = (BlackFormulaRepository.dualDelta(FORWARD, upStrikes[i], TIME_TO_EXPIRY, VOLS[j],
true) - BlackFormulaRepository.dualDelta(FORWARD, dwStrikes[i], TIME_TO_EXPIRY, VOLS[j], true)) /
2. /
STRIKES_INPUT[i] / DELTA;
assertEquals(finDualGamma,
BlackFormulaRepository.dualGamma(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, VOLS[j]),
Math.abs(finDualGamma) * DELTA);
double finCrossGamma = (BlackFormulaRepository.dualDelta(upFwd, STRIKES_INPUT[i], TIME_TO_EXPIRY,
VOLS[j], true) - BlackFormulaRepository.dualDelta(dwFwd, STRIKES_INPUT[i], TIME_TO_EXPIRY, VOLS[j], true)) /
2. / FORWARD / DELTA;
assertEquals(finCrossGamma,
BlackFormulaRepository.crossGamma(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, VOLS[j]),
Math.abs(finCrossGamma) * DELTA);
double finThetaC =
-(BlackFormulaRepository.price(FORWARD, STRIKES_INPUT[i], upTime, VOLS[j], true) - BlackFormulaRepository
.price(FORWARD, STRIKES_INPUT[i], dwTime, VOLS[j], true)) / 2. / TIME_TO_EXPIRY / DELTA;
assertEquals(finThetaC,
BlackFormulaRepository.driftlessTheta(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, VOLS[j]),
Math.abs(finThetaC) * DELTA);
double finVega = (BlackFormulaRepository
.price(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, upVOLS[j], true) - BlackFormulaRepository.price(FORWARD,
STRIKES_INPUT[i], TIME_TO_EXPIRY, dwVOLS[j], true)) /
2. / VOLS[j] / DELTA;
assertEquals(finVega, BlackFormulaRepository.vega(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, VOLS[j]),
Math.abs(finVega) * DELTA);
double finVanna = (BlackFormulaRepository.delta(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, upVOLS[j],
true) - BlackFormulaRepository.delta(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, dwVOLS[j], true)) /
2. /
VOLS[j] / DELTA;
assertEquals(finVanna, BlackFormulaRepository.vanna(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, VOLS[j]),
Math.abs(finVanna) * DELTA);
double finDualVanna = (BlackFormulaRepository.dualDelta(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY,
upVOLS[j], true) - BlackFormulaRepository.dualDelta(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, dwVOLS[j],
true)) /
2. / VOLS[j] / DELTA;
assertEquals(finDualVanna,
BlackFormulaRepository.dualVanna(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, VOLS[j]),
Math.abs(finDualVanna) * DELTA);
double finVomma =
(BlackFormulaRepository.vega(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, upVOLS[j]) - BlackFormulaRepository
.vega(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, dwVOLS[j])) / 2. / VOLS[j] / DELTA;
assertEquals(finVomma, BlackFormulaRepository.vomma(FORWARD, STRIKES_INPUT[i], TIME_TO_EXPIRY, VOLS[j]),
Math.abs(finVomma) * DELTA);
}
}
}
/**
* Large/small values for price
*/
public void exPriceTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
double inf = Double.POSITIVE_INFINITY;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.price(1.e-12 * strike, strike, TIME_TO_EXPIRY, vol, true);
double refC1 = BlackFormulaRepository.price(0., strike, TIME_TO_EXPIRY, vol, true);
double resC2 = BlackFormulaRepository.price(1.e12 * strike, strike, TIME_TO_EXPIRY, vol, true);
double refC2 = BlackFormulaRepository.price(inf, strike, TIME_TO_EXPIRY, vol, true);
double resP1 = BlackFormulaRepository.price(1.e-12 * strike, strike, TIME_TO_EXPIRY, vol, false);
double refP1 = BlackFormulaRepository.price(0., strike, TIME_TO_EXPIRY, vol, false);
double resP2 = BlackFormulaRepository.price(1.e12 * strike, strike, TIME_TO_EXPIRY, vol, false);
double refP2 = BlackFormulaRepository.price(inf, strike, TIME_TO_EXPIRY, vol, false);
assertEquals(0., resC1, EPS);
assertEquals(1.e12 * strike - strike, resC2, EPS * 1.e12 * strike);
assertEquals(strike - 1.e-12 * strike, resP1, EPS * strike);
assertEquals(0., resP2, EPS * strike);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-11);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-11);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.price(forward, 1.e-12 * forward, TIME_TO_EXPIRY, vol, true);
double resC2 = BlackFormulaRepository.price(forward, 1.e12 * forward, TIME_TO_EXPIRY, vol, true);
double resP1 = BlackFormulaRepository.price(forward, 1.e-12 * forward, TIME_TO_EXPIRY, vol, false);
double resP2 = BlackFormulaRepository.price(forward, 1.e12 * forward, TIME_TO_EXPIRY, vol, false);
double refC1 = BlackFormulaRepository.price(forward, 0., TIME_TO_EXPIRY, vol, true);
double refC2 = BlackFormulaRepository.price(forward, inf, TIME_TO_EXPIRY, vol, true);
double refP1 = BlackFormulaRepository.price(forward, 0., TIME_TO_EXPIRY, vol, false);
double refP2 = BlackFormulaRepository.price(forward, inf, TIME_TO_EXPIRY, vol, false);
assertEquals(forward, resC1, forward * EPS);
assertEquals(0., resC2, EPS);
assertEquals(1.e12 * forward, resP2, 1.e12 * forward * EPS);
assertEquals(0., resP1, EPS);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.price(FORWARD, strike, 1e-24, vol, true);
double resC2 = BlackFormulaRepository.price(FORWARD, strike, 1e24, vol, true);
double resP1 = BlackFormulaRepository.price(FORWARD, strike, 1e-24, vol, false);
double resP2 = BlackFormulaRepository.price(FORWARD, strike, 1e24, vol, false);
double refC1 = BlackFormulaRepository.price(FORWARD, strike, 0., vol, true);
double refC2 = BlackFormulaRepository.price(FORWARD, strike, inf, vol, true);
double refP1 = BlackFormulaRepository.price(FORWARD, strike, 0., vol, false);
double refP2 = BlackFormulaRepository.price(FORWARD, strike, inf, vol, false);
assertEquals(FORWARD > strike ? FORWARD - strike : 0., resC1, EPS);
assertEquals(FORWARD, resC2, FORWARD * EPS);
assertEquals(strike, resP2, strike * EPS);
assertEquals(FORWARD > strike ? 0. : -FORWARD + strike, resP1, EPS);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.price(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12, true);
double refC1 = BlackFormulaRepository.price(FORWARD, strike, TIME_TO_EXPIRY, 0., true);
double resC2 = BlackFormulaRepository.price(FORWARD, strike, TIME_TO_EXPIRY, 1.e12, true);
double refC2 = BlackFormulaRepository.price(FORWARD, strike, TIME_TO_EXPIRY, inf, true);
double resP1 = BlackFormulaRepository.price(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12, false);
double refP1 = BlackFormulaRepository.price(FORWARD, strike, TIME_TO_EXPIRY, 0., false);
double resP2 = BlackFormulaRepository.price(FORWARD, strike, TIME_TO_EXPIRY, 1.e12, false);
double refP2 = BlackFormulaRepository.price(FORWARD, strike, TIME_TO_EXPIRY, inf, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.price(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol, true);
double resC2 = BlackFormulaRepository.price(1.e-12, 1.e12, TIME_TO_EXPIRY, vol, true);
double resC3 = BlackFormulaRepository.price(1.e12, 1.e-12, TIME_TO_EXPIRY, vol, true);
double resP1 = BlackFormulaRepository.price(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol, false);
double resP2 = BlackFormulaRepository.price(1.e-12, 1.e12, TIME_TO_EXPIRY, vol, false);
double resP3 = BlackFormulaRepository.price(1.e12, 1.e-12, TIME_TO_EXPIRY, vol, false);
double resC4 = BlackFormulaRepository.price(1.e12, 1.e12, TIME_TO_EXPIRY, vol, true);
double resP4 = BlackFormulaRepository.price(1.e12, 1.e12, TIME_TO_EXPIRY, vol, false);
double refC1 = BlackFormulaRepository.price(0., 0., TIME_TO_EXPIRY, vol, true);
double refC2 = BlackFormulaRepository.price(0., inf, TIME_TO_EXPIRY, vol, true);
double refC3 = BlackFormulaRepository.price(inf, 0., TIME_TO_EXPIRY, vol, true);
double refP1 = BlackFormulaRepository.price(0., 0., TIME_TO_EXPIRY, vol, false);
double refP2 = BlackFormulaRepository.price(0., inf, TIME_TO_EXPIRY, vol, false);
double refP3 = BlackFormulaRepository.price(inf, 0., TIME_TO_EXPIRY, vol, false);
double refC4 = BlackFormulaRepository.price(inf, inf, TIME_TO_EXPIRY, vol, true);
double refP4 = BlackFormulaRepository.price(inf, inf, TIME_TO_EXPIRY, vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.price(1.e-12, strike, 1.e-12, vol, true);
double resC2 = BlackFormulaRepository.price(1.e-12, strike, 1.e12, vol, true);
double resC3 = BlackFormulaRepository.price(1.e12, strike, 1.e-12, vol, true);
double resP1 = BlackFormulaRepository.price(1.e-12, strike, 1.e-12, vol, false);
double resP2 = BlackFormulaRepository.price(1.e-12, strike, 1.e12, vol, false);
double resP3 = BlackFormulaRepository.price(1.e12, strike, 1.e-12, vol, false);
double resC4 = BlackFormulaRepository.price(1.e12, strike, 1.e24, vol, true);
double resP4 = BlackFormulaRepository.price(1.e12, strike, 1.e24, vol, false);
double refC1 = BlackFormulaRepository.price(0., strike, 0., vol, true);
double refC2 = BlackFormulaRepository.price(0., strike, inf, vol, true);
double refC3 = BlackFormulaRepository.price(inf, strike, 0., vol, true);
double refP1 = BlackFormulaRepository.price(0., strike, 0., vol, false);
double refP2 = BlackFormulaRepository.price(0., strike, inf, vol, false);
double refP3 = BlackFormulaRepository.price(inf, strike, 0., vol, false);
double refC4 = BlackFormulaRepository.price(inf, strike, inf, vol, true);
double refP4 = BlackFormulaRepository.price(inf, strike, inf, vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.price(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12, true);
double resC2 = BlackFormulaRepository.price(1.e-12, strike, TIME_TO_EXPIRY, 1.e12, true);
double resC3 = BlackFormulaRepository.price(1.e12, strike, TIME_TO_EXPIRY, 1.e-12, true);
double resP1 = BlackFormulaRepository.price(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12, false);
double resP2 = BlackFormulaRepository.price(1.e-12, strike, TIME_TO_EXPIRY, 1.e12, false);
double resP3 = BlackFormulaRepository.price(1.e12, strike, TIME_TO_EXPIRY, 1.e-12, false);
double resC4 = BlackFormulaRepository.price(1.e12, strike, TIME_TO_EXPIRY, 1.e12, true);
double resP4 = BlackFormulaRepository.price(1.e12, strike, TIME_TO_EXPIRY, 1.e12, false);
double refC1 = BlackFormulaRepository.price(0., strike, TIME_TO_EXPIRY, 0., true);
double refC2 = BlackFormulaRepository.price(0., strike, TIME_TO_EXPIRY, inf, true);
double refC3 = BlackFormulaRepository.price(inf, strike, TIME_TO_EXPIRY, 0., true);
double refP1 = BlackFormulaRepository.price(0., strike, TIME_TO_EXPIRY, 0., false);
double refP2 = BlackFormulaRepository.price(0., strike, TIME_TO_EXPIRY, inf, false);
double refP3 = BlackFormulaRepository.price(inf, strike, TIME_TO_EXPIRY, 0., false);
double refC4 = BlackFormulaRepository.price(inf, strike, TIME_TO_EXPIRY, inf, true);
double refP4 = BlackFormulaRepository.price(inf, strike, TIME_TO_EXPIRY, inf, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.price(forward, 1.e-12, 1.e-12, vol, true);
double resC2 = BlackFormulaRepository.price(forward, 1.e-12, 1.e12, vol, true);
double resC3 = BlackFormulaRepository.price(forward, 1.e12, 1.e-12, vol, true);
double resP1 = BlackFormulaRepository.price(forward, 1.e-12, 1.e-12, vol, false);
double resP2 = BlackFormulaRepository.price(forward, 1.e-12, 1.e12, vol, false);
double resP3 = BlackFormulaRepository.price(forward, 1.e12, 1.e-12, vol, false);
double resC4 = BlackFormulaRepository.price(forward, 1.e12, 1.e24, vol, true);
double resP4 = BlackFormulaRepository.price(forward, 1.e12, 1.e24, vol, false);
double refC1 = BlackFormulaRepository.price(forward, 0., 0., vol, true);
double refC2 = BlackFormulaRepository.price(forward, 0., inf, vol, true);
double refC3 = BlackFormulaRepository.price(forward, inf, 0., vol, true);
double refP1 = BlackFormulaRepository.price(forward, 0., 0., vol, false);
double refP2 = BlackFormulaRepository.price(forward, 0., inf, vol, false);
double refP3 = BlackFormulaRepository.price(forward, inf, 0., vol, false);
double refC4 = BlackFormulaRepository.price(forward, inf, inf, vol, true);
double refP4 = BlackFormulaRepository.price(forward, inf, inf, vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double forward = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.price(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12, true);
double resC2 = BlackFormulaRepository.price(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12, true);
double resC3 = BlackFormulaRepository.price(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12, true);
double resP1 = BlackFormulaRepository.price(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12, false);
double resP2 = BlackFormulaRepository.price(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12, false);
double resP3 = BlackFormulaRepository.price(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12, false);
double resC4 = BlackFormulaRepository.price(forward, 1.e12, TIME_TO_EXPIRY, 1.e12, true);
double resP4 = BlackFormulaRepository.price(forward, 1.e12, TIME_TO_EXPIRY, 1.e12, false);
double refC1 = BlackFormulaRepository.price(forward, 0., TIME_TO_EXPIRY, 0., true);
double refC2 = BlackFormulaRepository.price(forward, 0., TIME_TO_EXPIRY, inf, true);
double refC3 = BlackFormulaRepository.price(forward, inf, TIME_TO_EXPIRY, 0., true);
double refP1 = BlackFormulaRepository.price(forward, 0., TIME_TO_EXPIRY, 0., false);
double refP2 = BlackFormulaRepository.price(forward, 0., TIME_TO_EXPIRY, inf, false);
double refP3 = BlackFormulaRepository.price(forward, inf, TIME_TO_EXPIRY, 0., false);
double refC4 = BlackFormulaRepository.price(forward, inf, TIME_TO_EXPIRY, inf, true);
double refP4 = BlackFormulaRepository.price(forward, inf, TIME_TO_EXPIRY, inf, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.price(1.e-12, 1.e-12, 1.e-24, vol, true);
double resC2 = BlackFormulaRepository.price(1.e-12, 1.e-12, 1.e24, vol, true);
double resC3 = BlackFormulaRepository.price(1.e-12, 1.e12, 1.e-24, vol, true);
double resP1 = BlackFormulaRepository.price(1.e-12, 1.e-12, 1.e-24, vol, false);
double resP2 = BlackFormulaRepository.price(1.e-12, 1.e-12, 1.e24, vol, false);
double resP3 = BlackFormulaRepository.price(1.e-12, 1.e12, 1.e-24, vol, false);
double resC4 = BlackFormulaRepository.price(1.e12, 1.e-12, 1.e-24, vol, true);
double resP4 = BlackFormulaRepository.price(1.e12, 1.e-12, 1.e-24, vol, false);
double resC5 = BlackFormulaRepository.price(FORWARD, FORWARD * (1. + 1.e-12), 1.e-24, vol, true);
double resP5 = BlackFormulaRepository.price(FORWARD, FORWARD * (1. + 1.e-12), 1.e-24, vol, false);
double resC6 = BlackFormulaRepository.price(1.e12, 1.e12, 1.e24, vol, true);
double resP6 = BlackFormulaRepository.price(1.e12, 1.e12, 1.e24, vol, false);
double refC1 = BlackFormulaRepository.price(0., 0., 0., vol, true);
double refC2 = BlackFormulaRepository.price(0., 0., inf, vol, true);
double refC3 = BlackFormulaRepository.price(0., inf, 0., vol, true);
double refP1 = BlackFormulaRepository.price(0., 0., 0., vol, false);
double refP2 = BlackFormulaRepository.price(0., 0., inf, vol, false);
double refP3 = BlackFormulaRepository.price(0., inf, 0., vol, false);
double refC4 = BlackFormulaRepository.price(inf, 0., 0., vol, true);
double refP4 = BlackFormulaRepository.price(inf, 0., 0., vol, false);
double refC5 = BlackFormulaRepository.price(FORWARD, FORWARD, 0., vol, true);
double refP5 = BlackFormulaRepository.price(FORWARD, FORWARD, 0., vol, false);
double refC6 = BlackFormulaRepository.price(inf, inf, inf, vol, true);
double refP6 = BlackFormulaRepository.price(inf, inf, inf, vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6};
for (int k = 0; k < 12; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
{
double resC1 = BlackFormulaRepository.price(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, true);
double resC2 = BlackFormulaRepository.price(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12, true);
double resC3 = BlackFormulaRepository.price(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12, true);
double resP1 = BlackFormulaRepository.price(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, false);
double resP2 = BlackFormulaRepository.price(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12, false);
double resP3 = BlackFormulaRepository.price(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12, false);
double resC4 = BlackFormulaRepository.price(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, true);
double resP4 = BlackFormulaRepository.price(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, false);
double resC5 = BlackFormulaRepository.price(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12, true);
double resP5 = BlackFormulaRepository
.price(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12, false);
double refC1 = BlackFormulaRepository.price(0., 0., TIME_TO_EXPIRY, 0., true);
double refC2 = BlackFormulaRepository.price(0., 0., TIME_TO_EXPIRY, inf, true);
double refC3 = BlackFormulaRepository.price(0., inf, TIME_TO_EXPIRY, 0., true);
double refP1 = BlackFormulaRepository.price(0., 0., TIME_TO_EXPIRY, 0., false);
double refP2 = BlackFormulaRepository.price(0., 0., TIME_TO_EXPIRY, inf, false);
double refP3 = BlackFormulaRepository.price(0., inf, TIME_TO_EXPIRY, 0., false);
double refC4 = BlackFormulaRepository.price(inf, 0., TIME_TO_EXPIRY, 0., true);
double refP4 = BlackFormulaRepository.price(inf, 0., TIME_TO_EXPIRY, 0., false);
double refC5 = BlackFormulaRepository.price(FORWARD, FORWARD, TIME_TO_EXPIRY, 1.e-12, true);
double refP5 = BlackFormulaRepository.price(FORWARD, FORWARD, TIME_TO_EXPIRY, 1.e-12, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5};
for (int k = 0; k < 10; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.max(Math.abs(refVec[k]) * 1.e-10, 1.e-10));
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.price(strike, strike, inf, 0., true);
double resP1 = BlackFormulaRepository.price(strike, strike, inf, 0., false);
double refC1 = strike * NORMAL.getCDF(0.5) - strike * NORMAL.getCDF(-0.5);
double refP1 = -strike * NORMAL.getCDF(-0.5) + strike * NORMAL.getCDF(0.5);
double[] resVec = new double[] {resC1, resP1};
double[] refVec = new double[] {refC1, refP1};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.max(Math.abs(refVec[k]) * 1.e-10, 1.e-10));
}
}
}
}
}
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeVolErrorPriceTest() {
BlackFormulaRepository.price(FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, -0.5, true);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeFwdErrorPriceTest() {
BlackFormulaRepository.price(-FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1], true);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeStrikeErrorPriceTest() {
BlackFormulaRepository.price(FORWARD, -STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1], true);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeTimeErrorPriceTest() {
BlackFormulaRepository.price(FORWARD, STRIKES_INPUT[1], -TIME_TO_EXPIRY, VOLS[1], true);
}
/*
* Tests for "delta"
*/
/**
* Large/small value for delta
*/
public void exDeltaTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
double inf = Double.POSITIVE_INFINITY;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.delta(1.e-12 * strike, strike, TIME_TO_EXPIRY, vol, true);
double refC1 = BlackFormulaRepository.delta(0., strike, TIME_TO_EXPIRY, vol, true);
double resC2 = BlackFormulaRepository.delta(1.e12 * strike, strike, TIME_TO_EXPIRY, vol, true);
double refC2 = BlackFormulaRepository.delta(inf, strike, TIME_TO_EXPIRY, vol, true);
double resP1 = BlackFormulaRepository.delta(1.e-12 * strike, strike, TIME_TO_EXPIRY, vol, false);
double refP1 = BlackFormulaRepository.delta(0., strike, TIME_TO_EXPIRY, vol, false);
double resP2 = BlackFormulaRepository.delta(1.e12 * strike, strike, TIME_TO_EXPIRY, vol, false);
double refP2 = BlackFormulaRepository.delta(inf, strike, TIME_TO_EXPIRY, vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-11);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-11);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.delta(forward, 1.e-12 * forward, TIME_TO_EXPIRY, vol, true);
double resC2 = BlackFormulaRepository.delta(forward, 1.e12 * forward, TIME_TO_EXPIRY, vol, true);
double resP1 = BlackFormulaRepository.delta(forward, 1.e-12 * forward, TIME_TO_EXPIRY, vol, false);
double resP2 = BlackFormulaRepository.delta(forward, 1.e12 * forward, TIME_TO_EXPIRY, vol, false);
double refC1 = BlackFormulaRepository.delta(forward, 0., TIME_TO_EXPIRY, vol, true);
double refC2 = BlackFormulaRepository.delta(forward, inf, TIME_TO_EXPIRY, vol, true);
double refP1 = BlackFormulaRepository.delta(forward, 0., TIME_TO_EXPIRY, vol, false);
double refP2 = BlackFormulaRepository.delta(forward, inf, TIME_TO_EXPIRY, vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.delta(FORWARD, strike, 1e-24, vol, true);
double resC2 = BlackFormulaRepository.delta(FORWARD, strike, 1e24, vol, true);
double resP1 = BlackFormulaRepository.delta(FORWARD, strike, 1e-24, vol, false);
double resP2 = BlackFormulaRepository.delta(FORWARD, strike, 1e24, vol, false);
double refC1 = BlackFormulaRepository.delta(FORWARD, strike, 0., vol, true);
double refC2 = BlackFormulaRepository.delta(FORWARD, strike, inf, vol, true);
double refP1 = BlackFormulaRepository.delta(FORWARD, strike, 0., vol, false);
double refP2 = BlackFormulaRepository.delta(FORWARD, strike, inf, vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.delta(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12, true);
double refC1 = BlackFormulaRepository.delta(FORWARD, strike, TIME_TO_EXPIRY, 0., true);
double resC2 = BlackFormulaRepository.delta(FORWARD, strike, TIME_TO_EXPIRY, 1.e12, true);
double refC2 = BlackFormulaRepository.delta(FORWARD, strike, TIME_TO_EXPIRY, inf, true);
double resP1 = BlackFormulaRepository.delta(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12, false);
double refP1 = BlackFormulaRepository.delta(FORWARD, strike, TIME_TO_EXPIRY, 0., false);
double resP2 = BlackFormulaRepository.delta(FORWARD, strike, TIME_TO_EXPIRY, 1.e12, false);
double refP2 = BlackFormulaRepository.delta(FORWARD, strike, TIME_TO_EXPIRY, inf, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.delta(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol, true);
double resC2 = BlackFormulaRepository.delta(1.e-12, 1.e12, TIME_TO_EXPIRY, vol, true);
double resC3 = BlackFormulaRepository.delta(1.e12, 1.e-12, TIME_TO_EXPIRY, vol, true);
double resP1 = BlackFormulaRepository.delta(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol, false);
double resP2 = BlackFormulaRepository.delta(1.e-12, 1.e12, TIME_TO_EXPIRY, vol, false);
double resP3 = BlackFormulaRepository.delta(1.e12, 1.e-12, TIME_TO_EXPIRY, vol, false);
double resC4 = BlackFormulaRepository.delta(1.e12, 1.e12, TIME_TO_EXPIRY, vol, true);
double resP4 = BlackFormulaRepository.delta(1.e12, 1.e12, TIME_TO_EXPIRY, vol, false);
double refC1 = BlackFormulaRepository.delta(0., 0., TIME_TO_EXPIRY, vol, true);
double refC2 = BlackFormulaRepository.delta(0., inf, TIME_TO_EXPIRY, vol, true);
double refC3 = BlackFormulaRepository.delta(inf, 0., TIME_TO_EXPIRY, vol, true);
double refP1 = BlackFormulaRepository.delta(0., 0., TIME_TO_EXPIRY, vol, false);
double refP2 = BlackFormulaRepository.delta(0., inf, TIME_TO_EXPIRY, vol, false);
double refP3 = BlackFormulaRepository.delta(inf, 0., TIME_TO_EXPIRY, vol, false);
double refC4 = BlackFormulaRepository.delta(inf, inf, TIME_TO_EXPIRY, vol, true);
double refP4 = BlackFormulaRepository.delta(inf, inf, TIME_TO_EXPIRY, vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.delta(1.e-12, strike, 1.e-12, vol, true);
double resC2 = BlackFormulaRepository.delta(1.e-12, strike, 1.e12, vol, true);
double resC3 = BlackFormulaRepository.delta(1.e12, strike, 1.e-12, vol, true);
double resP1 = BlackFormulaRepository.delta(1.e-12, strike, 1.e-12, vol, false);
double resP2 = BlackFormulaRepository.delta(1.e-12, strike, 1.e12, vol, false);
double resP3 = BlackFormulaRepository.delta(1.e12, strike, 1.e-12, vol, false);
double resC4 = BlackFormulaRepository.delta(1.e12, strike, 1.e12, vol, true);
double resP4 = BlackFormulaRepository.delta(1.e12, strike, 1.e12, vol, false);
double refC1 = BlackFormulaRepository.delta(0., strike, 0., vol, true);
double refC2 = BlackFormulaRepository.delta(0., strike, inf, vol, true);
double refC3 = BlackFormulaRepository.delta(inf, strike, 0., vol, true);
double refP1 = BlackFormulaRepository.delta(0., strike, 0., vol, false);
double refP2 = BlackFormulaRepository.delta(0., strike, inf, vol, false);
double refP3 = BlackFormulaRepository.delta(inf, strike, 0., vol, false);
double refC4 = BlackFormulaRepository.delta(inf, strike, inf, vol, true);
double refP4 = BlackFormulaRepository.delta(inf, strike, inf, vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.delta(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12, true);
double resC2 = BlackFormulaRepository.delta(1.e-12, strike, TIME_TO_EXPIRY, 1.e12, true);
double resC3 = BlackFormulaRepository.delta(1.e12, strike, TIME_TO_EXPIRY, 1.e-12, true);
double resP1 = BlackFormulaRepository.delta(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12, false);
double resP2 = BlackFormulaRepository.delta(1.e-12, strike, TIME_TO_EXPIRY, 1.e12, false);
double resP3 = BlackFormulaRepository.delta(1.e12, strike, TIME_TO_EXPIRY, 1.e-12, false);
double refC1 = BlackFormulaRepository.delta(0., strike, TIME_TO_EXPIRY, 0., true);
double refC2 = BlackFormulaRepository.delta(0., strike, TIME_TO_EXPIRY, inf, true);
double refC3 = BlackFormulaRepository.delta(inf, strike, TIME_TO_EXPIRY, 0., true);
double refP1 = BlackFormulaRepository.delta(0., strike, TIME_TO_EXPIRY, 0., false);
double refP2 = BlackFormulaRepository.delta(0., strike, TIME_TO_EXPIRY, inf, false);
double refP3 = BlackFormulaRepository.delta(inf, strike, TIME_TO_EXPIRY, 0., false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3};
for (int k = 0; k < 6; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.delta(forward, 1.e-12, 1.e-12, vol, true);
double resC2 = BlackFormulaRepository.delta(forward, 1.e-12, 1.e12, vol, true);
double resC3 = BlackFormulaRepository.delta(forward, 1.e12, 1.e-12, vol, true);
double resP1 = BlackFormulaRepository.delta(forward, 1.e-12, 1.e-12, vol, false);
double resP2 = BlackFormulaRepository.delta(forward, 1.e-12, 1.e12, vol, false);
double resP3 = BlackFormulaRepository.delta(forward, 1.e12, 1.e-12, vol, false);
double resC4 = BlackFormulaRepository.delta(forward, 1.e12, 1.e12, vol, true);
double resP4 = BlackFormulaRepository.delta(forward, 1.e12, 1.e12, vol, false);
double refC1 = BlackFormulaRepository.delta(forward, 0., 0., vol, true);
double refC2 = BlackFormulaRepository.delta(forward, 0., inf, vol, true);
double refC3 = BlackFormulaRepository.delta(forward, inf, 0., vol, true);
double refP1 = BlackFormulaRepository.delta(forward, 0., 0., vol, false);
double refP2 = BlackFormulaRepository.delta(forward, 0., inf, vol, false);
double refP3 = BlackFormulaRepository.delta(forward, inf, 0., vol, false);
double refC4 = BlackFormulaRepository.delta(forward, inf, inf, vol, true);
double refP4 = BlackFormulaRepository.delta(forward, inf, inf, vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double forward = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.delta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12, true);
double resC2 = BlackFormulaRepository.delta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12, true);
double resC3 = BlackFormulaRepository.delta(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12, true);
double resP1 = BlackFormulaRepository.delta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12, false);
double resP2 = BlackFormulaRepository.delta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12, false);
double resP3 = BlackFormulaRepository.delta(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12, false);
double refC1 = BlackFormulaRepository.delta(forward, 0., TIME_TO_EXPIRY, 0., true);
double refC2 = BlackFormulaRepository.delta(forward, 0., TIME_TO_EXPIRY, inf, true);
double refC3 = BlackFormulaRepository.delta(forward, inf, TIME_TO_EXPIRY, 0., true);
double refP1 = BlackFormulaRepository.delta(forward, 0., TIME_TO_EXPIRY, 0., false);
double refP2 = BlackFormulaRepository.delta(forward, 0., TIME_TO_EXPIRY, inf, false);
double refP3 = BlackFormulaRepository.delta(forward, inf, TIME_TO_EXPIRY, 0., false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3};
for (int k = 0; k < 6; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.delta(1.e-12, 1.e-12, 1.e-24, vol, true);
double resC2 = BlackFormulaRepository.delta(1.e-12, 1.e-12, 1.e24, vol, true);
double resC3 = BlackFormulaRepository.delta(1.e-12, 1.e12, 1.e-24, vol, true);
double resP1 = BlackFormulaRepository.delta(1.e-12, 1.e-12, 1.e-24, vol, false);
double resP2 = BlackFormulaRepository.delta(1.e-12, 1.e-12, 1.e24, vol, false);
double resP3 = BlackFormulaRepository.delta(1.e-12, 1.e12, 1.e-24, vol, false);
double resC4 = BlackFormulaRepository.delta(1.e12, 1.e-12, 1.e-24, vol, true);
double resP4 = BlackFormulaRepository.delta(1.e12, 1.e-12, 1.e-24, vol, false);
double resC5 = BlackFormulaRepository.delta(FORWARD, FORWARD * (1. + 1.e-12), 1.e-24, vol, true);
double resP5 = BlackFormulaRepository.delta(FORWARD, FORWARD * (1. + 1.e-12), 1.e-24, vol, false);
double resC6 = BlackFormulaRepository.delta(1.e12, 1.e12, 1.e24, vol, true);
double resP6 = BlackFormulaRepository.delta(1.e12, 1.e12, 1.e24, vol, false);
double resC7 = BlackFormulaRepository.delta(1.e12, 1.e12, 1.e-24, vol, true);
double resP7 = BlackFormulaRepository.delta(1.e12, 1.e12, 1.e-24, vol, false);
double refC1 = BlackFormulaRepository.delta(0., 0., 0., vol, true);
double refC2 = BlackFormulaRepository.delta(0., 0., inf, vol, true);
double refC3 = BlackFormulaRepository.delta(0., inf, 0., vol, true);
double refP1 = BlackFormulaRepository.delta(0., 0., 0., vol, false);
double refP2 = BlackFormulaRepository.delta(0., 0., inf, vol, false);
double refP3 = BlackFormulaRepository.delta(0., inf, 0., vol, false);
double refC4 = BlackFormulaRepository.delta(inf, 0., 0., vol, true);
double refP4 = BlackFormulaRepository.delta(inf, 0., 0., vol, false);
double refC5 = BlackFormulaRepository.delta(FORWARD, FORWARD, 0., vol, true);
double refP5 = BlackFormulaRepository.delta(FORWARD, FORWARD, 0., vol, false);
double refC6 = BlackFormulaRepository.delta(inf, inf, inf, vol, true);
double refP6 = BlackFormulaRepository.delta(inf, inf, inf, vol, false);
double refC7 = BlackFormulaRepository.delta(inf, inf, 0., vol, true);
double refP7 = BlackFormulaRepository.delta(inf, inf, 0., vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7};
for (int k = 0; k < 14; ++k) {
if ((refVec[k] != 0.5) && (refVec[k] != -0.5)) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
{
double resC1 = BlackFormulaRepository.delta(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, true);
double resC2 = BlackFormulaRepository.delta(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12, true);
double resC3 = BlackFormulaRepository.delta(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12, true);
double resP1 = BlackFormulaRepository.delta(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, false);
double resP2 = BlackFormulaRepository.delta(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12, false);
double resP3 = BlackFormulaRepository.delta(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12, false);
double resC4 = BlackFormulaRepository.delta(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, true);
double resP4 = BlackFormulaRepository.delta(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, false);
double resC5 = BlackFormulaRepository.delta(FORWARD, FORWARD * (1. + 1.e-13), TIME_TO_EXPIRY, 1.e-13, true);
double resP5 = BlackFormulaRepository
.delta(FORWARD, FORWARD * (1. + 1.e-13), TIME_TO_EXPIRY, 1.e-13, false);
double refC1 = BlackFormulaRepository.delta(0., 0., TIME_TO_EXPIRY, 0., true);
double refC2 = BlackFormulaRepository.delta(0., 0., TIME_TO_EXPIRY, inf, true);
double refC3 = BlackFormulaRepository.delta(0., inf, TIME_TO_EXPIRY, 0., true);
double refP1 = BlackFormulaRepository.delta(0., 0., TIME_TO_EXPIRY, 0., false);
double refP2 = BlackFormulaRepository.delta(0., 0., TIME_TO_EXPIRY, inf, false);
double refP3 = BlackFormulaRepository.delta(0., inf, TIME_TO_EXPIRY, 0., false);
double refC4 = BlackFormulaRepository.delta(inf, 0., TIME_TO_EXPIRY, 0., true);
double refP4 = BlackFormulaRepository.delta(inf, 0., TIME_TO_EXPIRY, 0., false);
double refC5 = BlackFormulaRepository.delta(FORWARD, FORWARD, TIME_TO_EXPIRY, 0., true);
double refP5 = BlackFormulaRepository.delta(FORWARD, FORWARD, TIME_TO_EXPIRY, 0., false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5};
for (int k = 0; k < 10; ++k) {
if ((refVec[k] != 0.5) && (refVec[k] != -0.5)) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.delta(strike, strike, inf, 0., true);
double resP1 = BlackFormulaRepository.delta(strike, strike, inf, 0., false);
double refC1 = NORMAL.getCDF(0.5);
double refP1 = -NORMAL.getCDF(-0.5);
double[] resVec = new double[] {resC1, resP1};
double[] refVec = new double[] {refC1, refP1};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.max(Math.abs(refVec[k]) * 1.e-10, 1.e-10));
}
}
}
}
}
}
/**
*
*/
public void parityDeltaTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.delta(FORWARD, strike, TIME_TO_EXPIRY, vol, true);
double resP1 = BlackFormulaRepository.delta(FORWARD, strike, TIME_TO_EXPIRY, vol, false);
assertEquals(1., resC1 - resP1, EPS);
}
}
}
/**
*
*/
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeVolErrorDeltaTest() {
BlackFormulaRepository.delta(FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, -0.5, true);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeFwdErrorDeltaTest() {
BlackFormulaRepository.delta(-FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1], true);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeStrikeErrorDeltaTest() {
BlackFormulaRepository.delta(FORWARD, -STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1], true);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeTimeErrorDeltaTest() {
BlackFormulaRepository.delta(FORWARD, STRIKES_INPUT[1], -TIME_TO_EXPIRY, VOLS[1], true);
}
/*
* Tests for "strikeForDelta"
*/
public void strikeForDeltaRecoveryTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.delta(FORWARD, strike, TIME_TO_EXPIRY, vol, true);
double resP1 = BlackFormulaRepository.delta(FORWARD, strike, TIME_TO_EXPIRY, vol, false);
double strRecovC1 = BlackFormulaRepository.strikeForDelta(FORWARD, resC1, TIME_TO_EXPIRY, vol, true);
double strRecovP1 = BlackFormulaRepository.strikeForDelta(FORWARD, resP1, TIME_TO_EXPIRY, vol, false);
assertEquals(strike, strRecovC1, strike * EPS);
assertEquals(strike, strRecovP1, strike * EPS);
}
}
}
/**
* Note that the inverse is not necessarily possible because \pm 1, 0 are not taken by strikeForDelta method
*/
public void exDeltaStrikeForDeltaTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double fwd = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.strikeForDelta(fwd, 1. - 1.e-12, TIME_TO_EXPIRY, vol, true);
double resC2 = BlackFormulaRepository.strikeForDelta(fwd, 1.e-12, TIME_TO_EXPIRY, vol, true);
double resP1 = BlackFormulaRepository.strikeForDelta(fwd, -1. + 1.e-12, TIME_TO_EXPIRY, vol, false);
double resP2 = BlackFormulaRepository.strikeForDelta(fwd, -1.e-12, TIME_TO_EXPIRY, vol, false);
double strRecovC1 = BlackFormulaRepository.delta(fwd, resC1, TIME_TO_EXPIRY, vol, true);
double strRecovC2 = BlackFormulaRepository.delta(fwd, resC2, TIME_TO_EXPIRY, vol, true);
double strRecovP1 = BlackFormulaRepository.delta(fwd, resP1, TIME_TO_EXPIRY, vol, false);
double strRecovP2 = BlackFormulaRepository.delta(fwd, resP2, TIME_TO_EXPIRY, vol, false);
assertEquals(1. - 1.e-12, strRecovC1, EPS);
assertEquals(1.e-12, strRecovC2, EPS);
assertEquals(-1. + 1.e-12, strRecovP1, EPS);
assertEquals(-1.e-12, strRecovP2, EPS);
}
}
}
public void exFwdStrikeForDeltaTest() {
int nVols = VOLS.length;
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.strikeForDelta(1.e12, 1. - 1.e-12, TIME_TO_EXPIRY, vol, true);
double resC2 = BlackFormulaRepository.strikeForDelta(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol, true);
double resP1 = BlackFormulaRepository.strikeForDelta(1.e12, -1.e-12, TIME_TO_EXPIRY, vol, false);
double resP2 = BlackFormulaRepository.strikeForDelta(1.e-12, -1. + 1.e-12, TIME_TO_EXPIRY, vol, false);
double strRecovC1 = BlackFormulaRepository.delta(1.e12, resC1, TIME_TO_EXPIRY, vol, true);
double strRecovC2 = BlackFormulaRepository.delta(1.e-12, resC2, TIME_TO_EXPIRY, vol, true);
double strRecovP1 = BlackFormulaRepository.delta(1.e12, resP1, TIME_TO_EXPIRY, vol, false);
double strRecovP2 = BlackFormulaRepository.delta(1.e-12, resP2, TIME_TO_EXPIRY, vol, false);
assertEquals(1. - 1.e-12, strRecovC1, EPS);
assertEquals(1.e-12, strRecovC2, EPS);
assertEquals(-1.e-12, strRecovP1, EPS);
assertEquals(-1. + 1.e-12, strRecovP2, EPS);
}
}
public void exTimeStrikeForDeltaTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
double red = Math.sqrt(1.e12);
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double fwd = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.strikeForDelta(fwd, 1. - 1.e-12, 1.e-12, vol, true);
double resP1 = BlackFormulaRepository.strikeForDelta(fwd, -0.5, 1.e-12, vol, false);
double strRecovC1 = BlackFormulaRepository.delta(fwd, resC1, 1.e-12, vol, true);
double strRecovP1 = BlackFormulaRepository.delta(fwd, resP1, 1.e-12, vol, false);
assertEquals(1. - 1.e-12, strRecovC1, EPS * red);
/*
* This case is not correctly recovered because strike = infinity is obtained by strikeForDelta, coming from
* exp( 1.e12 ), which always results in delta = 0
*/
assertEquals(-0.5, strRecovP1, EPS * red);
/*
* This case gives strike = infinity
*/
}
}
}
public void exVolStrikeForDeltaTest() {
double small = 1.e-12;
double inf = Double.POSITIVE_INFINITY;
double resC2 = BlackFormulaRepository.strikeForDelta(FORWARD, 1.e-12, TIME_TO_EXPIRY, small, true);
double resP2 = BlackFormulaRepository.strikeForDelta(FORWARD, -1.e-12, TIME_TO_EXPIRY, small, false);
double strRecovC2 = BlackFormulaRepository.delta(FORWARD, resC2, TIME_TO_EXPIRY, small, true);
double strRecovP2 = BlackFormulaRepository.delta(FORWARD, resP2, TIME_TO_EXPIRY, small, false);
double resC3 = BlackFormulaRepository.strikeForDelta(FORWARD, 0.5, inf, 0., true);
double resP3 = BlackFormulaRepository.strikeForDelta(FORWARD, -0.5, inf, 0., false);
double strRecovC3 = BlackFormulaRepository.delta(FORWARD, resC3, inf, 0., true);
double strRecovP3 = BlackFormulaRepository.delta(FORWARD, resP3, inf, 0., false);
assertEquals(1.e-12, strRecovC2, EPS);
assertEquals(-1.e-12, strRecovP2, EPS);
assertEquals(0.5, strRecovC3, EPS);
assertEquals(-0.5, strRecovP3, EPS);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void outOfRangeStrikeForDeltaCall1Test() {
BlackFormulaRepository.strikeForDelta(FORWARD, -0.1, TIME_TO_EXPIRY, VOLS[1], true);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void outOfRangeStrikeForDeltaCall2Test() {
BlackFormulaRepository.strikeForDelta(FORWARD, 1.1, TIME_TO_EXPIRY, VOLS[1], true);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void outOfRangeStrikeForDeltaPut1Test() {
BlackFormulaRepository.strikeForDelta(FORWARD, 0.5, TIME_TO_EXPIRY, VOLS[1], false);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void outOfRangeStrikeForDeltaPut2Test() {
BlackFormulaRepository.strikeForDelta(FORWARD, -1.5, TIME_TO_EXPIRY, VOLS[1], false);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeFwdStrikeForDeltaCall2Test() {
BlackFormulaRepository.strikeForDelta(-FORWARD, 0.5, TIME_TO_EXPIRY, VOLS[1], true);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeTimeStrikeForDeltaPut1Test() {
BlackFormulaRepository.strikeForDelta(FORWARD, 0.5, -TIME_TO_EXPIRY, VOLS[1], true);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeVolStrikeForDeltaPut2Test() {
BlackFormulaRepository.strikeForDelta(FORWARD, 0.5, TIME_TO_EXPIRY, -VOLS[1], true);
}
/*
* Tests for "dualDelta"
*/
/**
* large/small values for dual delta
*/
public void exDualDeltaTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
double inf = Double.POSITIVE_INFINITY;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.dualDelta(1.e-12 * strike, strike, TIME_TO_EXPIRY, vol, true);
double refC1 = BlackFormulaRepository.dualDelta(0., strike, TIME_TO_EXPIRY, vol, true);
double resC2 = BlackFormulaRepository.dualDelta(1.e12 * strike, strike, TIME_TO_EXPIRY, vol, true);
double refC2 = BlackFormulaRepository.dualDelta(inf, strike, TIME_TO_EXPIRY, vol, true);
double resP1 = BlackFormulaRepository.dualDelta(1.e-12 * strike, strike, TIME_TO_EXPIRY, vol, false);
double refP1 = BlackFormulaRepository.dualDelta(0., strike, TIME_TO_EXPIRY, vol, false);
double resP2 = BlackFormulaRepository.dualDelta(1.e12 * strike, strike, TIME_TO_EXPIRY, vol, false);
double refP2 = BlackFormulaRepository.dualDelta(inf, strike, TIME_TO_EXPIRY, vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-11);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-11);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.dualDelta(forward, 1.e-12 * forward, TIME_TO_EXPIRY, vol, true);
double resC2 = BlackFormulaRepository.dualDelta(forward, 1.e12 * forward, TIME_TO_EXPIRY, vol, true);
double resP1 = BlackFormulaRepository.dualDelta(forward, 1.e-12 * forward, TIME_TO_EXPIRY, vol, false);
double resP2 = BlackFormulaRepository.dualDelta(forward, 1.e12 * forward, TIME_TO_EXPIRY, vol, false);
double refC1 = BlackFormulaRepository.dualDelta(forward, 0., TIME_TO_EXPIRY, vol, true);
double refC2 = BlackFormulaRepository.dualDelta(forward, inf, TIME_TO_EXPIRY, vol, true);
double refP1 = BlackFormulaRepository.dualDelta(forward, 0., TIME_TO_EXPIRY, vol, false);
double refP2 = BlackFormulaRepository.dualDelta(forward, inf, TIME_TO_EXPIRY, vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.dualDelta(FORWARD, strike, 1e-24, vol, true);
double resC2 = BlackFormulaRepository.dualDelta(FORWARD, strike, 1e24, vol, true);
double resP1 = BlackFormulaRepository.dualDelta(FORWARD, strike, 1e-24, vol, false);
double resP2 = BlackFormulaRepository.dualDelta(FORWARD, strike, 1e24, vol, false);
double refC1 = BlackFormulaRepository.dualDelta(FORWARD, strike, 0., vol, true);
double refC2 = BlackFormulaRepository.dualDelta(FORWARD, strike, inf, vol, true);
double refP1 = BlackFormulaRepository.dualDelta(FORWARD, strike, 0., vol, false);
double refP2 = BlackFormulaRepository.dualDelta(FORWARD, strike, inf, vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.dualDelta(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12, true);
double refC1 = BlackFormulaRepository.dualDelta(FORWARD, strike, TIME_TO_EXPIRY, 0., true);
double resC2 = BlackFormulaRepository.dualDelta(FORWARD, strike, TIME_TO_EXPIRY, 1.e12, true);
double refC2 = BlackFormulaRepository.dualDelta(FORWARD, strike, TIME_TO_EXPIRY, inf, true);
double resP1 = BlackFormulaRepository.dualDelta(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12, false);
double refP1 = BlackFormulaRepository.dualDelta(FORWARD, strike, TIME_TO_EXPIRY, 0., false);
double resP2 = BlackFormulaRepository.dualDelta(FORWARD, strike, TIME_TO_EXPIRY, 1.e12, false);
double refP2 = BlackFormulaRepository.dualDelta(FORWARD, strike, TIME_TO_EXPIRY, inf, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.dualDelta(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol, true);
double resC2 = BlackFormulaRepository.dualDelta(1.e-12, 1.e12, TIME_TO_EXPIRY, vol, true);
double resC3 = BlackFormulaRepository.dualDelta(1.e12, 1.e-12, TIME_TO_EXPIRY, vol, true);
double resP1 = BlackFormulaRepository.dualDelta(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol, false);
double resP2 = BlackFormulaRepository.dualDelta(1.e-12, 1.e12, TIME_TO_EXPIRY, vol, false);
double resP3 = BlackFormulaRepository.dualDelta(1.e12, 1.e-12, TIME_TO_EXPIRY, vol, false);
double resC4 = BlackFormulaRepository.dualDelta(1.e12, 1.e12, TIME_TO_EXPIRY, vol, true);
double resP4 = BlackFormulaRepository.dualDelta(1.e12, 1.e12, TIME_TO_EXPIRY, vol, false);
double refC1 = BlackFormulaRepository.dualDelta(0., 0., TIME_TO_EXPIRY, vol, true);
double refC2 = BlackFormulaRepository.dualDelta(0., inf, TIME_TO_EXPIRY, vol, true);
double refC3 = BlackFormulaRepository.dualDelta(inf, 0., TIME_TO_EXPIRY, vol, true);
double refP1 = BlackFormulaRepository.dualDelta(0., 0., TIME_TO_EXPIRY, vol, false);
double refP2 = BlackFormulaRepository.dualDelta(0., inf, TIME_TO_EXPIRY, vol, false);
double refP3 = BlackFormulaRepository.dualDelta(inf, 0., TIME_TO_EXPIRY, vol, false);
double refC4 = BlackFormulaRepository.dualDelta(inf, inf, TIME_TO_EXPIRY, vol, true);
double refP4 = BlackFormulaRepository.dualDelta(inf, inf, TIME_TO_EXPIRY, vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.dualDelta(1.e-12, strike, 1.e-12, vol, true);
double resC2 = BlackFormulaRepository.dualDelta(1.e-12, strike, 1.e12, vol, true);
double resC3 = BlackFormulaRepository.dualDelta(1.e12, strike, 1.e-12, vol, true);
double resP1 = BlackFormulaRepository.dualDelta(1.e-12, strike, 1.e-12, vol, false);
double resP2 = BlackFormulaRepository.dualDelta(1.e-12, strike, 1.e12, vol, false);
double resP3 = BlackFormulaRepository.dualDelta(1.e12, strike, 1.e-12, vol, false);
double resC4 = BlackFormulaRepository.dualDelta(1.e12, strike, 1.e12, vol, true);
double resP4 = BlackFormulaRepository.dualDelta(1.e12, strike, 1.e12, vol, false);
double refC1 = BlackFormulaRepository.dualDelta(0., strike, 0., vol, true);
double refC2 = BlackFormulaRepository.dualDelta(0., strike, inf, vol, true);
double refC3 = BlackFormulaRepository.dualDelta(inf, strike, 0., vol, true);
double refP1 = BlackFormulaRepository.dualDelta(0., strike, 0., vol, false);
double refP2 = BlackFormulaRepository.dualDelta(0., strike, inf, vol, false);
double refP3 = BlackFormulaRepository.dualDelta(inf, strike, 0., vol, false);
double refC4 = BlackFormulaRepository.dualDelta(inf, strike, inf, vol, true);
double refP4 = BlackFormulaRepository.dualDelta(inf, strike, inf, vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.dualDelta(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12, true);
double resC2 = BlackFormulaRepository.dualDelta(1.e-12, strike, TIME_TO_EXPIRY, 1.e12, true);
double resC3 = BlackFormulaRepository.dualDelta(1.e12, strike, TIME_TO_EXPIRY, 1.e-12, true);
double resP1 = BlackFormulaRepository.dualDelta(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12, false);
double resP2 = BlackFormulaRepository.dualDelta(1.e-12, strike, TIME_TO_EXPIRY, 1.e12, false);
double resP3 = BlackFormulaRepository.dualDelta(1.e12, strike, TIME_TO_EXPIRY, 1.e-12, false);
double refC1 = BlackFormulaRepository.dualDelta(0., strike, TIME_TO_EXPIRY, 0., true);
double refC2 = BlackFormulaRepository.dualDelta(0., strike, TIME_TO_EXPIRY, inf, true);
double refC3 = BlackFormulaRepository.dualDelta(inf, strike, TIME_TO_EXPIRY, 0., true);
double refP1 = BlackFormulaRepository.dualDelta(0., strike, TIME_TO_EXPIRY, 0., false);
double refP2 = BlackFormulaRepository.dualDelta(0., strike, TIME_TO_EXPIRY, inf, false);
double refP3 = BlackFormulaRepository.dualDelta(inf, strike, TIME_TO_EXPIRY, 0., false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3};
for (int k = 0; k < 6; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.dualDelta(forward, 1.e-12, 1.e-12, vol, true);
double resC2 = BlackFormulaRepository.dualDelta(forward, 1.e-12, 1.e12, vol, true);
double resC3 = BlackFormulaRepository.dualDelta(forward, 1.e12, 1.e-12, vol, true);
double resP1 = BlackFormulaRepository.dualDelta(forward, 1.e-12, 1.e-12, vol, false);
double resP2 = BlackFormulaRepository.dualDelta(forward, 1.e-12, 1.e12, vol, false);
double resP3 = BlackFormulaRepository.dualDelta(forward, 1.e12, 1.e-12, vol, false);
double resC4 = BlackFormulaRepository.dualDelta(forward, 1.e12, 1.e12, vol, true);
double resP4 = BlackFormulaRepository.dualDelta(forward, 1.e12, 1.e12, vol, false);
double refC1 = BlackFormulaRepository.dualDelta(forward, 0., 0., vol, true);
double refC2 = BlackFormulaRepository.dualDelta(forward, 0., inf, vol, true);
double refC3 = BlackFormulaRepository.dualDelta(forward, inf, 0., vol, true);
double refP1 = BlackFormulaRepository.dualDelta(forward, 0., 0., vol, false);
double refP2 = BlackFormulaRepository.dualDelta(forward, 0., inf, vol, false);
double refP3 = BlackFormulaRepository.dualDelta(forward, inf, 0., vol, false);
double refC4 = BlackFormulaRepository.dualDelta(forward, inf, inf, vol, true);
double refP4 = BlackFormulaRepository.dualDelta(forward, inf, inf, vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double forward = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.dualDelta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12, true);
double resC2 = BlackFormulaRepository.dualDelta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12, true);
double resC3 = BlackFormulaRepository.dualDelta(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12, true);
double resP1 = BlackFormulaRepository.dualDelta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12, false);
double resP2 = BlackFormulaRepository.dualDelta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12, false);
double resP3 = BlackFormulaRepository.dualDelta(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12, false);
double refC1 = BlackFormulaRepository.dualDelta(forward, 0., TIME_TO_EXPIRY, 0., true);
double refC2 = BlackFormulaRepository.dualDelta(forward, 0., TIME_TO_EXPIRY, inf, true);
double refC3 = BlackFormulaRepository.dualDelta(forward, inf, TIME_TO_EXPIRY, 0., true);
double refP1 = BlackFormulaRepository.dualDelta(forward, 0., TIME_TO_EXPIRY, 0., false);
double refP2 = BlackFormulaRepository.dualDelta(forward, 0., TIME_TO_EXPIRY, inf, false);
double refP3 = BlackFormulaRepository.dualDelta(forward, inf, TIME_TO_EXPIRY, 0., false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3};
for (int k = 0; k < 6; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.dualDelta(1.e-12, 1.e-12, 1.e-24, vol, true);
double resC2 = BlackFormulaRepository.dualDelta(1.e-12, 1.e-12, 1.e24, vol, true);
double resC3 = BlackFormulaRepository.dualDelta(1.e-12, 1.e12, 1.e-24, vol, true);
double resP1 = BlackFormulaRepository.dualDelta(1.e-12, 1.e-12, 1.e-24, vol, false);
double resP2 = BlackFormulaRepository.dualDelta(1.e-12, 1.e-12, 1.e24, vol, false);
double resP3 = BlackFormulaRepository.dualDelta(1.e-12, 1.e12, 1.e-24, vol, false);
double resC4 = BlackFormulaRepository.dualDelta(1.e12, 1.e-12, 1.e-24, vol, true);
double resP4 = BlackFormulaRepository.dualDelta(1.e12, 1.e-12, 1.e-24, vol, false);
double resC5 = BlackFormulaRepository.dualDelta(FORWARD, FORWARD * (1. + 1.e-12), 1.e-24, vol, true);
double resP5 = BlackFormulaRepository.dualDelta(FORWARD, FORWARD * (1. + 1.e-12), 1.e-24, vol, false);
double resC6 = BlackFormulaRepository.dualDelta(1.e12, 1.e12, 1.e24, vol, true);
double resP6 = BlackFormulaRepository.dualDelta(1.e12, 1.e12, 1.e24, vol, false);
double resC7 = BlackFormulaRepository.dualDelta(1.e12, 1.e12, 1.e-24, vol, true);
double resP7 = BlackFormulaRepository.dualDelta(1.e12, 1.e12, 1.e-24, vol, false);
double refC1 = BlackFormulaRepository.dualDelta(0., 0., 0., vol, true);
double refC2 = BlackFormulaRepository.dualDelta(0., 0., inf, vol, true);
double refC3 = BlackFormulaRepository.dualDelta(0., inf, 0., vol, true);
double refP1 = BlackFormulaRepository.dualDelta(0., 0., 0., vol, false);
double refP2 = BlackFormulaRepository.dualDelta(0., 0., inf, vol, false);
double refP3 = BlackFormulaRepository.dualDelta(0., inf, 0., vol, false);
double refC4 = BlackFormulaRepository.dualDelta(inf, 0., 0., vol, true);
double refP4 = BlackFormulaRepository.dualDelta(inf, 0., 0., vol, false);
double refC5 = BlackFormulaRepository.dualDelta(FORWARD, FORWARD, 0., vol, true);
double refP5 = BlackFormulaRepository.dualDelta(FORWARD, FORWARD, 0., vol, false);
double refC6 = BlackFormulaRepository.dualDelta(inf, inf, inf, vol, true);
double refP6 = BlackFormulaRepository.dualDelta(inf, inf, inf, vol, false);
double refC7 = BlackFormulaRepository.dualDelta(inf, inf, 0., vol, true);
double refP7 = BlackFormulaRepository.dualDelta(inf, inf, 0., vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7};
for (int k = 0; k < 14; ++k) {
if ((refVec[k] != 0.5) && (refVec[k] != -0.5)) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
{
double resC1 = BlackFormulaRepository.dualDelta(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, true);
double resC2 = BlackFormulaRepository.dualDelta(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12, true);
double resC3 = BlackFormulaRepository.dualDelta(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12, true);
double resP1 = BlackFormulaRepository.dualDelta(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, false);
double resP2 = BlackFormulaRepository.dualDelta(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12, false);
double resP3 = BlackFormulaRepository.dualDelta(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12, false);
double resC4 = BlackFormulaRepository.dualDelta(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, true);
double resP4 = BlackFormulaRepository.dualDelta(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, false);
double resC5 = BlackFormulaRepository.dualDelta(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12,
true);
double resP5 = BlackFormulaRepository.dualDelta(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12,
false);
double refC1 = BlackFormulaRepository.dualDelta(0., 0., TIME_TO_EXPIRY, 0., true);
double refC2 = BlackFormulaRepository.dualDelta(0., 0., TIME_TO_EXPIRY, inf, true);
double refC3 = BlackFormulaRepository.dualDelta(0., inf, TIME_TO_EXPIRY, 0., true);
double refP1 = BlackFormulaRepository.dualDelta(0., 0., TIME_TO_EXPIRY, 0., false);
double refP2 = BlackFormulaRepository.dualDelta(0., 0., TIME_TO_EXPIRY, inf, false);
double refP3 = BlackFormulaRepository.dualDelta(0., inf, TIME_TO_EXPIRY, 0., false);
double refC4 = BlackFormulaRepository.dualDelta(inf, 0., TIME_TO_EXPIRY, 0., true);
double refP4 = BlackFormulaRepository.dualDelta(inf, 0., TIME_TO_EXPIRY, 0., false);
double refC5 = BlackFormulaRepository.dualDelta(FORWARD, FORWARD, TIME_TO_EXPIRY, 0., true);
double refP5 = BlackFormulaRepository.dualDelta(FORWARD, FORWARD, TIME_TO_EXPIRY, 0., false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5};
for (int k = 0; k < 10; ++k) {
if ((refVec[k] != 0.5) && (refVec[k] != -0.5)) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.dualDelta(strike, strike, inf, 0., true);
double resP1 = BlackFormulaRepository.dualDelta(strike, strike, inf, 0., false);
double refC1 = -NORMAL.getCDF(-0.5);
double refP1 = NORMAL.getCDF(0.5);
double[] resVec = new double[] {resC1, resP1};
double[] refVec = new double[] {refC1, refP1};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.max(Math.abs(refVec[k]) * 1.e-10, 1.e-10));
}
}
}
}
}
}
public void parityDualDeltaTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.dualDelta(FORWARD, strike, TIME_TO_EXPIRY, vol, true);
double resP1 = BlackFormulaRepository.dualDelta(FORWARD, strike, TIME_TO_EXPIRY, vol, false);
assertEquals(-1., resC1 - resP1, EPS);
}
}
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeVolErrorDualDeltaTest() {
BlackFormulaRepository.dualDelta(FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, -0.5, true);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeFwdErrorDualDeltaTest() {
BlackFormulaRepository.dualDelta(-FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1], true);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeStrikeErrorDualDeltaTest() {
BlackFormulaRepository.dualDelta(FORWARD, -STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1], true);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeTimeErrorDualDeltaTest() {
BlackFormulaRepository.dualDelta(FORWARD, STRIKES_INPUT[1], -TIME_TO_EXPIRY, VOLS[1], true);
}
/*
* Tests for "simpleDelta"
*/
/**
* large/small values
*/
public void exSimpleDeltaTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
double inf = Double.POSITIVE_INFINITY;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.simpleDelta(1.e-12 * strike, strike, TIME_TO_EXPIRY, vol, true);
double refC1 = BlackFormulaRepository.simpleDelta(0., strike, TIME_TO_EXPIRY, vol, true);
double resC2 = BlackFormulaRepository.simpleDelta(1.e12 * strike, strike, TIME_TO_EXPIRY, vol, true);
double refC2 = BlackFormulaRepository.simpleDelta(inf, strike, TIME_TO_EXPIRY, vol, true);
double resP1 = BlackFormulaRepository.simpleDelta(1.e-12 * strike, strike, TIME_TO_EXPIRY, vol, false);
double refP1 = BlackFormulaRepository.simpleDelta(0., strike, TIME_TO_EXPIRY, vol, false);
double resP2 = BlackFormulaRepository.simpleDelta(1.e12 * strike, strike, TIME_TO_EXPIRY, vol, false);
double refP2 = BlackFormulaRepository.simpleDelta(inf, strike, TIME_TO_EXPIRY, vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-11);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-11);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.simpleDelta(forward, 1.e-12 * forward, TIME_TO_EXPIRY, vol, true);
double resC2 = BlackFormulaRepository.simpleDelta(forward, 1.e12 * forward, TIME_TO_EXPIRY, vol, true);
double resP1 = BlackFormulaRepository.simpleDelta(forward, 1.e-12 * forward, TIME_TO_EXPIRY, vol, false);
double resP2 = BlackFormulaRepository.simpleDelta(forward, 1.e12 * forward, TIME_TO_EXPIRY, vol, false);
double refC1 = BlackFormulaRepository.simpleDelta(forward, 0., TIME_TO_EXPIRY, vol, true);
double refC2 = BlackFormulaRepository.simpleDelta(forward, inf, TIME_TO_EXPIRY, vol, true);
double refP1 = BlackFormulaRepository.simpleDelta(forward, 0., TIME_TO_EXPIRY, vol, false);
double refP2 = BlackFormulaRepository.simpleDelta(forward, inf, TIME_TO_EXPIRY, vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.simpleDelta(FORWARD, strike, 1e-24, vol, true);
double resC2 = BlackFormulaRepository.simpleDelta(FORWARD, strike, 1e24, vol, true);
double resP1 = BlackFormulaRepository.simpleDelta(FORWARD, strike, 1e-24, vol, false);
double resP2 = BlackFormulaRepository.simpleDelta(FORWARD, strike, 1e24, vol, false);
double refC1 = BlackFormulaRepository.simpleDelta(FORWARD, strike, 0., vol, true);
double refC2 = BlackFormulaRepository.simpleDelta(FORWARD, strike, inf, vol, true);
double refP1 = BlackFormulaRepository.simpleDelta(FORWARD, strike, 0., vol, false);
double refP2 = BlackFormulaRepository.simpleDelta(FORWARD, strike, inf, vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.simpleDelta(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12, true);
double refC1 = BlackFormulaRepository.simpleDelta(FORWARD, strike, TIME_TO_EXPIRY, 0., true);
double resC2 = BlackFormulaRepository.simpleDelta(FORWARD, strike, TIME_TO_EXPIRY, 1.e12, true);
double refC2 = BlackFormulaRepository.simpleDelta(FORWARD, strike, TIME_TO_EXPIRY, inf, true);
double resP1 = BlackFormulaRepository.simpleDelta(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12, false);
double refP1 = BlackFormulaRepository.simpleDelta(FORWARD, strike, TIME_TO_EXPIRY, 0., false);
double resP2 = BlackFormulaRepository.simpleDelta(FORWARD, strike, TIME_TO_EXPIRY, 1.e12, false);
double refP2 = BlackFormulaRepository.simpleDelta(FORWARD, strike, TIME_TO_EXPIRY, inf, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.simpleDelta(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol, true);
double resC2 = BlackFormulaRepository.simpleDelta(1.e-12, 1.e12, TIME_TO_EXPIRY, vol, true);
double resC3 = BlackFormulaRepository.simpleDelta(1.e12, 1.e-12, TIME_TO_EXPIRY, vol, true);
double resP1 = BlackFormulaRepository.simpleDelta(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol, false);
double resP2 = BlackFormulaRepository.simpleDelta(1.e-12, 1.e12, TIME_TO_EXPIRY, vol, false);
double resP3 = BlackFormulaRepository.simpleDelta(1.e12, 1.e-12, TIME_TO_EXPIRY, vol, false);
double resC4 = BlackFormulaRepository.simpleDelta(1.e12, 1.e12, TIME_TO_EXPIRY, vol, true);
double resP4 = BlackFormulaRepository.simpleDelta(1.e12, 1.e12, TIME_TO_EXPIRY, vol, false);
double refC1 = BlackFormulaRepository.simpleDelta(0., 0., TIME_TO_EXPIRY, vol, true);
double refC2 = BlackFormulaRepository.simpleDelta(0., inf, TIME_TO_EXPIRY, vol, true);
double refC3 = BlackFormulaRepository.simpleDelta(inf, 0., TIME_TO_EXPIRY, vol, true);
double refP1 = BlackFormulaRepository.simpleDelta(0., 0., TIME_TO_EXPIRY, vol, false);
double refP2 = BlackFormulaRepository.simpleDelta(0., inf, TIME_TO_EXPIRY, vol, false);
double refP3 = BlackFormulaRepository.simpleDelta(inf, 0., TIME_TO_EXPIRY, vol, false);
double refC4 = BlackFormulaRepository.simpleDelta(inf, inf, TIME_TO_EXPIRY, vol, true);
double refP4 = BlackFormulaRepository.simpleDelta(inf, inf, TIME_TO_EXPIRY, vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.simpleDelta(1.e-12, strike, 1.e-24, vol, true);
double resC2 = BlackFormulaRepository.simpleDelta(1.e-12, strike, 1.e24, vol, true);
double resC3 = BlackFormulaRepository.simpleDelta(1.e12, strike, 1.e-24, vol, true);
double resP1 = BlackFormulaRepository.simpleDelta(1.e-12, strike, 1.e-24, vol, false);
double resP2 = BlackFormulaRepository.simpleDelta(1.e-12, strike, 1.e24, vol, false);
double resP3 = BlackFormulaRepository.simpleDelta(1.e12, strike, 1.e-24, vol, false);
double resC4 = BlackFormulaRepository.simpleDelta(1.e12, strike, 1.e24, vol, true);
double resP4 = BlackFormulaRepository.simpleDelta(1.e12, strike, 1.e24, vol, false);
double refC1 = BlackFormulaRepository.simpleDelta(0., strike, 0., vol, true);
double refC2 = BlackFormulaRepository.simpleDelta(0., strike, inf, vol, true);
double refC3 = BlackFormulaRepository.simpleDelta(inf, strike, 0., vol, true);
double refP1 = BlackFormulaRepository.simpleDelta(0., strike, 0., vol, false);
double refP2 = BlackFormulaRepository.simpleDelta(0., strike, inf, vol, false);
double refP3 = BlackFormulaRepository.simpleDelta(inf, strike, 0., vol, false);
double refC4 = BlackFormulaRepository.simpleDelta(inf, strike, inf, vol, true);
double refP4 = BlackFormulaRepository.simpleDelta(inf, strike, inf, vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.max(Math.abs(refVec[k]) * 1.e-9, 1.e-9));
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.simpleDelta(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12, true);
double resC2 = BlackFormulaRepository.simpleDelta(1.e-12, strike, TIME_TO_EXPIRY, 1.e12, true);
double resC3 = BlackFormulaRepository.simpleDelta(1.e12, strike, TIME_TO_EXPIRY, 1.e-12, true);
double resP1 = BlackFormulaRepository.simpleDelta(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12, false);
double resP2 = BlackFormulaRepository.simpleDelta(1.e-12, strike, TIME_TO_EXPIRY, 1.e12, false);
double resP3 = BlackFormulaRepository.simpleDelta(1.e12, strike, TIME_TO_EXPIRY, 1.e-12, false);
double refC1 = BlackFormulaRepository.simpleDelta(0., strike, TIME_TO_EXPIRY, 0., true);
double refC2 = BlackFormulaRepository.simpleDelta(0., strike, TIME_TO_EXPIRY, inf, true);
double refC3 = BlackFormulaRepository.simpleDelta(inf, strike, TIME_TO_EXPIRY, 0., true);
double refP1 = BlackFormulaRepository.simpleDelta(0., strike, TIME_TO_EXPIRY, 0., false);
double refP2 = BlackFormulaRepository.simpleDelta(0., strike, TIME_TO_EXPIRY, inf, false);
double refP3 = BlackFormulaRepository.simpleDelta(inf, strike, TIME_TO_EXPIRY, 0., false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3};
for (int k = 0; k < 6; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.simpleDelta(forward, 1.e-12, 1.e-24, vol, true);
double resC2 = BlackFormulaRepository.simpleDelta(forward, 1.e-12, 1.e24, vol, true);
double resC3 = BlackFormulaRepository.simpleDelta(forward, 1.e12, 1.e-24, vol, true);
double resP1 = BlackFormulaRepository.simpleDelta(forward, 1.e-12, 1.e-24, vol, false);
double resP2 = BlackFormulaRepository.simpleDelta(forward, 1.e-12, 1.e24, vol, false);
double resP3 = BlackFormulaRepository.simpleDelta(forward, 1.e12, 1.e-24, vol, false);
double resC4 = BlackFormulaRepository.simpleDelta(forward, 1.e12, 1.e24, vol, true);
double resP4 = BlackFormulaRepository.simpleDelta(forward, 1.e12, 1.e24, vol, false);
double refC1 = BlackFormulaRepository.simpleDelta(forward, 0., 0., vol, true);
double refC2 = BlackFormulaRepository.simpleDelta(forward, 0., inf, vol, true);
double refC3 = BlackFormulaRepository.simpleDelta(forward, inf, 0., vol, true);
double refP1 = BlackFormulaRepository.simpleDelta(forward, 0., 0., vol, false);
double refP2 = BlackFormulaRepository.simpleDelta(forward, 0., inf, vol, false);
double refP3 = BlackFormulaRepository.simpleDelta(forward, inf, 0., vol, false);
double refC4 = BlackFormulaRepository.simpleDelta(forward, inf, inf, vol, true);
double refP4 = BlackFormulaRepository.simpleDelta(forward, inf, inf, vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.max(Math.abs(refVec[k]) * 1.e-9, 1.e-9));
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double forward = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.simpleDelta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12, true);
double resC2 = BlackFormulaRepository.simpleDelta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12, true);
double resC3 = BlackFormulaRepository.simpleDelta(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12, true);
double resP1 = BlackFormulaRepository.simpleDelta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12, false);
double resP2 = BlackFormulaRepository.simpleDelta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12, false);
double resP3 = BlackFormulaRepository.simpleDelta(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12, false);
double refC1 = BlackFormulaRepository.simpleDelta(forward, 0., TIME_TO_EXPIRY, 0., true);
double refC2 = BlackFormulaRepository.simpleDelta(forward, 0., TIME_TO_EXPIRY, inf, true);
double refC3 = BlackFormulaRepository.simpleDelta(forward, inf, TIME_TO_EXPIRY, 0., true);
double refP1 = BlackFormulaRepository.simpleDelta(forward, 0., TIME_TO_EXPIRY, 0., false);
double refP2 = BlackFormulaRepository.simpleDelta(forward, 0., TIME_TO_EXPIRY, inf, false);
double refP3 = BlackFormulaRepository.simpleDelta(forward, inf, TIME_TO_EXPIRY, 0., false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3};
for (int k = 0; k < 6; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.simpleDelta(1.e-12, 1.e-12, 1.e-24, vol, true);
double resC2 = BlackFormulaRepository.simpleDelta(1.e-12, 1.e-12, 1.e24, vol, true);
double resC3 = BlackFormulaRepository.simpleDelta(1.e-12, 1.e12, 1.e-24, vol, true);
double resP1 = BlackFormulaRepository.simpleDelta(1.e-12, 1.e-12, 1.e-24, vol, false);
double resP2 = BlackFormulaRepository.simpleDelta(1.e-12, 1.e-12, 1.e24, vol, false);
double resP3 = BlackFormulaRepository.simpleDelta(1.e-12, 1.e12, 1.e-24, vol, false);
double resC4 = BlackFormulaRepository.simpleDelta(1.e12, 1.e-12, 1.e-24, vol, true);
double resP4 = BlackFormulaRepository.simpleDelta(1.e12, 1.e-12, 1.e-24, vol, false);
double resC5 = BlackFormulaRepository.simpleDelta(FORWARD, FORWARD * (1. + 1.e-12), 1.e-24, vol, true);
double resP5 = BlackFormulaRepository.simpleDelta(FORWARD, FORWARD * (1. + 1.e-12), 1.e-24, vol, false);
double resC6 = BlackFormulaRepository.simpleDelta(1.e12, 1.e12, 1.e24, vol, true);
double resP6 = BlackFormulaRepository.simpleDelta(1.e12, 1.e12, 1.e24, vol, false);
double resC7 = BlackFormulaRepository.simpleDelta(1.e12, 1.e12, 1.e-24, vol, true);
double resP7 = BlackFormulaRepository.simpleDelta(1.e12, 1.e12, 1.e-24, vol, false);
double refC1 = BlackFormulaRepository.simpleDelta(0., 0., 0., vol, true);
double refC2 = BlackFormulaRepository.simpleDelta(0., 0., inf, vol, true);
double refC3 = BlackFormulaRepository.simpleDelta(0., inf, 0., vol, true);
double refP1 = BlackFormulaRepository.simpleDelta(0., 0., 0., vol, false);
double refP2 = BlackFormulaRepository.simpleDelta(0., 0., inf, vol, false);
double refP3 = BlackFormulaRepository.simpleDelta(0., inf, 0., vol, false);
double refC4 = BlackFormulaRepository.simpleDelta(inf, 0., 0., vol, true);
double refP4 = BlackFormulaRepository.simpleDelta(inf, 0., 0., vol, false);
double refC5 = BlackFormulaRepository.simpleDelta(FORWARD, FORWARD, 0., vol, true);
double refP5 = BlackFormulaRepository.simpleDelta(FORWARD, FORWARD, 0., vol, false);
double refC6 = BlackFormulaRepository.simpleDelta(inf, inf, inf, vol, true);
double refP6 = BlackFormulaRepository.simpleDelta(inf, inf, inf, vol, false);
double refC7 = BlackFormulaRepository.simpleDelta(inf, inf, 0., vol, true);
double refP7 = BlackFormulaRepository.simpleDelta(inf, inf, 0., vol, false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7};
for (int k = 0; k < 14; ++k) {
if ((refVec[k] != 0.5) && (refVec[k] != -0.5)) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
{
double resC1 = BlackFormulaRepository.simpleDelta(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, true);
double resC2 = BlackFormulaRepository.simpleDelta(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12, true);
double resC3 = BlackFormulaRepository.simpleDelta(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12, true);
double resP1 = BlackFormulaRepository.simpleDelta(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, false);
double resP2 = BlackFormulaRepository.simpleDelta(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12, false);
double resP3 = BlackFormulaRepository.simpleDelta(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12, false);
double resC4 = BlackFormulaRepository.simpleDelta(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, true);
double resP4 = BlackFormulaRepository.simpleDelta(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, false);
double resC5 = BlackFormulaRepository.simpleDelta(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12,
true);
double resP5 = BlackFormulaRepository.simpleDelta(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12,
false);
double refC1 = BlackFormulaRepository.simpleDelta(0., 0., TIME_TO_EXPIRY, 0., true);
double refC2 = BlackFormulaRepository.simpleDelta(0., 0., TIME_TO_EXPIRY, inf, true);
double refC3 = BlackFormulaRepository.simpleDelta(0., inf, TIME_TO_EXPIRY, 0., true);
double refP1 = BlackFormulaRepository.simpleDelta(0., 0., TIME_TO_EXPIRY, 0., false);
double refP2 = BlackFormulaRepository.simpleDelta(0., 0., TIME_TO_EXPIRY, inf, false);
double refP3 = BlackFormulaRepository.simpleDelta(0., inf, TIME_TO_EXPIRY, 0., false);
double refC4 = BlackFormulaRepository.simpleDelta(inf, 0., TIME_TO_EXPIRY, 0., true);
double refP4 = BlackFormulaRepository.simpleDelta(inf, 0., TIME_TO_EXPIRY, 0., false);
double refC5 = BlackFormulaRepository.simpleDelta(FORWARD, FORWARD, TIME_TO_EXPIRY, 0., true);
double refP5 = BlackFormulaRepository.simpleDelta(FORWARD, FORWARD, TIME_TO_EXPIRY, 0., false);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5};
for (int k = 0; k < 10; ++k) {
if ((refVec[k] != 0.5) && (refVec[k] != -0.5)) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.simpleDelta(strike, strike, inf, 0., true);
double resP1 = BlackFormulaRepository.simpleDelta(strike, strike, inf, 0., false);
double refC1 = NORMAL.getCDF(0.);
double refP1 = -NORMAL.getCDF(0.);
double[] resVec = new double[] {resC1, resP1};
double[] refVec = new double[] {refC1, refP1};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.max(Math.abs(refVec[k]) * 1.e-10, 1.e-10));
}
}
}
}
}
}
public void paritySimpleDeltaTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.simpleDelta(FORWARD, strike, TIME_TO_EXPIRY, vol, true);
double resP1 = BlackFormulaRepository.simpleDelta(FORWARD, strike, TIME_TO_EXPIRY, vol, false);
assertEquals(1., resC1 - resP1, EPS);
}
}
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeVolErrorSimpleDeltaTest() {
BlackFormulaRepository.simpleDelta(FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, -0.5, true);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeFwdErrorSimpleDeltaTest() {
BlackFormulaRepository.simpleDelta(-FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1], true);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeStrikeErrorSimpleDeltaTest() {
BlackFormulaRepository.simpleDelta(FORWARD, -STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1], true);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeTimeErrorSimpleDeltaTest() {
BlackFormulaRepository.simpleDelta(FORWARD, STRIKES_INPUT[1], -TIME_TO_EXPIRY, VOLS[1], true);
}
/*
* Tests for "gamma"
*/
/**
* large/small values
*/
public void exGammaTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
double inf = Double.POSITIVE_INFINITY;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.gamma(1.e-12 * strike, strike, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.gamma(0., strike, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.gamma(1.e12 * strike, strike, TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.gamma(inf, strike, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.gamma(forward, 1.e-12 * forward, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.gamma(forward, 1.e12 * forward, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.gamma(forward, 0., TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.gamma(forward, inf, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.gamma(FORWARD, strike, 1e-24, vol);
double resC2 = BlackFormulaRepository.gamma(FORWARD, strike, 1e24, vol);
double refC1 = BlackFormulaRepository.gamma(FORWARD, strike, 0., vol);
double refC2 = BlackFormulaRepository.gamma(FORWARD, strike, inf, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.gamma(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12);
double refC1 = BlackFormulaRepository.gamma(FORWARD, strike, TIME_TO_EXPIRY, 0.);
double resC2 = BlackFormulaRepository.gamma(FORWARD, strike, TIME_TO_EXPIRY, 1.e12);
double refC2 = BlackFormulaRepository.gamma(FORWARD, strike, TIME_TO_EXPIRY, inf);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.gamma(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.gamma(1.e-12, 1.e12, TIME_TO_EXPIRY, vol);
double resC3 = BlackFormulaRepository.gamma(1.e12, 1.e-12, TIME_TO_EXPIRY, vol);
double resP1 = BlackFormulaRepository.gamma(1.e12, 1.e12, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.gamma(0., 0., TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.gamma(0., inf, TIME_TO_EXPIRY, vol);
double refC3 = BlackFormulaRepository.gamma(inf, 0., TIME_TO_EXPIRY, vol);
double refP1 = BlackFormulaRepository.gamma(inf, inf, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resP1, resC2, resC3};
double[] refVec = new double[] {refC1, refP1, refC2, refC3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.gamma(1.e-12, strike, 1.e-24, vol);
double resC2 = BlackFormulaRepository.gamma(1.e-12, strike, 1.e24, vol);
double resC3 = BlackFormulaRepository.gamma(1.e12, strike, 1.e-24, vol);
double resP1 = BlackFormulaRepository.gamma(1.e12, strike, 1.e24, vol);
double refC1 = BlackFormulaRepository.gamma(0., strike, 0., vol);
double refC2 = BlackFormulaRepository.gamma(0., strike, inf, vol);
double refC3 = BlackFormulaRepository.gamma(inf, strike, 0., vol);
double refP1 = BlackFormulaRepository.gamma(inf, strike, inf, vol);
double[] resVec = new double[] {resC1, resP1, resC2, resC3};
double[] refVec = new double[] {refC1, refP1, refC2, refC3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.gamma(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.gamma(1.e-12, strike, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.gamma(1.e12, strike, TIME_TO_EXPIRY, 1.e-12);
double refC1 = BlackFormulaRepository.gamma(0., strike, TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.gamma(0., strike, TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.gamma(inf, strike, TIME_TO_EXPIRY, 0.);
double[] resVec = new double[] {resC1, resC2, resC3};
double[] refVec = new double[] {refC1, refC2, refC3};
for (int k = 0; k < 3; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.gamma(forward, 1.e-12, 1.e-24, vol);
double resC2 = BlackFormulaRepository.gamma(forward, 1.e-12, 1.e24, vol);
double resC3 = BlackFormulaRepository.gamma(forward, 1.e12, 1.e-24, vol);
double resP1 = BlackFormulaRepository.gamma(forward, 1.e12, 1.e24, vol);
double refC1 = BlackFormulaRepository.gamma(forward, 0., 0., vol);
double refC2 = BlackFormulaRepository.gamma(forward, 0., inf, vol);
double refC3 = BlackFormulaRepository.gamma(forward, inf, 0., vol);
double refP1 = BlackFormulaRepository.gamma(forward, inf, inf, vol);
double[] resVec = new double[] {resC1, resP1, resC2, resC3};
double[] refVec = new double[] {refC1, refP1, refC2, refC3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double forward = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.gamma(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.gamma(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.gamma(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double refC1 = BlackFormulaRepository.gamma(forward, 0., TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.gamma(forward, 0., TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.gamma(forward, inf, TIME_TO_EXPIRY, 0.);
double[] resVec = new double[] {resC1, resC2, resC3};
double[] refVec = new double[] {refC1, refC2, refC3};
for (int k = 0; k < 3; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.gamma(1.e-12, 1.e-12, 1.e-24, vol);
double resC2 = BlackFormulaRepository.gamma(1.e-12, 1.e-12, 1.e24, vol);
double resC3 = BlackFormulaRepository.gamma(1.e-12, 1.e12, 1.e-24, vol);
double resP1 = BlackFormulaRepository.gamma(1.e12, 1.e12, 1.e24, vol);
double resC4 = BlackFormulaRepository.gamma(1.e12, 1.e-12, 1.e-24, vol);
double resC5 = BlackFormulaRepository.gamma(FORWARD, FORWARD, 1.e-24, vol); // / "* (1. + 1.e-12) " removed
double resP2 = BlackFormulaRepository.gamma(1.e12, 1.e12, 1.e-24, vol);
double refC1 = BlackFormulaRepository.gamma(0., 0., 0., vol);
double refC2 = BlackFormulaRepository.gamma(0., 0., inf, vol);
double refC3 = BlackFormulaRepository.gamma(0., inf, 0., vol);
double refP1 = BlackFormulaRepository.gamma(inf, inf, inf, vol);
double refC4 = BlackFormulaRepository.gamma(inf, 0., 0., vol);
double refC5 = BlackFormulaRepository.gamma(FORWARD, FORWARD, 0., vol);
double refP2 = BlackFormulaRepository.gamma(inf, inf, 0., vol);
double[] resVec = new double[] {resC1, resP1, resC2, resC3, resC4, resC5, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refC3, refC4, refC5, refP2};
for (int k = 0; k < 6; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e9);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
{
double resC1 = BlackFormulaRepository.gamma(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.gamma(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.gamma(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double resC4 = BlackFormulaRepository.gamma(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC5 = BlackFormulaRepository.gamma(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12);
double refC1 = BlackFormulaRepository.gamma(0., 0., TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.gamma(0., 0., TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.gamma(0., inf, TIME_TO_EXPIRY, 0.);
double refC4 = BlackFormulaRepository.gamma(inf, 0., TIME_TO_EXPIRY, 0.);
double refC5 = BlackFormulaRepository.gamma(FORWARD, FORWARD, TIME_TO_EXPIRY, 0.);
double[] resVec = new double[] {resC1, resC2, resC3, resC4, resC5};
double[] refVec = new double[] {refC1, refC2, refC3, refC4, refC5};
for (int k = 0; k < 5; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e9);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.gamma(strike, strike, inf, 0.);
double refC1 = NORMAL.getPDF(0.5) / strike;
double[] resVec = new double[] {resC1};
double[] refVec = new double[] {refC1};
for (int k = 0; k < 1; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.max(Math.abs(refVec[k]) * 1.e-10, 1.e-10));
}
}
}
}
}
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeVolErrorGammaTest() {
BlackFormulaRepository.gamma(FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, -0.5);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeFwdErrorGammaTest() {
BlackFormulaRepository.gamma(-FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1]);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeStrikeErrorGammaTest() {
BlackFormulaRepository.gamma(FORWARD, -STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1]);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeTimeErrorGammaTest() {
BlackFormulaRepository.gamma(FORWARD, STRIKES_INPUT[1], -TIME_TO_EXPIRY, VOLS[1]);
}
/*
* Tests for "dualGamma"
*/
/**
* large/small values
*/
public void exDualGammaTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
double inf = Double.POSITIVE_INFINITY;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.dualGamma(1.e-12 * strike, strike, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.dualGamma(0., strike, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.dualGamma(1.e12 * strike, strike, TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.dualGamma(inf, strike, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.dualGamma(forward, 1.e-12 * forward, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.dualGamma(forward, 1.e12 * forward, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.dualGamma(forward, 0., TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.dualGamma(forward, inf, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.dualGamma(FORWARD, strike, 1e-24, vol);
double resC2 = BlackFormulaRepository.dualGamma(FORWARD, strike, 1e24, vol);
double refC1 = BlackFormulaRepository.dualGamma(FORWARD, strike, 0., vol);
double refC2 = BlackFormulaRepository.dualGamma(FORWARD, strike, inf, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.dualGamma(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12);
double refC1 = BlackFormulaRepository.dualGamma(FORWARD, strike, TIME_TO_EXPIRY, 0.);
double resC2 = BlackFormulaRepository.dualGamma(FORWARD, strike, TIME_TO_EXPIRY, 1.e12);
double refC2 = BlackFormulaRepository.dualGamma(FORWARD, strike, TIME_TO_EXPIRY, inf);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.dualGamma(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.dualGamma(1.e-12, 1.e12, TIME_TO_EXPIRY, vol);
double resC3 = BlackFormulaRepository.dualGamma(1.e12, 1.e-12, TIME_TO_EXPIRY, vol);
double resP1 = BlackFormulaRepository.dualGamma(1.e12, 1.e12, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.dualGamma(0., 0., TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.dualGamma(0., inf, TIME_TO_EXPIRY, vol);
double refC3 = BlackFormulaRepository.dualGamma(inf, 0., TIME_TO_EXPIRY, vol);
double refP1 = BlackFormulaRepository.dualGamma(inf, inf, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resP1, resC2, resC3};
double[] refVec = new double[] {refC1, refP1, refC2, refC3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.dualGamma(1.e-12, strike, 1.e-24, vol);
double resC2 = BlackFormulaRepository.dualGamma(1.e-12, strike, 1.e24, vol);
double resC3 = BlackFormulaRepository.dualGamma(1.e12, strike, 1.e-24, vol);
double resP1 = BlackFormulaRepository.dualGamma(1.e12, strike, 1.e24, vol);
double refC1 = BlackFormulaRepository.dualGamma(0., strike, 0., vol);
double refC2 = BlackFormulaRepository.dualGamma(0., strike, inf, vol);
double refC3 = BlackFormulaRepository.dualGamma(inf, strike, 0., vol);
double refP1 = BlackFormulaRepository.dualGamma(inf, strike, inf, vol);
double[] resVec = new double[] {resC1, resP1, resC2, resC3};
double[] refVec = new double[] {refC1, refP1, refC2, refC3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.dualGamma(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.dualGamma(1.e-12, strike, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.dualGamma(1.e12, strike, TIME_TO_EXPIRY, 1.e-12);
double refC1 = BlackFormulaRepository.dualGamma(0., strike, TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.dualGamma(0., strike, TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.dualGamma(inf, strike, TIME_TO_EXPIRY, 0.);
double[] resVec = new double[] {resC1, resC2, resC3};
double[] refVec = new double[] {refC1, refC2, refC3};
for (int k = 0; k < 3; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.dualGamma(forward, 1.e-12, 1.e-24, vol);
double resC2 = BlackFormulaRepository.dualGamma(forward, 1.e-12, 1.e24, vol);
double resC3 = BlackFormulaRepository.dualGamma(forward, 1.e12, 1.e-24, vol);
double resP1 = BlackFormulaRepository.dualGamma(forward, 1.e12, 1.e24, vol);
double refC1 = BlackFormulaRepository.dualGamma(forward, 0., 0., vol);
double refC2 = BlackFormulaRepository.dualGamma(forward, 0., inf, vol);
double refC3 = BlackFormulaRepository.dualGamma(forward, inf, 0., vol);
double refP1 = BlackFormulaRepository.dualGamma(forward, inf, inf, vol);
double[] resVec = new double[] {resC1, resP1, resC2, resC3};
double[] refVec = new double[] {refC1, refP1, refC2, refC3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double forward = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.dualGamma(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.dualGamma(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.dualGamma(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double refC1 = BlackFormulaRepository.dualGamma(forward, 0., TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.dualGamma(forward, 0., TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.dualGamma(forward, inf, TIME_TO_EXPIRY, 0.);
double[] resVec = new double[] {resC1, resC2, resC3};
double[] refVec = new double[] {refC1, refC2, refC3};
for (int k = 0; k < 3; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.dualGamma(1.e-12, 1.e-12, 1.e-24, vol);
double resC2 = BlackFormulaRepository.dualGamma(1.e-12, 1.e-12, 1.e24, vol);
double resC3 = BlackFormulaRepository.dualGamma(1.e-12, 1.e12, 1.e-24, vol);
double resP1 = BlackFormulaRepository.dualGamma(1.e12, 1.e12, 1.e24, vol);
double resC4 = BlackFormulaRepository.dualGamma(1.e12, 1.e-12, 1.e-24, vol);
double resC5 = BlackFormulaRepository.dualGamma(FORWARD, FORWARD, 1.e-24, vol); // / "* (1. + 1.e-12) "
// removed
double resP2 = BlackFormulaRepository.dualGamma(1.e12, 1.e12, 1.e-24, vol);
double refC1 = BlackFormulaRepository.dualGamma(0., 0., 0., vol);
double refC2 = BlackFormulaRepository.dualGamma(0., 0., inf, vol);
double refC3 = BlackFormulaRepository.dualGamma(0., inf, 0., vol);
double refP1 = BlackFormulaRepository.dualGamma(inf, inf, inf, vol);
double refC4 = BlackFormulaRepository.dualGamma(inf, 0., 0., vol);
double refC5 = BlackFormulaRepository.dualGamma(FORWARD, FORWARD, 0., vol);
double refP2 = BlackFormulaRepository.dualGamma(inf, inf, 0., vol);
double[] resVec = new double[] {resC1, resP1, resC2, resC3, resC4, resC5, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refC3, refC4, refC5, refP2};
for (int k = 0; k < 6; ++k) {// k=7 ref value is not accurate due to non-unity of vol
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e9);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
{
double resC1 = BlackFormulaRepository.dualGamma(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.dualGamma(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.dualGamma(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double resC4 = BlackFormulaRepository.dualGamma(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC5 = BlackFormulaRepository.dualGamma(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12);
double refC1 = BlackFormulaRepository.dualGamma(0., 0., TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.dualGamma(0., 0., TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.dualGamma(0., inf, TIME_TO_EXPIRY, 0.);
double refC4 = BlackFormulaRepository.dualGamma(inf, 0., TIME_TO_EXPIRY, 0.);
double refC5 = BlackFormulaRepository.dualGamma(FORWARD, FORWARD, TIME_TO_EXPIRY, 0.);
double[] resVec = new double[] {resC1, resC2, resC3, resC4, resC5};
double[] refVec = new double[] {refC1, refC2, refC3, refC4, refC5};
for (int k = 0; k < 5; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e9);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.dualGamma(strike, strike, inf, 0.);
double refC1 = NORMAL.getPDF(0.5) / strike;
double[] resVec = new double[] {resC1};
double[] refVec = new double[] {refC1};
for (int k = 0; k < 1; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.max(Math.abs(refVec[k]) * 1.e-10, 1.e-10));
}
}
}
}
}
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeVolErrorDualGammaTest() {
BlackFormulaRepository.dualGamma(FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, -0.5);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeFwdErrorDualGammaTest() {
BlackFormulaRepository.dualGamma(-FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1]);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeStrikeErrorDualGammaTest() {
BlackFormulaRepository.dualGamma(FORWARD, -STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1]);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeTimeErrorDualGammaTest() {
BlackFormulaRepository.dualGamma(FORWARD, STRIKES_INPUT[1], -TIME_TO_EXPIRY, VOLS[1]);
}
/*
* crossGamma
*/
/**
* large/small value
*/
public void exCrossGammaTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
double inf = Double.POSITIVE_INFINITY;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.crossGamma(1.e-12 * strike, strike, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.crossGamma(0., strike, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.crossGamma(1.e12 * strike, strike, TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.crossGamma(inf, strike, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.crossGamma(forward, 1.e-12 * forward, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.crossGamma(forward, 1.e12 * forward, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.crossGamma(forward, 0., TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.crossGamma(forward, inf, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.crossGamma(FORWARD, strike, 1e-24, vol);
double resC2 = BlackFormulaRepository.crossGamma(FORWARD, strike, 1e24, vol);
double refC1 = BlackFormulaRepository.crossGamma(FORWARD, strike, 0., vol);
double refC2 = BlackFormulaRepository.crossGamma(FORWARD, strike, inf, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.crossGamma(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12);
double refC1 = BlackFormulaRepository.crossGamma(FORWARD, strike, TIME_TO_EXPIRY, 0.);
double resC2 = BlackFormulaRepository.crossGamma(FORWARD, strike, TIME_TO_EXPIRY, 1.e12);
double refC2 = BlackFormulaRepository.crossGamma(FORWARD, strike, TIME_TO_EXPIRY, inf);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.crossGamma(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.crossGamma(1.e-12, 1.e12, TIME_TO_EXPIRY, vol);
double resC3 = BlackFormulaRepository.crossGamma(1.e12, 1.e-12, TIME_TO_EXPIRY, vol);
double resP1 = BlackFormulaRepository.crossGamma(1.e12, 1.e12, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.crossGamma(0., 0., TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.crossGamma(0., inf, TIME_TO_EXPIRY, vol);
double refC3 = BlackFormulaRepository.crossGamma(inf, 0., TIME_TO_EXPIRY, vol);
double refP1 = BlackFormulaRepository.crossGamma(inf, inf, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resP1, resC2, resC3};
double[] refVec = new double[] {refC1, refP1, refC2, refC3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.crossGamma(1.e-12, strike, 1.e-24, vol);
double resC2 = BlackFormulaRepository.crossGamma(1.e-12, strike, 1.e24, vol);
double resC3 = BlackFormulaRepository.crossGamma(1.e12, strike, 1.e-24, vol);
double resP1 = BlackFormulaRepository.crossGamma(1.e12, strike, 1.e24, vol);
double refC1 = BlackFormulaRepository.crossGamma(0., strike, 0., vol);
double refC2 = BlackFormulaRepository.crossGamma(0., strike, inf, vol);
double refC3 = BlackFormulaRepository.crossGamma(inf, strike, 0., vol);
double refP1 = BlackFormulaRepository.crossGamma(inf, strike, inf, vol);
double[] resVec = new double[] {resC1, resP1, resC2, resC3};
double[] refVec = new double[] {refC1, refP1, refC2, refC3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.crossGamma(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.crossGamma(1.e-12, strike, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.crossGamma(1.e12, strike, TIME_TO_EXPIRY, 1.e-12);
double refC1 = BlackFormulaRepository.crossGamma(0., strike, TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.crossGamma(0., strike, TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.crossGamma(inf, strike, TIME_TO_EXPIRY, 0.);
double[] resVec = new double[] {resC1, resC2, resC3};
double[] refVec = new double[] {refC1, refC2, refC3};
for (int k = 0; k < 3; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.crossGamma(forward, 1.e-12, 1.e-24, vol);
double resC2 = BlackFormulaRepository.crossGamma(forward, 1.e-12, 1.e24, vol);
double resC3 = BlackFormulaRepository.crossGamma(forward, 1.e12, 1.e-24, vol);
double resP1 = BlackFormulaRepository.crossGamma(forward, 1.e12, 1.e24, vol);
double refC1 = BlackFormulaRepository.crossGamma(forward, 0., 0., vol);
double refC2 = BlackFormulaRepository.crossGamma(forward, 0., inf, vol);
double refC3 = BlackFormulaRepository.crossGamma(forward, inf, 0., vol);
double refP1 = BlackFormulaRepository.crossGamma(forward, inf, inf, vol);
double[] resVec = new double[] {resC1, resP1, resC2, resC3};
double[] refVec = new double[] {refC1, refP1, refC2, refC3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double forward = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.crossGamma(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.crossGamma(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.crossGamma(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double refC1 = BlackFormulaRepository.crossGamma(forward, 0., TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.crossGamma(forward, 0., TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.crossGamma(forward, inf, TIME_TO_EXPIRY, 0.);
double[] resVec = new double[] {resC1, resC2, resC3};
double[] refVec = new double[] {refC1, refC2, refC3};
for (int k = 0; k < 3; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.crossGamma(1.e-12, 1.e-12, 1.e-24, vol);
double resC2 = BlackFormulaRepository.crossGamma(1.e-12, 1.e-12, 1.e24, vol);
double resC3 = BlackFormulaRepository.crossGamma(1.e-12, 1.e12, 1.e-24, vol);
double resP1 = BlackFormulaRepository.crossGamma(1.e12, 1.e12, 1.e24, vol);
double resC4 = BlackFormulaRepository.crossGamma(1.e12, 1.e-12, 1.e-24, vol);
double resC5 = BlackFormulaRepository.crossGamma(FORWARD, FORWARD, 1.e-24, vol); // / "* (1. + 1.e-12) "
// removed
double resP2 = BlackFormulaRepository.crossGamma(1.e12, 1.e12, 1.e-24, vol);
double refC1 = BlackFormulaRepository.crossGamma(0., 0., 0., vol);
double refC2 = BlackFormulaRepository.crossGamma(0., 0., inf, vol);
double refC3 = BlackFormulaRepository.crossGamma(0., inf, 0., vol);
double refP1 = BlackFormulaRepository.crossGamma(inf, inf, inf, vol);
double refC4 = BlackFormulaRepository.crossGamma(inf, 0., 0., vol);
double refC5 = BlackFormulaRepository.crossGamma(FORWARD, FORWARD, 0., vol);
double refP2 = BlackFormulaRepository.crossGamma(inf, inf, 0., vol);
double[] resVec = new double[] {resC1, resP1, resC2, resC3, resC4, resC5, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refC3, refC4, refC5, refP2};
for (int k = 0; k < 6; ++k) {// k=7 ref value is not accurate due to non-unity of vol
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e9);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e9);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
{
double resC1 = BlackFormulaRepository.crossGamma(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.crossGamma(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.crossGamma(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double resC4 = BlackFormulaRepository.crossGamma(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC5 = BlackFormulaRepository.crossGamma(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12);
double refC1 = BlackFormulaRepository.crossGamma(0., 0., TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.crossGamma(0., 0., TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.crossGamma(0., inf, TIME_TO_EXPIRY, 0.);
double refC4 = BlackFormulaRepository.crossGamma(inf, 0., TIME_TO_EXPIRY, 0.);
double refC5 = BlackFormulaRepository.crossGamma(FORWARD, FORWARD, TIME_TO_EXPIRY, 0.);
double[] resVec = new double[] {resC1, resC2, resC3, resC4, resC5};
double[] refVec = new double[] {refC1, refC2, refC3, refC4, refC5};
for (int k = 0; k < 5; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e9);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e9);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.crossGamma(strike, strike, inf, 0.);
double refC1 = -NORMAL.getPDF(0.5) / strike;
double[] resVec = new double[] {resC1};
double[] refVec = new double[] {refC1};
for (int k = 0; k < 1; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.max(Math.abs(refVec[k]) * 1.e-10, 1.e-10));
}
}
}
}
}
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeVolErrorCrossGammaTest() {
BlackFormulaRepository.crossGamma(FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, -0.5);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeFwdErrorCrossGammaTest() {
BlackFormulaRepository.crossGamma(-FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1]);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeStrikeErrorCrossGammaTest() {
BlackFormulaRepository.crossGamma(FORWARD, -STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1]);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeTimeErrorCrossGammaTest() {
BlackFormulaRepository.crossGamma(FORWARD, STRIKES_INPUT[1], -TIME_TO_EXPIRY, VOLS[1]);
}
/*
* Theta tests
*/
/**
* large/small input
*/
public void exThetaTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
double inf = Double.POSITIVE_INFINITY;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.theta(1.e-12 * strike, strike, TIME_TO_EXPIRY, vol, true, 0.05);
double refC1 = BlackFormulaRepository.theta(0., strike, TIME_TO_EXPIRY, vol, true, 0.05);
double resC2 = BlackFormulaRepository.theta(1.e12 * strike, strike, TIME_TO_EXPIRY, vol, true, 0.05);
double refC2 = BlackFormulaRepository.theta(inf, strike, TIME_TO_EXPIRY, vol, true, 0.05);
double resP1 = BlackFormulaRepository.theta(1.e-12 * strike, strike, TIME_TO_EXPIRY, vol, false, 0.05);
double refP1 = BlackFormulaRepository.theta(0., strike, TIME_TO_EXPIRY, vol, false, 0.05);
double resP2 = BlackFormulaRepository.theta(1.e12 * strike, strike, TIME_TO_EXPIRY, vol, false, 0.05);
double refP2 = BlackFormulaRepository.theta(inf, strike, TIME_TO_EXPIRY, vol, false, 0.05);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.theta(forward, 1.e-14 * forward, TIME_TO_EXPIRY, vol, true, 0.05);
double resC2 = BlackFormulaRepository.theta(forward, 1.e12 * forward, TIME_TO_EXPIRY, vol, true, 0.05);
double resP1 = BlackFormulaRepository.theta(forward, 1.e-12 * forward, TIME_TO_EXPIRY, vol, false, 0.05);
double resP2 = BlackFormulaRepository.theta(forward, 1.e12 * forward, TIME_TO_EXPIRY, vol, false, 0.05);
double refC1 = BlackFormulaRepository.theta(forward, 0., TIME_TO_EXPIRY, vol, true, 0.05);
double refC2 = BlackFormulaRepository.theta(forward, inf, TIME_TO_EXPIRY, vol, true, 0.05);
double refP1 = BlackFormulaRepository.theta(forward, 0., TIME_TO_EXPIRY, vol, false, 0.05);
double refP2 = BlackFormulaRepository.theta(forward, inf, TIME_TO_EXPIRY, vol, false, 0.05);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.theta(FORWARD, strike, 1e-12, vol, true, 0.05);
double resC2 = BlackFormulaRepository.theta(FORWARD, strike, 1e12, vol, true, 0.05);
double resP1 = BlackFormulaRepository.theta(FORWARD, strike, 1e-12, vol, false, 0.05);
double resP2 = BlackFormulaRepository.theta(FORWARD, strike, 1e12, vol, false, 0.05);
double refC1 = BlackFormulaRepository.theta(FORWARD, strike, 0., vol, true, 0.05);
double refC2 = BlackFormulaRepository.theta(FORWARD, strike, inf, vol, true, 0.05);
double refP1 = BlackFormulaRepository.theta(FORWARD, strike, 0., vol, false, 0.05);
double refP2 = BlackFormulaRepository.theta(FORWARD, strike, inf, vol, false, 0.05);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, 1.e-24, true, 0.05);
double refC1 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, 0., true, 0.05);
double resC2 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, 1.e24, true, 0.05);
double refC2 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, inf, true, 0.05);
double resP1 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, 1.e-24, false, 0.05);
double refP1 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, 0., false, 0.05);
double resP2 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, 1.e24, false, 0.05);
double refP2 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, inf, false, 0.05);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, vol, true, 1.e-12);
double resP1 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, vol, false, 1.e-12);
double refC1 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, vol, true, 0.);
double refP1 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, vol, false, 0.);
double resC2 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, vol, true, 1.e12);
double resP2 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, vol, false, 1.e12);
double refC2 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, vol, true, inf);
double refP2 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, vol, false, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e8);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e9);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.max(Math.abs(refVec[k]) * 1.e-9, 1.e-9));
}
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.theta(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol, true, 0.05);
double resC2 = BlackFormulaRepository.theta(1.e-12, 1.e12, TIME_TO_EXPIRY, vol, true, 0.05);
double resC3 = BlackFormulaRepository.theta(1.e12, 1.e-12, TIME_TO_EXPIRY, vol, true, 0.05);
double resP1 = BlackFormulaRepository.theta(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol, false, 0.05);
double resP2 = BlackFormulaRepository.theta(1.e-12, 1.e12, TIME_TO_EXPIRY, vol, false, 0.05);
double resP3 = BlackFormulaRepository.theta(1.e12, 1.e-12, TIME_TO_EXPIRY, vol, false, 0.05);
double resC4 = BlackFormulaRepository.theta(1.e12, 1.e12, TIME_TO_EXPIRY, vol, true, 0.05);
double resP4 = BlackFormulaRepository.theta(1.e12, 1.e12, TIME_TO_EXPIRY, vol, false, 0.05);
double resC5 = BlackFormulaRepository.theta(1.e10, 1.e11, TIME_TO_EXPIRY, vol, true, 0.05);
double resP5 = BlackFormulaRepository.theta(1.e11, 1.e10, TIME_TO_EXPIRY, vol, false, 0.05);
double refC1 = BlackFormulaRepository.theta(0., 0., TIME_TO_EXPIRY, vol, true, 0.05);
double refC2 = BlackFormulaRepository.theta(0., inf, TIME_TO_EXPIRY, vol, true, 0.05);
double refC3 = BlackFormulaRepository.theta(inf, 0., TIME_TO_EXPIRY, vol, true, 0.05);
double refP1 = BlackFormulaRepository.theta(0., 0., TIME_TO_EXPIRY, vol, false, 0.05);
double refP2 = BlackFormulaRepository.theta(0., inf, TIME_TO_EXPIRY, vol, false, 0.05);
double refP3 = BlackFormulaRepository.theta(inf, 0., TIME_TO_EXPIRY, vol, false, 0.05);
double refC4 = BlackFormulaRepository.theta(inf, inf, TIME_TO_EXPIRY, vol, true, 0.05);
double refP4 = BlackFormulaRepository.theta(inf, inf, TIME_TO_EXPIRY, vol, false, 0.05);
double refC5 = BlackFormulaRepository.theta(1.e15, 1.e16, TIME_TO_EXPIRY, vol, true, 0.05);
double refP5 = BlackFormulaRepository.theta(1.e16, 1.e15, TIME_TO_EXPIRY, vol, false, 0.05);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5};
for (int k = 0; k < 6; ++k) {// ref values
if (k != 6 && k != 7) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e8);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e9);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.theta(1.e-12, strike, 1.e-24, vol, true, 0.05);
double resC2 = BlackFormulaRepository.theta(1.e-12, strike, 1.e24, vol, true, 0.05);
double resC3 = BlackFormulaRepository.theta(1.e12, strike, 1.e-24, vol, true, 0.05);
double resP1 = BlackFormulaRepository.theta(1.e-12, strike, 1.e-24, vol, false, 0.05);
double resP2 = BlackFormulaRepository.theta(1.e-12, strike, 1.e24, vol, false, 0.05);
double resP3 = BlackFormulaRepository.theta(1.e12, strike, 1.e-24, vol, false, 0.05);
double resC4 = BlackFormulaRepository.theta(1.e12, strike, 1.e24, vol, true, 0.05);
double resP4 = BlackFormulaRepository.theta(1.e12, strike, 1.e24, vol, false, 0.05);
double refC1 = BlackFormulaRepository.theta(0., strike, 0., vol, true, 0.05);
double refC2 = BlackFormulaRepository.theta(0., strike, inf, vol, true, 0.05);
double refC3 = BlackFormulaRepository.theta(inf, strike, 0., vol, true, 0.05);
double refP1 = BlackFormulaRepository.theta(0., strike, 0., vol, false, 0.05);
double refP2 = BlackFormulaRepository.theta(0., strike, inf, vol, false, 0.05);
double refP3 = BlackFormulaRepository.theta(inf, strike, 0., vol, false, 0.05);
double refC4 = BlackFormulaRepository.theta(inf, strike, inf, vol, true, 0.05);
double refP4 = BlackFormulaRepository.theta(inf, strike, inf, vol, false, 0.05);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.theta(1.e-12, strike, TIME_TO_EXPIRY, 1.e-24, true, 0.05);
double resC2 = BlackFormulaRepository.theta(1.e-12, strike, TIME_TO_EXPIRY, 1.e24, true, 0.05);
double resC3 = BlackFormulaRepository.theta(1.e12, strike, TIME_TO_EXPIRY, 1.e-24, true, 0.05);
double resP1 = BlackFormulaRepository.theta(1.e-12, strike, TIME_TO_EXPIRY, 1.e-24, false, 0.05);
double resP2 = BlackFormulaRepository.theta(1.e-12, strike, TIME_TO_EXPIRY, 1.e24, false, 0.05);
double resP3 = BlackFormulaRepository.theta(1.e12, strike, TIME_TO_EXPIRY, 1.e-24, false, 0.05);
double resC4 = BlackFormulaRepository.theta(1.e12, strike, TIME_TO_EXPIRY, 1.e24, true, 0.05);
double resP4 = BlackFormulaRepository.theta(1.e12, strike, TIME_TO_EXPIRY, 1.e24, false, 0.05);
double refC1 = BlackFormulaRepository.theta(0., strike, TIME_TO_EXPIRY, 0., true, 0.05);
double refC2 = BlackFormulaRepository.theta(0., strike, TIME_TO_EXPIRY, inf, true, 0.05);
double refC3 = BlackFormulaRepository.theta(inf, strike, TIME_TO_EXPIRY, 0., true, 0.05);
double refP1 = BlackFormulaRepository.theta(0., strike, TIME_TO_EXPIRY, 0., false, 0.05);
double refP2 = BlackFormulaRepository.theta(0., strike, TIME_TO_EXPIRY, inf, false, 0.05);
double refP3 = BlackFormulaRepository.theta(inf, strike, TIME_TO_EXPIRY, 0., false, 0.05);
double refC4 = BlackFormulaRepository.theta(inf, strike, TIME_TO_EXPIRY, inf, true, 0.05);
double refP4 = BlackFormulaRepository.theta(inf, strike, TIME_TO_EXPIRY, inf, false, 0.05);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.theta(forward, 1.e-12, 1.e-24, vol, true, 0.05);
double resC2 = BlackFormulaRepository.theta(forward, 1.e-12, 1.e24, vol, true, 0.05);
double resC3 = BlackFormulaRepository.theta(forward, 1.e12, 1.e-24, vol, true, 0.05);
double resP1 = BlackFormulaRepository.theta(forward, 1.e-12, 1.e-24, vol, false, 0.05);
double resP2 = BlackFormulaRepository.theta(forward, 1.e-12, 1.e24, vol, false, 0.05);
double resP3 = BlackFormulaRepository.theta(forward, 1.e12, 1.e-24, vol, false, 0.05);
double resC4 = BlackFormulaRepository.theta(forward, 1.e12, 1.e24, vol, true, 0.05);
double resP4 = BlackFormulaRepository.theta(forward, 1.e12, 1.e24, vol, false, 0.05);
double refC1 = BlackFormulaRepository.theta(forward, 0., 0., vol, true, 0.05);
double refC2 = BlackFormulaRepository.theta(forward, 0., inf, vol, true, 0.05);
double refC3 = BlackFormulaRepository.theta(forward, inf, 0., vol, true, 0.05);
double refP1 = BlackFormulaRepository.theta(forward, 0., 0., vol, false, 0.05);
double refP2 = BlackFormulaRepository.theta(forward, 0., inf, vol, false, 0.05);
double refP3 = BlackFormulaRepository.theta(forward, inf, 0., vol, false, 0.05);
double refC4 = BlackFormulaRepository.theta(forward, inf, inf, vol, true, 0.05);
double refP4 = BlackFormulaRepository.theta(forward, inf, inf, vol, false, 0.05);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double forward = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.theta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12, true, 0.05);
double resC2 = BlackFormulaRepository.theta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12, true, 0.05);
double resC3 = BlackFormulaRepository.theta(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12, true, 0.05);
double resP1 = BlackFormulaRepository.theta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12, false, 0.05);
double resP2 = BlackFormulaRepository.theta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12, false, 0.05);
double resP3 = BlackFormulaRepository.theta(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12, false, 0.05);
double resC4 = BlackFormulaRepository.theta(forward, 1.e12, TIME_TO_EXPIRY, 1.e12, true, 0.05);
double resP4 = BlackFormulaRepository.theta(forward, 1.e12, TIME_TO_EXPIRY, 1.e12, false, 0.05);
double refC1 = BlackFormulaRepository.theta(forward, 0., TIME_TO_EXPIRY, 0., true, 0.05);
double refC2 = BlackFormulaRepository.theta(forward, 0., TIME_TO_EXPIRY, inf, true, 0.05);
double refC3 = BlackFormulaRepository.theta(forward, inf, TIME_TO_EXPIRY, 0., true, 0.05);
double refP1 = BlackFormulaRepository.theta(forward, 0., TIME_TO_EXPIRY, 0., false, 0.05);
double refP2 = BlackFormulaRepository.theta(forward, 0., TIME_TO_EXPIRY, inf, false, 0.05);
double refP3 = BlackFormulaRepository.theta(forward, inf, TIME_TO_EXPIRY, 0., false, 0.05);
double refC4 = BlackFormulaRepository.theta(forward, inf, TIME_TO_EXPIRY, inf, true, 0.05);
double refP4 = BlackFormulaRepository.theta(forward, inf, TIME_TO_EXPIRY, inf, false, 0.05);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.theta(FORWARD, strike, 1.e-12, vol, true, 1.e-12);
double resC2 = BlackFormulaRepository.theta(FORWARD, strike, 1.e12, vol, true, 1.e-12);
double resP1 = BlackFormulaRepository.theta(FORWARD, strike, 1.e-12, vol, false, 1.e-12);
double resP2 = BlackFormulaRepository.theta(FORWARD, strike, 1.e12, vol, false, 1.e-12);
double resC3 = BlackFormulaRepository.theta(FORWARD, strike, 1.e12, vol, true, 1.e12);
double resP3 = BlackFormulaRepository.theta(FORWARD, strike, 1.e12, vol, false, 1.e12);
double resC4 = BlackFormulaRepository.theta(FORWARD, strike, 1.e-12, vol, true, 1.e12);
double resP4 = BlackFormulaRepository.theta(FORWARD, strike, 1.e-12, vol, false, 1.e12);
double refC1 = BlackFormulaRepository.theta(FORWARD, strike, 0., vol, true, 0.);
double refC2 = BlackFormulaRepository.theta(FORWARD, strike, inf, vol, true, 0.);
double refP1 = BlackFormulaRepository.theta(FORWARD, strike, 0., vol, false, 0.);
double refP2 = BlackFormulaRepository.theta(FORWARD, strike, inf, vol, false, 0.);
double refC3 = BlackFormulaRepository.theta(FORWARD, strike, inf, vol, true, inf);
double refP3 = BlackFormulaRepository.theta(FORWARD, strike, inf, vol, false, inf);
double refC4 = BlackFormulaRepository.theta(FORWARD, strike, 0., vol, true, inf);
double refP4 = BlackFormulaRepository.theta(FORWARD, strike, 0., vol, false, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 6; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.theta(strike, 1.e-12, TIME_TO_EXPIRY, vol, true, 1.e-12);
double resC2 = BlackFormulaRepository.theta(strike, 1.e12, TIME_TO_EXPIRY, vol, true, 1.e-12);
double resP1 = BlackFormulaRepository.theta(strike, 1.e-12, TIME_TO_EXPIRY, vol, false, 1.e-12);
double resP2 = BlackFormulaRepository.theta(strike, 1.e12, TIME_TO_EXPIRY, vol, false, 1.e-12);
double resC3 = BlackFormulaRepository.theta(strike, 1.e12, TIME_TO_EXPIRY, vol, true, 1.e12);
double resP3 = BlackFormulaRepository.theta(strike, 1.e12, TIME_TO_EXPIRY, vol, false, 1.e12);
double refC1 = BlackFormulaRepository.theta(strike, 0., TIME_TO_EXPIRY, vol, true, 0.);
double refC2 = BlackFormulaRepository.theta(strike, inf, TIME_TO_EXPIRY, vol, true, 0.);
double refP1 = BlackFormulaRepository.theta(strike, 0., TIME_TO_EXPIRY, vol, false, 0.);
double refP2 = BlackFormulaRepository.theta(strike, inf, TIME_TO_EXPIRY, vol, false, 0.);
double refC3 = BlackFormulaRepository.theta(strike, inf, TIME_TO_EXPIRY, vol, true, inf);
double refP3 = BlackFormulaRepository.theta(strike, inf, TIME_TO_EXPIRY, vol, false, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3};
for (int k = 0; k < 6; ++k) {
if (k != 3) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.max(Math.abs(refVec[k]) * 1.e-9, 1.e-9));
}
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12, true, 1.e-12);
double resC2 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, 1.e12, true, 1.e-12);
double resP1 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12, false, 1.e-12);
double resP2 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, 1.e12, false, 1.e-12);
double resC3 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, 1.e12, true, 1.e12);
double resP3 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, 1.e12, false, 1.e12);
double resC4 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12, true, 1.e12);
double resP4 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12, false, 1.e12);
double refC1 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, 0., true, 0.);
double refC2 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, inf, true, 0.);
double refP1 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, 0., false, 0.);
double refP2 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, inf, false, 0.);
double refC3 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, inf, true, inf);
double refP3 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, inf, false, inf);
double refC4 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, 0., true, inf);
double refP4 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, 0., false, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 6; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e9);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.theta(1.e-12, strike, TIME_TO_EXPIRY, vol, true, 1.e-12);
double resC2 = BlackFormulaRepository.theta(1.e12, strike, TIME_TO_EXPIRY, vol, true, 1.e-12);
double resP1 = BlackFormulaRepository.theta(1.e-12, strike, TIME_TO_EXPIRY, vol, false, 1.e-12);
double resP2 = BlackFormulaRepository.theta(1.e12, strike, TIME_TO_EXPIRY, vol, false, 1.e-12);
double resC3 = BlackFormulaRepository.theta(1.e12, strike, TIME_TO_EXPIRY, vol, true, 1.e12);
double resP3 = BlackFormulaRepository.theta(1.e12, strike, TIME_TO_EXPIRY, vol, false, 1.e12);
double resC4 = BlackFormulaRepository.theta(1.e-12, strike, TIME_TO_EXPIRY, vol, true, 1.e12);
double resP4 = BlackFormulaRepository.theta(1.e-12, strike, TIME_TO_EXPIRY, vol, false, 1.e12);
double refC1 = BlackFormulaRepository.theta(0., strike, TIME_TO_EXPIRY, vol, true, 0.);
double refC2 = BlackFormulaRepository.theta(inf, strike, TIME_TO_EXPIRY, vol, true, 0.);
double refP1 = BlackFormulaRepository.theta(0., strike, TIME_TO_EXPIRY, vol, false, 0.);
double refP2 = BlackFormulaRepository.theta(inf, strike, TIME_TO_EXPIRY, vol, false, 0.);
double refC3 = BlackFormulaRepository.theta(inf, strike, TIME_TO_EXPIRY, vol, true, inf);
double refP3 = BlackFormulaRepository.theta(inf, strike, TIME_TO_EXPIRY, vol, false, inf);
double refC4 = BlackFormulaRepository.theta(0., strike, TIME_TO_EXPIRY, vol, true, inf);
double refP4 = BlackFormulaRepository.theta(0., strike, TIME_TO_EXPIRY, vol, false, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (k != 2 && k != 7) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.max(Math.abs(refVec[k]) * 1.e-9, 1.e-9));
}
}
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.theta(1.e-12, 1.e-12, 1.e-24, vol, true, 0.05);
double resC2 = BlackFormulaRepository.theta(1.e-12, 1.e-12, 1.e24, vol, true, 0.05);
double resC3 = BlackFormulaRepository.theta(1.e-12, 1.e12, 1.e-24, vol, true, 0.05);
double resP1 = BlackFormulaRepository.theta(1.e-12, 1.e-12, 1.e-24, vol, false, 0.05);
double resP2 = BlackFormulaRepository.theta(1.e-12, 1.e-12, 1.e24, vol, false, 0.05);
double resP3 = BlackFormulaRepository.theta(1.e-12, 1.e12, 1.e-24, vol, false, 0.05);
double resC4 = BlackFormulaRepository.theta(1.e12, 1.e-12, 1.e-24, vol, true, 0.05);
double resP4 = BlackFormulaRepository.theta(1.e12, 1.e-12, 1.e-24, vol, false, 0.05);
double resC5 = BlackFormulaRepository.theta(FORWARD, FORWARD * (1. + 1.e-12), 1.e-24, vol, true, 0.05);
double resP5 = BlackFormulaRepository.theta(FORWARD, FORWARD * (1. + 1.e-12), 1.e-24, vol, false, 0.05);
double resC6 = BlackFormulaRepository.theta(1.e12, 1.e12, 1.e24, vol, true, 0.05);
double resP6 = BlackFormulaRepository.theta(1.e12, 1.e12, 1.e24, vol, false, 0.05);
double refC1 = BlackFormulaRepository.theta(0., 0., 0., vol, true, 0.05);
double refC2 = BlackFormulaRepository.theta(0., 0., inf, vol, true, 0.05);
double refC3 = BlackFormulaRepository.theta(0., inf, 0., vol, true, 0.05);
double refP1 = BlackFormulaRepository.theta(0., 0., 0., vol, false, 0.05);
double refP2 = BlackFormulaRepository.theta(0., 0., inf, vol, false, 0.05);
double refP3 = BlackFormulaRepository.theta(0., inf, 0., vol, false, 0.05);
double refC4 = BlackFormulaRepository.theta(inf, 0., 0., vol, true, 0.05);
double refP4 = BlackFormulaRepository.theta(inf, 0., 0., vol, false, 0.05);
double refC5 = BlackFormulaRepository.theta(FORWARD, FORWARD, 0., vol, true, 0.05);
double refP5 = BlackFormulaRepository.theta(FORWARD, FORWARD, 0., vol, false, 0.05);
double refC6 = BlackFormulaRepository.theta(inf, inf, inf, vol, true, 0.05);
double refP6 = BlackFormulaRepository.theta(inf, inf, inf, vol, false, 0.05);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6};
for (int k = 0; k < 12; ++k) {
if ((refVec[k] != -0.5 * vol) && (refVec[k] != -0.5 * FORWARD) && (refVec[k] != Double.NEGATIVE_INFINITY) &&
k != 11) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-7);// //should be rechecked
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
{
double resC1 = BlackFormulaRepository.theta(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, true, 0.05);
double resC2 = BlackFormulaRepository.theta(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12, true, 0.05);
double resC3 = BlackFormulaRepository.theta(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12, true, 0.05);
double resP1 = BlackFormulaRepository.theta(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, false, 0.05);
double resP2 = BlackFormulaRepository.theta(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12, false, 0.05);
double resP3 = BlackFormulaRepository.theta(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12, false, 0.05);
double resC4 = BlackFormulaRepository.theta(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, true, 0.05);
double resP4 = BlackFormulaRepository.theta(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, false, 0.05);
double resC5 = BlackFormulaRepository.theta(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12, true,
0.05);
double resP5 = BlackFormulaRepository.theta(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12,
false, 0.05);
double resC6 = BlackFormulaRepository.theta(1.e12, 1.e12, TIME_TO_EXPIRY, 1.e24, true, 0.05);
double resP6 = BlackFormulaRepository.theta(1.e12, 1.e12, TIME_TO_EXPIRY, 1.e24, false, 0.05);
double refC1 = BlackFormulaRepository.theta(0., 0., TIME_TO_EXPIRY, 0., true, 0.05);
double refC2 = BlackFormulaRepository.theta(0., 0., TIME_TO_EXPIRY, inf, true, 0.05);
double refC3 = BlackFormulaRepository.theta(0., inf, TIME_TO_EXPIRY, 0., true, 0.05);
double refP1 = BlackFormulaRepository.theta(0., 0., TIME_TO_EXPIRY, 0., false, 0.05);
double refP2 = BlackFormulaRepository.theta(0., 0., TIME_TO_EXPIRY, inf, false, 0.05);
double refP3 = BlackFormulaRepository.theta(0., inf, TIME_TO_EXPIRY, 0., false, 0.05);
double refC4 = BlackFormulaRepository.theta(inf, 0., TIME_TO_EXPIRY, 0., true, 0.05);
double refP4 = BlackFormulaRepository.theta(inf, 0., TIME_TO_EXPIRY, 0., false, 0.05);
double refC5 = BlackFormulaRepository.theta(FORWARD, FORWARD, TIME_TO_EXPIRY, 0., true, 0.05);
double refP5 = BlackFormulaRepository.theta(FORWARD, FORWARD, TIME_TO_EXPIRY, 0., false, 0.05);
double refC6 = BlackFormulaRepository.theta(inf, inf, TIME_TO_EXPIRY, inf, true, 0.05);
double refP6 = BlackFormulaRepository.theta(inf, inf, TIME_TO_EXPIRY, inf, false, 0.05);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC6, resP6,
resC5, resP5};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC6, refP6,
refC5, refP5};
for (int k = 0; k < 10; ++k) {// The last two cases return reference values
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.theta(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol, true, 1.e-12);
double resC2 = BlackFormulaRepository.theta(1.e-12, 1.e12, TIME_TO_EXPIRY, vol, true, 1.e-12);
double resC3 = BlackFormulaRepository.theta(1.e12, 1.e-12, TIME_TO_EXPIRY, vol, true, 1.e-12);
double resP1 = BlackFormulaRepository.theta(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol, false, 1.e-12);
double resP2 = BlackFormulaRepository.theta(1.e-12, 1.e12, TIME_TO_EXPIRY, vol, false, 1.e-12);
double resP3 = BlackFormulaRepository.theta(1.e12, 1.e-12, TIME_TO_EXPIRY, vol, false, 1.e-12);
double resC4 = BlackFormulaRepository.theta(1.e12, 1.e12, TIME_TO_EXPIRY, vol, true, 1.e12);
double resP4 = BlackFormulaRepository.theta(1.e12, 1.e12, TIME_TO_EXPIRY, vol, false, 1.e12);
double resC5 = BlackFormulaRepository.theta(1.e12, 1.e-12, TIME_TO_EXPIRY, vol, true, 1.e12);
double resP5 = BlackFormulaRepository.theta(1.e12, 1.e-12, TIME_TO_EXPIRY, vol, false, 1.e12);
double resC6 = BlackFormulaRepository.theta(1.e-12, 1.e12, TIME_TO_EXPIRY, vol, true, 1.e12);
double resP6 = BlackFormulaRepository.theta(1.e-12, 1.e12, TIME_TO_EXPIRY, vol, false, 1.e12);
double resC7 = BlackFormulaRepository.theta(1.e-12, 2.e-12, TIME_TO_EXPIRY, vol, true, 1.e12);
double resP7 = BlackFormulaRepository.theta(1.e-12, 0.5e-12, TIME_TO_EXPIRY, vol, false, 1.e12);
double resC8 = BlackFormulaRepository.theta(1.e12, 1.e12, TIME_TO_EXPIRY, vol, true, 1.e-12);
double resP8 = BlackFormulaRepository.theta(1.e12, 1.e12, TIME_TO_EXPIRY, vol, false, 1.e-12);
double refC1 = BlackFormulaRepository.theta(0., 0., TIME_TO_EXPIRY, vol, true, 0.);
double refC2 = BlackFormulaRepository.theta(0., inf, TIME_TO_EXPIRY, vol, true, 0.);
double refC3 = BlackFormulaRepository.theta(inf, 0., TIME_TO_EXPIRY, vol, true, 0.);
double refP1 = BlackFormulaRepository.theta(0., 0., TIME_TO_EXPIRY, vol, false, 0.);
double refP2 = BlackFormulaRepository.theta(0., inf, TIME_TO_EXPIRY, vol, false, 0.);
double refP3 = BlackFormulaRepository.theta(inf, 0., TIME_TO_EXPIRY, vol, false, 0.);
double refC4 = BlackFormulaRepository.theta(inf, inf, TIME_TO_EXPIRY, vol, true, inf);
double refP4 = BlackFormulaRepository.theta(inf, inf, TIME_TO_EXPIRY, vol, false, inf);
double refC5 = BlackFormulaRepository.theta(inf, 0., TIME_TO_EXPIRY, vol, true, inf);
double refP5 = BlackFormulaRepository.theta(inf, 0., TIME_TO_EXPIRY, vol, false, inf);
double refC6 = BlackFormulaRepository.theta(0., inf, TIME_TO_EXPIRY, vol, true, inf);
double refP6 = BlackFormulaRepository.theta(0., inf, TIME_TO_EXPIRY, vol, false, inf);
double refC7 = BlackFormulaRepository.theta(0., 0., TIME_TO_EXPIRY, vol, true, inf);
double refP7 = BlackFormulaRepository.theta(0., 0., TIME_TO_EXPIRY, vol, false, inf);
double refC8 = BlackFormulaRepository.theta(inf, inf, TIME_TO_EXPIRY, vol, true, 0.);
double refP8 = BlackFormulaRepository.theta(inf, inf, TIME_TO_EXPIRY, vol, false, 0.);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7, resC8, resP8};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7, refC8, refP8};
for (int k = 0; k < 14; ++k) {
if (k != 3 && k != 4 && k != 7 && k != 11) {
if (k != 12 && k != 13) {// ref values are returned
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e9);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e9);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.theta(1.e-12, strike, 1.e-24, vol, true, 1.e-12);
double resC2 = BlackFormulaRepository.theta(1.e-12, strike, 1.e24, vol, true, 1.e-12);
double resC3 = BlackFormulaRepository.theta(1.e12, strike, 1.e-24, vol, true, 1.e-12);
double resP1 = BlackFormulaRepository.theta(1.e-12, strike, 1.e-24, vol, false, 1.e-12);
double resP2 = BlackFormulaRepository.theta(1.e-12, strike, 1.e24, vol, false, 1.e-12);
double resP3 = BlackFormulaRepository.theta(1.e12, strike, 1.e-24, vol, false, 1.e-12);
double resC4 = BlackFormulaRepository.theta(1.e12, strike, 1.e24, vol, true, 1.e12);
double resP4 = BlackFormulaRepository.theta(1.e12, strike, 1.e24, vol, false, 1.e12);
double resC5 = BlackFormulaRepository.theta(1.e-12, strike, 1.e24, vol, true, 1.e12);
double resP5 = BlackFormulaRepository.theta(1.e-12, strike, 1.e24, vol, false, 1.e12);
double resC6 = BlackFormulaRepository.theta(1.e12, strike, 1.e-24, vol, true, 1.e12);
double resP6 = BlackFormulaRepository.theta(1.e12, strike, 1.e-24, vol, false, 1.e12);
double resC7 = BlackFormulaRepository.theta(1.e12, strike, 1.e24, vol, true, 1.e-12);
double resP7 = BlackFormulaRepository.theta(1.e12, strike, 1.e24, vol, false, 1.e-12);
double resC8 = BlackFormulaRepository.theta(1.e-12, strike, 1.e-24, vol, true, 1.e12);
double resP8 = BlackFormulaRepository.theta(1.e-12, strike, 1.e-24, vol, false, 1.e12);
double refC1 = BlackFormulaRepository.theta(0., strike, 0., vol, true, 0.);
double refC2 = BlackFormulaRepository.theta(0., strike, inf, vol, true, 0.);
double refC3 = BlackFormulaRepository.theta(inf, strike, 0., vol, true, 0.);
double refP1 = BlackFormulaRepository.theta(0., strike, 0., vol, false, 0.);
double refP2 = BlackFormulaRepository.theta(0., strike, inf, vol, false, 0.);
double refP3 = BlackFormulaRepository.theta(inf, strike, 0., vol, false, 0.);
double refC4 = BlackFormulaRepository.theta(inf, strike, inf, vol, true, inf);
double refP4 = BlackFormulaRepository.theta(inf, strike, inf, vol, false, inf);
double refC5 = BlackFormulaRepository.theta(0., strike, inf, vol, true, inf);
double refP5 = BlackFormulaRepository.theta(0., strike, inf, vol, false, inf);
double refC6 = BlackFormulaRepository.theta(inf, strike, 0., vol, true, inf);
double refP6 = BlackFormulaRepository.theta(inf, strike, 0., vol, false, inf);
double refC7 = BlackFormulaRepository.theta(inf, strike, inf, vol, true, 0.);
double refP7 = BlackFormulaRepository.theta(inf, strike, inf, vol, false, 0.);
double refC8 = BlackFormulaRepository.theta(0., strike, 0., vol, true, inf);
double refP8 = BlackFormulaRepository.theta(0., strike, 0., vol, false, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7, resC8, resP8};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7, refC8, refP8};
for (int k = 0; k < 16; ++k) {
if (k != 4 && k != 8 && k != 12) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-9);
}
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.theta(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12, true, 1.e-12);
double resC2 = BlackFormulaRepository.theta(1.e-12, strike, TIME_TO_EXPIRY, 1.e12, true, 1.e-12);
double resC3 = BlackFormulaRepository.theta(1.e12, strike, TIME_TO_EXPIRY, 1.e-12, true, 1.e-12);
double resP1 = BlackFormulaRepository.theta(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12, false, 1.e-12);
double resP2 = BlackFormulaRepository.theta(1.e-12, strike, TIME_TO_EXPIRY, 1.e12, false, 1.e-12);
double resP3 = BlackFormulaRepository.theta(1.e12, strike, TIME_TO_EXPIRY, 1.e-12, false, 1.e-12);
double resC4 = BlackFormulaRepository.theta(1.e12, strike, TIME_TO_EXPIRY, 1.e12, true, 1.e12);
double resP4 = BlackFormulaRepository.theta(1.e12, strike, TIME_TO_EXPIRY, 1.e12, false, 1.e12);
double resC5 = BlackFormulaRepository.theta(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12, true, 1.e12);
double resP5 = BlackFormulaRepository.theta(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12, false, 1.e12);
double resC6 = BlackFormulaRepository.theta(1.e12, strike, TIME_TO_EXPIRY, 1.e-12, true, 1.e12);
double resP6 = BlackFormulaRepository.theta(1.e12, strike, TIME_TO_EXPIRY, 1.e-12, false, 1.e12);
double resC7 = BlackFormulaRepository.theta(1.e-12, strike, TIME_TO_EXPIRY, 1.e12, true, 1.e12);
double resP7 = BlackFormulaRepository.theta(1.e-12, strike, TIME_TO_EXPIRY, 1.e12, false, 1.e12);
double resC8 = BlackFormulaRepository.theta(1.e12, strike, TIME_TO_EXPIRY, 1.e12, true, 1.e-12);
double resP8 = BlackFormulaRepository.theta(1.e12, strike, TIME_TO_EXPIRY, 1.e12, false, 1.e-12);
double refC1 = BlackFormulaRepository.theta(0., strike, TIME_TO_EXPIRY, 0., true, 0.);
double refC2 = BlackFormulaRepository.theta(0., strike, TIME_TO_EXPIRY, inf, true, 0.);
double refC3 = BlackFormulaRepository.theta(inf, strike, TIME_TO_EXPIRY, 0., true, 0.);
double refP1 = BlackFormulaRepository.theta(0., strike, TIME_TO_EXPIRY, 0., false, 0.);
double refP2 = BlackFormulaRepository.theta(0., strike, TIME_TO_EXPIRY, inf, false, 0.);
double refP3 = BlackFormulaRepository.theta(inf, strike, TIME_TO_EXPIRY, 0., false, 0.);
double refC4 = BlackFormulaRepository.theta(inf, strike, TIME_TO_EXPIRY, inf, true, inf);
double refP4 = BlackFormulaRepository.theta(inf, strike, TIME_TO_EXPIRY, inf, false, inf);
double refC5 = BlackFormulaRepository.theta(0., strike, TIME_TO_EXPIRY, 0., true, inf);
double refP5 = BlackFormulaRepository.theta(0., strike, TIME_TO_EXPIRY, 0., false, inf);
double refC6 = BlackFormulaRepository.theta(inf, strike, TIME_TO_EXPIRY, 0., true, inf);
double refP6 = BlackFormulaRepository.theta(inf, strike, TIME_TO_EXPIRY, 0., false, inf);
double refC7 = BlackFormulaRepository.theta(0., strike, TIME_TO_EXPIRY, inf, true, inf);
double refP7 = BlackFormulaRepository.theta(0., strike, TIME_TO_EXPIRY, inf, false, inf);
double refC8 = BlackFormulaRepository.theta(inf, strike, TIME_TO_EXPIRY, inf, true, 0.);
double refP8 = BlackFormulaRepository.theta(inf, strike, TIME_TO_EXPIRY, inf, false, 0.);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7, resC8, resP8};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7, refC8, refP8};
for (int k = 0; k < 16; ++k) {
if (k != 4 && k != 9 && k != 12 && k != 14) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-9);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.theta(forward, 1.e-12, 1.e-24, vol, true, 1.e-12);
double resC2 = BlackFormulaRepository.theta(forward, 1.e-12, 1.e24, vol, true, 1.e-12);
double resC3 = BlackFormulaRepository.theta(forward, 1.e12, 1.e-24, vol, true, 1.e-12);
double resP1 = BlackFormulaRepository.theta(forward, 1.e-12, 1.e-24, vol, false, 1.e-12);
double resP2 = BlackFormulaRepository.theta(forward, 1.e-12, 1.e24, vol, false, 1.e-12);
double resP3 = BlackFormulaRepository.theta(forward, 1.e12, 1.e-24, vol, false, 1.e-12);
double resC4 = BlackFormulaRepository.theta(forward, 1.e12, 1.e24, vol, true, 1.e12);
double resP4 = BlackFormulaRepository.theta(forward, 1.e12, 1.e24, vol, false, 1.e12);
double resC5 = BlackFormulaRepository.theta(forward, 1.e-12, 1.e24, vol, true, 1.e12);
double resP5 = BlackFormulaRepository.theta(forward, 1.e-12, 1.e24, vol, false, 1.e12);
double resC6 = BlackFormulaRepository.theta(forward, 1.e12, 1.e-12, vol, true, 1.e12);
double resP6 = BlackFormulaRepository.theta(forward, 1.e12, 1.e-12, vol, false, 1.e12);
double resC7 = BlackFormulaRepository.theta(forward, 1.e-12, 1.e-12, vol, true, 1.e12);
double resP7 = BlackFormulaRepository.theta(forward, 1.e-12, 1.e-12, vol, false, 1.e12);
double resC8 = BlackFormulaRepository.theta(forward, 1.e12, 1.e24, vol, true, 1.e-12);
double resP8 = BlackFormulaRepository.theta(forward, 1.e12, 1.e24, vol, false, 1.e-12);
double refC1 = BlackFormulaRepository.theta(forward, 0., 0., vol, true, 0.);
double refC2 = BlackFormulaRepository.theta(forward, 0., inf, vol, true, 0.);
double refC3 = BlackFormulaRepository.theta(forward, inf, 0., vol, true, 0.);
double refP1 = BlackFormulaRepository.theta(forward, 0., 0., vol, false, 0.);
double refP2 = BlackFormulaRepository.theta(forward, 0., inf, vol, false, 0.);
double refP3 = BlackFormulaRepository.theta(forward, inf, 0., vol, false, 0.);
double refC4 = BlackFormulaRepository.theta(forward, inf, inf, vol, true, inf);
double refP4 = BlackFormulaRepository.theta(forward, inf, inf, vol, false, inf);
double refC5 = BlackFormulaRepository.theta(forward, 0., inf, vol, true, inf);
double refP5 = BlackFormulaRepository.theta(forward, 0., inf, vol, false, inf);
double refC6 = BlackFormulaRepository.theta(forward, inf, 0., vol, true, inf);
double refP6 = BlackFormulaRepository.theta(forward, inf, 0., vol, false, inf);
double refC7 = BlackFormulaRepository.theta(forward, 0., inf, vol, true, inf);
double refP7 = BlackFormulaRepository.theta(forward, 0., inf, vol, false, inf);
double refC8 = BlackFormulaRepository.theta(forward, 0., 0., vol, true, inf);
double refP8 = BlackFormulaRepository.theta(forward, 0., 0., vol, false, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7, resC8, resP8};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7, refC8, refP8};
for (int k = 0; k < 14; ++k) {// some of ref values skipped
if (k != 5 && k != 9) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-9);
}
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double forward = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.theta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12, true, 1.e-12);
double resC2 = BlackFormulaRepository.theta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12, true, 1.e-12);
double resC3 = BlackFormulaRepository.theta(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12, true, 1.e-12);
double resP1 = BlackFormulaRepository.theta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12, false, 1.e-12);
double resP2 = BlackFormulaRepository.theta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12, false, 1.e-12);
double resP3 = BlackFormulaRepository.theta(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12, false, 1.e-12);
double resC4 = BlackFormulaRepository.theta(forward, 1.e12, TIME_TO_EXPIRY, 1.e12, true, 1.e12);
double resP4 = BlackFormulaRepository.theta(forward, 1.e12, TIME_TO_EXPIRY, 1.e12, false, 1.e12);
double resC5 = BlackFormulaRepository.theta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12, true, 1.e12);
double resP5 = BlackFormulaRepository.theta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12, false, 1.e12);
double resC6 = BlackFormulaRepository.theta(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12, true, 1.e12);
double resP6 = BlackFormulaRepository.theta(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12, false, 1.e12);
double resC7 = BlackFormulaRepository.theta(forward, 1.e12, TIME_TO_EXPIRY, 1.e12, true, 1.e-12);
double resP7 = BlackFormulaRepository.theta(forward, 1.e12, TIME_TO_EXPIRY, 1.e12, false, 1.e-12);
double resC8 = BlackFormulaRepository.theta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12, true, 1.e12);
double resP8 = BlackFormulaRepository.theta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12, false, 1.e12);
double refC1 = BlackFormulaRepository.theta(forward, 0., TIME_TO_EXPIRY, 0., true, 0.);
double refC2 = BlackFormulaRepository.theta(forward, 0., TIME_TO_EXPIRY, inf, true, 0.);
double refC3 = BlackFormulaRepository.theta(forward, inf, TIME_TO_EXPIRY, 0., true, 0.);
double refP1 = BlackFormulaRepository.theta(forward, 0., TIME_TO_EXPIRY, 0., false, 0.);
double refP2 = BlackFormulaRepository.theta(forward, 0., TIME_TO_EXPIRY, inf, false, 0.);
double refP3 = BlackFormulaRepository.theta(forward, inf, TIME_TO_EXPIRY, 0., false, 0.);
double refC4 = BlackFormulaRepository.theta(forward, inf, TIME_TO_EXPIRY, inf, true, inf);
double refP4 = BlackFormulaRepository.theta(forward, inf, TIME_TO_EXPIRY, inf, false, inf);
double refC5 = BlackFormulaRepository.theta(forward, 0., TIME_TO_EXPIRY, inf, true, inf);
double refP5 = BlackFormulaRepository.theta(forward, 0., TIME_TO_EXPIRY, inf, false, inf);
double refC6 = BlackFormulaRepository.theta(forward, inf, TIME_TO_EXPIRY, 0., true, inf);
double refP6 = BlackFormulaRepository.theta(forward, inf, TIME_TO_EXPIRY, 0., false, inf);
double refC7 = BlackFormulaRepository.theta(forward, inf, TIME_TO_EXPIRY, inf, true, 0.);
double refP7 = BlackFormulaRepository.theta(forward, inf, TIME_TO_EXPIRY, inf, false, 0.);
double refC8 = BlackFormulaRepository.theta(forward, 0., TIME_TO_EXPIRY, 0., true, inf);
double refP8 = BlackFormulaRepository.theta(forward, 0., TIME_TO_EXPIRY, 0., false, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7, resC8, resP8};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7, refC8, refP8};
for (int k = 0; k < 16; ++k) {
if (k != 5 && k != 9 && k != 11 && k != 13) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-9);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.theta(strike, strike, inf, 0., true, 1.);
double resP1 = BlackFormulaRepository.theta(strike, strike, inf, 0., false, 1.);
double resC2 = BlackFormulaRepository.theta(strike, strike, inf, 0., true, 0.);
double resP2 = BlackFormulaRepository.theta(strike, strike, inf, 0., false, 0.);
double refC1 = strike * (NORMAL.getCDF(0.5));
double refP1 = -strike * (NORMAL.getCDF(-0.5));
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, 0., 0.};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.max(Math.abs(refVec[k]) * 1.e-10, 1.e-10));
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, VOLS[0], true, -inf);
double resP1 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, VOLS[1], false, -inf);
double resC2 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, VOLS[2], true, -inf);
double resP2 = BlackFormulaRepository.theta(FORWARD, strike, TIME_TO_EXPIRY, VOLS[3], false, -inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {0., 0., 0., 0.};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.max(Math.abs(refVec[k]) * 1.e-10, 1.e-10));
}
}
}
}
}
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeVolErrorThetaTest() {
BlackFormulaRepository.theta(FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, -0.5, true, 0.1);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeFwdErrorThetaTest() {
BlackFormulaRepository.theta(-FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1], true, 0.1);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeStrikeErrorThetaTest() {
BlackFormulaRepository.theta(FORWARD, -STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1], true, 0.1);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeTimeErrorThetaTest() {
BlackFormulaRepository.theta(FORWARD, STRIKES_INPUT[1], -TIME_TO_EXPIRY, VOLS[1], true, 0.1);
}
/*
* driftlessTheta
*/
/**
* large/small input
*/
public void exDriftlessThetaTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
double inf = Double.POSITIVE_INFINITY;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.driftlessTheta(1.e-12 * strike, strike, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.driftlessTheta(0., strike, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.driftlessTheta(1.e12 * strike, strike, TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.driftlessTheta(inf, strike, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-11);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-11);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.driftlessTheta(forward, 1.e-12 * forward, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.driftlessTheta(forward, 1.e12 * forward, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.driftlessTheta(forward, 0., TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.driftlessTheta(forward, inf, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.driftlessTheta(FORWARD, strike, 1e-24, vol);
double resC2 = BlackFormulaRepository.driftlessTheta(FORWARD, strike, 1e24, vol);
double refC1 = BlackFormulaRepository.driftlessTheta(FORWARD, strike, 0., vol);
double refC2 = BlackFormulaRepository.driftlessTheta(FORWARD, strike, inf, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.driftlessTheta(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12);
double refC1 = BlackFormulaRepository.driftlessTheta(FORWARD, strike, TIME_TO_EXPIRY, 0.);
double resC2 = BlackFormulaRepository.driftlessTheta(FORWARD, strike, TIME_TO_EXPIRY, 1.e12);
double refC2 = BlackFormulaRepository.driftlessTheta(FORWARD, strike, TIME_TO_EXPIRY, inf);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.driftlessTheta(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.driftlessTheta(1.e-12, 1.e12, TIME_TO_EXPIRY, vol);
double resC3 = BlackFormulaRepository.driftlessTheta(1.e12, 1.e-12, TIME_TO_EXPIRY, vol);
double resP3 = BlackFormulaRepository.driftlessTheta(1.e12, 1.e12, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.driftlessTheta(0., 0., TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.driftlessTheta(0., inf, TIME_TO_EXPIRY, vol);
double refC3 = BlackFormulaRepository.driftlessTheta(inf, 0., TIME_TO_EXPIRY, vol);
double refP3 = BlackFormulaRepository.driftlessTheta(inf, inf, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e12) {
assertTrue(resVec[k] > 1.e9);
} else {
if (refVec[k] < -1.e12) {
assertTrue(resVec[k] < -1.e9);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.driftlessTheta(1.e-12, strike, 1.e-24, vol);
double resC2 = BlackFormulaRepository.driftlessTheta(1.e-12, strike, 1.e24, vol);
double resC3 = BlackFormulaRepository.driftlessTheta(1.e12, strike, 1.e-24, vol);
double resP3 = BlackFormulaRepository.driftlessTheta(1.e12, strike, 1.e24, vol);
double refC1 = BlackFormulaRepository.driftlessTheta(0., strike, 0., vol);
double refC2 = BlackFormulaRepository.driftlessTheta(0., strike, inf, vol);
double refC3 = BlackFormulaRepository.driftlessTheta(inf, strike, 0., vol);
double refP3 = BlackFormulaRepository.driftlessTheta(inf, strike, inf, vol);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.driftlessTheta(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.driftlessTheta(1.e-12, strike, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.driftlessTheta(1.e12, strike, TIME_TO_EXPIRY, 1.e-12);
double resP3 = BlackFormulaRepository.driftlessTheta(1.e12, strike, TIME_TO_EXPIRY, 1.e12);
double refC1 = BlackFormulaRepository.driftlessTheta(0., strike, TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.driftlessTheta(0., strike, TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.driftlessTheta(inf, strike, TIME_TO_EXPIRY, 0.);
double refP3 = BlackFormulaRepository.driftlessTheta(inf, strike, TIME_TO_EXPIRY, inf);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.driftlessTheta(forward, 1.e-12, 1.e-24, vol);
double resC2 = BlackFormulaRepository.driftlessTheta(forward, 1.e-12, 1.e24, vol);
double resC3 = BlackFormulaRepository.driftlessTheta(forward, 1.e12, 1.e-24, vol);
double resP3 = BlackFormulaRepository.driftlessTheta(forward, 1.e12, 1.e24, vol);
double refC1 = BlackFormulaRepository.driftlessTheta(forward, 0., 0., vol);
double refC2 = BlackFormulaRepository.driftlessTheta(forward, 0., inf, vol);
double refC3 = BlackFormulaRepository.driftlessTheta(forward, inf, 0., vol);
double refP3 = BlackFormulaRepository.driftlessTheta(forward, inf, inf, vol);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double forward = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.driftlessTheta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.driftlessTheta(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.driftlessTheta(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double resP3 = BlackFormulaRepository.driftlessTheta(forward, 1.e12, TIME_TO_EXPIRY, 1.e12);
double refC1 = BlackFormulaRepository.driftlessTheta(forward, 0., TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.driftlessTheta(forward, 0., TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.driftlessTheta(forward, inf, TIME_TO_EXPIRY, 0.);
double refP3 = BlackFormulaRepository.driftlessTheta(forward, inf, TIME_TO_EXPIRY, inf);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.driftlessTheta(1.e-14, 1.e-14, 1.e-11, vol);
double resC2 = BlackFormulaRepository.driftlessTheta(1.e-12, 1.e-12, 1.e24, vol);
double resC3 = BlackFormulaRepository.driftlessTheta(1.e-12, 1.e12, 1.e-24, vol);
double resP1 = BlackFormulaRepository.driftlessTheta(1.e-14, 1.e-14, 1.e-11, vol);
double resP2 = BlackFormulaRepository.driftlessTheta(1.e-12, 1.e-12, 1.e24, vol);
double resP3 = BlackFormulaRepository.driftlessTheta(1.e-12, 1.e12, 1.e-24, vol);
double resC4 = BlackFormulaRepository.driftlessTheta(1.e12, 1.e-12, 1.e-24, vol);
double resP4 = BlackFormulaRepository.driftlessTheta(1.e12, 1.e-12, 1.e-24, vol);
double resC5 = BlackFormulaRepository.driftlessTheta(FORWARD, FORWARD * (1. + 1.e-14), 1.e-24, vol);
double resP5 = BlackFormulaRepository.driftlessTheta(FORWARD, FORWARD * (1. + 1.e-14), 1.e-24, vol);
double resC6 = BlackFormulaRepository.driftlessTheta(1.e12, 1.e12, 1.e24, vol);
double resP6 = BlackFormulaRepository.driftlessTheta(1.e12, 1.e12, 1.e-24, vol);
double resC7 = BlackFormulaRepository.driftlessTheta(1.e12, 1.e-12, 1.e24, vol);
double resP7 = BlackFormulaRepository.driftlessTheta(1.e-12, 1.e12, 1.e24, vol);
double resP8 = BlackFormulaRepository.driftlessTheta(1.e-12, 1.e-12, 1.e-24, vol);
double refC1 = BlackFormulaRepository.driftlessTheta(0., 0., 0., vol);
double refC2 = BlackFormulaRepository.driftlessTheta(0., 0., inf, vol);
double refC3 = BlackFormulaRepository.driftlessTheta(0., inf, 0., vol);
double refP1 = BlackFormulaRepository.driftlessTheta(0., 0., 0., vol);
double refP2 = BlackFormulaRepository.driftlessTheta(0., 0., inf, vol);
double refP3 = BlackFormulaRepository.driftlessTheta(0., inf, 0., vol);
double refC4 = BlackFormulaRepository.driftlessTheta(inf, 0., 0., vol);
double refP4 = BlackFormulaRepository.driftlessTheta(inf, 0., 0., vol);
double refC5 = BlackFormulaRepository.driftlessTheta(FORWARD, FORWARD, 0., vol);
double refP5 = BlackFormulaRepository.driftlessTheta(FORWARD, FORWARD, 0., vol);
double refC6 = BlackFormulaRepository.driftlessTheta(inf, inf, inf, vol);
double refP6 = BlackFormulaRepository.driftlessTheta(inf, inf, 0., vol);
double refC7 = BlackFormulaRepository.driftlessTheta(inf, 0., inf, vol);
double refP7 = BlackFormulaRepository.driftlessTheta(0., inf, inf, vol);
double refP8 = BlackFormulaRepository.driftlessTheta(0., 0., 0., vol);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7, resP8};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7, refP8};
for (int k = 0; k < 15; ++k) {
if ((refVec[k] != -0.5 * vol * NORMAL.getPDF(0.)) && (refVec[k] != -0.5 * FORWARD * NORMAL.getPDF(0.)) &&
(refVec[k] != Double.NEGATIVE_INFINITY)) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
{
double resC1 = BlackFormulaRepository.driftlessTheta(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.driftlessTheta(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.driftlessTheta(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double resP1 = BlackFormulaRepository.driftlessTheta(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resP2 = BlackFormulaRepository.driftlessTheta(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resP3 = BlackFormulaRepository.driftlessTheta(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double resC4 = BlackFormulaRepository.driftlessTheta(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resP4 = BlackFormulaRepository.driftlessTheta(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC5 = BlackFormulaRepository.driftlessTheta(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY,
1.e-12);
double resP5 = BlackFormulaRepository.driftlessTheta(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY,
1.e-12);
double resC6 = BlackFormulaRepository.driftlessTheta(1.e12, 1.e12, TIME_TO_EXPIRY, 1.e12);
double resP6 = BlackFormulaRepository.driftlessTheta(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resC7 = BlackFormulaRepository.driftlessTheta(1.e12, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double resP7 = BlackFormulaRepository.driftlessTheta(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e12);
double resP8 = BlackFormulaRepository.driftlessTheta(1.e12, 1.e12, 1.e-24, 1.e-12);
double refC1 = BlackFormulaRepository.driftlessTheta(0., 0., TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.driftlessTheta(0., 0., TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.driftlessTheta(0., inf, TIME_TO_EXPIRY, 0.);
double refP1 = BlackFormulaRepository.driftlessTheta(0., 0., TIME_TO_EXPIRY, 0.);
double refP2 = BlackFormulaRepository.driftlessTheta(0., 0., TIME_TO_EXPIRY, inf);
double refP3 = BlackFormulaRepository.driftlessTheta(0., inf, TIME_TO_EXPIRY, 0.);
double refC4 = BlackFormulaRepository.driftlessTheta(inf, 0., TIME_TO_EXPIRY, 0.);
double refP4 = BlackFormulaRepository.driftlessTheta(inf, 0., TIME_TO_EXPIRY, 0.);
double refC5 = BlackFormulaRepository.driftlessTheta(FORWARD, FORWARD, TIME_TO_EXPIRY, 1.e-12);
double refP5 = BlackFormulaRepository.driftlessTheta(FORWARD, FORWARD, TIME_TO_EXPIRY, 1.e-12);
double refC6 = BlackFormulaRepository.driftlessTheta(inf, inf, TIME_TO_EXPIRY, inf);
double refP6 = BlackFormulaRepository.driftlessTheta(inf, 0., TIME_TO_EXPIRY, inf);
double refC7 = BlackFormulaRepository.driftlessTheta(inf, inf, TIME_TO_EXPIRY, 0.);
double refP7 = BlackFormulaRepository.driftlessTheta(0., inf, TIME_TO_EXPIRY, inf);
double refP8 = BlackFormulaRepository.driftlessTheta(inf, inf, 0., 0.);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7, resP8};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7, refP8};
for (int k = 0; k < 15; ++k) {
if (k != 12) {// ref value
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (Math.abs(refVec[k]) < 1.e-10) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeVolErrorDriftlessThetaTest() {
BlackFormulaRepository.driftlessTheta(FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, -0.5);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeFwdErrorDriftlessThetaTest() {
BlackFormulaRepository.driftlessTheta(-FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1]);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeStrikeErrorDriftlessThetaTest() {
BlackFormulaRepository.driftlessTheta(FORWARD, -STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1]);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeTimeErrorDriftlessThetaTest() {
BlackFormulaRepository.driftlessTheta(FORWARD, STRIKES_INPUT[1], -TIME_TO_EXPIRY, VOLS[1]);
}
/*
* thetaMod tests
*/
/**
* large/small input
*/
public void exthetaModTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
double inf = Double.POSITIVE_INFINITY;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.thetaMod(1.e-12 * strike, strike, TIME_TO_EXPIRY, vol, true, 0.05);
double refC1 = BlackFormulaRepository.thetaMod(0., strike, TIME_TO_EXPIRY, vol, true, 0.05);
double resC2 = BlackFormulaRepository.thetaMod(1.e12 * strike, strike, TIME_TO_EXPIRY, vol, true, 0.05);
double refC2 = BlackFormulaRepository.thetaMod(inf, strike, TIME_TO_EXPIRY, vol, true, 0.05);
double resP1 = BlackFormulaRepository.thetaMod(1.e-12 * strike, strike, TIME_TO_EXPIRY, vol, false, 0.05);
double refP1 = BlackFormulaRepository.thetaMod(0., strike, TIME_TO_EXPIRY, vol, false, 0.05);
double resP2 = BlackFormulaRepository.thetaMod(1.e12 * strike, strike, TIME_TO_EXPIRY, vol, false, 0.05);
double refP2 = BlackFormulaRepository.thetaMod(inf, strike, TIME_TO_EXPIRY, vol, false, 0.05);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository
.thetaMod(forward, 1.e-14 * forward, TIME_TO_EXPIRY, vol, true, 0.05);
double resC2 = BlackFormulaRepository.thetaMod(forward, 1.e12 * forward, TIME_TO_EXPIRY, vol, true, 0.05);
double resP1 = BlackFormulaRepository.thetaMod(forward, 1.e-12 * forward, TIME_TO_EXPIRY, vol, false,
0.05);
double resP2 = BlackFormulaRepository
.thetaMod(forward, 1.e12 * forward, TIME_TO_EXPIRY, vol, false, 0.05);
double refC1 = BlackFormulaRepository.thetaMod(forward, 0., TIME_TO_EXPIRY, vol, true, 0.05);
double refC2 = BlackFormulaRepository.thetaMod(forward, inf, TIME_TO_EXPIRY, vol, true, 0.05);
double refP1 = BlackFormulaRepository.thetaMod(forward, 0., TIME_TO_EXPIRY, vol, false, 0.05);
double refP2 = BlackFormulaRepository.thetaMod(forward, inf, TIME_TO_EXPIRY, vol, false, 0.05);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.thetaMod(FORWARD, strike, 1e-12, vol, true, 0.05);
double resC2 = BlackFormulaRepository.thetaMod(FORWARD, strike, 1e12, vol, true, 0.05);
double resP1 = BlackFormulaRepository.thetaMod(FORWARD, strike, 1e-12, vol, false, 0.05);
double resP2 = BlackFormulaRepository.thetaMod(FORWARD, strike, 1e12, vol, false, 0.05);
double refC1 = BlackFormulaRepository.thetaMod(FORWARD, strike, 0., vol, true, 0.05);
double refC2 = BlackFormulaRepository.thetaMod(FORWARD, strike, inf, vol, true, 0.05);
double refP1 = BlackFormulaRepository.thetaMod(FORWARD, strike, 0., vol, false, 0.05);
double refP2 = BlackFormulaRepository.thetaMod(FORWARD, strike, inf, vol, false, 0.05);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, 1.e-24, true, 0.05);
double refC1 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, 0., true, 0.05);
double resC2 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, 1.e24, true, 0.05);
double refC2 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, inf, true, 0.05);
double resP1 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, 1.e-24, false, 0.05);
double refP1 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, 0., false, 0.05);
double resP2 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, 1.e24, false, 0.05);
double refP2 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, inf, false, 0.05);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, vol, true, 1.e-12);
double resP1 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, vol, false, 1.e-12);
double refC1 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, vol, true, 0.);
double refP1 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, vol, false, 0.);
double resC2 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, vol, true, 1.e12);
double resP2 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, vol, false, 1.e12);
double refC2 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, vol, true, inf);
double refP2 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, vol, false, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, refC2, refP2};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e8);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e9);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.max(Math.abs(refVec[k]) * 1.e-9, 1.e-9));
}
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.thetaMod(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol, true, 0.05);
double resC2 = BlackFormulaRepository.thetaMod(1.e-12, 1.e12, TIME_TO_EXPIRY, vol, true, 0.05);
double resC3 = BlackFormulaRepository.thetaMod(1.e12, 1.e-12, TIME_TO_EXPIRY, vol, true, 0.05);
double resP1 = BlackFormulaRepository.thetaMod(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol, false, 0.05);
double resP2 = BlackFormulaRepository.thetaMod(1.e-12, 1.e12, TIME_TO_EXPIRY, vol, false, 0.05);
double resP3 = BlackFormulaRepository.thetaMod(1.e12, 1.e-12, TIME_TO_EXPIRY, vol, false, 0.05);
double resC4 = BlackFormulaRepository.thetaMod(1.e12, 1.e12, TIME_TO_EXPIRY, vol, true, 0.05);
double resP4 = BlackFormulaRepository.thetaMod(1.e12, 1.e12, TIME_TO_EXPIRY, vol, false, 0.05);
double resC5 = BlackFormulaRepository.thetaMod(1.e10, 1.e11, TIME_TO_EXPIRY, vol, true, 0.05);
double resP5 = BlackFormulaRepository.thetaMod(1.e11, 1.e10, TIME_TO_EXPIRY, vol, false, 0.05);
double refC1 = BlackFormulaRepository.thetaMod(0., 0., TIME_TO_EXPIRY, vol, true, 0.05);
double refC2 = BlackFormulaRepository.thetaMod(0., inf, TIME_TO_EXPIRY, vol, true, 0.05);
double refC3 = BlackFormulaRepository.thetaMod(inf, 0., TIME_TO_EXPIRY, vol, true, 0.05);
double refP1 = BlackFormulaRepository.thetaMod(0., 0., TIME_TO_EXPIRY, vol, false, 0.05);
double refP2 = BlackFormulaRepository.thetaMod(0., inf, TIME_TO_EXPIRY, vol, false, 0.05);
double refP3 = BlackFormulaRepository.thetaMod(inf, 0., TIME_TO_EXPIRY, vol, false, 0.05);
double refC4 = BlackFormulaRepository.thetaMod(inf, inf, TIME_TO_EXPIRY, vol, true, 0.05);
double refP4 = BlackFormulaRepository.thetaMod(inf, inf, TIME_TO_EXPIRY, vol, false, 0.05);
double refC5 = BlackFormulaRepository.thetaMod(1.e15, 1.e16, TIME_TO_EXPIRY, vol, true, 0.05);
double refP5 = BlackFormulaRepository.thetaMod(1.e16, 1.e15, TIME_TO_EXPIRY, vol, false, 0.05);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5};
for (int k = 0; k < 6; ++k) {// ref values
if (k != 6 && k != 7) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e8);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e9);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.thetaMod(1.e-12, strike, 1.e-24, vol, true, 0.05);
double resC2 = BlackFormulaRepository.thetaMod(1.e-12, strike, 1.e24, vol, true, 0.05);
double resC3 = BlackFormulaRepository.thetaMod(1.e12, strike, 1.e-24, vol, true, 0.05);
double resP1 = BlackFormulaRepository.thetaMod(1.e-12, strike, 1.e-24, vol, false, 0.05);
double resP2 = BlackFormulaRepository.thetaMod(1.e-12, strike, 1.e24, vol, false, 0.05);
double resP3 = BlackFormulaRepository.thetaMod(1.e12, strike, 1.e-24, vol, false, 0.05);
double resC4 = BlackFormulaRepository.thetaMod(1.e12, strike, 1.e24, vol, true, 0.05);
double resP4 = BlackFormulaRepository.thetaMod(1.e12, strike, 1.e24, vol, false, 0.05);
double refC1 = BlackFormulaRepository.thetaMod(0., strike, 0., vol, true, 0.05);
double refC2 = BlackFormulaRepository.thetaMod(0., strike, inf, vol, true, 0.05);
double refC3 = BlackFormulaRepository.thetaMod(inf, strike, 0., vol, true, 0.05);
double refP1 = BlackFormulaRepository.thetaMod(0., strike, 0., vol, false, 0.05);
double refP2 = BlackFormulaRepository.thetaMod(0., strike, inf, vol, false, 0.05);
double refP3 = BlackFormulaRepository.thetaMod(inf, strike, 0., vol, false, 0.05);
double refC4 = BlackFormulaRepository.thetaMod(inf, strike, inf, vol, true, 0.05);
double refP4 = BlackFormulaRepository.thetaMod(inf, strike, inf, vol, false, 0.05);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.thetaMod(1.e-12, strike, TIME_TO_EXPIRY, 1.e-24, true, 0.05);
double resC2 = BlackFormulaRepository.thetaMod(1.e-12, strike, TIME_TO_EXPIRY, 1.e24, true, 0.05);
double resC3 = BlackFormulaRepository.thetaMod(1.e12, strike, TIME_TO_EXPIRY, 1.e-24, true, 0.05);
double resP1 = BlackFormulaRepository.thetaMod(1.e-12, strike, TIME_TO_EXPIRY, 1.e-24, false, 0.05);
double resP2 = BlackFormulaRepository.thetaMod(1.e-12, strike, TIME_TO_EXPIRY, 1.e24, false, 0.05);
double resP3 = BlackFormulaRepository.thetaMod(1.e12, strike, TIME_TO_EXPIRY, 1.e-24, false, 0.05);
double resC4 = BlackFormulaRepository.thetaMod(1.e12, strike, TIME_TO_EXPIRY, 1.e24, true, 0.05);
double resP4 = BlackFormulaRepository.thetaMod(1.e12, strike, TIME_TO_EXPIRY, 1.e24, false, 0.05);
double refC1 = BlackFormulaRepository.thetaMod(0., strike, TIME_TO_EXPIRY, 0., true, 0.05);
double refC2 = BlackFormulaRepository.thetaMod(0., strike, TIME_TO_EXPIRY, inf, true, 0.05);
double refC3 = BlackFormulaRepository.thetaMod(inf, strike, TIME_TO_EXPIRY, 0., true, 0.05);
double refP1 = BlackFormulaRepository.thetaMod(0., strike, TIME_TO_EXPIRY, 0., false, 0.05);
double refP2 = BlackFormulaRepository.thetaMod(0., strike, TIME_TO_EXPIRY, inf, false, 0.05);
double refP3 = BlackFormulaRepository.thetaMod(inf, strike, TIME_TO_EXPIRY, 0., false, 0.05);
double refC4 = BlackFormulaRepository.thetaMod(inf, strike, TIME_TO_EXPIRY, inf, true, 0.05);
double refP4 = BlackFormulaRepository.thetaMod(inf, strike, TIME_TO_EXPIRY, inf, false, 0.05);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.thetaMod(forward, 1.e-12, 1.e-24, vol, true, 0.05);
double resC2 = BlackFormulaRepository.thetaMod(forward, 1.e-12, 1.e24, vol, true, 0.05);
double resC3 = BlackFormulaRepository.thetaMod(forward, 1.e12, 1.e-24, vol, true, 0.05);
double resP1 = BlackFormulaRepository.thetaMod(forward, 1.e-12, 1.e-24, vol, false, 0.05);
double resP2 = BlackFormulaRepository.thetaMod(forward, 1.e-12, 1.e24, vol, false, 0.05);
double resP3 = BlackFormulaRepository.thetaMod(forward, 1.e12, 1.e-24, vol, false, 0.05);
double resC4 = BlackFormulaRepository.thetaMod(forward, 1.e12, 1.e24, vol, true, 0.05);
double resP4 = BlackFormulaRepository.thetaMod(forward, 1.e12, 1.e24, vol, false, 0.05);
double refC1 = BlackFormulaRepository.thetaMod(forward, 0., 0., vol, true, 0.05);
double refC2 = BlackFormulaRepository.thetaMod(forward, 0., inf, vol, true, 0.05);
double refC3 = BlackFormulaRepository.thetaMod(forward, inf, 0., vol, true, 0.05);
double refP1 = BlackFormulaRepository.thetaMod(forward, 0., 0., vol, false, 0.05);
double refP2 = BlackFormulaRepository.thetaMod(forward, 0., inf, vol, false, 0.05);
double refP3 = BlackFormulaRepository.thetaMod(forward, inf, 0., vol, false, 0.05);
double refC4 = BlackFormulaRepository.thetaMod(forward, inf, inf, vol, true, 0.05);
double refP4 = BlackFormulaRepository.thetaMod(forward, inf, inf, vol, false, 0.05);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double forward = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.thetaMod(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12, true, 0.05);
double resC2 = BlackFormulaRepository.thetaMod(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12, true, 0.05);
double resC3 = BlackFormulaRepository.thetaMod(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12, true, 0.05);
double resP1 = BlackFormulaRepository.thetaMod(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12, false, 0.05);
double resP2 = BlackFormulaRepository.thetaMod(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12, false, 0.05);
double resP3 = BlackFormulaRepository.thetaMod(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12, false, 0.05);
double resC4 = BlackFormulaRepository.thetaMod(forward, 1.e12, TIME_TO_EXPIRY, 1.e12, true, 0.05);
double resP4 = BlackFormulaRepository.thetaMod(forward, 1.e12, TIME_TO_EXPIRY, 1.e12, false, 0.05);
double refC1 = BlackFormulaRepository.thetaMod(forward, 0., TIME_TO_EXPIRY, 0., true, 0.05);
double refC2 = BlackFormulaRepository.thetaMod(forward, 0., TIME_TO_EXPIRY, inf, true, 0.05);
double refC3 = BlackFormulaRepository.thetaMod(forward, inf, TIME_TO_EXPIRY, 0., true, 0.05);
double refP1 = BlackFormulaRepository.thetaMod(forward, 0., TIME_TO_EXPIRY, 0., false, 0.05);
double refP2 = BlackFormulaRepository.thetaMod(forward, 0., TIME_TO_EXPIRY, inf, false, 0.05);
double refP3 = BlackFormulaRepository.thetaMod(forward, inf, TIME_TO_EXPIRY, 0., false, 0.05);
double refC4 = BlackFormulaRepository.thetaMod(forward, inf, TIME_TO_EXPIRY, inf, true, 0.05);
double refP4 = BlackFormulaRepository.thetaMod(forward, inf, TIME_TO_EXPIRY, inf, false, 0.05);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.thetaMod(FORWARD, strike, 1.e-12, vol, true, 1.e-12);
double resC2 = BlackFormulaRepository.thetaMod(FORWARD, strike, 1.e12, vol, true, 1.e-12);
double resP1 = BlackFormulaRepository.thetaMod(FORWARD, strike, 1.e-12, vol, false, 1.e-12);
double resP2 = BlackFormulaRepository.thetaMod(FORWARD, strike, 1.e12, vol, false, 1.e-12);
double resC3 = BlackFormulaRepository.thetaMod(FORWARD, strike, 1.e12, vol, true, 1.e12);
double resP3 = BlackFormulaRepository.thetaMod(FORWARD, strike, 1.e12, vol, false, 1.e12);
double resC4 = BlackFormulaRepository.thetaMod(FORWARD, strike, 1.e-12, vol, true, 1.e12);
double resP4 = BlackFormulaRepository.thetaMod(FORWARD, strike, 1.e-12, vol, false, 1.e12);
double refC1 = BlackFormulaRepository.thetaMod(FORWARD, strike, 0., vol, true, 0.);
double refC2 = BlackFormulaRepository.thetaMod(FORWARD, strike, inf, vol, true, 0.);
double refP1 = BlackFormulaRepository.thetaMod(FORWARD, strike, 0., vol, false, 0.);
double refP2 = BlackFormulaRepository.thetaMod(FORWARD, strike, inf, vol, false, 0.);
double refC3 = BlackFormulaRepository.thetaMod(FORWARD, strike, inf, vol, true, inf);
double refP3 = BlackFormulaRepository.thetaMod(FORWARD, strike, inf, vol, false, inf);
double refC4 = BlackFormulaRepository.thetaMod(FORWARD, strike, 0., vol, true, inf);
double refP4 = BlackFormulaRepository.thetaMod(FORWARD, strike, 0., vol, false, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 6; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.thetaMod(strike, 1.e-12, TIME_TO_EXPIRY, vol, true, 1.e-12);
double resC2 = BlackFormulaRepository.thetaMod(strike, 1.e12, TIME_TO_EXPIRY, vol, true, 1.e-12);
double resP1 = BlackFormulaRepository.thetaMod(strike, 1.e-12, TIME_TO_EXPIRY, vol, false, 1.e-12);
double resP2 = BlackFormulaRepository.thetaMod(strike, 1.e12, TIME_TO_EXPIRY, vol, false, 1.e-12);
double resC3 = BlackFormulaRepository.thetaMod(strike, 1.e12, TIME_TO_EXPIRY, vol, true, 1.e12);
double resP3 = BlackFormulaRepository.thetaMod(strike, 1.e12, TIME_TO_EXPIRY, vol, false, 1.e12);
double refC1 = BlackFormulaRepository.thetaMod(strike, 0., TIME_TO_EXPIRY, vol, true, 0.);
double refC2 = BlackFormulaRepository.thetaMod(strike, inf, TIME_TO_EXPIRY, vol, true, 0.);
double refP1 = BlackFormulaRepository.thetaMod(strike, 0., TIME_TO_EXPIRY, vol, false, 0.);
double refP2 = BlackFormulaRepository.thetaMod(strike, inf, TIME_TO_EXPIRY, vol, false, 0.);
double refC3 = BlackFormulaRepository.thetaMod(strike, inf, TIME_TO_EXPIRY, vol, true, inf);
double refP3 = BlackFormulaRepository.thetaMod(strike, inf, TIME_TO_EXPIRY, vol, false, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3};
for (int k = 0; k < 6; ++k) {
if (k != 3) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.max(Math.abs(refVec[k]) * 1.e-9, 1.e-9));
}
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12, true, 1.e-12);
double resC2 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, 1.e12, true, 1.e-12);
double resP1 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12, false, 1.e-12);
double resP2 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, 1.e12, false, 1.e-12);
double resC3 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, 1.e12, true, 1.e12);
double resP3 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, 1.e12, false, 1.e12);
double resC4 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12, true, 1.e12);
double resP4 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12, false, 1.e12);
double refC1 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, 0., true, 0.);
double refC2 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, inf, true, 0.);
double refP1 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, 0., false, 0.);
double refP2 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, inf, false, 0.);
double refC3 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, inf, true, inf);
double refP3 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, inf, false, inf);
double refC4 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, 0., true, inf);
double refP4 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, 0., false, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 6; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e9);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.thetaMod(1.e-12, strike, TIME_TO_EXPIRY, vol, true, 1.e-12);
double resC2 = BlackFormulaRepository.thetaMod(1.e12, strike, TIME_TO_EXPIRY, vol, true, 1.e-12);
double resP1 = BlackFormulaRepository.thetaMod(1.e-12, strike, TIME_TO_EXPIRY, vol, false, 1.e-12);
double resP2 = BlackFormulaRepository.thetaMod(1.e12, strike, TIME_TO_EXPIRY, vol, false, 1.e-12);
double resC3 = BlackFormulaRepository.thetaMod(1.e12, strike, TIME_TO_EXPIRY, vol, true, 1.e12);
double resP3 = BlackFormulaRepository.thetaMod(1.e12, strike, TIME_TO_EXPIRY, vol, false, 1.e12);
double resC4 = BlackFormulaRepository.thetaMod(1.e-12, strike, TIME_TO_EXPIRY, vol, true, 1.e12);
double resP4 = BlackFormulaRepository.thetaMod(1.e-12, strike, TIME_TO_EXPIRY, vol, false, 1.e12);
double refC1 = BlackFormulaRepository.thetaMod(0., strike, TIME_TO_EXPIRY, vol, true, 0.);
double refC2 = BlackFormulaRepository.thetaMod(inf, strike, TIME_TO_EXPIRY, vol, true, 0.);
double refP1 = BlackFormulaRepository.thetaMod(0., strike, TIME_TO_EXPIRY, vol, false, 0.);
double refP2 = BlackFormulaRepository.thetaMod(inf, strike, TIME_TO_EXPIRY, vol, false, 0.);
double refC3 = BlackFormulaRepository.thetaMod(inf, strike, TIME_TO_EXPIRY, vol, true, inf);
double refP3 = BlackFormulaRepository.thetaMod(inf, strike, TIME_TO_EXPIRY, vol, false, inf);
double refC4 = BlackFormulaRepository.thetaMod(0., strike, TIME_TO_EXPIRY, vol, true, inf);
double refP4 = BlackFormulaRepository.thetaMod(0., strike, TIME_TO_EXPIRY, vol, false, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4};
for (int k = 0; k < 8; ++k) {
if (k != 2 && k != 7) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.max(Math.abs(refVec[k]) * 1.e-9, 1.e-9));
}
}
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.thetaMod(1.e-12, 1.e-12, 1.e-24, vol, true, 0.05);
double resC2 = BlackFormulaRepository.thetaMod(1.e-12, 1.e-12, 1.e24, vol, true, 0.05);
double resC3 = BlackFormulaRepository.thetaMod(1.e-12, 1.e12, 1.e-24, vol, true, 0.05);
double resP1 = BlackFormulaRepository.thetaMod(1.e-12, 1.e-12, 1.e-24, vol, false, 0.05);
double resP2 = BlackFormulaRepository.thetaMod(1.e-12, 1.e-12, 1.e24, vol, false, 0.05);
double resP3 = BlackFormulaRepository.thetaMod(1.e-12, 1.e12, 1.e-24, vol, false, 0.05);
double resC4 = BlackFormulaRepository.thetaMod(1.e12, 1.e-12, 1.e-24, vol, true, 0.05);
double resP4 = BlackFormulaRepository.thetaMod(1.e12, 1.e-12, 1.e-24, vol, false, 0.05);
double resC5 = BlackFormulaRepository.thetaMod(FORWARD, FORWARD * (1. + 1.e-12), 1.e-24, vol, true, 0.05);
double resP5 = BlackFormulaRepository.thetaMod(FORWARD, FORWARD * (1. + 1.e-12), 1.e-24, vol, false, 0.05);
double resC6 = BlackFormulaRepository.thetaMod(1.e12, 1.e12, 1.e24, vol, true, 0.05);
double resP6 = BlackFormulaRepository.thetaMod(1.e12, 1.e12, 1.e24, vol, false, 0.05);
double refC1 = BlackFormulaRepository.thetaMod(0., 0., 0., vol, true, 0.05);
double refC2 = BlackFormulaRepository.thetaMod(0., 0., inf, vol, true, 0.05);
double refC3 = BlackFormulaRepository.thetaMod(0., inf, 0., vol, true, 0.05);
double refP1 = BlackFormulaRepository.thetaMod(0., 0., 0., vol, false, 0.05);
double refP2 = BlackFormulaRepository.thetaMod(0., 0., inf, vol, false, 0.05);
double refP3 = BlackFormulaRepository.thetaMod(0., inf, 0., vol, false, 0.05);
double refC4 = BlackFormulaRepository.thetaMod(inf, 0., 0., vol, true, 0.05);
double refP4 = BlackFormulaRepository.thetaMod(inf, 0., 0., vol, false, 0.05);
double refC5 = BlackFormulaRepository.thetaMod(FORWARD, FORWARD, 0., vol, true, 0.05);
double refP5 = BlackFormulaRepository.thetaMod(FORWARD, FORWARD, 0., vol, false, 0.05);
double refC6 = BlackFormulaRepository.thetaMod(inf, inf, inf, vol, true, 0.05);
double refP6 = BlackFormulaRepository.thetaMod(inf, inf, inf, vol, false, 0.05);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6};
for (int k = 0; k < 12; ++k) {
if ((refVec[k] != -0.5 * vol) && (refVec[k] != -0.5 * FORWARD) && (refVec[k] != Double.NEGATIVE_INFINITY) &&
k != 11) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-7);// //should be rechecked
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
{
double resC1 = BlackFormulaRepository.thetaMod(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, true, 0.05);
double resC2 = BlackFormulaRepository.thetaMod(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12, true, 0.05);
double resC3 = BlackFormulaRepository.thetaMod(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12, true, 0.05);
double resP1 = BlackFormulaRepository.thetaMod(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, false, 0.05);
double resP2 = BlackFormulaRepository.thetaMod(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12, false, 0.05);
double resP3 = BlackFormulaRepository.thetaMod(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12, false, 0.05);
double resC4 = BlackFormulaRepository.thetaMod(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, true, 0.05);
double resP4 = BlackFormulaRepository.thetaMod(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12, false, 0.05);
double resC5 = BlackFormulaRepository.thetaMod(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12,
true, 0.05);
double resP5 = BlackFormulaRepository.thetaMod(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12,
false, 0.05);
double resC6 = BlackFormulaRepository.thetaMod(1.e12, 1.e12, TIME_TO_EXPIRY, 1.e24, true, 0.05);
double resP6 = BlackFormulaRepository.thetaMod(1.e12, 1.e12, TIME_TO_EXPIRY, 1.e24, false, 0.05);
double refC1 = BlackFormulaRepository.thetaMod(0., 0., TIME_TO_EXPIRY, 0., true, 0.05);
double refC2 = BlackFormulaRepository.thetaMod(0., 0., TIME_TO_EXPIRY, inf, true, 0.05);
double refC3 = BlackFormulaRepository.thetaMod(0., inf, TIME_TO_EXPIRY, 0., true, 0.05);
double refP1 = BlackFormulaRepository.thetaMod(0., 0., TIME_TO_EXPIRY, 0., false, 0.05);
double refP2 = BlackFormulaRepository.thetaMod(0., 0., TIME_TO_EXPIRY, inf, false, 0.05);
double refP3 = BlackFormulaRepository.thetaMod(0., inf, TIME_TO_EXPIRY, 0., false, 0.05);
double refC4 = BlackFormulaRepository.thetaMod(inf, 0., TIME_TO_EXPIRY, 0., true, 0.05);
double refP4 = BlackFormulaRepository.thetaMod(inf, 0., TIME_TO_EXPIRY, 0., false, 0.05);
double refC5 = BlackFormulaRepository.thetaMod(FORWARD, FORWARD, TIME_TO_EXPIRY, 0., true, 0.05);
double refP5 = BlackFormulaRepository.thetaMod(FORWARD, FORWARD, TIME_TO_EXPIRY, 0., false, 0.05);
double refC6 = BlackFormulaRepository.thetaMod(inf, inf, TIME_TO_EXPIRY, inf, true, 0.05);
double refP6 = BlackFormulaRepository.thetaMod(inf, inf, TIME_TO_EXPIRY, inf, false, 0.05);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC6, resP6,
resC5, resP5};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC6, refP6,
refC5, refP5};
for (int k = 0; k < 10; ++k) {// The last two cases return reference values
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.thetaMod(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol, true, 1.e-12);
double resC2 = BlackFormulaRepository.thetaMod(1.e-12, 1.e12, TIME_TO_EXPIRY, vol, true, 1.e-12);
double resC3 = BlackFormulaRepository.thetaMod(1.e12, 1.e-12, TIME_TO_EXPIRY, vol, true, 1.e-12);
double resP1 = BlackFormulaRepository.thetaMod(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol, false, 1.e-12);
double resP2 = BlackFormulaRepository.thetaMod(1.e-12, 1.e12, TIME_TO_EXPIRY, vol, false, 1.e-12);
double resP3 = BlackFormulaRepository.thetaMod(1.e12, 1.e-12, TIME_TO_EXPIRY, vol, false, 1.e-12);
double resC4 = BlackFormulaRepository.thetaMod(1.e12, 1.e12, TIME_TO_EXPIRY, vol, true, 1.e12);
double resP4 = BlackFormulaRepository.thetaMod(1.e12, 1.e12, TIME_TO_EXPIRY, vol, false, 1.e12);
double resC5 = BlackFormulaRepository.thetaMod(1.e12, 1.e-12, TIME_TO_EXPIRY, vol, true, 1.e12);
double resP5 = BlackFormulaRepository.thetaMod(1.e12, 1.e-12, TIME_TO_EXPIRY, vol, false, 1.e12);
double resC6 = BlackFormulaRepository.thetaMod(1.e-12, 1.e12, TIME_TO_EXPIRY, vol, true, 1.e12);
double resP6 = BlackFormulaRepository.thetaMod(1.e-12, 1.e12, TIME_TO_EXPIRY, vol, false, 1.e12);
double resC7 = BlackFormulaRepository.thetaMod(1.e-12, 2.e-12, TIME_TO_EXPIRY, vol, true, 1.e12);
double resP7 = BlackFormulaRepository.thetaMod(1.e-12, 0.5e-12, TIME_TO_EXPIRY, vol, false, 1.e12);
double resC8 = BlackFormulaRepository.thetaMod(1.e12, 1.e12, TIME_TO_EXPIRY, vol, true, 1.e-12);
double resP8 = BlackFormulaRepository.thetaMod(1.e12, 1.e12, TIME_TO_EXPIRY, vol, false, 1.e-12);
double refC1 = BlackFormulaRepository.thetaMod(0., 0., TIME_TO_EXPIRY, vol, true, 0.);
double refC2 = BlackFormulaRepository.thetaMod(0., inf, TIME_TO_EXPIRY, vol, true, 0.);
double refC3 = BlackFormulaRepository.thetaMod(inf, 0., TIME_TO_EXPIRY, vol, true, 0.);
double refP1 = BlackFormulaRepository.thetaMod(0., 0., TIME_TO_EXPIRY, vol, false, 0.);
double refP2 = BlackFormulaRepository.thetaMod(0., inf, TIME_TO_EXPIRY, vol, false, 0.);
double refP3 = BlackFormulaRepository.thetaMod(inf, 0., TIME_TO_EXPIRY, vol, false, 0.);
double refC4 = BlackFormulaRepository.thetaMod(inf, inf, TIME_TO_EXPIRY, vol, true, inf);
double refP4 = BlackFormulaRepository.thetaMod(inf, inf, TIME_TO_EXPIRY, vol, false, inf);
double refC5 = BlackFormulaRepository.thetaMod(inf, 0., TIME_TO_EXPIRY, vol, true, inf);
double refP5 = BlackFormulaRepository.thetaMod(inf, 0., TIME_TO_EXPIRY, vol, false, inf);
double refC6 = BlackFormulaRepository.thetaMod(0., inf, TIME_TO_EXPIRY, vol, true, inf);
double refP6 = BlackFormulaRepository.thetaMod(0., inf, TIME_TO_EXPIRY, vol, false, inf);
double refC7 = BlackFormulaRepository.thetaMod(0., 0., TIME_TO_EXPIRY, vol, true, inf);
double refP7 = BlackFormulaRepository.thetaMod(0., 0., TIME_TO_EXPIRY, vol, false, inf);
double refC8 = BlackFormulaRepository.thetaMod(inf, inf, TIME_TO_EXPIRY, vol, true, 0.);
double refP8 = BlackFormulaRepository.thetaMod(inf, inf, TIME_TO_EXPIRY, vol, false, 0.);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7, resC8, resP8};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7, refC8, refP8};
for (int k = 0; k < 14; ++k) {
if (k != 3 && k != 8) {
if (k != 12 && k != 13) {// ref values are returned
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e9);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e9);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.thetaMod(1.e-12, strike, 1.e-24, vol, true, 1.e-12);
double resC2 = BlackFormulaRepository.thetaMod(1.e-12, strike, 1.e24, vol, true, 1.e-12);
double resC3 = BlackFormulaRepository.thetaMod(1.e12, strike, 1.e-24, vol, true, 1.e-12);
double resP1 = BlackFormulaRepository.thetaMod(1.e-12, strike, 1.e-24, vol, false, 1.e-12);
double resP2 = BlackFormulaRepository.thetaMod(1.e-12, strike, 1.e24, vol, false, 1.e-12);
double resP3 = BlackFormulaRepository.thetaMod(1.e12, strike, 1.e-24, vol, false, 1.e-12);
double resC4 = BlackFormulaRepository.thetaMod(1.e12, strike, 1.e24, vol, true, 1.e12);
double resP4 = BlackFormulaRepository.thetaMod(1.e12, strike, 1.e24, vol, false, 1.e12);
double resC5 = BlackFormulaRepository.thetaMod(1.e-12, strike, 1.e24, vol, true, 1.e12);
double resP5 = BlackFormulaRepository.thetaMod(1.e-12, strike, 1.e24, vol, false, 1.e12);
double resC6 = BlackFormulaRepository.thetaMod(1.e12, strike, 1.e-24, vol, true, 1.e12);
double resP6 = BlackFormulaRepository.thetaMod(1.e12, strike, 1.e-24, vol, false, 1.e12);
double resC7 = BlackFormulaRepository.thetaMod(1.e12, strike, 1.e24, vol, true, 1.e-12);
double resP7 = BlackFormulaRepository.thetaMod(1.e12, strike, 1.e24, vol, false, 1.e-12);
double resC8 = BlackFormulaRepository.thetaMod(1.e-12, strike, 1.e-24, vol, true, 1.e12);
double resP8 = BlackFormulaRepository.thetaMod(1.e-12, strike, 1.e-24, vol, false, 1.e12);
double refC1 = BlackFormulaRepository.thetaMod(0., strike, 0., vol, true, 0.);
double refC2 = BlackFormulaRepository.thetaMod(0., strike, inf, vol, true, 0.);
double refC3 = BlackFormulaRepository.thetaMod(inf, strike, 0., vol, true, 0.);
double refP1 = BlackFormulaRepository.thetaMod(0., strike, 0., vol, false, 0.);
double refP2 = BlackFormulaRepository.thetaMod(0., strike, inf, vol, false, 0.);
double refP3 = BlackFormulaRepository.thetaMod(inf, strike, 0., vol, false, 0.);
double refC4 = BlackFormulaRepository.thetaMod(inf, strike, inf, vol, true, inf);
double refP4 = BlackFormulaRepository.thetaMod(inf, strike, inf, vol, false, inf);
double refC5 = BlackFormulaRepository.thetaMod(0., strike, inf, vol, true, inf);
double refP5 = BlackFormulaRepository.thetaMod(0., strike, inf, vol, false, inf);
double refC6 = BlackFormulaRepository.thetaMod(inf, strike, 0., vol, true, inf);
double refP6 = BlackFormulaRepository.thetaMod(inf, strike, 0., vol, false, inf);
double refC7 = BlackFormulaRepository.thetaMod(inf, strike, inf, vol, true, 0.);
double refP7 = BlackFormulaRepository.thetaMod(inf, strike, inf, vol, false, 0.);
double refC8 = BlackFormulaRepository.thetaMod(0., strike, 0., vol, true, inf);
double refP8 = BlackFormulaRepository.thetaMod(0., strike, 0., vol, false, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7, resC8, resP8};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7, refC8, refP8};
for (int k = 0; k < 16; ++k) {
if (k != 4 && k != 8 && k != 12) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-9);
}
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.thetaMod(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12, true, 1.e-12);
double resC2 = BlackFormulaRepository.thetaMod(1.e-12, strike, TIME_TO_EXPIRY, 1.e12, true, 1.e-12);
double resC3 = BlackFormulaRepository.thetaMod(1.e12, strike, TIME_TO_EXPIRY, 1.e-12, true, 1.e-12);
double resP1 = BlackFormulaRepository.thetaMod(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12, false, 1.e-12);
double resP2 = BlackFormulaRepository.thetaMod(1.e-12, strike, TIME_TO_EXPIRY, 1.e12, false, 1.e-12);
double resP3 = BlackFormulaRepository.thetaMod(1.e12, strike, TIME_TO_EXPIRY, 1.e-12, false, 1.e-12);
double resC4 = BlackFormulaRepository.thetaMod(1.e12, strike, TIME_TO_EXPIRY, 1.e12, true, 1.e12);
double resP4 = BlackFormulaRepository.thetaMod(1.e12, strike, TIME_TO_EXPIRY, 1.e12, false, 1.e12);
double resC5 = BlackFormulaRepository.thetaMod(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12, true, 1.e12);
double resP5 = BlackFormulaRepository.thetaMod(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12, false, 1.e12);
double resC6 = BlackFormulaRepository.thetaMod(1.e12, strike, TIME_TO_EXPIRY, 1.e-12, true, 1.e12);
double resP6 = BlackFormulaRepository.thetaMod(1.e12, strike, TIME_TO_EXPIRY, 1.e-12, false, 1.e12);
double resC7 = BlackFormulaRepository.thetaMod(1.e-12, strike, TIME_TO_EXPIRY, 1.e12, true, 1.e12);
double resP7 = BlackFormulaRepository.thetaMod(1.e-12, strike, TIME_TO_EXPIRY, 1.e12, false, 1.e12);
double resC8 = BlackFormulaRepository.thetaMod(1.e12, strike, TIME_TO_EXPIRY, 1.e12, true, 1.e-12);
double resP8 = BlackFormulaRepository.thetaMod(1.e12, strike, TIME_TO_EXPIRY, 1.e12, false, 1.e-12);
double refC1 = BlackFormulaRepository.thetaMod(0., strike, TIME_TO_EXPIRY, 0., true, 0.);
double refC2 = BlackFormulaRepository.thetaMod(0., strike, TIME_TO_EXPIRY, inf, true, 0.);
double refC3 = BlackFormulaRepository.thetaMod(inf, strike, TIME_TO_EXPIRY, 0., true, 0.);
double refP1 = BlackFormulaRepository.thetaMod(0., strike, TIME_TO_EXPIRY, 0., false, 0.);
double refP2 = BlackFormulaRepository.thetaMod(0., strike, TIME_TO_EXPIRY, inf, false, 0.);
double refP3 = BlackFormulaRepository.thetaMod(inf, strike, TIME_TO_EXPIRY, 0., false, 0.);
double refC4 = BlackFormulaRepository.thetaMod(inf, strike, TIME_TO_EXPIRY, inf, true, inf);
double refP4 = BlackFormulaRepository.thetaMod(inf, strike, TIME_TO_EXPIRY, inf, false, inf);
double refC5 = BlackFormulaRepository.thetaMod(0., strike, TIME_TO_EXPIRY, 0., true, inf);
double refP5 = BlackFormulaRepository.thetaMod(0., strike, TIME_TO_EXPIRY, 0., false, inf);
double refC6 = BlackFormulaRepository.thetaMod(inf, strike, TIME_TO_EXPIRY, 0., true, inf);
double refP6 = BlackFormulaRepository.thetaMod(inf, strike, TIME_TO_EXPIRY, 0., false, inf);
double refC7 = BlackFormulaRepository.thetaMod(0., strike, TIME_TO_EXPIRY, inf, true, inf);
double refP7 = BlackFormulaRepository.thetaMod(0., strike, TIME_TO_EXPIRY, inf, false, inf);
double refC8 = BlackFormulaRepository.thetaMod(inf, strike, TIME_TO_EXPIRY, inf, true, 0.);
double refP8 = BlackFormulaRepository.thetaMod(inf, strike, TIME_TO_EXPIRY, inf, false, 0.);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7, resC8, resP8};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7, refC8, refP8};
for (int k = 0; k < 16; ++k) {
if (k != 9 && k != 10) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-9);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.thetaMod(forward, 1.e-12, 1.e-24, vol, true, 1.e-12);
double resC2 = BlackFormulaRepository.thetaMod(forward, 1.e-12, 1.e24, vol, true, 1.e-12);
double resC3 = BlackFormulaRepository.thetaMod(forward, 1.e12, 1.e-24, vol, true, 1.e-12);
double resP1 = BlackFormulaRepository.thetaMod(forward, 1.e-12, 1.e-24, vol, false, 1.e-12);
double resP2 = BlackFormulaRepository.thetaMod(forward, 1.e-12, 1.e24, vol, false, 1.e-12);
double resP3 = BlackFormulaRepository.thetaMod(forward, 1.e12, 1.e-24, vol, false, 1.e-12);
double resC4 = BlackFormulaRepository.thetaMod(forward, 1.e12, 1.e24, vol, true, 1.e12);
double resP4 = BlackFormulaRepository.thetaMod(forward, 1.e12, 1.e24, vol, false, 1.e12);
double resC5 = BlackFormulaRepository.thetaMod(forward, 1.e-12, 1.e24, vol, true, 1.e12);
double resP5 = BlackFormulaRepository.thetaMod(forward, 1.e-12, 1.e24, vol, false, 1.e12);
double resC6 = BlackFormulaRepository.thetaMod(forward, 1.e12, 1.e-12, vol, true, 1.e12);
double resP6 = BlackFormulaRepository.thetaMod(forward, 1.e12, 1.e-12, vol, false, 1.e12);
double resC7 = BlackFormulaRepository.thetaMod(forward, 1.e-12, 1.e-12, vol, true, 1.e12);
double resP7 = BlackFormulaRepository.thetaMod(forward, 1.e-12, 1.e-12, vol, false, 1.e12);
double resC8 = BlackFormulaRepository.thetaMod(forward, 1.e12, 1.e24, vol, true, 1.e-12);
double resP8 = BlackFormulaRepository.thetaMod(forward, 1.e12, 1.e24, vol, false, 1.e-12);
double refC1 = BlackFormulaRepository.thetaMod(forward, 0., 0., vol, true, 0.);
double refC2 = BlackFormulaRepository.thetaMod(forward, 0., inf, vol, true, 0.);
double refC3 = BlackFormulaRepository.thetaMod(forward, inf, 0., vol, true, 0.);
double refP1 = BlackFormulaRepository.thetaMod(forward, 0., 0., vol, false, 0.);
double refP2 = BlackFormulaRepository.thetaMod(forward, 0., inf, vol, false, 0.);
double refP3 = BlackFormulaRepository.thetaMod(forward, inf, 0., vol, false, 0.);
double refC4 = BlackFormulaRepository.thetaMod(forward, inf, inf, vol, true, inf);
double refP4 = BlackFormulaRepository.thetaMod(forward, inf, inf, vol, false, inf);
double refC5 = BlackFormulaRepository.thetaMod(forward, 0., inf, vol, true, inf);
double refP5 = BlackFormulaRepository.thetaMod(forward, 0., inf, vol, false, inf);
double refC6 = BlackFormulaRepository.thetaMod(forward, inf, 0., vol, true, inf);
double refP6 = BlackFormulaRepository.thetaMod(forward, inf, 0., vol, false, inf);
double refC7 = BlackFormulaRepository.thetaMod(forward, 0., inf, vol, true, inf);
double refP7 = BlackFormulaRepository.thetaMod(forward, 0., inf, vol, false, inf);
double refC8 = BlackFormulaRepository.thetaMod(forward, 0., 0., vol, true, inf);
double refP8 = BlackFormulaRepository.thetaMod(forward, 0., 0., vol, false, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7, resC8, resP8};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7, refC8, refP8};
for (int k = 0; k < 14; ++k) {// some of ref values skipped
if (k != 5 && k != 9 && k != 12) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-9);
}
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double forward = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.thetaMod(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12, true, 1.e-12);
double resC2 = BlackFormulaRepository.thetaMod(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12, true, 1.e-12);
double resC3 = BlackFormulaRepository.thetaMod(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12, true, 1.e-12);
double resP1 = BlackFormulaRepository.thetaMod(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12, false, 1.e-12);
double resP2 = BlackFormulaRepository.thetaMod(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12, false, 1.e-12);
double resP3 = BlackFormulaRepository.thetaMod(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12, false, 1.e-12);
double resC4 = BlackFormulaRepository.thetaMod(forward, 1.e12, TIME_TO_EXPIRY, 1.e12, true, 1.e12);
double resP4 = BlackFormulaRepository.thetaMod(forward, 1.e12, TIME_TO_EXPIRY, 1.e12, false, 1.e12);
double resC5 = BlackFormulaRepository.thetaMod(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12, true, 1.e12);
double resP5 = BlackFormulaRepository.thetaMod(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12, false, 1.e12);
double resC6 = BlackFormulaRepository.thetaMod(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12, true, 1.e12);
double resP6 = BlackFormulaRepository.thetaMod(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12, false, 1.e12);
double resC7 = BlackFormulaRepository.thetaMod(forward, 1.e12, TIME_TO_EXPIRY, 1.e12, true, 1.e-12);
double resP7 = BlackFormulaRepository.thetaMod(forward, 1.e12, TIME_TO_EXPIRY, 1.e12, false, 1.e-12);
double resC8 = BlackFormulaRepository.thetaMod(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12, true, 1.e12);
double resP8 = BlackFormulaRepository.thetaMod(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12, false, 1.e12);
double refC1 = BlackFormulaRepository.thetaMod(forward, 0., TIME_TO_EXPIRY, 0., true, 0.);
double refC2 = BlackFormulaRepository.thetaMod(forward, 0., TIME_TO_EXPIRY, inf, true, 0.);
double refC3 = BlackFormulaRepository.thetaMod(forward, inf, TIME_TO_EXPIRY, 0., true, 0.);
double refP1 = BlackFormulaRepository.thetaMod(forward, 0., TIME_TO_EXPIRY, 0., false, 0.);
double refP2 = BlackFormulaRepository.thetaMod(forward, 0., TIME_TO_EXPIRY, inf, false, 0.);
double refP3 = BlackFormulaRepository.thetaMod(forward, inf, TIME_TO_EXPIRY, 0., false, 0.);
double refC4 = BlackFormulaRepository.thetaMod(forward, inf, TIME_TO_EXPIRY, inf, true, inf);
double refP4 = BlackFormulaRepository.thetaMod(forward, inf, TIME_TO_EXPIRY, inf, false, inf);
double refC5 = BlackFormulaRepository.thetaMod(forward, 0., TIME_TO_EXPIRY, inf, true, inf);
double refP5 = BlackFormulaRepository.thetaMod(forward, 0., TIME_TO_EXPIRY, inf, false, inf);
double refC6 = BlackFormulaRepository.thetaMod(forward, inf, TIME_TO_EXPIRY, 0., true, inf);
double refP6 = BlackFormulaRepository.thetaMod(forward, inf, TIME_TO_EXPIRY, 0., false, inf);
double refC7 = BlackFormulaRepository.thetaMod(forward, inf, TIME_TO_EXPIRY, inf, true, 0.);
double refP7 = BlackFormulaRepository.thetaMod(forward, inf, TIME_TO_EXPIRY, inf, false, 0.);
double refC8 = BlackFormulaRepository.thetaMod(forward, 0., TIME_TO_EXPIRY, 0., true, inf);
double refP8 = BlackFormulaRepository.thetaMod(forward, 0., TIME_TO_EXPIRY, 0., false, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7, resC8, resP8};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7, refC8, refP8};
for (int k = 0; k < 16; ++k) {
if (k != 5 && k != 9 && k != 11 && k != 13 && k != 14) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-9);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.thetaMod(strike, strike, inf, 0., true, 1.);
double resP1 = BlackFormulaRepository.thetaMod(strike, strike, inf, 0., false, 1.);
double resC2 = BlackFormulaRepository.thetaMod(strike, strike, inf, 0., true, 0.);
double resP2 = BlackFormulaRepository.thetaMod(strike, strike, inf, 0., false, 0.);
double refC1 = strike * (NORMAL.getCDF(0.5));
double refP1 = -strike * (NORMAL.getCDF(-0.5));
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {refC1, refP1, 0., 0.};
for (int k = 2; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.max(Math.abs(refVec[k]) * 1.e-10, 1.e-10));
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, VOLS[0], true, -inf);
double resP1 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, VOLS[1], false, -inf);
double resC2 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, VOLS[2], true, -inf);
double resP2 = BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, VOLS[3], false, -inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2};
double[] refVec = new double[] {0., 0., 0., 0.};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.max(Math.abs(refVec[k]) * 1.e-10, 1.e-10));
}
}
}
}
}
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeVolErrorthetaModTest() {
BlackFormulaRepository.thetaMod(FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, -0.5, true, 0.1);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeFwdErrorthetaModTest() {
BlackFormulaRepository.thetaMod(-FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1], true, 0.1);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeStrikeErrorthetaModTest() {
BlackFormulaRepository.thetaMod(FORWARD, -STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1], true, 0.1);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeTimeErrorthetaModTest() {
BlackFormulaRepository.thetaMod(FORWARD, STRIKES_INPUT[1], -TIME_TO_EXPIRY, VOLS[1], true, 0.1);
}
public void consistencyWithBlackScholestest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
double interestRate = 0.02;
double df = Math.exp(-interestRate * TIME_TO_EXPIRY);
double spot = FORWARD * df;
boolean[] tfSet = new boolean[] {true, false};
for (boolean isCall : tfSet) {
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double price1 = df *
BlackFormulaRepository.thetaMod(FORWARD, strike, TIME_TO_EXPIRY, vol, isCall, interestRate);
double price2 = BlackScholesFormulaRepository.theta(spot, strike, TIME_TO_EXPIRY, vol, interestRate,
interestRate, isCall);
assertEquals(price1, price2, 1.e-14);
}
}
}
}
/*
* vega
*/
/**
* large/small input
*/
public void exVegaTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
double inf = Double.POSITIVE_INFINITY;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.vega(1.e-12 * strike, strike, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.vega(0., strike, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.vega(1.e12 * strike, strike, TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.vega(inf, strike, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-11);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-11);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.vega(forward, 1.e-12 * forward, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.vega(forward, 1.e12 * forward, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.vega(forward, 0., TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.vega(forward, inf, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.vega(FORWARD, strike, 1e-24, vol);
double resC2 = BlackFormulaRepository.vega(FORWARD, strike, 1e24, vol);
double refC1 = BlackFormulaRepository.vega(FORWARD, strike, 0., vol);
double refC2 = BlackFormulaRepository.vega(FORWARD, strike, inf, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.vega(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12);
double refC1 = BlackFormulaRepository.vega(FORWARD, strike, TIME_TO_EXPIRY, 0.);
double resC2 = BlackFormulaRepository.vega(FORWARD, strike, TIME_TO_EXPIRY, 1.e12);
double refC2 = BlackFormulaRepository.vega(FORWARD, strike, TIME_TO_EXPIRY, inf);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.vega(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.vega(1.e-12, 1.e12, TIME_TO_EXPIRY, vol);
double resC3 = BlackFormulaRepository.vega(1.e12, 1.e-12, TIME_TO_EXPIRY, vol);
double resP3 = BlackFormulaRepository.vega(1.e12, 1.e12, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.vega(0., 0., TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.vega(0., inf, TIME_TO_EXPIRY, vol);
double refC3 = BlackFormulaRepository.vega(inf, 0., TIME_TO_EXPIRY, vol);
double refP3 = BlackFormulaRepository.vega(inf, inf, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e12) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e12) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.vega(1.e-12, strike, 1.e-24, vol);
double resC2 = BlackFormulaRepository.vega(1.e-12, strike, 1.e24, vol);
double resC3 = BlackFormulaRepository.vega(1.e12, strike, 1.e-24, vol);
double resP3 = BlackFormulaRepository.vega(1.e12, strike, 1.e24, vol);
double refC1 = BlackFormulaRepository.vega(0., strike, 0., vol);
double refC2 = BlackFormulaRepository.vega(0., strike, inf, vol);
double refC3 = BlackFormulaRepository.vega(inf, strike, 0., vol);
double refP3 = BlackFormulaRepository.vega(inf, strike, inf, vol);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.vega(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.vega(1.e-12, strike, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.vega(1.e12, strike, TIME_TO_EXPIRY, 1.e-12);
double resP3 = BlackFormulaRepository.vega(1.e12, strike, TIME_TO_EXPIRY, 1.e12);
double refC1 = BlackFormulaRepository.vega(0., strike, TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.vega(0., strike, TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.vega(inf, strike, TIME_TO_EXPIRY, 0.);
double refP3 = BlackFormulaRepository.vega(inf, strike, TIME_TO_EXPIRY, inf);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.vega(forward, 1.e-12, 1.e-24, vol);
double resC2 = BlackFormulaRepository.vega(forward, 1.e-12, 1.e24, vol);
double resC3 = BlackFormulaRepository.vega(forward, 1.e12, 1.e-24, vol);
double resP3 = BlackFormulaRepository.vega(forward, 1.e12, 1.e24, vol);
double refC1 = BlackFormulaRepository.vega(forward, 0., 0., vol);
double refC2 = BlackFormulaRepository.vega(forward, 0., inf, vol);
double refC3 = BlackFormulaRepository.vega(forward, inf, 0., vol);
double refP3 = BlackFormulaRepository.vega(forward, inf, inf, vol);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double forward = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.vega(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.vega(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.vega(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double resP3 = BlackFormulaRepository.vega(forward, 1.e12, TIME_TO_EXPIRY, 1.e12);
double refC1 = BlackFormulaRepository.vega(forward, 0., TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.vega(forward, 0., TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.vega(forward, inf, TIME_TO_EXPIRY, 0.);
double refP3 = BlackFormulaRepository.vega(forward, inf, TIME_TO_EXPIRY, inf);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.vega(1.e-12, 1.e-14, 1.e-24, vol);
double resC2 = BlackFormulaRepository.vega(1.e-12, 1.e-12, 1.e24, vol);
double resC3 = BlackFormulaRepository.vega(1.e-12, 1.e12, 1.e-24, vol);
double resP1 = BlackFormulaRepository.vega(1.e-12, 1.e-14, 1.e-24, vol);
double resP2 = BlackFormulaRepository.vega(1.e-12, 1.e-12, 1.e24, vol);
double resP3 = BlackFormulaRepository.vega(1.e-12, 1.e12, 1.e-24, vol);
double resC4 = BlackFormulaRepository.vega(1.e12, 1.e-12, 1.e-24, vol);
double resP4 = BlackFormulaRepository.vega(1.e12, 1.e-12, 1.e-24, vol);
double resC5 = BlackFormulaRepository.vega(FORWARD, FORWARD * (1. + 1.e-14), 1.e-24, vol);
double resP5 = BlackFormulaRepository.vega(FORWARD, FORWARD * (1. + 1.e-14), 1.e-24, vol);
double resC6 = BlackFormulaRepository.vega(1.e12, 1.e12, 1.e24, vol);
double resP6 = BlackFormulaRepository.vega(1.e12, 1.e-12, 1.e24, vol);
double resC7 = BlackFormulaRepository.vega(1.e12, 1.e12, 1.e-24, vol);
double resP7 = BlackFormulaRepository.vega(1.e-12, 1.e12, 1.e24, vol);
double refC1 = BlackFormulaRepository.vega(0., 0., 0., vol);
double refC2 = BlackFormulaRepository.vega(0., 0., inf, vol);
double refC3 = BlackFormulaRepository.vega(0., inf, 0., vol);
double refP1 = BlackFormulaRepository.vega(0., 0., 0., vol);
double refP2 = BlackFormulaRepository.vega(0., 0., inf, vol);
double refP3 = BlackFormulaRepository.vega(0., inf, 0., vol);
double refC4 = BlackFormulaRepository.vega(inf, 0., 0., vol);
double refP4 = BlackFormulaRepository.vega(inf, 0., 0., vol);
double refC5 = BlackFormulaRepository.vega(FORWARD, FORWARD, 0., vol);
double refP5 = BlackFormulaRepository.vega(FORWARD, FORWARD, 0., vol);
double refC6 = BlackFormulaRepository.vega(inf, inf, inf, vol);
double refP6 = BlackFormulaRepository.vega(inf, 0., inf, vol);
double refC7 = BlackFormulaRepository.vega(inf, inf, 0., vol);
double refP7 = BlackFormulaRepository.vega(0., inf, inf, vol);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7};
for (int k = 0; k < 14; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
{
double resC1 = BlackFormulaRepository.vega(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.vega(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.vega(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double resP1 = BlackFormulaRepository.vega(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resP2 = BlackFormulaRepository.vega(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resP3 = BlackFormulaRepository.vega(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double resC4 = BlackFormulaRepository.vega(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resP4 = BlackFormulaRepository.vega(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC5 = BlackFormulaRepository.vega(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12);
double resP5 = BlackFormulaRepository.vega(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12);
double resC6 = BlackFormulaRepository.vega(1.e12, 1.e12, TIME_TO_EXPIRY, 1.e12);
double resP6 = BlackFormulaRepository.vega(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resC7 = BlackFormulaRepository.vega(1.e12, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double resP7 = BlackFormulaRepository.vega(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e12);
double refC1 = BlackFormulaRepository.vega(0., 0., TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.vega(0., 0., TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.vega(0., inf, TIME_TO_EXPIRY, 0.);
double refP1 = BlackFormulaRepository.vega(0., 0., TIME_TO_EXPIRY, 0.);
double refP2 = BlackFormulaRepository.vega(0., 0., TIME_TO_EXPIRY, inf);
double refP3 = BlackFormulaRepository.vega(0., inf, TIME_TO_EXPIRY, 0.);
double refC4 = BlackFormulaRepository.vega(inf, 0., TIME_TO_EXPIRY, 0.);
double refP4 = BlackFormulaRepository.vega(inf, 0., TIME_TO_EXPIRY, 0.);
double refC5 = BlackFormulaRepository.vega(FORWARD, FORWARD, TIME_TO_EXPIRY, 0.);
double refP5 = BlackFormulaRepository.vega(FORWARD, FORWARD, TIME_TO_EXPIRY, 0.);
double refC6 = BlackFormulaRepository.vega(inf, inf, TIME_TO_EXPIRY, inf);
double refP6 = BlackFormulaRepository.vega(inf, 0., TIME_TO_EXPIRY, inf);
double refC7 = BlackFormulaRepository.vega(inf, inf, TIME_TO_EXPIRY, 0.);
double refP7 = BlackFormulaRepository.vega(0., inf, TIME_TO_EXPIRY, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7};
for (int k = 0; k < 14; ++k) {
if (refVec[k] != FORWARD * Math.sqrt(TIME_TO_EXPIRY) * NORMAL.getPDF(0.)) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (Math.abs(refVec[k]) < 1.e-10) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double resC1 = BlackFormulaRepository.vega(FORWARD, 1.e-12, 1.e-24, 1.e-12);
double resC2 = BlackFormulaRepository.vega(FORWARD, 1.e-12, 1.e-24, 1.e12);
double resC3 = BlackFormulaRepository.vega(FORWARD, 1.e-12, 1.e24, 1.e-12);
double resP1 = BlackFormulaRepository.vega(FORWARD, 1.e-12, 1.e-24, 1.e-12);
double resP2 = BlackFormulaRepository.vega(FORWARD, 1.e-12, 1.e-24, 1.e12);
double resP3 = BlackFormulaRepository.vega(FORWARD, 1.e-12, 1.e24, 1.e-12);
double resC4 = BlackFormulaRepository.vega(FORWARD, 1.e12, 1.e-24, 1.e-12);
double resP4 = BlackFormulaRepository.vega(FORWARD, 1.e12, 1.e-24, 1.e-12);
double resC6 = BlackFormulaRepository.vega(FORWARD, 1.e12, 1.e24, 1.e12);
double resP6 = BlackFormulaRepository.vega(FORWARD, 1.e12, 1.e-24, 1.e12);
double resC7 = BlackFormulaRepository.vega(FORWARD, 1.e12, 1.e24, 1.e-12);
double resP7 = BlackFormulaRepository.vega(FORWARD, 1.e-12, 1.e24, 1.e12);
double refC1 = BlackFormulaRepository.vega(FORWARD, 0., 0., 0.);
double refC2 = BlackFormulaRepository.vega(FORWARD, 0., 0., inf);
double refC3 = BlackFormulaRepository.vega(FORWARD, 0., inf, 0.);
double refP1 = BlackFormulaRepository.vega(FORWARD, 0., 0., 0.);
double refP2 = BlackFormulaRepository.vega(FORWARD, 0., 0., inf);
double refP3 = BlackFormulaRepository.vega(FORWARD, 0., inf, 0.);
double refC4 = BlackFormulaRepository.vega(FORWARD, inf, 0., 0.);
double refP4 = BlackFormulaRepository.vega(FORWARD, inf, 0., 0.);
double refC6 = BlackFormulaRepository.vega(FORWARD, inf, inf, inf);
double refP6 = BlackFormulaRepository.vega(FORWARD, inf, 0., inf);
double refC7 = BlackFormulaRepository.vega(FORWARD, inf, inf, 0.);
double refP7 = BlackFormulaRepository.vega(FORWARD, 0., inf, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC6, resP6,
resC7, resP7};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC6, refP6,
refC7, refP7};
for (int k = 0; k < 12; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeVolErrorVegaTest() {
BlackFormulaRepository.vega(FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, -0.5);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeFwdErrorVegaTest() {
BlackFormulaRepository.vega(-FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1]);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeStrikeErrorVegaTest() {
BlackFormulaRepository.vega(FORWARD, -STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1]);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeTimeErrorVegaTest() {
BlackFormulaRepository.vega(FORWARD, STRIKES_INPUT[1], -TIME_TO_EXPIRY, VOLS[1]);
}
/*
* vanna
*/
public void exVannaTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
double inf = Double.POSITIVE_INFINITY;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.vanna(1.e-12 * strike, strike, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.vanna(0., strike, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.vanna(1.e12 * strike, strike, TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.vanna(inf, strike, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-11);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-11);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.vanna(forward, 1.e-12 * forward, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.vanna(forward, 1.e12 * forward, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.vanna(forward, 0., TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.vanna(forward, inf, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.vanna(FORWARD, strike, 1e-24, vol);
double resC2 = BlackFormulaRepository.vanna(FORWARD, strike, 1e24, vol);
double refC1 = BlackFormulaRepository.vanna(FORWARD, strike, 0., vol);
double refC2 = BlackFormulaRepository.vanna(FORWARD, strike, inf, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.vanna(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12);
double refC1 = BlackFormulaRepository.vanna(FORWARD, strike, TIME_TO_EXPIRY, 0.);
double resC2 = BlackFormulaRepository.vanna(FORWARD, strike, TIME_TO_EXPIRY, 1.e12);
double refC2 = BlackFormulaRepository.vanna(FORWARD, strike, TIME_TO_EXPIRY, inf);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.vanna(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.vanna(1.e-12, 1.e12, TIME_TO_EXPIRY, vol);
double resC3 = BlackFormulaRepository.vanna(1.e12, 1.e12, TIME_TO_EXPIRY, vol);
double resP3 = BlackFormulaRepository.vanna(1.e12, 1.e12, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.vanna(0., 0., TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.vanna(0., inf, TIME_TO_EXPIRY, vol);
double refC3 = BlackFormulaRepository.vanna(inf, inf, TIME_TO_EXPIRY, vol);
double refP3 = BlackFormulaRepository.vanna(inf, inf, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e12) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e12) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.vanna(1.e-12, strike, 1.e-24, vol);
double resC2 = BlackFormulaRepository.vanna(1.e-12, strike, 1.e24, vol);
double resC3 = BlackFormulaRepository.vanna(1.e12, strike, 1.e-24, vol);
double resP3 = BlackFormulaRepository.vanna(1.e12, strike, 1.e24, vol);
double refC1 = BlackFormulaRepository.vanna(0., strike, 0., vol);
double refC2 = BlackFormulaRepository.vanna(0., strike, inf, vol);
double refC3 = BlackFormulaRepository.vanna(inf, strike, 0., vol);
double refP3 = BlackFormulaRepository.vanna(inf, strike, inf, vol);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.vanna(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.vanna(1.e-12, strike, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.vanna(1.e12, strike, TIME_TO_EXPIRY, 1.e-12);
double resP3 = BlackFormulaRepository.vanna(1.e12, strike, TIME_TO_EXPIRY, 1.e12);
double refC1 = BlackFormulaRepository.vanna(0., strike, TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.vanna(0., strike, TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.vanna(inf, strike, TIME_TO_EXPIRY, 0.);
double refP3 = BlackFormulaRepository.vanna(inf, strike, TIME_TO_EXPIRY, inf);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.vanna(forward, 1.e-12, 1.e-24, vol);
double resC2 = BlackFormulaRepository.vanna(forward, 1.e-12, 1.e24, vol);
double resC3 = BlackFormulaRepository.vanna(forward, 1.e12, 1.e-24, vol);
double resP3 = BlackFormulaRepository.vanna(forward, 1.e12, 1.e24, vol);
double refC1 = BlackFormulaRepository.vanna(forward, 0., 0., vol);
double refC2 = BlackFormulaRepository.vanna(forward, 0., inf, vol);
double refC3 = BlackFormulaRepository.vanna(forward, inf, 0., vol);
double refP3 = BlackFormulaRepository.vanna(forward, inf, inf, vol);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double forward = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.vanna(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.vanna(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.vanna(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double resP3 = BlackFormulaRepository.vanna(forward, 1.e12, TIME_TO_EXPIRY, 1.e12);
double refC1 = BlackFormulaRepository.vanna(forward, 0., TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.vanna(forward, 0., TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.vanna(forward, inf, TIME_TO_EXPIRY, 0.);
;
double refP3 = BlackFormulaRepository.vanna(forward, inf, TIME_TO_EXPIRY, inf);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.vanna(1.e-12, 1.e-12, 1.e-24, vol);
double resC2 = BlackFormulaRepository.vanna(1.e-12, 1.e-12, 1.e24, vol);
double resC3 = BlackFormulaRepository.vanna(1.e-12, 1.e12, 1.e-24, vol);
double resP1 = BlackFormulaRepository.vanna(1.e-12, 1.e-14, 1.e-24, vol);
double resP2 = BlackFormulaRepository.vanna(1.e-12, 1.e-12, 1.e24, vol);
double resP3 = BlackFormulaRepository.vanna(1.e-12, 1.e12, 1.e-24, vol);
double resC4 = BlackFormulaRepository.vanna(1.e12, 1.e-12, 1.e-24, vol);
double resP4 = BlackFormulaRepository.vanna(1.e12, 1.e-12, 1.e-24, vol);
double resC5 = BlackFormulaRepository.vanna(FORWARD, FORWARD * (1. + 1.e-14), 1.e-24, vol);
double resP5 = BlackFormulaRepository.vanna(FORWARD, FORWARD * (1. + 1.e-14), 1.e-24, vol);
double resC6 = BlackFormulaRepository.vanna(1.e12, 1.e12, 1.e24, vol);
double resP6 = BlackFormulaRepository.vanna(1.e12, 1.e-12, 1.e24, vol);
double resC7 = BlackFormulaRepository.vanna(1.e12, 1.e12, 1.e-24, vol);
double resP7 = BlackFormulaRepository.vanna(1.e-12, 1.e12, 1.e24, vol);
double refC1 = BlackFormulaRepository.vanna(0., 0., 0., vol);
double refC2 = BlackFormulaRepository.vanna(0., 0., inf, vol);
double refC3 = BlackFormulaRepository.vanna(0., inf, 0., vol);
double refP1 = BlackFormulaRepository.vanna(0., 0., 0., vol);
double refP2 = BlackFormulaRepository.vanna(0., 0., inf, vol);
double refP3 = BlackFormulaRepository.vanna(0., inf, 0., vol);
double refC4 = BlackFormulaRepository.vanna(inf, 0., 0., vol);
double refP4 = BlackFormulaRepository.vanna(inf, 0., 0., vol);
double refC5 = BlackFormulaRepository.vanna(FORWARD, FORWARD, 0., vol);
double refP5 = BlackFormulaRepository.vanna(FORWARD, FORWARD, 0., vol);
double refC6 = BlackFormulaRepository.vanna(inf, inf, inf, vol);
double refP6 = BlackFormulaRepository.vanna(inf, 0., inf, vol);
double refC7 = BlackFormulaRepository.vanna(inf, inf, 0., vol);
double refP7 = BlackFormulaRepository.vanna(0., inf, inf, vol);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7};
for (int k = 0; k < 14; ++k) {
// refC5 and refP5 are ambiguous cases
if (k != 8 && k != 9) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
{
double resC1 = BlackFormulaRepository.vanna(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.vanna(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.vanna(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double resP1 = BlackFormulaRepository.vanna(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resP2 = BlackFormulaRepository.vanna(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resP3 = BlackFormulaRepository.vanna(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double resC4 = BlackFormulaRepository.vanna(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resP4 = BlackFormulaRepository.vanna(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC5 = BlackFormulaRepository.vanna(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12);
double resP5 = BlackFormulaRepository.vanna(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12);
double resC6 = BlackFormulaRepository.vanna(1.e12, 1.e12, TIME_TO_EXPIRY, 1.e12);
double resP6 = BlackFormulaRepository.vanna(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resC7 = BlackFormulaRepository.vanna(1.e12, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double resP7 = BlackFormulaRepository.vanna(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e12);
double refC1 = BlackFormulaRepository.vanna(0., 0., TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.vanna(0., 0., TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.vanna(0., inf, TIME_TO_EXPIRY, 0.);
double refP1 = BlackFormulaRepository.vanna(0., 0., TIME_TO_EXPIRY, 0.);
double refP2 = BlackFormulaRepository.vanna(0., 0., TIME_TO_EXPIRY, inf);
double refP3 = BlackFormulaRepository.vanna(0., inf, TIME_TO_EXPIRY, 0.);
double refC4 = BlackFormulaRepository.vanna(inf, 0., TIME_TO_EXPIRY, 0.);
double refP4 = BlackFormulaRepository.vanna(inf, 0., TIME_TO_EXPIRY, 0.);
double refC5 = BlackFormulaRepository.vanna(FORWARD, FORWARD, TIME_TO_EXPIRY, 0.);
double refP5 = BlackFormulaRepository.vanna(FORWARD, FORWARD, TIME_TO_EXPIRY, 0.);
double refC6 = BlackFormulaRepository.vanna(inf, inf, TIME_TO_EXPIRY, inf);
double refP6 = BlackFormulaRepository.vanna(inf, 0., TIME_TO_EXPIRY, inf);
double refC7 = BlackFormulaRepository.vanna(inf, inf, TIME_TO_EXPIRY, 0.);
double refP7 = BlackFormulaRepository.vanna(0., inf, TIME_TO_EXPIRY, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7};
for (int k = 2; k < 12; ++k) {
if (k != 8 && k != 9) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (Math.abs(refVec[k]) < 1.e-10) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
{
double resC1 = BlackFormulaRepository.vanna(FORWARD, 1.e-12, 1.e-24, 1.e-12);
double resC2 = BlackFormulaRepository.vanna(FORWARD, 1.e-12, 1.e-24, 1.e12);
double resC3 = BlackFormulaRepository.vanna(FORWARD, 1.e-12, 1.e24, 1.e-12);
double resP1 = BlackFormulaRepository.vanna(FORWARD, 1.e-12, 1.e-24, 1.e-12);
double resP2 = BlackFormulaRepository.vanna(FORWARD, 1.e-12, 1.e-24, 1.e12);
double resP3 = BlackFormulaRepository.vanna(FORWARD, 1.e-12, 1.e24, 1.e-12);
double resC4 = BlackFormulaRepository.vanna(FORWARD, 1.e12, 1.e-24, 1.e-12);
double resP4 = BlackFormulaRepository.vanna(FORWARD, 1.e12, 1.e-24, 1.e-12);
double resC6 = BlackFormulaRepository.vanna(FORWARD, 1.e12, 1.e24, 1.e12);
double resP6 = BlackFormulaRepository.vanna(FORWARD, 1.e12, 1.e-24, 1.e12);
double resC7 = BlackFormulaRepository.vanna(FORWARD, 1.e12, 1.e24, 1.e-12);
double resP7 = BlackFormulaRepository.vanna(FORWARD, 1.e-12, 1.e24, 1.e12);
double refC1 = BlackFormulaRepository.vanna(FORWARD, 0., 0., 0.);
double refC2 = BlackFormulaRepository.vanna(FORWARD, 0., 0., inf);
double refC3 = BlackFormulaRepository.vanna(FORWARD, 0., inf, 0.);
double refP1 = BlackFormulaRepository.vanna(FORWARD, 0., 0., 0.);
double refP2 = BlackFormulaRepository.vanna(FORWARD, 0., 0., inf);
double refP3 = BlackFormulaRepository.vanna(FORWARD, 0., inf, 0.);
double refC4 = BlackFormulaRepository.vanna(FORWARD, inf, 0., 0.);
double refP4 = BlackFormulaRepository.vanna(FORWARD, inf, 0., 0.);
double refC6 = BlackFormulaRepository.vanna(FORWARD, inf, inf, inf);
double refP6 = BlackFormulaRepository.vanna(FORWARD, inf, 0., inf);
double refC7 = BlackFormulaRepository.vanna(FORWARD, inf, inf, 0.);
double refP7 = BlackFormulaRepository.vanna(FORWARD, 0., inf, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC6, resP6,
resC7, resP7};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC6, refP6,
refC7, refP7};
for (int k = 0; k < 12; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (Math.abs(refVec[k]) < 1.e-10) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeVolErrorVannaTest() {
BlackFormulaRepository.vanna(FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, -0.5);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeFwdErrorVannaTest() {
BlackFormulaRepository.vanna(-FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1]);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeStrikeErrorVannaTest() {
BlackFormulaRepository.vanna(FORWARD, -STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1]);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeTimeErrorVannaTest() {
BlackFormulaRepository.vanna(FORWARD, STRIKES_INPUT[1], -TIME_TO_EXPIRY, VOLS[1]);
}
/*
* dualVanna
*/
/**
* large/small input
*/
public void exDualVannaTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
double inf = Double.POSITIVE_INFINITY;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.dualVanna(1.e-12 * strike, strike, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.dualVanna(0., strike, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.dualVanna(1.e12 * strike, strike, TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.dualVanna(inf, strike, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-11);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-11);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.dualVanna(forward, 1.e-12 * forward, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.dualVanna(forward, 1.e12 * forward, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.dualVanna(forward, 0., TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.dualVanna(forward, inf, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.dualVanna(FORWARD, strike, 1e-24, vol);
double resC2 = BlackFormulaRepository.dualVanna(FORWARD, strike, 1e24, vol);
double refC1 = BlackFormulaRepository.dualVanna(FORWARD, strike, 0., vol);
double refC2 = BlackFormulaRepository.dualVanna(FORWARD, strike, inf, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.dualVanna(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12);
double refC1 = BlackFormulaRepository.dualVanna(FORWARD, strike, TIME_TO_EXPIRY, 0.);
double resC2 = BlackFormulaRepository.dualVanna(FORWARD, strike, TIME_TO_EXPIRY, 1.e12);
double refC2 = BlackFormulaRepository.dualVanna(FORWARD, strike, TIME_TO_EXPIRY, inf);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.dualVanna(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.dualVanna(1.e-12, 1.e12, TIME_TO_EXPIRY, vol);
double resC3 = BlackFormulaRepository.dualVanna(1.e12, 1.e-12, TIME_TO_EXPIRY, vol);
double resP3 = BlackFormulaRepository.dualVanna(1.e12, 1.e12, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.dualVanna(0., 0., TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.dualVanna(0., inf, TIME_TO_EXPIRY, vol);
double refC3 = BlackFormulaRepository.dualVanna(inf, 0., TIME_TO_EXPIRY, vol);
double refP3 = BlackFormulaRepository.dualVanna(inf, inf, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e12) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e12) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.dualVanna(1.e-12, strike, 1.e-24, vol);
double resC2 = BlackFormulaRepository.dualVanna(1.e-12, strike, 1.e24, vol);
double resC3 = BlackFormulaRepository.dualVanna(1.e12, strike, 1.e-24, vol);
double resP3 = BlackFormulaRepository.dualVanna(1.e12, strike, 1.e24, vol);
double refC1 = BlackFormulaRepository.dualVanna(0., strike, 0., vol);
double refC2 = BlackFormulaRepository.dualVanna(0., strike, inf, vol);
double refC3 = BlackFormulaRepository.dualVanna(inf, strike, 0., vol);
double refP3 = BlackFormulaRepository.dualVanna(inf, strike, inf, vol);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.dualVanna(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.dualVanna(1.e-12, strike, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.dualVanna(1.e12, strike, TIME_TO_EXPIRY, 1.e-12);
double resP3 = BlackFormulaRepository.dualVanna(1.e12, strike, TIME_TO_EXPIRY, 1.e12);
double refC1 = BlackFormulaRepository.dualVanna(0., strike, TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.dualVanna(0., strike, TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.dualVanna(inf, strike, TIME_TO_EXPIRY, 0.);
double refP3 = BlackFormulaRepository.dualVanna(inf, strike, TIME_TO_EXPIRY, inf);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.dualVanna(forward, 1.e-12, 1.e-24, vol);
double resC2 = BlackFormulaRepository.dualVanna(forward, 1.e-12, 1.e24, vol);
double resC3 = BlackFormulaRepository.dualVanna(forward, 1.e12, 1.e-24, vol);
double resP3 = BlackFormulaRepository.dualVanna(forward, 1.e12, 1.e24, vol);
double refC1 = BlackFormulaRepository.dualVanna(forward, 0., 0., vol);
double refC2 = BlackFormulaRepository.dualVanna(forward, 0., inf, vol);
double refC3 = BlackFormulaRepository.dualVanna(forward, inf, 0., vol);
double refP3 = BlackFormulaRepository.dualVanna(forward, inf, inf, vol);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double forward = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.dualVanna(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.dualVanna(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.dualVanna(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double resP3 = BlackFormulaRepository.dualVanna(forward, 1.e12, TIME_TO_EXPIRY, 1.e12);
double refC1 = BlackFormulaRepository.dualVanna(forward, 0., TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.dualVanna(forward, 0., TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.dualVanna(forward, inf, TIME_TO_EXPIRY, 0.);
double refP3 = BlackFormulaRepository.dualVanna(forward, inf, TIME_TO_EXPIRY, inf);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.dualVanna(1.e-12, 1.e-12, 1.e-24, vol);
double resC2 = BlackFormulaRepository.dualVanna(1.e-12, 1.e-12, 1.e24, vol);
double resC3 = BlackFormulaRepository.dualVanna(1.e-12, 1.e12, 1.e-24, vol);
double resP1 = BlackFormulaRepository.dualVanna(1.e-12, 1.e-14, 1.e-24, vol);
double resP2 = BlackFormulaRepository.dualVanna(1.e-12, 1.e-12, 1.e24, vol);
double resP3 = BlackFormulaRepository.dualVanna(1.e-12, 1.e12, 1.e-24, vol);
double resC4 = BlackFormulaRepository.dualVanna(1.e12, 1.e-12, 1.e-24, vol);
double resP4 = BlackFormulaRepository.dualVanna(1.e12, 1.e-12, 1.e-24, vol);
double resC5 = BlackFormulaRepository.dualVanna(FORWARD, FORWARD * (1. + 1.e-14), 1.e-24, vol);
double resP5 = BlackFormulaRepository.dualVanna(FORWARD, FORWARD * (1. + 1.e-14), 1.e-24, vol);
double resC6 = BlackFormulaRepository.dualVanna(1.e12, 1.e12, 1.e24, vol);
double resP6 = BlackFormulaRepository.dualVanna(1.e12, 1.e-12, 1.e24, vol);
double resC7 = BlackFormulaRepository.dualVanna(1.e12, 1.e12, 1.e-24, vol);
double resP7 = BlackFormulaRepository.dualVanna(1.e-12, 1.e12, 1.e24, vol);
double refC1 = BlackFormulaRepository.dualVanna(0., 0., 0., vol);
double refC2 = BlackFormulaRepository.dualVanna(0., 0., inf, vol);
double refC3 = BlackFormulaRepository.dualVanna(0., inf, 0., vol);
double refP1 = BlackFormulaRepository.dualVanna(0., 0., 0., vol);
double refP2 = BlackFormulaRepository.dualVanna(0., 0., inf, vol);
double refP3 = BlackFormulaRepository.dualVanna(0., inf, 0., vol);
double refC4 = BlackFormulaRepository.dualVanna(inf, 0., 0., vol);
double refP4 = BlackFormulaRepository.dualVanna(inf, 0., 0., vol);
double refC5 = BlackFormulaRepository.dualVanna(FORWARD, FORWARD, 0., vol);
double refP5 = BlackFormulaRepository.dualVanna(FORWARD, FORWARD, 0., vol);
double refC6 = BlackFormulaRepository.dualVanna(inf, inf, inf, vol);
double refP6 = BlackFormulaRepository.dualVanna(inf, 0., inf, vol);
double refC7 = BlackFormulaRepository.dualVanna(inf, inf, 0., vol);
double refP7 = BlackFormulaRepository.dualVanna(0., inf, inf, vol);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7};
for (int k = 0; k < 14; ++k) {
if (k != 8 && k != 9) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
{
double resC1 = BlackFormulaRepository.dualVanna(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.dualVanna(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.dualVanna(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double resP1 = BlackFormulaRepository.dualVanna(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resP2 = BlackFormulaRepository.dualVanna(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resP3 = BlackFormulaRepository.dualVanna(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double resC4 = BlackFormulaRepository.dualVanna(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resP4 = BlackFormulaRepository.dualVanna(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC5 = BlackFormulaRepository.dualVanna(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12);
double resP5 = BlackFormulaRepository.dualVanna(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12);
double resC6 = BlackFormulaRepository.dualVanna(1.e12, 1.e12, TIME_TO_EXPIRY, 1.e12);
double resP6 = BlackFormulaRepository.dualVanna(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resC7 = BlackFormulaRepository.dualVanna(1.e12, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double resP7 = BlackFormulaRepository.dualVanna(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e12);
double refC1 = BlackFormulaRepository.dualVanna(0., 0., TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.dualVanna(0., 0., TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.dualVanna(0., inf, TIME_TO_EXPIRY, 0.);
double refP1 = BlackFormulaRepository.dualVanna(0., 0., TIME_TO_EXPIRY, 0.);
double refP2 = BlackFormulaRepository.dualVanna(0., 0., TIME_TO_EXPIRY, inf);
double refP3 = BlackFormulaRepository.dualVanna(0., inf, TIME_TO_EXPIRY, 0.);
double refC4 = BlackFormulaRepository.dualVanna(inf, 0., TIME_TO_EXPIRY, 0.);
double refP4 = BlackFormulaRepository.dualVanna(inf, 0., TIME_TO_EXPIRY, 0.);
double refC5 = BlackFormulaRepository.dualVanna(FORWARD, FORWARD, TIME_TO_EXPIRY, 0.);
double refP5 = BlackFormulaRepository.dualVanna(FORWARD, FORWARD, TIME_TO_EXPIRY, 0.);
double refC6 = BlackFormulaRepository.dualVanna(inf, inf, TIME_TO_EXPIRY, inf);
double refP6 = BlackFormulaRepository.dualVanna(inf, 0., TIME_TO_EXPIRY, inf);
double refC7 = BlackFormulaRepository.dualVanna(inf, inf, TIME_TO_EXPIRY, 0.);
double refP7 = BlackFormulaRepository.dualVanna(0., inf, TIME_TO_EXPIRY, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7};
for (int k = 2; k < 12; ++k) {
if (k != 8 && k != 9) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (Math.abs(refVec[k]) < 1.e-10) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
{
double resC1 = BlackFormulaRepository.dualVanna(FORWARD, 1.e-12, 1.e-12, 1.e-12);
double resC2 = BlackFormulaRepository.dualVanna(FORWARD, 1.e-12, 1.e-12, 1.e12);
double resC3 = BlackFormulaRepository.dualVanna(FORWARD, 1.e-12, 1.e12, 1.e-12);
double resP1 = BlackFormulaRepository.dualVanna(FORWARD, 1.e-12, 1.e-12, 1.e-12);
double resP2 = BlackFormulaRepository.dualVanna(FORWARD, 1.e-12, 1.e-12, 1.e12);
double resP3 = BlackFormulaRepository.dualVanna(FORWARD, 1.e-12, 1.e12, 1.e-12);
double resC4 = BlackFormulaRepository.dualVanna(FORWARD, 1.e12, 1.e-12, 1.e-12);
double resP4 = BlackFormulaRepository.dualVanna(FORWARD, 1.e12, 1.e-12, 1.e-12);
double resC6 = BlackFormulaRepository.dualVanna(FORWARD, 1.e12, 1.e12, 1.e12);
double resP6 = BlackFormulaRepository.dualVanna(FORWARD, 1.e12, 1.e-12, 1.e12);
double resC7 = BlackFormulaRepository.dualVanna(FORWARD, 1.e12, 1.e12, 1.e-12);
double resP7 = BlackFormulaRepository.dualVanna(FORWARD, 1.e-12, 1.e12, 1.e12);
double refC1 = BlackFormulaRepository.dualVanna(FORWARD, 0., 0., 0.);
double refC2 = BlackFormulaRepository.dualVanna(FORWARD, 0., 0., inf);
double refC3 = BlackFormulaRepository.dualVanna(FORWARD, 0., inf, 0.);
double refP1 = BlackFormulaRepository.dualVanna(FORWARD, 0., 0., 0.);
double refP2 = BlackFormulaRepository.dualVanna(FORWARD, 0., 0., inf);
double refP3 = BlackFormulaRepository.dualVanna(FORWARD, 0., inf, 0.);
double refC4 = BlackFormulaRepository.dualVanna(FORWARD, inf, 0., 0.);
double refP4 = BlackFormulaRepository.dualVanna(FORWARD, inf, 0., 0.);
double refC6 = BlackFormulaRepository.dualVanna(FORWARD, inf, inf, inf);
double refP6 = BlackFormulaRepository.dualVanna(FORWARD, inf, 0., inf);
double refC7 = BlackFormulaRepository.dualVanna(FORWARD, inf, inf, 0.);
double refP7 = BlackFormulaRepository.dualVanna(FORWARD, 0., inf, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC6, resP6,
resC7, resP7};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC6, refP6,
refC7, refP7};
for (int k = 0; k < 12; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (Math.abs(refVec[k]) < 1.e-10) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeVolErrorDualVannaTest() {
BlackFormulaRepository.dualVanna(FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, -0.5);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeFwdErrorDualVannaTest() {
BlackFormulaRepository.dualVanna(-FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1]);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeStrikeErrorDualVannaTest() {
BlackFormulaRepository.dualVanna(FORWARD, -STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1]);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeTimeErrorDualVannaTest() {
BlackFormulaRepository.dualVanna(FORWARD, STRIKES_INPUT[1], -TIME_TO_EXPIRY, VOLS[1]);
}
/*
* vomma
*/
/**
* large/small input
*/
public void exVommaTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
double inf = Double.POSITIVE_INFINITY;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.vomma(1.e-12 * strike, strike, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.vomma(0., strike, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.vomma(1.e12 * strike, strike, TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.vomma(inf, strike, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-11);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-11);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.vomma(forward, 1.e-12 * forward, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.vomma(forward, 1.e12 * forward, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.vomma(forward, 0., TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.vomma(forward, inf, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.vomma(FORWARD, strike, 1e-24, vol);
double resC2 = BlackFormulaRepository.vomma(FORWARD, strike, 1e24, vol);
double refC1 = BlackFormulaRepository.vomma(FORWARD, strike, 0., vol);
double refC2 = BlackFormulaRepository.vomma(FORWARD, strike, inf, vol);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.vomma(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12);
double refC1 = BlackFormulaRepository.vomma(FORWARD, strike, TIME_TO_EXPIRY, 0.);
double resC2 = BlackFormulaRepository.vomma(FORWARD, strike, TIME_TO_EXPIRY, 1.e12);
double refC2 = BlackFormulaRepository.vomma(FORWARD, strike, TIME_TO_EXPIRY, inf);
double[] resVec = new double[] {resC1, resC2};
double[] refVec = new double[] {refC1, refC2};
for (int k = 0; k < 2; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e12);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.vomma(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol);
double resC2 = BlackFormulaRepository.vomma(1.e-12, 1.e12, TIME_TO_EXPIRY, vol);
double resC3 = BlackFormulaRepository.vomma(1.e12, 1.e-12, TIME_TO_EXPIRY, vol);
double resP3 = BlackFormulaRepository.vomma(1.e12, 1.e12, TIME_TO_EXPIRY, vol);
double refC1 = BlackFormulaRepository.vomma(0., 0., TIME_TO_EXPIRY, vol);
double refC2 = BlackFormulaRepository.vomma(0., inf, TIME_TO_EXPIRY, vol);
double refC3 = BlackFormulaRepository.vomma(inf, 0., TIME_TO_EXPIRY, vol);
double refP3 = BlackFormulaRepository.vomma(inf, inf, TIME_TO_EXPIRY, vol);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e12) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e12) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-12);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-12);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.vomma(1.e-12, strike, 1.e-24, vol);
double resC2 = BlackFormulaRepository.vomma(1.e-12, strike, 1.e24, vol);
double resC3 = BlackFormulaRepository.vomma(1.e12, strike, 1.e-24, vol);
double resP3 = BlackFormulaRepository.vomma(1.e12, strike, 1.e24, vol);
double refC1 = BlackFormulaRepository.vomma(0., strike, 0., vol);
double refC2 = BlackFormulaRepository.vomma(0., strike, inf, vol);
double refC3 = BlackFormulaRepository.vomma(inf, strike, 0., vol);
double refP3 = BlackFormulaRepository.vomma(inf, strike, inf, vol);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double strike = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.vomma(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.vomma(1.e-12, strike, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.vomma(1.e12, strike, TIME_TO_EXPIRY, 1.e-12);
double resP3 = BlackFormulaRepository.vomma(1.e12, strike, TIME_TO_EXPIRY, 1.e12);
double refC1 = BlackFormulaRepository.vomma(0., strike, TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.vomma(0., strike, TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.vomma(inf, strike, TIME_TO_EXPIRY, 0.);
double refP3 = BlackFormulaRepository.vomma(inf, strike, TIME_TO_EXPIRY, inf);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double forward = STRIKES_INPUT[i];
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.vomma(forward, 1.e-12, 1.e-24, vol);
double resC2 = BlackFormulaRepository.vomma(forward, 1.e-12, 1.e24, vol);
double resC3 = BlackFormulaRepository.vomma(forward, 1.e12, 1.e-24, vol);
double resP3 = BlackFormulaRepository.vomma(forward, 1.e12, 1.e24, vol);
double refC1 = BlackFormulaRepository.vomma(forward, 0., 0., vol);
double refC2 = BlackFormulaRepository.vomma(forward, 0., inf, vol);
double refC3 = BlackFormulaRepository.vomma(forward, inf, 0., vol);
double refP3 = BlackFormulaRepository.vomma(forward, inf, inf, vol);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
for (int i = 0; i < nStrikes; ++i) {
double forward = STRIKES_INPUT[i];
double resC1 = BlackFormulaRepository.vomma(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.vomma(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.vomma(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12);
;
double resP3 = BlackFormulaRepository.vomma(forward, 1.e12, TIME_TO_EXPIRY, 1.e12);
double refC1 = BlackFormulaRepository.vomma(forward, 0., TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.vomma(forward, 0., TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.vomma(forward, inf, TIME_TO_EXPIRY, 0.);
double refP3 = BlackFormulaRepository.vomma(forward, inf, TIME_TO_EXPIRY, inf);
double[] resVec = new double[] {resC1, resC2, resC3, resP3};
double[] refVec = new double[] {refC1, refC2, refC3, refP3};
for (int k = 0; k < 4; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
for (int j = 0; j < nVols; ++j) {
double vol = VOLS[j];
double resC1 = BlackFormulaRepository.vomma(1.e-12, 1.e-12, 1.e-24, vol);
double resC2 = BlackFormulaRepository.vomma(1.e-12, 1.e-12, 1.e24, vol);
double resC3 = BlackFormulaRepository.vomma(1.e-12, 1.e12, 1.e-24, vol);
double resP1 = BlackFormulaRepository.vomma(1.e-12, 1.e-14, 1.e-24, vol);
double resP2 = BlackFormulaRepository.vomma(1.e-12, 1.e-12, 1.e24, vol);
double resP3 = BlackFormulaRepository.vomma(1.e-12, 1.e12, 1.e-24, vol);
double resC4 = BlackFormulaRepository.vomma(1.e12, 1.e-12, 1.e-24, vol);
double resP4 = BlackFormulaRepository.vomma(1.e12, 1.e-12, 1.e-24, vol);
double resC5 = BlackFormulaRepository.vomma(FORWARD, FORWARD * (1. + 1.e-14), 1.e-24, vol);
double resP5 = BlackFormulaRepository.vomma(FORWARD, FORWARD * (1. + 1.e-14), 1.e-24, vol);
double resC6 = BlackFormulaRepository.vomma(1.e12, 1.e12, 1.e24, vol);
double resP6 = BlackFormulaRepository.vomma(1.e12, 1.e-12, 1.e24, vol);
double resC7 = BlackFormulaRepository.vomma(1.e12, 1.e12, 1.e-24, vol);
double resP7 = BlackFormulaRepository.vomma(1.e-12, 1.e12, 1.e24, vol);
double refC1 = BlackFormulaRepository.vomma(0., 0., 0., vol);
double refC2 = BlackFormulaRepository.vomma(0., 0., inf, vol);
double refC3 = BlackFormulaRepository.vomma(0., inf, 0., vol);
double refP1 = BlackFormulaRepository.vomma(0., 0., 0., vol);
double refP2 = BlackFormulaRepository.vomma(0., 0., inf, vol);
double refP3 = BlackFormulaRepository.vomma(0., inf, 0., vol);
double refC4 = BlackFormulaRepository.vomma(inf, 0., 0., vol);
double refP4 = BlackFormulaRepository.vomma(inf, 0., 0., vol);
double refC5 = BlackFormulaRepository.vomma(FORWARD, FORWARD, 0., vol);
double refP5 = BlackFormulaRepository.vomma(FORWARD, FORWARD, 0., vol);
double refC6 = BlackFormulaRepository.vomma(inf, inf, inf, vol);
double refP6 = BlackFormulaRepository.vomma(inf, 0., inf, vol);
double refC7 = BlackFormulaRepository.vomma(inf, inf, 0., vol);
double refP7 = BlackFormulaRepository.vomma(0., inf, inf, vol);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7};
for (int k = 0; k < 14; ++k) {
if (k != 12) {// ref val
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e12);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (refVec[k] == 0.) {
assertTrue(Math.abs(resVec[k]) < 1.e-9);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
{
double resC1 = BlackFormulaRepository.vomma(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC2 = BlackFormulaRepository.vomma(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resC3 = BlackFormulaRepository.vomma(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double resP1 = BlackFormulaRepository.vomma(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resP2 = BlackFormulaRepository.vomma(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resP3 = BlackFormulaRepository.vomma(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double resC4 = BlackFormulaRepository.vomma(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resP4 = BlackFormulaRepository.vomma(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12);
double resC5 = BlackFormulaRepository.vomma(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12);
double resP5 = BlackFormulaRepository.vomma(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12);
double resC6 = BlackFormulaRepository.vomma(1.e12, 1.e12, TIME_TO_EXPIRY, 1.e12);
double resP6 = BlackFormulaRepository.vomma(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e12);
double resC7 = BlackFormulaRepository.vomma(1.e12, 1.e12, TIME_TO_EXPIRY, 1.e-12);
double resP7 = BlackFormulaRepository.vomma(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e12);
double refC1 = BlackFormulaRepository.vomma(0., 0., TIME_TO_EXPIRY, 0.);
double refC2 = BlackFormulaRepository.vomma(0., 0., TIME_TO_EXPIRY, inf);
double refC3 = BlackFormulaRepository.vomma(0., inf, TIME_TO_EXPIRY, 0.);
double refP1 = BlackFormulaRepository.vomma(0., 0., TIME_TO_EXPIRY, 0.);
double refP2 = BlackFormulaRepository.vomma(0., 0., TIME_TO_EXPIRY, inf);
double refP3 = BlackFormulaRepository.vomma(0., inf, TIME_TO_EXPIRY, 0.);
double refC4 = BlackFormulaRepository.vomma(inf, 0., TIME_TO_EXPIRY, 0.);
double refP4 = BlackFormulaRepository.vomma(inf, 0., TIME_TO_EXPIRY, 0.);
double refC5 = BlackFormulaRepository.vomma(FORWARD, FORWARD, TIME_TO_EXPIRY, 0.);
double refP5 = BlackFormulaRepository.vomma(FORWARD, FORWARD, TIME_TO_EXPIRY, 0.);
double refC6 = BlackFormulaRepository.vomma(inf, inf, TIME_TO_EXPIRY, inf);
double refP6 = BlackFormulaRepository.vomma(inf, 0., TIME_TO_EXPIRY, inf);
double refC7 = BlackFormulaRepository.vomma(inf, inf, TIME_TO_EXPIRY, 0.);
double refP7 = BlackFormulaRepository.vomma(0., inf, TIME_TO_EXPIRY, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5,
resC6, resP6, resC7, resP7};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC5, refP5,
refC6, refP6, refC7, refP7};
for (int k = 2; k < 12; ++k) {
if (k != 8 && k != 9) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (Math.abs(refVec[k]) < 1.e-10) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
{
double resC1 = BlackFormulaRepository.vomma(FORWARD, 1.e-12, 1.e-12, 1.e-12);
double resC2 = BlackFormulaRepository.vomma(FORWARD, 1.e-12, 1.e-12, 1.e12);
double resC3 = BlackFormulaRepository.vomma(FORWARD, 1.e-12, 1.e12, 1.e-12);
double resP1 = BlackFormulaRepository.vomma(FORWARD, 1.e-12, 1.e-12, 1.e-12);
double resP2 = BlackFormulaRepository.vomma(FORWARD, 1.e-12, 1.e-12, 1.e12);
double resP3 = BlackFormulaRepository.vomma(FORWARD, 1.e-12, 1.e12, 1.e-12);
double resC4 = BlackFormulaRepository.vomma(FORWARD, 1.e12, 1.e-12, 1.e-12);
double resP4 = BlackFormulaRepository.vomma(FORWARD, 1.e12, 1.e-12, 1.e-12);
double resC6 = BlackFormulaRepository.vomma(FORWARD, 1.e12, 1.e12, 1.e12);
double resP6 = BlackFormulaRepository.vomma(FORWARD, 1.e12, 1.e-12, 1.e12);
double resC7 = BlackFormulaRepository.vomma(FORWARD, 1.e12, 1.e12, 1.e-12);
double resP7 = BlackFormulaRepository.vomma(FORWARD, 1.e-12, 1.e12, 1.e12);
double refC1 = BlackFormulaRepository.vomma(FORWARD, 0., 0., 0.);
double refC2 = BlackFormulaRepository.vomma(FORWARD, 0., 0., inf);
double refC3 = BlackFormulaRepository.vomma(FORWARD, 0., inf, 0.);
double refP1 = BlackFormulaRepository.vomma(FORWARD, 0., 0., 0.);
double refP2 = BlackFormulaRepository.vomma(FORWARD, 0., 0., inf);
double refP3 = BlackFormulaRepository.vomma(FORWARD, 0., inf, 0.);
double refC4 = BlackFormulaRepository.vomma(FORWARD, inf, 0., 0.);
double refP4 = BlackFormulaRepository.vomma(FORWARD, inf, 0., 0.);
double refC6 = BlackFormulaRepository.vomma(FORWARD, inf, inf, inf);
double refP6 = BlackFormulaRepository.vomma(FORWARD, inf, 0., inf);
double refC7 = BlackFormulaRepository.vomma(FORWARD, inf, inf, 0.);
double refP7 = BlackFormulaRepository.vomma(FORWARD, 0., inf, inf);
double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC6, resP6,
resC7, resP7};
double[] refVec = new double[] {refC1, refP1, refC2, refP2, refC3, refP3, refC4, refP4, refC6, refP6,
refC7, refP7};
for (int k = 2; k < 12; ++k) {
if (refVec[k] > 1.e10) {
assertTrue(resVec[k] > 1.e10);
} else {
if (refVec[k] < -1.e10) {
assertTrue(resVec[k] < -1.e10);
} else {
if (Math.abs(refVec[k]) < 1.e-10) {
assertTrue(Math.abs(resVec[k]) < 1.e-10);
} else {
assertEquals(refVec[k], resVec[k], Math.abs(refVec[k]) * 1.e-10);
}
}
}
}
}
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeVolErrorVommaTest() {
BlackFormulaRepository.vomma(FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, -0.5);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeFwdErrorVommaTest() {
BlackFormulaRepository.vomma(-FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1]);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeStrikeErrorVommaTest() {
BlackFormulaRepository.vomma(FORWARD, -STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1]);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeTimeErrorVommaTest() {
BlackFormulaRepository.vomma(FORWARD, STRIKES_INPUT[1], -TIME_TO_EXPIRY, VOLS[1]);
}
/*
* Volga test
*/
public void volgaTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double volga = BlackFormulaRepository.volga(FORWARD, strike, TIME_TO_EXPIRY, vol);
double vomma = BlackFormulaRepository.vomma(strike, FORWARD, TIME_TO_EXPIRY, vol);
assertEquals(vomma, volga, Math.abs(vomma) * 1.e-8);
}
}
}
/*
* Implied vol tests
*/
public void volRecoveryTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double cPrice = BlackFormulaRepository.price(FORWARD, strike, TIME_TO_EXPIRY, vol, true);
double pPrice = BlackFormulaRepository.price(FORWARD, strike, TIME_TO_EXPIRY, vol, false);
double cRes = BlackFormulaRepository.impliedVolatility(cPrice, FORWARD, strike, TIME_TO_EXPIRY, true);
double pRes = BlackFormulaRepository.impliedVolatility(pPrice, FORWARD, strike, TIME_TO_EXPIRY, false);
assertEquals(vol, cRes, Math.abs(vol) * 1.e-8);
assertEquals(vol, pRes, Math.abs(vol) * 1.e-8);
}
}
}
public void impliedVolTest() {
double vol = 0.4342; // Deliberately picked an arbitrary vol
double t = 0.1;
double f = 0.01;
double p = 4.1;
double ivCall = 0;
double ivPut = 0;
double iv = 0;
for (int i = 0; i < 100; i++) {
double k = 0.004 + 0.022 * i / 100.;
double cPrice = p * BlackFormulaRepository.price(f, k, t, vol, true);
double pPrice = p * BlackFormulaRepository.price(f, k, t, vol, false);
ivCall = BlackFormulaRepository.impliedVolatility(cPrice / p, f, k, t, true);
ivPut = BlackFormulaRepository.impliedVolatility(pPrice / p, f, k, t, false);
boolean isCall = k > f;
double otmP = (isCall ? cPrice : pPrice) / p;
iv = BlackFormulaRepository.impliedVolatility(otmP, f, k, t, isCall);
// this is why we should compute OTM prices if an implied vol is required
assertEquals(vol, ivCall, 5e-4);
assertEquals(vol, ivPut, 2e-3);
assertEquals(vol, iv, 1e-9);
}
}
public void implied_volatility_adjoint() {
double vol = 0.4342; // Deliberately picked an arbitrary vol
double t = 0.1;
double f = 10.0d;
double shiftFd = 1.0E-6;
double toleranceVol = 1.0E-3;
double toleranceVolDelta = 1.0E-3;
int nbPoints = 25;
for (int i = 0; i <= nbPoints; i++) {
double k = 0.75 * f + i * 0.5 * f / 25;
double cPrice = BlackFormulaRepository.price(f, k, t, vol, true);
double pPrice = BlackFormulaRepository.price(f, k, t, vol, false);
ValueDerivatives ivCallAdj = BlackFormulaRepository.impliedVolatilityAdjoint(cPrice, f, k, t, true);
ValueDerivatives ivPutAdj = BlackFormulaRepository.impliedVolatilityAdjoint(pPrice, f, k, t, false);
assertEquals(ivCallAdj.getValue(), vol, toleranceVol);
assertEquals(ivPutAdj.getValue(), vol, toleranceVol);
double ivCallP = BlackFormulaRepository.impliedVolatility(cPrice + shiftFd, f, k, t, true);
double ivCallM = BlackFormulaRepository.impliedVolatility(cPrice - shiftFd, f, k, t, true);
double ivCallDerivative = (ivCallP - ivCallM) / (2 * shiftFd);
assertEquals(ivCallAdj.getDerivative(0), ivCallDerivative, toleranceVolDelta);
assertEquals(ivPutAdj.getDerivative(0), ivCallAdj.getDerivative(0), toleranceVolDelta);
// Vega and its inverse are the same for call and puts
}
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativePriceErrorImpliedVolatilityTest() {
BlackFormulaRepository.impliedVolatility(-10., FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, true);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeFwdErrorImpliedVolatilityTest() {
BlackFormulaRepository.impliedVolatility(10., -FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, true);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeStrikeErrorImpliedVolatilityTest() {
BlackFormulaRepository.impliedVolatility(10., FORWARD, -STRIKES_INPUT[1], TIME_TO_EXPIRY, true);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void negativeTimeErrorImpliedVolatilityTest() {
BlackFormulaRepository.impliedVolatility(10., FORWARD, STRIKES_INPUT[1], -TIME_TO_EXPIRY, true);
}
public void volInitialGuessTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double zero = BlackFormulaRepository.impliedVolatility(0., FORWARD, strike, TIME_TO_EXPIRY, vol);
double atm = BlackFormulaRepository.impliedVolatility(Math.pow(strike, 0.6), strike, strike,
TIME_TO_EXPIRY, vol);
assertEquals(0., zero, Math.abs(vol) * 1.e-13);
assertEquals(NORMAL.getInverseCDF(0.5 * (Math.pow(strike, 0.6) / strike + 1)) * 2 / Math.sqrt(TIME_TO_EXPIRY),
atm, 1.e-13);
}
}
}
/*
* Implied strike tests
*/
public void strikeRecoveryTest() {
int nStrikes = STRIKES_INPUT.length;
int nVols = VOLS.length;
for (int i = 0; i < nStrikes; ++i) {
for (int j = 0; j < nVols; ++j) {
double strike = STRIKES_INPUT[i];
double vol = VOLS[j];
double cDelta = BlackFormulaRepository.delta(FORWARD, strike, TIME_TO_EXPIRY, vol, true);
double pdelta = BlackFormulaRepository.delta(FORWARD, strike, TIME_TO_EXPIRY, vol, false);
double cRes = BlackFormulaRepository.impliedStrike(cDelta, true, FORWARD, TIME_TO_EXPIRY, vol);
double pRes = BlackFormulaRepository.impliedStrike(pdelta, false, FORWARD, TIME_TO_EXPIRY, vol);
assertEquals(strike, cRes, Math.abs(strike) * 1.e-8);
assertEquals(strike, pRes, Math.abs(strike) * 1.e-8);
}
}
}
/*
* Tests below are for debugging
*/
@Test(enabled = false)
public void sampleTest() {
double inf = Double.POSITIVE_INFINITY;
double resC0 = BlackFormulaRepository.crossGamma(inf, FORWARD, 0.01, VOLS[2]);
double resC00 = BlackFormulaRepository.crossGamma(1.e12, FORWARD, 0.01, VOLS[2]);
System.out.println(resC0 + "\t" + resC00);
System.out.println("\n");
double resP0 = BlackFormulaRepository.crossGamma(inf, FORWARD, 0.01, VOLS[2]);
double resP00 = BlackFormulaRepository.crossGamma(1.e12, FORWARD, 0.01, VOLS[2]);
System.out.println(resP0 + "\t" + resP00);
System.out.println("\n");
double resC1 = BlackFormulaRepository.crossGamma(FORWARD * 0.9, inf, 0.001, VOLS[2]);
double resC2 = BlackFormulaRepository.crossGamma(FORWARD * 0.9, 1.e12, 0.01, VOLS[2]);
System.out.println(resC1 + "\t" + resC2);
System.out.println("\n");
double resP1 = BlackFormulaRepository.crossGamma(FORWARD * 0.9, inf, 0.01, VOLS[2]);
double resP2 = BlackFormulaRepository.crossGamma(FORWARD * 0.9, 1.e12, 0.01, VOLS[2]);
System.out.println(resP1 + "\t" + resP2);
System.out.println("\n");
double resC3 = BlackFormulaRepository.crossGamma(FORWARD * 0.9, FORWARD, inf, VOLS[2]);
double resC4 = BlackFormulaRepository.crossGamma(FORWARD * 0.9, FORWARD, 1.e12, VOLS[2]);
System.out.println(resC3 + "\t" + resC4);
System.out.println("\n");
double resP3 = BlackFormulaRepository.crossGamma(FORWARD * 0.9, FORWARD, inf, VOLS[2]);
double resP4 = BlackFormulaRepository.crossGamma(FORWARD * 0.9, FORWARD, 1.e12, VOLS[2]);
System.out.println(resP3 + "\t" + resP4);
System.out.println("\n");
double resC5 = BlackFormulaRepository.crossGamma(FORWARD * 0.9, FORWARD, 1.e-12, VOLS[2]);
double resC6 = BlackFormulaRepository.crossGamma(FORWARD * 0.9, FORWARD, 1.e-11, VOLS[2]);
System.out.println(resC5 + "\t" + resC6);
System.out.println("\n");
double resP5 = BlackFormulaRepository.crossGamma(0., FORWARD, 0.01, VOLS[2]);
double resP6 = BlackFormulaRepository.crossGamma(1.e-12, FORWARD, 0.01, VOLS[2]);
System.out.println(resP5 + "\t" + resP6);
System.out.println("\n");
double resC7 = BlackFormulaRepository.crossGamma(0., 0., 0.01, VOLS[2]);
double resC8 = BlackFormulaRepository.crossGamma(1.e-12, 1.e-12, 0.01, VOLS[2]);
System.out.println(resC7 + "\t" + resC8);
System.out.println("\n");
double resP7 = BlackFormulaRepository.crossGamma(FORWARD, FORWARD, 0., VOLS[2]);
double resP8 = BlackFormulaRepository.crossGamma(FORWARD, FORWARD, 1.e-60, VOLS[2]);
System.out.println(resP7 + "\t" + resP8);
System.out.println("\n");
double resP9 = BlackFormulaRepository.crossGamma(FORWARD, 0., 0.01, VOLS[2]);
double resP10 = BlackFormulaRepository.crossGamma(FORWARD, 1.e-12, 0.01, VOLS[2]);
System.out.println(resP9 + "\t" + resP10);
System.out.println("\n");
double resC11 = BlackFormulaRepository.crossGamma(0., 0., 0., VOLS[2]);
double resC12 = BlackFormulaRepository.crossGamma(1.e-12, 1.e-12, 1.e-20, VOLS[2]);
System.out.println(resC11 + "\t" + resC12);
System.out.println("\n");
double resC13 = BlackFormulaRepository.crossGamma(FORWARD, 0., 0., VOLS[2]);
double resC14 = BlackFormulaRepository.crossGamma(FORWARD, 1.e-12, 1.e-20, VOLS[2]);
System.out.println(resC13 + "\t" + resC14);
System.out.println("\n");
double resC15 = BlackFormulaRepository.crossGamma(0., FORWARD, 0., VOLS[2]);
double resC16 = BlackFormulaRepository.crossGamma(1.e-12, FORWARD, 1.e-20, VOLS[2]);
System.out.println(resC15 + "\t" + resC16);
System.out.println("\n");
}
@Test(enabled = false)
public void sample2Test() {
double inf = Double.POSITIVE_INFINITY;
double resC0 = BlackFormulaRepository.price(inf, FORWARD, 0.01, VOLS[2], true);
double resC00 = BlackFormulaRepository.price(1.e14, FORWARD, 0.01, VOLS[2], true);
System.out.println(resC0 + "\t" + resC00);
System.out.println("\n");
double resP0 = BlackFormulaRepository.price(inf, FORWARD, 0.01, VOLS[2], false);
double resP00 = BlackFormulaRepository.price(1.e12, FORWARD, 0.01, VOLS[2], false);
System.out.println(resP0 + "\t" + resP00);
System.out.println("\n");
double resC1 = BlackFormulaRepository.price(FORWARD * 0.9, inf, 0.001, VOLS[2], true);
double resC2 = BlackFormulaRepository.price(FORWARD * 0.9, 1.e12, 0.01, VOLS[2], true);
System.out.println(resC1 + "\t" + resC2);
System.out.println("\n");
double resP1 = BlackFormulaRepository.price(FORWARD * 0.9, inf, 0.01, VOLS[2], false);
double resP2 = BlackFormulaRepository.price(FORWARD * 0.9, 1.e12, 0.01, VOLS[2], false);
System.out.println(resP1 + "\t" + resP2);
System.out.println("\n");
double resC3 = BlackFormulaRepository.price(FORWARD * 0.9, FORWARD, inf, VOLS[2], true);
double resC4 = BlackFormulaRepository.price(FORWARD * 0.9, FORWARD, 1.e12, VOLS[2], true);
System.out.println(resC3 + "\t" + resC4);
System.out.println("\n");
double resP3 = BlackFormulaRepository.price(FORWARD * 0.9, FORWARD, inf, VOLS[2], false);
double resP4 = BlackFormulaRepository.price(FORWARD * 0.9, FORWARD, 1.e12, VOLS[2], false);
System.out.println(resP3 + "\t" + resP4);
System.out.println("\n");
double resC5 = BlackFormulaRepository.price(FORWARD * 0.9, FORWARD, 1.e-12, VOLS[2], true);
double resC6 = BlackFormulaRepository.price(FORWARD * 0.9, FORWARD, 1.e-11, VOLS[2], true);
System.out.println(resC5 + "\t" + resC6);
System.out.println("\n");
double resP5 = BlackFormulaRepository.price(0., FORWARD, 0.01, VOLS[2], false);
double resP6 = BlackFormulaRepository.price(1.e-12, FORWARD, 0.01, VOLS[2], false);
System.out.println(resP5 + "\t" + resP6);
System.out.println("\n");
double resC7 = BlackFormulaRepository.price(0., 0., 0.01, VOLS[2], true);
double resC8 = BlackFormulaRepository.price(1.e-12, 1.e-12, 0.01, VOLS[2], true);
System.out.println(resC7 + "\t" + resC8);
System.out.println("\n");
double resP7 = BlackFormulaRepository.price(FORWARD, FORWARD, 0., VOLS[2], false);
double resP8 = BlackFormulaRepository.price(FORWARD, FORWARD, 1.e-60, VOLS[2], false);
System.out.println(resP7 + "\t" + resP8);
System.out.println("\n");
double resP9 = BlackFormulaRepository.price(FORWARD, 0., 0.01, VOLS[2], true);
double resP10 = BlackFormulaRepository.price(FORWARD, 1.e-12, 0.01, VOLS[2], true);
System.out.println(resP9 + "\t" + resP10);
System.out.println("\n");
double resC11 = BlackFormulaRepository.price(0., 0., 0., VOLS[2], false);
double resC12 = BlackFormulaRepository.price(1.e-12, 1.e-12, 1.e-20, VOLS[2], false);
System.out.println(resC11 + "\t" + resC12);
System.out.println("\n");
double resC13 = BlackFormulaRepository.price(FORWARD, 0., 0., VOLS[2], true);
double resC14 = BlackFormulaRepository.price(FORWARD, 1.e-12, 1.e-20, VOLS[2], true);
System.out.println(resC13 + "\t" + resC14);
System.out.println("\n");
double resC15 = BlackFormulaRepository.price(0., FORWARD, 0., VOLS[2], false);
double resC16 = BlackFormulaRepository.price(1.e-12, FORWARD, 1.e-20, VOLS[2], false);
System.out.println(resC15 + "\t" + resC16);
System.out.println("\n");
double resP17 = BlackFormulaRepository.price(FORWARD, 0., 0.01, VOLS[2], false);
double resP18 = BlackFormulaRepository.price(FORWARD, 1.e-12, 0.01, VOLS[2], false);
System.out.println(resP17 + "\t" + resP18);
System.out.println("\n");
}
@Test(enabled = false)
public void sample3Test() {
double inf = Double.POSITIVE_INFINITY;
double resC0 = BlackFormulaRepository.theta(inf, FORWARD, 0.01, VOLS[2], true, 0.05);
double resC00 = BlackFormulaRepository.theta(1.e14, FORWARD, 0.01, VOLS[2], true, 0.05);
System.out.println(resC0 + "\t" + resC00);
System.out.println("\n");
double resP0 = BlackFormulaRepository.theta(inf, FORWARD, 0.01, VOLS[2], false, 0.05);
double resP00 = BlackFormulaRepository.theta(1.e12, FORWARD, 0.01, VOLS[2], false, 0.05);
System.out.println(resP0 + "\t" + resP00);
System.out.println("\n");
double resC1 = BlackFormulaRepository.theta(FORWARD * 0.9, inf, 0.001, VOLS[2], true, 0.05);
double resC2 = BlackFormulaRepository.theta(FORWARD * 0.9, 1.e12, 0.01, VOLS[2], true, 0.05);
System.out.println(resC1 + "\t" + resC2);
System.out.println("\n");
double resP1 = BlackFormulaRepository.theta(FORWARD * 0.9, inf, 0.01, VOLS[2], false, 0.05);
double resP2 = BlackFormulaRepository.theta(FORWARD * 0.9, 1.e12, 0.01, VOLS[2], false, 0.05);
System.out.println(resP1 + "\t" + resP2);
System.out.println("\n");
double resC3 = BlackFormulaRepository.theta(FORWARD * 0.9, FORWARD, inf, VOLS[2], true, 0.05);
double resC4 = BlackFormulaRepository.theta(FORWARD * 0.9, FORWARD, 1.e12, VOLS[2], true, 0.05);
System.out.println(resC3 + "\t" + resC4);
System.out.println("\n");
double resP3 = BlackFormulaRepository.theta(FORWARD * 0.9, FORWARD, inf, VOLS[2], false, 0.05);
double resP4 = BlackFormulaRepository.theta(FORWARD * 0.9, FORWARD, 1.e12, VOLS[2], false, 0.05);
System.out.println(resP3 + "\t" + resP4);
System.out.println("\n");
double resC5 = BlackFormulaRepository.theta(FORWARD * 0.9, FORWARD, 1.e-12, VOLS[2], true, 0.05);
double resC6 = BlackFormulaRepository.theta(FORWARD * 0.9, FORWARD, 1.e-11, VOLS[2], true, 0.05);
System.out.println(resC5 + "\t" + resC6);
System.out.println("\n");
double resP5 = BlackFormulaRepository.theta(0., FORWARD, 0.01, VOLS[2], false, 0.05);
double resP6 = BlackFormulaRepository.theta(1.e-12, FORWARD, 0.01, VOLS[2], false, 0.05);
System.out.println(resP5 + "\t" + resP6);
System.out.println("\n");
double resC7 = BlackFormulaRepository.theta(0., 0., 0.01, VOLS[2], true, 0.05);
double resC8 = BlackFormulaRepository.theta(1.e-12, 1.e-12, 0.01, VOLS[2], true, 0.05);
System.out.println(resC7 + "\t" + resC8);
System.out.println("\n");
double resP7 = BlackFormulaRepository.theta(FORWARD, FORWARD, 0., VOLS[2], false, 0.05);
double resP8 = BlackFormulaRepository.theta(FORWARD, FORWARD, 1.e-60, VOLS[2], false, 0.05);
System.out.println(resP7 + "\t" + resP8);
System.out.println("\n");
double resP9 = BlackFormulaRepository.theta(FORWARD, 0., 0.01, VOLS[2], true, 0.05);
double resP10 = BlackFormulaRepository.theta(FORWARD, 1.e-12, 0.01, VOLS[2], true, 0.05);
System.out.println(resP9 + "\t" + resP10);
System.out.println("\n");
double resC11 = BlackFormulaRepository.theta(0., 0., 0., VOLS[2], false, 0.05);
double resC12 = BlackFormulaRepository.theta(1.e-12, 1.e-12, 1.e-24, VOLS[2], false, 0.05);
System.out.println(resC11 + "\t" + resC12);
System.out.println("\n");
double resC13 = BlackFormulaRepository.theta(FORWARD, 0., 0., VOLS[2], true, 0.05);
double resC14 = BlackFormulaRepository.theta(FORWARD, 1.e-12, 1.e-20, VOLS[2], true, 0.05);
System.out.println(resC13 + "\t" + resC14);
System.out.println("\n");
double resC15 = BlackFormulaRepository.theta(0., FORWARD, 0., VOLS[2], false, 0.05);
double resC16 = BlackFormulaRepository.theta(1.e-12, FORWARD, 1.e-20, VOLS[2], false, 0.05);
System.out.println(resC15 + "\t" + resC16);
System.out.println("\n");
double resC17 = BlackFormulaRepository.theta(FORWARD, inf, 1., VOLS[2], false, 0.05);
double resC18 = BlackFormulaRepository.theta(FORWARD, 1.e12, 1., VOLS[2], false, 0.05);
System.out.println(resC17 + "\t" + resC18);
System.out.println("\n");
double resC19 = BlackFormulaRepository.theta(FORWARD * 0.9, FORWARD, 1., inf, false, 0.05);
double resC20 = BlackFormulaRepository.theta(FORWARD * 0.9, FORWARD, 1., 1.e15, false, 0.05);
System.out.println(resC19 + "\t" + resC20);
System.out.println("\n");
}
@Test(enabled = false)
public void sample4Test() {
double inf = Double.POSITIVE_INFINITY;
double resC0 = BlackFormulaRepository.vomma(inf, FORWARD, 0.01, VOLS[2]);
double resC00 = BlackFormulaRepository.vomma(1.e14, FORWARD, 0.01, VOLS[2]);
System.out.println(resC0 + "\t" + resC00);
System.out.println("\n");
double resP0 = BlackFormulaRepository.vomma(inf, FORWARD, 0.01, VOLS[2]);
double resP00 = BlackFormulaRepository.vomma(1.e12, FORWARD, 0.01, VOLS[2]);
System.out.println(resP0 + "\t" + resP00);
System.out.println("\n");
double resC1 = BlackFormulaRepository.vomma(FORWARD * 0.9, inf, 0.001, VOLS[2]);
double resC2 = BlackFormulaRepository.vomma(FORWARD * 0.9, 1.e12, 0.01, VOLS[2]);
System.out.println(resC1 + "\t" + resC2);
System.out.println("\n");
double resP1 = BlackFormulaRepository.vomma(FORWARD * 0.9, inf, 0.01, VOLS[2]);
double resP2 = BlackFormulaRepository.vomma(FORWARD * 0.9, 1.e12, 0.01, VOLS[2]);
System.out.println(resP1 + "\t" + resP2);
System.out.println("\n");
double resC3 = BlackFormulaRepository.vomma(FORWARD * 0.9, FORWARD, inf, VOLS[2]);
double resC4 = BlackFormulaRepository.vomma(FORWARD * 0.9, FORWARD, 1.e12, VOLS[2]);
System.out.println(resC3 + "\t" + resC4);
System.out.println("\n");
double resP3 = BlackFormulaRepository.vomma(FORWARD * 0.9, FORWARD, inf, VOLS[2]);
double resP4 = BlackFormulaRepository.vomma(FORWARD * 0.9, FORWARD, 1.e12, VOLS[2]);
System.out.println(resP3 + "\t" + resP4);
System.out.println("\n");
double resC5 = BlackFormulaRepository.vomma(FORWARD * 0.9, FORWARD, 1.e-12, VOLS[2]);
double resC6 = BlackFormulaRepository.vomma(FORWARD * 0.9, FORWARD, 1.e-11, VOLS[2]);
System.out.println(resC5 + "\t" + resC6);
System.out.println("\n");
double resP5 = BlackFormulaRepository.vomma(0., FORWARD, 0.01, VOLS[2]);
double resP6 = BlackFormulaRepository.vomma(1.e-12, FORWARD, 0.01, VOLS[2]);
System.out.println(resP5 + "\t" + resP6);
System.out.println("\n");
double resC7 = BlackFormulaRepository.vomma(0., 0., 0.01, VOLS[2]);
double resC8 = BlackFormulaRepository.vomma(1.e-12, 1.e-12, 0.01, VOLS[2]);
System.out.println(resC7 + "\t" + resC8);
System.out.println("\n");
double resP7 = BlackFormulaRepository.vomma(FORWARD, FORWARD, 0., VOLS[2]);
double resP8 = BlackFormulaRepository.vomma(FORWARD, FORWARD, 1.e-60, VOLS[2]);
System.out.println(resP7 + "\t" + resP8);
System.out.println("\n");
double resP9 = BlackFormulaRepository.vomma(FORWARD, 0., 0.01, VOLS[2]);
double resP10 = BlackFormulaRepository.vomma(FORWARD, 1.e-12, 0.01, VOLS[2]);
System.out.println(resP9 + "\t" + resP10);
System.out.println("\n");
double resC11 = BlackFormulaRepository.vomma(0., 0., 0., VOLS[2]);
double resC12 = BlackFormulaRepository.vomma(1.e-12, 1.e-12, 1.e-60, VOLS[2]);
System.out.println(resC11 + "\t" + resC12);
System.out.println("\n");
double resC13 = BlackFormulaRepository.vomma(FORWARD, 0., 0., VOLS[2]);
double resC14 = BlackFormulaRepository.vomma(FORWARD, 1.e-12, 1.e-12, VOLS[2]);
System.out.println(resC13 + "\t" + resC14);
System.out.println("\n");
double resC15 = BlackFormulaRepository.vomma(0., FORWARD, 0., VOLS[2]);
double resC16 = BlackFormulaRepository.vomma(1.e-12, FORWARD, 1.e-20, VOLS[2]);
System.out.println(resC15 + "\t" + resC16);
System.out.println("\n");
double resC17 = BlackFormulaRepository.vomma(FORWARD, inf, 1., VOLS[2]);
double resC18 = BlackFormulaRepository.vomma(FORWARD, 1.e12, 1., VOLS[2]);
System.out.println(resC17 + "\t" + resC18);
System.out.println("\n");
double resC19 = BlackFormulaRepository.vomma(FORWARD * 0.9, FORWARD, 1., inf);
double resC20 = BlackFormulaRepository.vomma(FORWARD * 0.9, FORWARD, 1., 1.e15);
System.out.println(resC19 + "\t" + resC20);
System.out.println("\n");
}
@Test(enabled = false)
public void sTest() {
double forward = 140.;
double strike = 140 + 1.e-10;
double lognormalVol = 1.e-26;
double rootT = 2.;
double d1 = Math.log(forward / strike) / lognormalVol / rootT + 0.5 * lognormalVol * rootT;
double d2 = Math.log(forward / strike) / lognormalVol / rootT - 0.5 * lognormalVol * rootT;
System.out.println((-d2 * NORMAL.getPDF(d1) / lognormalVol));
forward = 140.;
strike = 140.;
lognormalVol = 0.;
d1 = Math.log(forward / strike) / lognormalVol / rootT + 0.5 * lognormalVol * rootT;
System.out.println((-d2 * NORMAL.getPDF(d1) / lognormalVol));
}
//-------------------------------------------------------------------------
// This test demonstrates why it is a bad idea to use quadrature methods for non-smooth functions
// Test was originally in GaussianQuadratureIntegrator1DTest but moved here due to BlackFormulaRepository dependency
@Test
public void testBlackFormula() {
double fwd = 5;
double strike = 6.5;
double t = 1.5;
double vol = 0.35;
double expected = BlackFormulaRepository.price(fwd, strike, t, vol, true);
Function<Double, Double> func = getBlackIntergrand(fwd, strike, t, vol);
Function<Double, Double> fullIntergrand = new Function<Double, Double>() {
@Override
public Double apply(Double x) {
return func.apply(x) * Math.exp(-x * x);
}
};
RungeKuttaIntegrator1D rk = new RungeKuttaIntegrator1D(1e-15);
double resRK = rk.integrate(fullIntergrand, 0., 10.); //The strike > fwd, so can start the integration at z=0 (i.e. s = fwd)
assertEquals(expected, resRK, 1e-15, "Runge Kutta");
GaussHermiteQuadratureIntegrator1D gh = new GaussHermiteQuadratureIntegrator1D(40);
double resGH = gh.integrateFromPolyFunc(func);
assertEquals(expected, resGH, 1e-2, "Gauss Hermite"); //terrible accuracy even with 40 points
}
private Function<Double, Double> getBlackIntergrand(double fwd, double k, double t, double vol) {
double rootPI = Math.sqrt(Math.PI);
double sigmaSqrTO2 = vol * vol * t / 2;
double sigmaRoot2T = vol * Math.sqrt(2 * t);
return new Function<Double, Double>() {
@Override
public Double apply(Double x) {
double s = fwd * Math.exp(-sigmaSqrTO2 + sigmaRoot2T * x);
return Math.max(s - k, 0) / rootPI;
}
};
}
private static final int N = 10;
private static final double[] STRIKES = new double[N];
private static final double[] STRIKES_ATM = new double[N];
private static final double[] SIGMA_NORMAL = new double[N];
static {
for (int i = 0; i < 10; i++) {
STRIKES[i] = FORWARD - 40.0d * (1.0d - 2.0d / N * i);
STRIKES_ATM[i] = FORWARD + (-0.5d * N + i) / 100.0d;
SIGMA_NORMAL[i] = 15.0 + i / 10.0d;
}
}
private static final double TOLERANCE_PRICE = 1.0E-6;
private static final double TOLERANCE_VOL_DELTA = 1.0E-8;
@Test(expectedExceptions = IllegalArgumentException.class)
public void wrong_strike() {
BlackFormulaRepository.impliedVolatilityFromNormalApproximated(FORWARD, -1.0d, TIME_TO_EXPIRY, 0.20d);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void wrong_forward() {
BlackFormulaRepository.impliedVolatilityFromNormalApproximated(-1.0d, FORWARD, TIME_TO_EXPIRY, 0.20d);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void wrong_strike2() {
BlackFormulaRepository.impliedVolatilityFromNormalApproximated2(FORWARD, -1.0d, TIME_TO_EXPIRY, 0.20d);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void wrong_forward2() {
BlackFormulaRepository.impliedVolatilityFromNormalApproximated2(-1.0d, FORWARD, TIME_TO_EXPIRY, 0.20d);
}
public void price_comparison_normal() {
priceCheck(STRIKES);
priceCheck(STRIKES_ATM);
}
private void priceCheck(double[] strikes) {
for (int i = 0; i < N; i++) {
double ivBlackComputed = BlackFormulaRepository
.impliedVolatilityFromNormalApproximated(FORWARD, strikes[i], TIME_TO_EXPIRY, SIGMA_NORMAL[i]);
double priceBlackComputed = BlackFormulaRepository
.price(FORWARD, strikes[i], TIME_TO_EXPIRY, ivBlackComputed, true);
double priceNormal = NormalFormulaRepository
.price(FORWARD, strikes[i], TIME_TO_EXPIRY, SIGMA_NORMAL[i], CALL);
assertEquals(priceNormal, priceBlackComputed, TOLERANCE_PRICE);
}
}
public void implied_volatility_from_normal_adjoint() {
double shiftFd = 1.0E-6;
for (int i = 0; i < N; i++) {
double ivBlackComputed = BlackFormulaRepository
.impliedVolatilityFromNormalApproximated(FORWARD, STRIKES[i], TIME_TO_EXPIRY, SIGMA_NORMAL[i]);
ValueDerivatives ivBlackAdj = BlackFormulaRepository
.impliedVolatilityFromNormalApproximatedAdjoint(FORWARD, STRIKES[i], TIME_TO_EXPIRY, SIGMA_NORMAL[i]);
assertEquals(ivBlackComputed, ivBlackAdj.getValue(), TOLERANCE_1);
assertEquals(1, ivBlackAdj.getDerivatives().size());
double ivBlackComputedP = BlackFormulaRepository
.impliedVolatilityFromNormalApproximated(FORWARD, STRIKES[i], TIME_TO_EXPIRY, SIGMA_NORMAL[i] + shiftFd);
double ivBlackComputedM = BlackFormulaRepository
.impliedVolatilityFromNormalApproximated(FORWARD, STRIKES[i], TIME_TO_EXPIRY, SIGMA_NORMAL[i] - shiftFd);
double derivativeApproximated = (ivBlackComputedP - ivBlackComputedM) / (2 * shiftFd);
assertEquals(derivativeApproximated, ivBlackAdj.getDerivative(0), TOLERANCE_VOL_DELTA);
}
}
private static final double T = 4.5;
private static final double F = 104;
private static final double DELTA_F = 10;
private static final double SIGMA = 0.5;
private static final double TOLERANCE_PRICE2 = 1.0E-8;
private static final double TOLERANCE_PRICE_DELTA = 1.0E-6;
public void priceAdjoint() {
// Price
double price = BlackFormulaRepository.price(F, F - DELTA_F, T, SIGMA, true);
ValueDerivatives priceAdjoint = BlackFormulaRepository.priceAdjoint(F, F - DELTA_F, T, SIGMA, true);
assertEquals(price, priceAdjoint.getValue(), TOLERANCE_PRICE2);
// Price with 0 volatility
double price0 = BlackFormulaRepository.price(F, F - DELTA_F, T, 0.0d, true);
ValueDerivatives price0Adjoint = BlackFormulaRepository.priceAdjoint(F, F - DELTA_F, T, 0.0d, true);
assertEquals(price0, price0Adjoint.getValue(), TOLERANCE_PRICE2);
// Derivative forward.
double deltaF = 0.01;
double priceFP = BlackFormulaRepository.price(F + deltaF, F - DELTA_F, T, SIGMA, true);
double priceFM = BlackFormulaRepository.price(F - deltaF, F - DELTA_F, T, SIGMA, true);
double derivativeF_FD = (priceFP - priceFM) / (2 * deltaF);
assertEquals(derivativeF_FD, priceAdjoint.getDerivative(0), TOLERANCE_PRICE_DELTA);
// Derivative strike.
double deltaK = 0.01;
double priceKP = BlackFormulaRepository.price(F, F - DELTA_F + deltaK, T, SIGMA, true);
double priceKM = BlackFormulaRepository.price(F, F - DELTA_F - deltaK, T, SIGMA, true);
double derivativeK_FD = (priceKP - priceKM) / (2 * deltaK);
assertEquals(derivativeK_FD, priceAdjoint.getDerivative(1), TOLERANCE_PRICE_DELTA);
// Derivative time.
double deltaT = 1.0 / 365.0;
double priceTP = BlackFormulaRepository.price(F, F - DELTA_F, T + deltaT, SIGMA, true);
double priceTM = BlackFormulaRepository.price(F, F - DELTA_F, T - deltaT, SIGMA, true);
double derivativeT_FD = (priceTP - priceTM) / (2 * deltaT);
assertEquals(derivativeT_FD, priceAdjoint.getDerivative(2), TOLERANCE_PRICE_DELTA);
// Derivative volatility.
double deltaV = 0.0001;
double priceVP = BlackFormulaRepository.price(F, F - DELTA_F, T, SIGMA + deltaV, true);
double priceVM = BlackFormulaRepository.price(F, F - DELTA_F, T, SIGMA - deltaV, true);
double derivativeV_FD = (priceVP - priceVM) / (2 * deltaV);
assertEquals(derivativeV_FD, priceAdjoint.getDerivative(3), TOLERANCE_PRICE_DELTA);
}
private static final double TOLERANCE_1 = 1.0E-10;
private static final double TOLERANCE_2_FWD_FWD = 1.0E-6;
private static final double TOLERANCE_2_VOL_VOL = 1.0E-6;
private static final double TOLERANCE_2_STR_STR = 1.0E-6;
private static final double TOLERANCE_2_FWD_VOL = 1.0E-7;
private static final double TOLERANCE_2_FWD_STR = 1.0E-6;
private static final double TOLERANCE_2_STR_VOL = 1.0E-6;
/** Tests second order Algorithmic Differentiation version of BlackFunction with several data sets. */
public void testPriceAdjoint2() {
// forward, numeraire, sigma, strike, time
double[][] testData = {
{104.0d, 0.9d, 0.50d, 94.0d, 4.5d},
{104.0d, 0.9d, 0.50d, 124.0d, 4.5d},
{104.0d, 0.9d, 0.50d, 104.0d, 4.5d},
{0.0250d, 1000.0d, 0.25d, 0.0150d, 10.0d},
{0.0250d, 1000.0d, 0.25d, 0.0400d, 10.0d},
{1700.0d, 0.9d, 1.00d, 1500.0d, 0.01d},
{1700.0d, 0.9d, 1.00d, 1900.0d, 20.0d}
};
int nbTest = testData.length;
for (int i = 0; i < nbTest; i++) {
testPriceAdjointSecondOrder(testData[i][0], testData[i][1], testData[i][2], testData[i][3], testData[i][4], CALL, i);
testPriceAdjointSecondOrder(testData[i][0], testData[i][1], testData[i][2], testData[i][3], testData[i][4], PUT, i);
}
}
private void testPriceAdjointSecondOrder(double forward, double numeraire, double sigma, double strike, double time,
PutCall putCall, int i) {
// Price
ValueDerivatives priceAdjoint =
BlackFormulaRepository.priceAdjoint(forward, strike, time, sigma, putCall.equals(PutCall.CALL));
Pair<ValueDerivatives, double[][]> bs =
BlackFormulaRepository.priceAdjoint2(forward, strike, time, sigma, putCall.equals(PutCall.CALL));
double[][] bsD2 = bs.getSecond();
assertEquals(priceAdjoint.getValue(), bs.getFirst().getValue(), TOLERANCE_1, "AD Second order: price");
// First derivative
for (int loopder = 0; loopder < 3; loopder++) {
assertEquals(priceAdjoint.getDerivatives().get(loopder), bs.getFirst().getDerivative(loopder),
TOLERANCE_1, "AD Second order: 1st");
}
// Second derivative
// Derivative forward-forward.
double deltaF = 1.0E-3 * forward;
ValueDerivatives priceAdjointFP = BlackFormulaRepository
.priceAdjoint(forward + deltaF, strike, time, sigma, putCall.equals(PutCall.CALL));
ValueDerivatives priceAdjointFM = BlackFormulaRepository
.priceAdjoint(forward - deltaF, strike, time, sigma, putCall.equals(PutCall.CALL));
double derivativeFF_FD = (priceAdjointFP.getDerivative(0) - priceAdjointFM.getDerivative(0)) / (2 * deltaF);
assertEquals(derivativeFF_FD, bs.getSecond()[0][0],
TOLERANCE_2_FWD_FWD * Math.abs(bs.getFirst().getValue() / (deltaF * deltaF)), "AD Second order: 2nd - fwd-fwd " + i);
// Derivative volatility-volatility.
double deltaV = 0.00001;
double deltaV2 = (deltaV * deltaV);
ValueDerivatives priceAdjointVP = BlackFormulaRepository
.priceAdjoint(forward, strike, time, sigma + deltaV, putCall.equals(PutCall.CALL));
ValueDerivatives priceAdjointVM = BlackFormulaRepository
.priceAdjoint(forward, strike, time, sigma - deltaV, putCall.equals(PutCall.CALL));
double derivativeVV_FD = (priceAdjointVP.getDerivative(3) - priceAdjointVM.getDerivative(3)) / (2 * deltaV);
assertEquals(derivativeVV_FD, bsD2[2][2], TOLERANCE_2_VOL_VOL * Math.abs(bs.getFirst().getValue() / deltaV2),
"AD Second order: 2nd - vol-vol " + i);
// Derivative forward-volatility.
double derivativeFV_FD = (priceAdjointVP.getDerivative(0) - priceAdjointVM.getDerivative(0)) / (2 * deltaV);
assertEquals(derivativeFV_FD, bsD2[2][0], TOLERANCE_2_FWD_VOL * Math.abs(bs.getFirst().getValue() / (deltaF * deltaV)),
"AD Second order: 2nd - fwd-vol " + i);
assertEquals(bsD2[0][2], bsD2[2][0], TOLERANCE_1, "AD Second order: 2nd - fwd-vol");
// Derivative strike-strike.
double deltaK = 1.0E-4 * strike;
ValueDerivatives priceAdjointKP = BlackFormulaRepository
.priceAdjoint(forward, strike + deltaK, time, sigma, putCall.equals(PutCall.CALL));
ValueDerivatives priceAdjointKM = BlackFormulaRepository
.priceAdjoint(forward, strike - deltaK, time, sigma, putCall.equals(PutCall.CALL));
double derivativeKK_FD = (priceAdjointKP.getDerivative(1) - priceAdjointKM.getDerivative(1)) / (2 * deltaK);
assertEquals(derivativeKK_FD, bsD2[1][1], TOLERANCE_2_STR_STR * Math.abs(derivativeKK_FD),
"AD Second order: 2nd - strike-strike " + i);
// Derivative forward-strike.
double derivativeFK_FD = (priceAdjointKP.getDerivative(0) - priceAdjointKM.getDerivative(0)) / (2 * deltaK);
assertEquals(derivativeFK_FD, bsD2[1][0], TOLERANCE_2_FWD_STR * Math.abs(bs.getFirst().getValue() / (deltaF * deltaK)),
"AD Second order: 2nd - fwd-str " + i);
assertEquals(bsD2[0][1], bsD2[1][0], TOLERANCE_1, "AD Second order: 2nd - fwd-str");
// Derivative strike-volatility.
double derivativeKV_FD = (priceAdjointVP.getDerivative(1) - priceAdjointVM.getDerivative(1)) / (2 * deltaV);
assertEquals(derivativeKV_FD, bsD2[2][1], TOLERANCE_2_STR_VOL * Math.abs(bs.getFirst().getValue()),
"AD Second order: 2nd - str-vol " + i);
assertEquals(bsD2[1][2], bsD2[2][1], TOLERANCE_1, "AD Second order: 2nd - str-vol");
}
}