BlackFormulaRepository { @ExternalFunction public static double dualVanna(final double forward, final double strike, final double timeToExpiry, final double lognormalVol) { ArgumentChecker.isTrue(forward >= 0.0, "negative/NaN forward; have {}", forward); ArgumentChecker.isTrue(strike >= 0.0, "negative/NaN strike; have {}", strike); ArgumentChecker.isTrue(timeToExpiry >= 0.0, "negative/NaN timeToExpiry; have {}", timeToExpiry); ArgumentChecker.isTrue(lognormalVol >= 0.0, "negative/NaN lognormalVol; have {}", lognormalVol); final double rootT = Math.sqrt(timeToExpiry); double sigmaRootT = lognormalVol * rootT; if (Double.isNaN(sigmaRootT)) { s_logger.info("lognormalVol * Math.sqrt(timeToExpiry) ambiguous"); sigmaRootT = 1.; } final boolean bFwd = (forward > LARGE); final boolean bStr = (strike > LARGE); final boolean bSigRt = (sigmaRootT > LARGE); double d1 = 0.; double d2 = 0.; if (bSigRt) { return 0.; } if (sigmaRootT < SMALL) { if (Math.abs(forward - strike) >= SMALL && !(bFwd && bStr)) { return 0.0; } s_logger.info("log(1)/0 ambiguous"); return lognormalVol < SMALL ? -NORMAL.getPDF(0.) / lognormalVol : -NORMAL.getPDF(0.) * rootT; } if (Math.abs(forward - strike) < SMALL | (bFwd && bStr)) { d1 = 0.5 * sigmaRootT; d2 = -0.5 * sigmaRootT; } else { d1 = Math.log(forward / strike) / sigmaRootT + 0.5 * sigmaRootT; d2 = d1 - sigmaRootT; } final double nVal = NORMAL.getPDF(d2); return nVal == 0. ? 0. : nVal * d1 / lognormalVol; }  @ExternalFunction static double price(final double forward, final double strike, final double timeToExpiry,
      final double lognormalVol, final boolean isCall); static double price(final SimpleOptionData data, final double lognormalVol); static double price(final SimpleOptionData[] data, final double lognormalVol); @ExternalFunction static double delta(final double forward, final double strike, final double timeToExpiry,
      final double lognormalVol, final boolean isCall); static double strikeForDelta(final double forward, final double forwardDelta, final double timeToExpiry,
      final double lognormalVol, final boolean isCall); @ExternalFunction static double dualDelta(final double forward, final double strike, final double timeToExpiry,
      final double lognormalVol, final boolean isCall); @ExternalFunction static double simpleDelta(final double forward, final double strike, final double timeToExpiry,
      final double lognormalVol, final boolean isCall); @ExternalFunction static double gamma(final double forward, final double strike, final double timeToExpiry,
      final double lognormalVol); @ExternalFunction static double dualGamma(final double forward, final double strike, final double timeToExpiry,
      final double lognormalVol); @ExternalFunction static double crossGamma(final double forward, final double strike, final double timeToExpiry,
      final double lognormalVol); @ExternalFunction static double theta(final double forward, final double strike, final double timeToExpiry,
      final double lognormalVol, final boolean isCall, final double interestRate); @ExternalFunction static double thetaMod(final double forward, final double strike, final double timeToExpiry,
      final double lognormalVol, final boolean isCall, final double interestRate); @ExternalFunction static double driftlessTheta(final double forward, final double strike, final double timeToExpiry,
      final double lognormalVol); @ExternalFunction static double vega(final double forward, final double strike, final double timeToExpiry,
      final double lognormalVol); @ExternalFunction static double vega(final SimpleOptionData data, final double lognormalVol); @ExternalFunction static double vanna(final double forward, final double strike, final double timeToExpiry,
      final double lognormalVol); @ExternalFunction static double dualVanna(final double forward, final double strike, final double timeToExpiry,
      final double lognormalVol); @ExternalFunction static double vomma(final double forward, final double strike, final double timeToExpiry,
      final double lognormalVol); @ExternalFunction static double volga(final double forward, final double strike, final double timeToExpiry,
      final double lognormalVol); static double impliedVolatility(final double price, final double forward, final double strike,
      final double timeToExpiry, final boolean isCall); @ExternalFunction static double impliedVolatility(final double otmPrice, final double forward, final double strike,
      final double timeToExpiry, final double volGuess); static double impliedVolatility(final SimpleOptionData data, final double price); static double impliedVolatility(final SimpleOptionData[] data, final double price); @ExternalFunction static double impliedStrike(final double delta, final boolean isCall, final double forward, final double time,
      final double volatility); static double impliedStrike(final double delta, final boolean isCall, final double forward, final double time,
      final double volatility, final double[] derivatives);  }
@Test public void exDualVannaTest() { final int nStrikes = STRIKES_INPUT.length; final int nVols = VOLS.length; final double inf = Double.POSITIVE_INFINITY; for (int i = 0; i < nStrikes; ++i) { for (int j = 0; j < nVols; ++j) { final double strike = STRIKES_INPUT[i]; final double vol = VOLS[j]; final double resC1 = BlackFormulaRepository.dualVanna(1.e-12 * strike, strike, TIME_TO_EXPIRY, vol); final double refC1 = BlackFormulaRepository.dualVanna(0., strike, TIME_TO_EXPIRY, vol); final double resC2 = BlackFormulaRepository.dualVanna(1.e12 * strike, strike, TIME_TO_EXPIRY, vol); final double refC2 = BlackFormulaRepository.dualVanna(inf, strike, TIME_TO_EXPIRY, vol); final double[] resVec = new double[] {resC1, resC2 }; final 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) { final double forward = STRIKES_INPUT[i]; final double vol = VOLS[j]; final double resC1 = BlackFormulaRepository.dualVanna(forward, 1.e-12 * forward, TIME_TO_EXPIRY, vol); final double resC2 = BlackFormulaRepository.dualVanna(forward, 1.e12 * forward, TIME_TO_EXPIRY, vol); final double refC1 = BlackFormulaRepository.dualVanna(forward, 0., TIME_TO_EXPIRY, vol); final double refC2 = BlackFormulaRepository.dualVanna(forward, inf, TIME_TO_EXPIRY, vol); final double[] resVec = new double[] {resC1, resC2 }; final 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) { final double strike = STRIKES_INPUT[i]; final double vol = VOLS[j]; final double resC1 = BlackFormulaRepository.dualVanna(FORWARD, strike, 1e-24, vol); final double resC2 = BlackFormulaRepository.dualVanna(FORWARD, strike, 1e24, vol); final double refC1 = BlackFormulaRepository.dualVanna(FORWARD, strike, 0., vol); final double refC2 = BlackFormulaRepository.dualVanna(FORWARD, strike, inf, vol); final double[] resVec = new double[] {resC1, resC2 }; final 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) { final double strike = STRIKES_INPUT[i]; final double resC1 = BlackFormulaRepository.dualVanna(FORWARD, strike, TIME_TO_EXPIRY, 1.e-12); final double refC1 = BlackFormulaRepository.dualVanna(FORWARD, strike, TIME_TO_EXPIRY, 0.); final double resC2 = BlackFormulaRepository.dualVanna(FORWARD, strike, TIME_TO_EXPIRY, 1.e12); final double refC2 = BlackFormulaRepository.dualVanna(FORWARD, strike, TIME_TO_EXPIRY, inf); final double[] resVec = new double[] {resC1, resC2 }; final 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) { final double vol = VOLS[j]; final double resC1 = BlackFormulaRepository.dualVanna(1.e-12, 1.e-12, TIME_TO_EXPIRY, vol); final double resC2 = BlackFormulaRepository.dualVanna(1.e-12, 1.e12, TIME_TO_EXPIRY, vol); final double resC3 = BlackFormulaRepository.dualVanna(1.e12, 1.e-12, TIME_TO_EXPIRY, vol); final double resP3 = BlackFormulaRepository.dualVanna(1.e12, 1.e12, TIME_TO_EXPIRY, vol); final double refC1 = BlackFormulaRepository.dualVanna(0., 0., TIME_TO_EXPIRY, vol); final double refC2 = BlackFormulaRepository.dualVanna(0., inf, TIME_TO_EXPIRY, vol); final double refC3 = BlackFormulaRepository.dualVanna(inf, 0., TIME_TO_EXPIRY, vol); final double refP3 = BlackFormulaRepository.dualVanna(inf, inf, TIME_TO_EXPIRY, vol); final double[] resVec = new double[] {resC1, resC2, resC3, resP3 }; final 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) { final double strike = STRIKES_INPUT[i]; final double vol = VOLS[j]; final double resC1 = BlackFormulaRepository.dualVanna(1.e-12, strike, 1.e-24, vol); final double resC2 = BlackFormulaRepository.dualVanna(1.e-12, strike, 1.e24, vol); final double resC3 = BlackFormulaRepository.dualVanna(1.e12, strike, 1.e-24, vol); final double resP3 = BlackFormulaRepository.dualVanna(1.e12, strike, 1.e24, vol); final double refC1 = BlackFormulaRepository.dualVanna(0., strike, 0., vol); final double refC2 = BlackFormulaRepository.dualVanna(0., strike, inf, vol); final double refC3 = BlackFormulaRepository.dualVanna(inf, strike, 0., vol); final double refP3 = BlackFormulaRepository.dualVanna(inf, strike, inf, vol); final double[] resVec = new double[] {resC1, resC2, resC3, resP3 }; final 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) { final double strike = STRIKES_INPUT[i]; final double resC1 = BlackFormulaRepository.dualVanna(1.e-12, strike, TIME_TO_EXPIRY, 1.e-12); final double resC2 = BlackFormulaRepository.dualVanna(1.e-12, strike, TIME_TO_EXPIRY, 1.e12); final double resC3 = BlackFormulaRepository.dualVanna(1.e12, strike, TIME_TO_EXPIRY, 1.e-12); final double resP3 = BlackFormulaRepository.dualVanna(1.e12, strike, TIME_TO_EXPIRY, 1.e12); final double refC1 = BlackFormulaRepository.dualVanna(0., strike, TIME_TO_EXPIRY, 0.); final double refC2 = BlackFormulaRepository.dualVanna(0., strike, TIME_TO_EXPIRY, inf); final double refC3 = BlackFormulaRepository.dualVanna(inf, strike, TIME_TO_EXPIRY, 0.); final double refP3 = BlackFormulaRepository.dualVanna(inf, strike, TIME_TO_EXPIRY, inf); final double[] resVec = new double[] {resC1, resC2, resC3, resP3 }; final 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) { final double forward = STRIKES_INPUT[i]; final double vol = VOLS[j]; final double resC1 = BlackFormulaRepository.dualVanna(forward, 1.e-12, 1.e-24, vol); final double resC2 = BlackFormulaRepository.dualVanna(forward, 1.e-12, 1.e24, vol); final double resC3 = BlackFormulaRepository.dualVanna(forward, 1.e12, 1.e-24, vol); final double resP3 = BlackFormulaRepository.dualVanna(forward, 1.e12, 1.e24, vol); final double refC1 = BlackFormulaRepository.dualVanna(forward, 0., 0., vol); final double refC2 = BlackFormulaRepository.dualVanna(forward, 0., inf, vol); final double refC3 = BlackFormulaRepository.dualVanna(forward, inf, 0., vol); final double refP3 = BlackFormulaRepository.dualVanna(forward, inf, inf, vol); final double[] resVec = new double[] {resC1, resC2, resC3, resP3 }; final 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) { final double forward = STRIKES_INPUT[i]; final double resC1 = BlackFormulaRepository.dualVanna(forward, 1.e-12, TIME_TO_EXPIRY, 1.e-12); final double resC2 = BlackFormulaRepository.dualVanna(forward, 1.e-12, TIME_TO_EXPIRY, 1.e12); final double resC3 = BlackFormulaRepository.dualVanna(forward, 1.e12, TIME_TO_EXPIRY, 1.e-12); final double resP3 = BlackFormulaRepository.dualVanna(forward, 1.e12, TIME_TO_EXPIRY, 1.e12); final double refC1 = BlackFormulaRepository.dualVanna(forward, 0., TIME_TO_EXPIRY, 0.); final double refC2 = BlackFormulaRepository.dualVanna(forward, 0., TIME_TO_EXPIRY, inf); final double refC3 = BlackFormulaRepository.dualVanna(forward, inf, TIME_TO_EXPIRY, 0.); final double refP3 = BlackFormulaRepository.dualVanna(forward, inf, TIME_TO_EXPIRY, inf); final double[] resVec = new double[] {resC1, resC2, resC3, resP3 }; final 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) { final double vol = VOLS[j]; final double resC1 = BlackFormulaRepository.dualVanna(1.e-12, 1.e-12, 1.e-24, vol); final double resC2 = BlackFormulaRepository.dualVanna(1.e-12, 1.e-12, 1.e24, vol); final double resC3 = BlackFormulaRepository.dualVanna(1.e-12, 1.e12, 1.e-24, vol); final double resP1 = BlackFormulaRepository.dualVanna(1.e-12, 1.e-14, 1.e-24, vol); final double resP2 = BlackFormulaRepository.dualVanna(1.e-12, 1.e-12, 1.e24, vol); final double resP3 = BlackFormulaRepository.dualVanna(1.e-12, 1.e12, 1.e-24, vol); final double resC4 = BlackFormulaRepository.dualVanna(1.e12, 1.e-12, 1.e-24, vol); final double resP4 = BlackFormulaRepository.dualVanna(1.e12, 1.e-12, 1.e-24, vol); final double resC5 = BlackFormulaRepository.dualVanna(FORWARD, FORWARD * (1. + 1.e-14), 1.e-24, vol); final double resP5 = BlackFormulaRepository.dualVanna(FORWARD, FORWARD * (1. + 1.e-14), 1.e-24, vol); final double resC6 = BlackFormulaRepository.dualVanna(1.e12, 1.e12, 1.e24, vol); final double resP6 = BlackFormulaRepository.dualVanna(1.e12, 1.e-12, 1.e24, vol); final double resC7 = BlackFormulaRepository.dualVanna(1.e12, 1.e12, 1.e-24, vol); final double resP7 = BlackFormulaRepository.dualVanna(1.e-12, 1.e12, 1.e24, vol); final double refC1 = BlackFormulaRepository.dualVanna(0., 0., 0., vol); final double refC2 = BlackFormulaRepository.dualVanna(0., 0., inf, vol); final double refC3 = BlackFormulaRepository.dualVanna(0., inf, 0., vol); final double refP1 = BlackFormulaRepository.dualVanna(0., 0., 0., vol); final double refP2 = BlackFormulaRepository.dualVanna(0., 0., inf, vol); final double refP3 = BlackFormulaRepository.dualVanna(0., inf, 0., vol); final double refC4 = BlackFormulaRepository.dualVanna(inf, 0., 0., vol); final double refP4 = BlackFormulaRepository.dualVanna(inf, 0., 0., vol); final double refC5 = BlackFormulaRepository.dualVanna(FORWARD, FORWARD, 0., vol); final double refP5 = BlackFormulaRepository.dualVanna(FORWARD, FORWARD, 0., vol); final double refC6 = BlackFormulaRepository.dualVanna(inf, inf, inf, vol); final double refP6 = BlackFormulaRepository.dualVanna(inf, 0., inf, vol); final double refC7 = BlackFormulaRepository.dualVanna(inf, inf, 0., vol); final double refP7 = BlackFormulaRepository.dualVanna(0., inf, inf, vol); final double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5, resC6, resP6, resC7, resP7 }; final 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); } } } } } } { final double resC1 = BlackFormulaRepository.dualVanna(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12); final double resC2 = BlackFormulaRepository.dualVanna(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12); final double resC3 = BlackFormulaRepository.dualVanna(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12); final double resP1 = BlackFormulaRepository.dualVanna(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e-12); final double resP2 = BlackFormulaRepository.dualVanna(1.e-12, 1.e-12, TIME_TO_EXPIRY, 1.e12); final double resP3 = BlackFormulaRepository.dualVanna(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e-12); final double resC4 = BlackFormulaRepository.dualVanna(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12); final double resP4 = BlackFormulaRepository.dualVanna(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e-12); final double resC5 = BlackFormulaRepository.dualVanna(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12); final double resP5 = BlackFormulaRepository.dualVanna(FORWARD, FORWARD * (1. + 1.e-12), TIME_TO_EXPIRY, 1.e-12); final double resC6 = BlackFormulaRepository.dualVanna(1.e12, 1.e12, TIME_TO_EXPIRY, 1.e12); final double resP6 = BlackFormulaRepository.dualVanna(1.e12, 1.e-12, TIME_TO_EXPIRY, 1.e12); final double resC7 = BlackFormulaRepository.dualVanna(1.e12, 1.e12, TIME_TO_EXPIRY, 1.e-12); final double resP7 = BlackFormulaRepository.dualVanna(1.e-12, 1.e12, TIME_TO_EXPIRY, 1.e12); final double refC1 = BlackFormulaRepository.dualVanna(0., 0., TIME_TO_EXPIRY, 0.); final double refC2 = BlackFormulaRepository.dualVanna(0., 0., TIME_TO_EXPIRY, inf); final double refC3 = BlackFormulaRepository.dualVanna(0., inf, TIME_TO_EXPIRY, 0.); final double refP1 = BlackFormulaRepository.dualVanna(0., 0., TIME_TO_EXPIRY, 0.); final double refP2 = BlackFormulaRepository.dualVanna(0., 0., TIME_TO_EXPIRY, inf); final double refP3 = BlackFormulaRepository.dualVanna(0., inf, TIME_TO_EXPIRY, 0.); final double refC4 = BlackFormulaRepository.dualVanna(inf, 0., TIME_TO_EXPIRY, 0.); final double refP4 = BlackFormulaRepository.dualVanna(inf, 0., TIME_TO_EXPIRY, 0.); final double refC5 = BlackFormulaRepository.dualVanna(FORWARD, FORWARD, TIME_TO_EXPIRY, 0.); final double refP5 = BlackFormulaRepository.dualVanna(FORWARD, FORWARD, TIME_TO_EXPIRY, 0.); final double refC6 = BlackFormulaRepository.dualVanna(inf, inf, TIME_TO_EXPIRY, inf); final double refP6 = BlackFormulaRepository.dualVanna(inf, 0., TIME_TO_EXPIRY, inf); final double refC7 = BlackFormulaRepository.dualVanna(inf, inf, TIME_TO_EXPIRY, 0.); final double refP7 = BlackFormulaRepository.dualVanna(0., inf, TIME_TO_EXPIRY, inf); final double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC5, resP5, resC6, resP6, resC7, resP7 }; final 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); } } } } } } { final double resC1 = BlackFormulaRepository.dualVanna(FORWARD, 1.e-12, 1.e-12, 1.e-12); final double resC2 = BlackFormulaRepository.dualVanna(FORWARD, 1.e-12, 1.e-12, 1.e12); final double resC3 = BlackFormulaRepository.dualVanna(FORWARD, 1.e-12, 1.e12, 1.e-12); final double resP1 = BlackFormulaRepository.dualVanna(FORWARD, 1.e-12, 1.e-12, 1.e-12); final double resP2 = BlackFormulaRepository.dualVanna(FORWARD, 1.e-12, 1.e-12, 1.e12); final double resP3 = BlackFormulaRepository.dualVanna(FORWARD, 1.e-12, 1.e12, 1.e-12); final double resC4 = BlackFormulaRepository.dualVanna(FORWARD, 1.e12, 1.e-12, 1.e-12); final double resP4 = BlackFormulaRepository.dualVanna(FORWARD, 1.e12, 1.e-12, 1.e-12); final double resC6 = BlackFormulaRepository.dualVanna(FORWARD, 1.e12, 1.e12, 1.e12); final double resP6 = BlackFormulaRepository.dualVanna(FORWARD, 1.e12, 1.e-12, 1.e12); final double resC7 = BlackFormulaRepository.dualVanna(FORWARD, 1.e12, 1.e12, 1.e-12); final double resP7 = BlackFormulaRepository.dualVanna(FORWARD, 1.e-12, 1.e12, 1.e12); final double refC1 = BlackFormulaRepository.dualVanna(FORWARD, 0., 0., 0.); final double refC2 = BlackFormulaRepository.dualVanna(FORWARD, 0., 0., inf); final double refC3 = BlackFormulaRepository.dualVanna(FORWARD, 0., inf, 0.); final double refP1 = BlackFormulaRepository.dualVanna(FORWARD, 0., 0., 0.); final double refP2 = BlackFormulaRepository.dualVanna(FORWARD, 0., 0., inf); final double refP3 = BlackFormulaRepository.dualVanna(FORWARD, 0., inf, 0.); final double refC4 = BlackFormulaRepository.dualVanna(FORWARD, inf, 0., 0.); final double refP4 = BlackFormulaRepository.dualVanna(FORWARD, inf, 0., 0.); final double refC6 = BlackFormulaRepository.dualVanna(FORWARD, inf, inf, inf); final double refP6 = BlackFormulaRepository.dualVanna(FORWARD, inf, 0., inf); final double refC7 = BlackFormulaRepository.dualVanna(FORWARD, inf, inf, 0.); final double refP7 = BlackFormulaRepository.dualVanna(FORWARD, 0., inf, inf); final double[] resVec = new double[] {resC1, resP1, resC2, resP2, resC3, resP3, resC4, resP4, resC6, resP6, resC7, resP7 }; final 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]); }