// -------------------------------------------------------------------------
  private double forecastValueFwdSensitivity(Fra fra, double forwardRate, double eps) {

    RateObservationFn<RateObservation> obsFuncNew = mock(RateObservationFn.class);
    RatesProvider provNew = mock(RatesProvider.class);
    when(provNew.getValuationDate()).thenReturn(VAL_DATE);
    ExpandedFra fraExp = fra.expand();
    when(obsFuncNew.rate(fraExp.getFloatingRate(), fra.getStartDate(), fra.getEndDate(), provNew))
        .thenReturn(forwardRate + eps);
    CurrencyAmount upValue =
        new DiscountingFraProductPricer(obsFuncNew).forecastValue(fraExp, provNew);
    when(obsFuncNew.rate(fraExp.getFloatingRate(), fra.getStartDate(), fra.getEndDate(), provNew))
        .thenReturn(forwardRate - eps);
    CurrencyAmount downValue =
        new DiscountingFraProductPricer(obsFuncNew).forecastValue(fraExp, provNew);
    return upValue.minus(downValue).multipliedBy(0.5 / eps).getAmount();
  }
  // calibrated sum PV01 for one scenario
  MultiCurrencyAmount pv01CalibratedSum(ResolvedDsfTrade trade, RatesProvider ratesProvider) {

    PointSensitivities pointSensitivity = tradePricer.presentValueSensitivity(trade, ratesProvider);
    return ratesProvider
        .parameterSensitivity(pointSensitivity)
        .total()
        .multipliedBy(ONE_BASIS_POINT);
  }
  private double dscSensitivity(
      Fra fra, double forwardRate, double discountFactor, double paymentTime, double eps) {

    RatesProvider provNew = mock(RatesProvider.class);
    when(provNew.getValuationDate()).thenReturn(VAL_DATE);
    RateObservationFn<RateObservation> obsFuncNew = mock(RateObservationFn.class);
    ExpandedFra fraExp = fra.expand();
    when(obsFuncNew.rate(fraExp.getFloatingRate(), fra.getStartDate(), fra.getEndDate(), provNew))
        .thenReturn(forwardRate);
    when(provNew.discountFactor(fra.getCurrency(), fraExp.getPaymentDate()))
        .thenReturn(discountFactor * Math.exp(-eps * paymentTime));
    CurrencyAmount upDscValue =
        new DiscountingFraProductPricer(obsFuncNew).presentValue(fraExp, provNew);
    when(provNew.discountFactor(fra.getCurrency(), fraExp.getPaymentDate()))
        .thenReturn(discountFactor * Math.exp(eps * paymentTime));
    CurrencyAmount downDscValue =
        new DiscountingFraProductPricer(obsFuncNew).presentValue(fraExp, provNew);
    return upDscValue.minus(downDscValue).multipliedBy(0.5 / eps).getAmount();
  }
 // -------------------------------------------------------------------------
 // gets the settlement price
 private double settlementPrice(ResolvedDsfTrade trade, RatesProvider ratesProvider) {
   StandardId standardId = trade.getProduct().getSecurityId().getStandardId();
   QuoteId id = QuoteId.of(standardId, FieldName.SETTLEMENT_PRICE);
   double price = ratesProvider.data(id);
   ArgChecker.isTrue(
       price < 10,
       "Price must be in decimal form, such as 1.007 for a 0.7% present value, but was: {}",
       price);
   return price;
 }
  // 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);
  }
 // validate that the rates and volatilities providers are coherent
 private void validate(
     RatesProvider ratesProvider,
     ExpandedSwaption swaption,
     NormalVolatilitySwaptionProvider volatilityProvider) {
   ArgChecker.isTrue(
       volatilityProvider
           .getValuationDateTime()
           .toLocalDate()
           .equals(ratesProvider.getValuationDate()),
       "volatility and rate data should be for the same date");
   ArgChecker.isFalse(
       swaption.getUnderlying().isCrossCurrency(), "underlying swap should be single currency");
   ArgChecker.isTrue(
       swaption.getSwaptionSettlement().getSettlementType().equals(SettlementType.PHYSICAL),
       "swaption should be physical settlement");
 }
 public void test_currencyExposure() {
   MultiCurrencyAmount ceComputed =
       PRICER_TRADE.currencyExposure(OPTION_TRADE, RATES_PROVIDER, VOLS);
   PointSensitivities point =
       PRICER_TRADE.presentValueSensitivityRates(OPTION_TRADE, RATES_PROVIDER, VOLS);
   MultiCurrencyAmount pv = PRICER_TRADE.presentValue(OPTION_TRADE, RATES_PROVIDER, VOLS);
   MultiCurrencyAmount ceExpected = RATES_PROVIDER.currencyExposure(point).plus(pv);
   assertEquals(ceComputed.size(), 2);
   assertEquals(
       ceComputed.getAmount(EUR).getAmount(),
       ceExpected.getAmount(EUR).getAmount(),
       TOL * NOTIONAL);
   assertEquals(
       ceComputed.getAmount(USD).getAmount(),
       ceExpected.getAmount(USD).getAmount(),
       TOL * NOTIONAL);
 }
 @Override
 protected MultiCurrencyAmount execute(ExpandedFxSwap product, RatesProvider provider) {
   PointSensitivities pointSensitivity = pricer().presentValueSensitivity(product, provider);
   return provider.curveParameterSensitivity(pointSensitivity).total();
 }
 @Override
 protected CurveCurrencyParameterSensitivities execute(
     ExpandedFxSingle product, RatesProvider provider) {
   PointSensitivities pointSensitivity = pricer().presentValueSensitivity(product, provider);
   return provider.curveParameterSensitivity(pointSensitivity).multipliedBy(ONE_BASIS_POINT);
 }