private void calibration_market_quote_sensitivity_check( Function<MarketData, ImmutableRatesProvider> calibrator, double shift) { double notional = 100_000_000.0; double fx = 1.1111; double fxPts = 0.0012; FxSwapTrade trade = EUR_USD.toTrade( VAL_DATE, Period.ofWeeks(6), Period.ofMonths(5), BuySell.BUY, notional, fx, fxPts); ImmutableRatesProvider result = CALIBRATOR.calibrate(CURVE_GROUP_CONFIG, VAL_DATE, ALL_QUOTES, TS); PointSensitivities pts = FX_PRICER.presentValueSensitivity(trade.getProduct(), result); CurveCurrencyParameterSensitivities ps = result.curveParameterSensitivity(pts); CurveCurrencyParameterSensitivities mqs = MQC.sensitivity(ps, result); double pvUsd = FX_PRICER.presentValue(trade.getProduct(), result).getAmount(USD).getAmount(); double pvEur = FX_PRICER.presentValue(trade.getProduct(), result).getAmount(EUR).getAmount(); double[] mqsUsd1Computed = mqs.getSensitivity(USD_DSCON_CURVE_NAME, USD).getSensitivity().toArray(); for (int i = 0; i < USD_DSC_NB_NODES; i++) { Map<MarketDataKey<?>, Object> map = new HashMap<>(ALL_QUOTES.getValues()); map.put( QuoteKey.of(StandardId.of(SCHEME, USD_DSC_ID_VALUE[i])), USD_DSC_MARKET_QUOTES[i] + shift); ImmutableMarketData marketData = ImmutableMarketData.of(map); ImmutableRatesProvider rpShifted = calibrator.apply(marketData); double pvS = FX_PRICER.presentValue(trade.getProduct(), rpShifted).getAmount(USD).getAmount(); assertEquals(mqsUsd1Computed[i], (pvS - pvUsd) / shift, TOLERANCE_PV_DELTA); } double[] mqsUsd2Computed = mqs.getSensitivity(USD_DSCON_CURVE_NAME, EUR).getSensitivity().toArray(); for (int i = 0; i < USD_DSC_NB_NODES; i++) { Map<MarketDataKey<?>, Object> map = new HashMap<>(ALL_QUOTES.getValues()); map.put( QuoteKey.of(StandardId.of(SCHEME, USD_DSC_ID_VALUE[i])), USD_DSC_MARKET_QUOTES[i] + shift); ImmutableMarketData ov = ImmutableMarketData.of(map); ImmutableRatesProvider rpShifted = calibrator.apply(ov); double pvS = FX_PRICER.presentValue(trade.getProduct(), rpShifted).getAmount(EUR).getAmount(); assertEquals(mqsUsd2Computed[i], (pvS - pvEur) / shift, TOLERANCE_PV_DELTA); } double[] mqsEur1Computed = mqs.getSensitivity(EUR_DSC_CURVE_NAME, USD).getSensitivity().toArray(); for (int i = 0; i < EUR_DSC_NB_NODES; i++) { assertEquals(mqsEur1Computed[i], 0.0, TOLERANCE_PV_DELTA); } double[] mqsEur2Computed = mqs.getSensitivity(EUR_DSC_CURVE_NAME, EUR).getSensitivity().toArray(); for (int i = 0; i < EUR_DSC_NB_NODES; i++) { Map<MarketDataKey<?>, Object> map = new HashMap<>(ALL_QUOTES.getValues()); map.put( QuoteKey.of(StandardId.of(SCHEME, EUR_DSC_ID_VALUE[i])), EUR_DSC_MARKET_QUOTES[i] + shift); ImmutableMarketData marketData = ImmutableMarketData.of(map); ImmutableRatesProvider rpShifted = calibrator.apply(marketData); double pvS = FX_PRICER.presentValue(trade.getProduct(), rpShifted).getAmount(EUR).getAmount(); assertEquals(mqsEur2Computed[i], (pvS - pvEur) / shift, TOLERANCE_PV_DELTA, "Node " + i); } }
// market quote bucketed PV01 for one scenario CurrencyParameterSensitivities pv01MarketQuoteBucketed( ResolvedDsfTrade trade, RatesProvider ratesProvider) { PointSensitivities pointSensitivity = tradePricer.presentValueSensitivity(trade, ratesProvider); CurrencyParameterSensitivities parameterSensitivity = ratesProvider.parameterSensitivity(pointSensitivity); return MARKET_QUOTE_SENS .sensitivity(parameterSensitivity, ratesProvider) .multipliedBy(ONE_BASIS_POINT); }