SABRExtrapolationLeftFunction extends SABRExtrapolationLeftRightFunction { public double price(final EuropeanVanillaOption option) { ArgumentChecker.notNull(option, "option"); double p = 0.0; double k = option.getStrike(); if (k >= _cutOffStrike) { Function1D<SABRFormulaData, Double> funcSabr = getVolatilityFunction().getVolatilityFunction(option, _forward); double volatility = funcSabr.evaluate(_sabrData); if (volatility < 0.0) { volatility = 0.0; } BlackFunctionData dataBlack = new BlackFunctionData(_forward, 1.0, volatility); Function1D<BlackFunctionData, Double> funcBlack = BLACK_FUNCTION.getPriceFunction(option); p = funcBlack.evaluate(dataBlack); } else { p = extrapolation(k); if (option.isCall()) { p = p + (_forward - option.getStrike()); } } return p; } SABRExtrapolationLeftFunction(final double forward, final SABRFormulaData sabrData, final double cutOffStrike, final double timeToExpiry, final double mu,
      final VolatilityFunctionProvider<SABRFormulaData> volatilityFunction); double price(final EuropeanVanillaOption option); SABRFormulaData getSabrData(); double getCutOffStrike(); double getMu(); double getTimeToExpiry(); double[] getParameter(); @Override int hashCode(); @Override boolean equals(Object obj);  }
@Test public void smallForwardTest() { double smallForward = 0.9e-6; double smallCutoff = 0.5e-6; for (VolatilityFunctionProvider<SABRFormulaData> func : FUNCTIONS) { SABRExtrapolationLeftFunction left = new SABRExtrapolationLeftFunction(smallForward, DATA, smallCutoff, EXPIRY, MU, func); EuropeanVanillaOption optionBase = new EuropeanVanillaOption(smallCutoff, EXPIRY, false); EuropeanVanillaOption optionUp = new EuropeanVanillaOption(smallCutoff + EPS * 0.1, EXPIRY, false); EuropeanVanillaOption optionDw = new EuropeanVanillaOption(smallCutoff - EPS * 0.1, EXPIRY, false); double priceBase = left.price(optionBase); double priceUp = left.price(optionUp); double priceDw = left.price(optionDw); assertEquals(priceBase, priceUp, EPS * 10.0); assertEquals(priceBase, priceDw, EPS * 10.0); } }