ForexOptionVanillaBlackFlatMethod { public MultipleCurrencyAmount presentValue(final ForexOptionVanilla optionForex, final BlackForexFlatProviderInterface black) { Validate.notNull(optionForex, "Forex option"); Validate.notNull(black, "Smile"); final MulticurveProviderInterface multicurves = black.getMulticurveProvider(); final double dfDomestic = multicurves.getDiscountFactor(optionForex.getCurrency2(), optionForex.getUnderlyingForex().getPaymentTime()); final double dfForeign = multicurves.getDiscountFactor(optionForex.getCurrency1(), optionForex.getUnderlyingForex().getPaymentTime()); final double spot = multicurves.getFxRate(optionForex.getCurrency1(), optionForex.getCurrency2()); final double forward = spot * dfForeign / dfDomestic; final double volatility = black.getVolatility(optionForex.getCurrency1(), optionForex.getCurrency2(), optionForex.getTimeToExpiry()); final BlackFunctionData dataBlack = new BlackFunctionData(forward, dfDomestic, volatility); final Function1D<BlackFunctionData, Double> func = BLACK_FUNCTION.getPriceFunction(optionForex); final double price = func.evaluate(dataBlack) * Math.abs(optionForex.getUnderlyingForex().getPaymentCurrency1().getAmount()) * (optionForex.isLong() ? 1.0 : -1.0); final CurrencyAmount priceCurrency = CurrencyAmount.of(optionForex.getUnderlyingForex().getCurrency2(), price); return MultipleCurrencyAmount.of(priceCurrency); } private  ForexOptionVanillaBlackFlatMethod(); static ForexOptionVanillaBlackFlatMethod getInstance(); MultipleCurrencyAmount presentValue(final ForexOptionVanilla optionForex, final BlackForexFlatProviderInterface black); double impliedVolatility(final ForexOptionVanilla optionForex, final BlackForexFlatProviderInterface black); MultipleCurrencyAmount currencyExposure(final ForexOptionVanilla optionForex, final BlackForexFlatProviderInterface black); double deltaRelative(final ForexOptionVanilla optionForex, final BlackForexFlatProviderInterface black, final boolean directQuote); double deltaRelativeSpot(final ForexOptionVanilla optionForex, final BlackForexFlatProviderInterface black, final boolean directQuote); double gammaRelative(final ForexOptionVanilla optionForex, final BlackForexFlatProviderInterface black, final boolean directQuote); double gammaRelativeSpot(final ForexOptionVanilla optionForex, final BlackForexFlatProviderInterface black, final boolean directQuote); CurrencyAmount gamma(final ForexOptionVanilla optionForex, final BlackForexFlatProviderInterface black, final boolean directQuote); CurrencyAmount gammaSpot(final ForexOptionVanilla optionForex, final BlackForexFlatProviderInterface black, final boolean directQuote); CurrencyAmount thetaTheoretical(final ForexOptionVanilla optionForex, final BlackForexFlatProviderInterface black); double forwardForexRate(final ForexOptionVanilla optionForex, final MulticurveProviderInterface multicurves); MultipleCurrencyMulticurveSensitivity presentValueCurveSensitivity(final ForexOptionVanilla optionForex, final BlackForexFlatProviderInterface black); PresentValueForexBlackVolatilitySensitivity presentValueBlackVolatilitySensitivity(final ForexOptionVanilla optionForex, final BlackForexFlatProviderInterface black); double[] presentValueBlackVolatilityNodeSensitivity(final ForexOptionVanilla optionForex, final BlackForexFlatProviderInterface black);  }
@Test public void presentValue() { final double timeToExpiry = TimeCalculator.getTimeBetween(REFERENCE_DATE, OPT_EXP_DATE); final double df = MULTICURVES.getDiscountFactor(USD, TimeCalculator.getTimeBetween(REFERENCE_DATE, OPT_PAY_DATE)); final double forward = SPOT * MULTICURVES.getDiscountFactor(EUR, TimeCalculator.getTimeBetween(REFERENCE_DATE, OPT_PAY_DATE)) / df; final double volatility = TERM_STRUCTURE_VOL.getYValue(timeToExpiry); final BlackFunctionData dataBlack = new BlackFunctionData(forward, df, volatility); final Function1D<BlackFunctionData, Double> func = BLACK_FUNCTION.getPriceFunction(CALL_LONG); final double priceExpected = func.evaluate(dataBlack) * NOTIONAL_EUR; final MultipleCurrencyAmount priceComputed = METHOD_BLACK_FLAT.presentValue(CALL_LONG, BLACK_MULTICURVES); assertEquals("Forex vanilla option: present value", priceExpected, priceComputed.getAmount(USD), TOLERANCE_PV); }
@Test public void presentValuePutCallParity() { final MultipleCurrencyAmount pvCall = METHOD_BLACK_FLAT.presentValue(CALL_LONG, BLACK_MULTICURVES); final MultipleCurrencyAmount pvPut = METHOD_BLACK_FLAT.presentValue(PUT_SHORT, BLACK_MULTICURVES); final MultipleCurrencyAmount pvForward = FX.accept(PVDC, MULTICURVES); assertEquals("Forex vanilla option: present value put/call parity", MULTICURVES.getFxRates().convert(pvForward, EUR).getAmount(), MULTICURVES.getFxRates().convert(pvCall.plus(pvPut), EUR).getAmount(), TOLERANCE_PV); }
@Test public void presentValueMethodVsCalculator() { final MultipleCurrencyAmount pvMethod = METHOD_BLACK_FLAT.presentValue(CALL_LONG, BLACK_MULTICURVES); final MultipleCurrencyAmount pvCalculator = CALL_LONG.accept(PVFBFC, BLACK_MULTICURVES); assertEquals("Forex vanilla option: present value Method vs Calculator", pvMethod.getAmount(USD), pvCalculator.getAmount(USD), TOLERANCE_PV); }