SABRExtrapolationRightFunction extends SABRExtrapolationLeftRightFunction { public double priceDerivativeStrike(final EuropeanVanillaOption option) { double pDK = 0.0; final double k = option.getStrike(); if (k <= _cutOffStrike) { final BlackPriceFunction blackFunction = new BlackPriceFunction(); final double[] volatilityAdjoint = getVolatilityAdjoint(option, _forward, _sabrData); final BlackFunctionData dataBlack = new BlackFunctionData(_forward, 1.0, volatilityAdjoint[0]); final double[] bsAdjoint = blackFunction.getPriceAdjoint(option, dataBlack); pDK = bsAdjoint[3] + bsAdjoint[2] * volatilityAdjoint[2]; } else { pDK = extrapolationDerivative(k); if (!option.isCall()) { pDK += 1.0; } } return pDK; } SABRExtrapolationRightFunction(final double forward, final SABRFormulaData sabrData, final double cutOffStrike, final double timeToExpiry, final double mu);  SABRExtrapolationRightFunction(final double forward, final SABRFormulaData sabrData, final double cutOffStrike, final double timeToExpiry, final double mu,
      final VolatilityFunctionProvider<SABRFormulaData> volatilityFunction); double price(final EuropeanVanillaOption option); double priceDerivativeStrike(final EuropeanVanillaOption option); double priceDerivativeForward(final EuropeanVanillaOption option); double priceAdjointSABR(final EuropeanVanillaOption option, final double[] priceDerivativeSABR); SABRFormulaData getSabrData(); double getCutOffStrike(); double getMu(); double getTimeToExpiry(); double[] getParameter(); double[] getParameterDerivativeForward(); double[][] getParameterDerivativeSABR();  }
@Test public void priceDerivativeStrike() { double strikeIn = 0.08; double strikeAt = CUT_OFF_STRIKE; double strikeOut = 0.12; double shiftK = 0.000001; EuropeanVanillaOption optionIn = new EuropeanVanillaOption(strikeIn, TIME_TO_EXPIRY, true); EuropeanVanillaOption optionAt = new EuropeanVanillaOption(strikeAt, TIME_TO_EXPIRY, true); EuropeanVanillaOption optionOut = new EuropeanVanillaOption(strikeOut, TIME_TO_EXPIRY, true); EuropeanVanillaOption optionInKP = new EuropeanVanillaOption(strikeIn + shiftK, TIME_TO_EXPIRY, true); EuropeanVanillaOption optionAtKP = new EuropeanVanillaOption(strikeAt + shiftK, TIME_TO_EXPIRY, true); EuropeanVanillaOption optionOutKP = new EuropeanVanillaOption(strikeOut + shiftK, TIME_TO_EXPIRY, true); double priceIn = SABR_EXTRAPOLATION.price(optionIn); double priceInKP = SABR_EXTRAPOLATION.price(optionInKP); double priceInDK = SABR_EXTRAPOLATION.priceDerivativeStrike(optionIn); double priceInDFExpected = (priceInKP - priceIn) / shiftK; assertEquals("SABR extrapolation: derivative with respect to strike, below cut-off", priceInDFExpected, priceInDK, 1E-5); double priceAt = SABR_EXTRAPOLATION.price(optionAt); double priceAtKP = SABR_EXTRAPOLATION.price(optionAtKP); double priceAtDK = SABR_EXTRAPOLATION.priceDerivativeStrike(optionAt); double priceAtDFExpected = (priceAtKP - priceAt) / shiftK; assertEquals("SABR extrapolation: derivative with respect to strike, at cut-off", priceAtDFExpected, priceAtDK, 1E-5); double priceOut = SABR_EXTRAPOLATION.price(optionOut); double priceOutKP = SABR_EXTRAPOLATION.price(optionOutKP); double priceOutDK = SABR_EXTRAPOLATION.priceDerivativeStrike(optionOut); double priceOutDFExpected = (priceOutKP - priceOut) / shiftK; assertEquals("SABR extrapolation: derivative with respect to strike, above cut-off", priceOutDFExpected, priceOutDK, 1E-5); }