@Override public Double apply(Double x) { return vega(forward, strike, timeToExpiry, x); } };
@Override public double priceVega(double expiry, PutCall putCall, double strike, double forward, double volatility) { return BlackFormulaRepository.vega(forward, strike, expiry, volatility); }
@Override public double priceVega(double expiry, double tenor, PutCall putCall, double strike, double forward, double volatility) { return BlackFormulaRepository.vega(forward, strike, expiry, volatility); }
private double[] vannaVolgaWeights( double forward, double strike, double timeToExpiry, double volATM, double[] strikesReference) { double lnk21 = Math.log(strikesReference[1] / strikesReference[0]); double lnk31 = Math.log(strikesReference[2] / strikesReference[0]); double lnk32 = Math.log(strikesReference[2] / strikesReference[1]); double[] lnk = new double[3]; for (int loopvv = 0; loopvv < 3; loopvv++) { lnk[loopvv] = Math.log(strikesReference[loopvv] / strike); } double[] x = new double[3]; double vega0 = BlackFormulaRepository.vega(forward, strikesReference[0], timeToExpiry, volATM); double vegaFlat = BlackFormulaRepository.vega(forward, strike, timeToExpiry, volATM); double vega2 = BlackFormulaRepository.vega(forward, strikesReference[2], timeToExpiry, volATM); x[0] = vegaFlat * lnk[1] * lnk[2] / (vega0 * lnk21 * lnk31); x[2] = vegaFlat * lnk[0] * lnk[1] / (vega2 * lnk31 * lnk32); return x; }
@Override public double priceVega(double expiry, double tenor, PutCall putCall, double strike, double forward, double volatility) { double shift = parameters.shift(expiry, tenor); return BlackFormulaRepository.vega(forward + shift, strike + shift, expiry, volatility); }
@Override public double priceVega(double expiry, PutCall putCall, double strike, double forward, double volatility) { double shift = parameters.shift(expiry); return BlackFormulaRepository.vega(forward + shift, strike + shift, expiry, volatility); }
@Override public double priceVega(double expiry, PutCall putCall, double strike, double forward, double volatility) { double shift = shiftCurve.yValue(expiry); return BlackFormulaRepository.vega(forward + shift, strike + shift, expiry, volatility); }
@Test(expectedExceptions = IllegalArgumentException.class) public void negativeTimeErrorVegaTest() { BlackFormulaRepository.vega(FORWARD, STRIKES_INPUT[1], -TIME_TO_EXPIRY, VOLS[1]); }
@Test(expectedExceptions = IllegalArgumentException.class) public void negativeVolErrorVegaTest() { BlackFormulaRepository.vega(FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, -0.5); }
@Test(expectedExceptions = IllegalArgumentException.class) public void negativeStrikeErrorVegaTest() { BlackFormulaRepository.vega(FORWARD, -STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1]); }
@Test(expectedExceptions = IllegalArgumentException.class) public void negativeFwdErrorVegaTest() { BlackFormulaRepository.vega(-FORWARD, STRIKES_INPUT[1], TIME_TO_EXPIRY, VOLS[1]); }
private double[] weights(double forward, double strike, double[] strikes, double timeToExpiry, double atmVol) { double[][] mat = new double[3][3]; double[] vec = new double[3]; for (int i = 0; i < 3; ++i) { mat[0][i] = BlackFormulaRepository.vega(forward, strikes[i], timeToExpiry, atmVol); mat[1][i] = BlackFormulaRepository.vanna(forward, strikes[i], timeToExpiry, atmVol); mat[2][i] = BlackFormulaRepository.volga(forward, strikes[i], timeToExpiry, atmVol); } vec[0] = BlackFormulaRepository.vega(forward, strike, timeToExpiry, atmVol); vec[1] = BlackFormulaRepository.vanna(forward, strike, timeToExpiry, atmVol); vec[2] = BlackFormulaRepository.volga(forward, strike, timeToExpiry, atmVol); DecompositionResult res = SVD.apply(DoubleMatrix.ofUnsafe(mat)); return res.solve(vec); }
public void test_vega_presentValueVega() { double vegaCall = PRICER.vega(CALL_OTM, RATES_PROVIDER, VOLS); CurrencyAmount pvVegaCall = PRICER.presentValueVega(CALL_OTM, RATES_PROVIDER, VOLS); double vegaPut = PRICER.vega(PUT_ITM, RATES_PROVIDER, VOLS); CurrencyAmount pvVegaPut = PRICER.presentValueVega(PUT_ITM, RATES_PROVIDER, VOLS); double timeToExpiry = VOLS.relativeTime(EXPIRY); double dfDom = RATES_PROVIDER.discountFactor(USD, PAYMENT_DATE); double forward = PRICER.getDiscountingFxSingleProductPricer().forwardFxRate(FX_PRODUCT_HIGH, RATES_PROVIDER) .fxRate(CURRENCY_PAIR); double vol = SMILE_TERM.volatility(timeToExpiry, STRIKE_RATE_HIGH, forward); double expectedVega = dfDom * BlackFormulaRepository.vega(forward, STRIKE_RATE_HIGH, timeToExpiry, vol); double expectedPvVega = -NOTIONAL * dfDom * BlackFormulaRepository.vega(forward, STRIKE_RATE_HIGH, timeToExpiry, vol); assertEquals(vegaCall, expectedVega, TOL); assertEquals(pvVegaCall.getCurrency(), USD); assertEquals(pvVegaCall.getAmount(), expectedPvVega, NOTIONAL * TOL); assertEquals(vegaPut, expectedVega, TOL); assertEquals(pvVegaPut.getCurrency(), USD); assertEquals(pvVegaPut.getAmount(), -expectedPvVega, NOTIONAL * TOL); }
public void test_price_formula() { double sampleVol = 0.2; for (int i = 0; i < NB_TEST; i++) { double expiryTime = VOLS.relativeTime(TEST_OPTION_EXPIRY[i]); for (int j = 0; j < NB_TEST; j++) { for (PutCall putCall : new PutCall[] {PutCall.CALL, PutCall.PUT}) { double price = VOLS.price(expiryTime, putCall, TEST_STRIKE[j], TEST_FORWARD, sampleVol); double delta = VOLS.priceDelta(expiryTime, putCall, TEST_STRIKE[j], TEST_FORWARD, sampleVol); double gamma = VOLS.priceGamma(expiryTime, putCall, TEST_STRIKE[j], TEST_FORWARD, sampleVol); double theta = VOLS.priceTheta(expiryTime, putCall, TEST_STRIKE[j], TEST_FORWARD, sampleVol); double vega = VOLS.priceVega(expiryTime, putCall, TEST_STRIKE[j], TEST_FORWARD, sampleVol); assertEquals(price, BlackFormulaRepository.price(TEST_FORWARD, TEST_STRIKE[j], expiryTime, sampleVol, putCall.isCall())); assertEquals(delta, BlackFormulaRepository.delta(TEST_FORWARD, TEST_STRIKE[j], expiryTime, sampleVol, putCall.isCall())); assertEquals(gamma, BlackFormulaRepository.gamma(TEST_FORWARD, TEST_STRIKE[j], expiryTime, sampleVol)); assertEquals(theta, BlackFormulaRepository.driftlessTheta(TEST_FORWARD, TEST_STRIKE[j], expiryTime, sampleVol)); assertEquals(vega, BlackFormulaRepository.vega(TEST_FORWARD, TEST_STRIKE[j], expiryTime, sampleVol)); } } } }
public void test_presentValueSensitivity() { PointSensitivities point = OPTION_TRADE_PRICER.presentValueSensitivityRates(OPTION_TRADE, RATE_PROVIDER, VOLS); CurrencyParameterSensitivities computed = RATE_PROVIDER.parameterSensitivity(point); double futurePrice = FUTURE_PRICER.price(OPTION_PRODUCT.getUnderlyingFuture(), RATE_PROVIDER); double strike = OPTION_PRODUCT.getStrikePrice(); double expiryTime = ACT_365F.relativeYearFraction(VAL_DATE, OPTION_PRODUCT.getExpiryDate()); double logMoneyness = Math.log(strike / futurePrice); double logMoneynessUp = Math.log(strike / (futurePrice + EPS)); double logMoneynessDw = Math.log(strike / (futurePrice - EPS)); double vol = SURFACE.zValue(expiryTime, logMoneyness); double volUp = SURFACE.zValue(expiryTime, logMoneynessUp); double volDw = SURFACE.zValue(expiryTime, logMoneynessDw); double volSensi = 0.5 * (volUp - volDw) / EPS; double vega = BlackFormulaRepository.vega(futurePrice, strike, expiryTime, vol); CurrencyParameterSensitivities sensiVol = RATE_PROVIDER.parameterSensitivity( FUTURE_PRICER.priceSensitivity(OPTION_PRODUCT.getUnderlyingFuture(), RATE_PROVIDER)) .multipliedBy(-vega * volSensi * NOTIONAL * QUANTITY); CurrencyParameterSensitivities expected = FD_CAL.sensitivity(RATE_PROVIDER, (p) -> OPTION_TRADE_PRICER.presentValue(OPTION_TRADE, (p), VOLS, REFERENCE_PRICE)); assertTrue(computed.equalWithTolerance(expected.combinedWith(sensiVol), 30d * EPS * NOTIONAL * QUANTITY)); }
/** * Calculates the price sensitivity to the Black volatility used for the pricing of the bond future option * based on the price of the underlying future. * * @param futureOption the option product * @param discountingProvider the discounting provider * @param volatilities the volatilities * @param futurePrice the underlying future price * @return the sensitivity */ public BondFutureOptionSensitivity priceSensitivityModelParamsVolatility( ResolvedBondFutureOption futureOption, LegalEntityDiscountingProvider discountingProvider, BlackBondFutureVolatilities volatilities, double futurePrice) { ArgChecker.isTrue(futureOption.getPremiumStyle().equals(FutureOptionPremiumStyle.DAILY_MARGIN), "Premium style should be DAILY_MARGIN"); double strike = futureOption.getStrikePrice(); ResolvedBondFuture future = futureOption.getUnderlyingFuture(); double volatility = volatilities.volatility(futureOption.getExpiry(), future.getLastTradeDate(), strike, futurePrice); double timeToExpiry = volatilities.relativeTime(futureOption.getExpiry()); double vega = BlackFormulaRepository.vega(futurePrice, strike, timeToExpiry, volatility); return BondFutureOptionSensitivity.of( volatilities.getName(), timeToExpiry, future.getLastTradeDate(), strike, futurePrice, future.getCurrency(), vega); }
public void test_priceSensitivity() { PointSensitivities point = OPTION_PRICER.priceSensitivityRatesStickyStrike( FUTURE_OPTION_PRODUCT, RATE_PROVIDER, VOLS); CurrencyParameterSensitivities computed = RATE_PROVIDER.parameterSensitivity(point); CurrencyParameterSensitivities expected = FD_CAL.sensitivity(RATE_PROVIDER, (p) -> CurrencyAmount.of(EUR, OPTION_PRICER.price(FUTURE_OPTION_PRODUCT, (p), VOLS))); double futurePrice = FUTURE_PRICER.price(FUTURE_OPTION_PRODUCT.getUnderlyingFuture(), RATE_PROVIDER); double strike = FUTURE_OPTION_PRODUCT.getStrikePrice(); double expiryTime = ACT_365F.relativeYearFraction(VAL_DATE, FUTURE_OPTION_PRODUCT.getExpiryDate()); double logMoneyness = Math.log(strike / futurePrice); double logMoneynessUp = Math.log(strike / (futurePrice + EPS)); double logMoneynessDw = Math.log(strike / (futurePrice - EPS)); double vol = SURFACE.zValue(expiryTime, logMoneyness); double volUp = SURFACE.zValue(expiryTime, logMoneynessUp); double volDw = SURFACE.zValue(expiryTime, logMoneynessDw); double volSensi = 0.5 * (volUp - volDw) / EPS; double vega = BlackFormulaRepository.vega(futurePrice, strike, expiryTime, vol); CurrencyParameterSensitivities sensiVol = RATE_PROVIDER.parameterSensitivity( FUTURE_PRICER.priceSensitivity(FUTURE_OPTION_PRODUCT.getUnderlyingFuture(), RATE_PROVIDER)).multipliedBy( -vega * volSensi); expected = expected.combinedWith(sensiVol); assertTrue(computed.equalWithTolerance(expected, 30d * EPS)); }
public void test_presentValueSensitivityBlackVolatility() { FxOptionSensitivity computedCall = (FxOptionSensitivity) PRICER.presentValueSensitivityModelParamsVolatility(CALL_OTM, RATES_PROVIDER, VOLS); FxOptionSensitivity computedPut = (FxOptionSensitivity) PRICER.presentValueSensitivityModelParamsVolatility(PUT_ITM, RATES_PROVIDER, VOLS); double timeToExpiry = VOLS.relativeTime(EXPIRY); double df = RATES_PROVIDER.discountFactor(USD, PAYMENT_DATE); double forward = PRICER.getDiscountingFxSingleProductPricer().forwardFxRate(FX_PRODUCT_HIGH, RATES_PROVIDER) .fxRate(CURRENCY_PAIR); double vol = SMILE_TERM.volatility(timeToExpiry, STRIKE_RATE_HIGH, forward); FxOptionSensitivity expected = FxOptionSensitivity.of( VOLS.getName(), CURRENCY_PAIR, timeToExpiry, STRIKE_RATE_HIGH, forward, USD, -NOTIONAL * df * BlackFormulaRepository.vega(forward, STRIKE_RATE_HIGH, timeToExpiry, vol)); assertTrue(computedCall.build().equalWithTolerance(expected.build(), NOTIONAL * TOL)); assertTrue(computedPut.build().equalWithTolerance(expected.build().multipliedBy(-1d), NOTIONAL * TOL)); }
public void test_presentValueSensitivityModelParamsSabr() { PointSensitivities sensiRec = SWAPTION_PRICER.presentValueSensitivityModelParamsSabr(SWAPTION_REC_LONG, RATE_PROVIDER, VOLS).build(); PointSensitivities sensiPay = SWAPTION_PRICER.presentValueSensitivityModelParamsSabr(SWAPTION_PAY_SHORT, RATE_PROVIDER, VOLS).build(); double forward = SWAP_PRICER.parRate(RSWAP_REC, RATE_PROVIDER); double pvbp = SWAP_PRICER.getLegPricer().pvbp(RSWAP_REC.getLegs(SwapLegType.FIXED).get(0), RATE_PROVIDER); double volatility = VOLS.volatility(SWAPTION_REC_LONG.getExpiry(), TENOR_YEAR, RATE, forward); double maturity = VOLS.relativeTime(SWAPTION_REC_LONG.getExpiry()); double[] volSensi = VOLS.getParameters() .volatilityAdjoint(maturity, TENOR_YEAR, RATE, forward).getDerivatives().toArray(); double vegaRec = pvbp * BlackFormulaRepository.vega(forward + SwaptionSabrRateVolatilityDataSet.SHIFT, RATE + SwaptionSabrRateVolatilityDataSet.SHIFT, maturity, volatility); double vegaPay = -pvbp * BlackFormulaRepository.vega(forward + SwaptionSabrRateVolatilityDataSet.SHIFT, RATE + SwaptionSabrRateVolatilityDataSet.SHIFT, maturity, volatility); assertSensitivity(sensiRec, SabrParameterType.ALPHA, vegaRec * volSensi[2], TOL); assertSensitivity(sensiRec, SabrParameterType.BETA, vegaRec * volSensi[3], TOL); assertSensitivity(sensiRec, SabrParameterType.RHO, vegaRec * volSensi[4], TOL); assertSensitivity(sensiRec, SabrParameterType.NU, vegaRec * volSensi[5], TOL); assertSensitivity(sensiPay, SabrParameterType.ALPHA, vegaPay * volSensi[2], TOL); assertSensitivity(sensiPay, SabrParameterType.BETA, vegaPay * volSensi[3], TOL); assertSensitivity(sensiPay, SabrParameterType.RHO, vegaPay * volSensi[4], TOL); assertSensitivity(sensiPay, SabrParameterType.NU, vegaPay * volSensi[5], TOL); }
public void test_presentValueSensitivityModelParamsSabr() { PointSensitivities sensiRec = PRICER.presentValueSensitivityModelParamsSabr(SWAPTION_REC_LONG, RATE_PROVIDER, VOLS).build(); PointSensitivities sensiPay = PRICER.presentValueSensitivityModelParamsSabr(SWAPTION_PAY_SHORT, RATE_PROVIDER, VOLS).build(); double forward = PRICER_SWAP.parRate(RSWAP_REC, RATE_PROVIDER); double annuityCash = PRICER_SWAP.getLegPricer().annuityCash(RFIXED_LEG_REC, forward); double expiry = VOLS.relativeTime(MATURITY); double volatility = VOLS.volatility(SWAPTION_REC_LONG.getExpiry(), TENOR_YEAR, RATE, forward); double df = RATE_PROVIDER.discountFactor(EUR, SETTLE); double[] volSensi = VOLS.getParameters().volatilityAdjoint(expiry, TENOR_YEAR, RATE, forward).getDerivatives().toArray(); double vegaRec = df * annuityCash * BlackFormulaRepository.vega(forward + SwaptionSabrRateVolatilityDataSet.SHIFT, RATE + SwaptionSabrRateVolatilityDataSet.SHIFT, expiry, volatility); double vegaPay = -df * annuityCash * BlackFormulaRepository.vega(forward + SwaptionSabrRateVolatilityDataSet.SHIFT, RATE + SwaptionSabrRateVolatilityDataSet.SHIFT, expiry, volatility); assertSensitivity(sensiRec, SabrParameterType.ALPHA, vegaRec * volSensi[2]); assertSensitivity(sensiRec, SabrParameterType.BETA, vegaRec * volSensi[3]); assertSensitivity(sensiRec, SabrParameterType.RHO, vegaRec * volSensi[4]); assertSensitivity(sensiRec, SabrParameterType.NU, vegaRec * volSensi[5]); assertSensitivity(sensiPay, SabrParameterType.ALPHA, vegaPay * volSensi[2]); assertSensitivity(sensiPay, SabrParameterType.BETA, vegaPay * volSensi[3]); assertSensitivity(sensiPay, SabrParameterType.RHO, vegaPay * volSensi[4]); assertSensitivity(sensiPay, SabrParameterType.NU, vegaPay * volSensi[5]); }