//-------------------------------------------------------------------------
	  /// <summary>
	  /// Test present value for ISDA FRA Discounting method.
	  /// </summary>
	  public virtual void test_presentValue_ISDA()
	  {
		SimpleRatesProvider prov = createProvider(RFRA);

		DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT;
		CurrencyAmount pvComputed = test.presentValue(RFRA, prov);
		CurrencyAmount pvExpected = test.forecastValue(RFRA, prov).multipliedBy(DISCOUNT_FACTOR);
		assertEquals(pvComputed.Amount, pvExpected.Amount, TOLERANCE);

		// test via FraTrade
		DiscountingFraTradePricer testTrade = new DiscountingFraTradePricer(test);
		assertEquals(testTrade.presentValue(RFRA_TRADE, prov), test.presentValue(RFRA, prov));
	  }
	  /// <summary>
	  /// Test FRA paying in the past.
	  /// </summary>
	  public virtual void test_presentValue_inPast()
	  {
		ResolvedFra fra = RFRA.toBuilder().paymentDate(VAL_DATE.minusDays(1)).build();
		SimpleRatesProvider prov = createProvider(fra);

		DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT;
		CurrencyAmount computed = test.presentValue(fra, prov);
		assertEquals(computed.Amount, 0d, TOLERANCE);
	  }
	  /// <summary>
	  /// Test present value for ISDA FRA Discounting method.
	  /// </summary>
	  public virtual void test_presentValue_AFMA()
	  {
		SimpleRatesProvider prov = createProvider(RFRA_AFMA);

		DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT;
		CurrencyAmount pvComputed = test.presentValue(RFRA_AFMA, prov);
		CurrencyAmount pvExpected = test.forecastValue(RFRA_AFMA, prov).multipliedBy(DISCOUNT_FACTOR);
		assertEquals(pvComputed.Amount, pvExpected.Amount, TOLERANCE);
	  }
	  /// <summary>
	  /// Test par spread for AFMA FRA Discounting method.
	  /// </summary>
	  public virtual void test_parSpread_AFMA()
	  {
		ResolvedFra fraExp = RFRA_AFMA;
		SimpleRatesProvider prov = createProvider(fraExp);

		DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT;
		double parSpread = test.parSpread(fraExp, prov);
		ResolvedFra fra = createNewFra(FRA_AFMA, FRA_AFMA.FixedRate + parSpread);
		CurrencyAmount pv = test.presentValue(fra, prov);
		assertEquals(pv.Amount, 0.0, TOLERANCE);
	  }
	  public virtual void test_presentValueSensitivity_dfCurve_FD()
	  {
		double eps = 1.0e-6;
		ImmutableRatesProvider prov = RatesProviderDataSets.MULTI_GBP_USD_SIMPLE;
		RatesFiniteDifferenceSensitivityCalculator cal = new RatesFiniteDifferenceSensitivityCalculator(eps);
		DiscountingFraProductPricer pricer = DiscountingFraProductPricer.DEFAULT;
		ResolvedFra fraExp = RFRA;
		PointSensitivities point = pricer.presentValueSensitivity(fraExp, prov);
		CurrencyParameterSensitivities computed = prov.parameterSensitivity(point);
		CurrencyParameterSensitivities expected = cal.sensitivity(prov, p => pricer.presentValue(fraExp, p));
		assertTrue(computed.equalWithTolerance(expected, eps * FRA.Notional));
	  }
	  /// <summary>
	  /// Test par rate for NONE FRA Discounting method.
	  /// </summary>
	  public virtual void test_parRate_NONE()
	  {
		ResolvedFra fraExp = RFRA_NONE;
		SimpleRatesProvider prov = createProvider(fraExp);

		DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT;
		double parRate = test.parRate(fraExp, prov);
		assertEquals(parRate, FORWARD_RATE);
		ResolvedFra fra = createNewFra(FRA_NONE, parRate);
		CurrencyAmount pv = test.presentValue(fra, prov);
		assertEquals(pv.Amount, 0.0, TOLERANCE);
	  }
	  /// <summary>
	  /// Test par spread for ISDA FRA Discounting method.
	  /// </summary>
	  public virtual void test_parSpread_ISDA()
	  {
		ResolvedFra fraExp = RFRA;
		SimpleRatesProvider prov = createProvider(fraExp);

		DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT;
		double parSpread = test.parSpread(fraExp, prov);
		ResolvedFra fra = createNewFra(FRA, FRA.FixedRate + parSpread);
		CurrencyAmount pv = test.presentValue(fra, prov);
		assertEquals(pv.Amount, 0.0, TOLERANCE);

		// test via FraTrade
		DiscountingFraTradePricer testTrade = new DiscountingFraTradePricer(test);
		assertEquals(testTrade.parSpread(RFRA_TRADE, prov), test.parSpread(RFRA, prov));
	  }
	  //-------------------------------------------------------------------------
	  /// <summary>
	  /// Test explain.
	  /// </summary>
	  public virtual void test_explainPresentValue_ISDA()
	  {
		ResolvedFra fraExp = RFRA;
		SimpleRatesProvider prov = createProvider(fraExp);

		DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT;
		CurrencyAmount fvExpected = test.forecastValue(fraExp, prov);
		CurrencyAmount pvExpected = test.presentValue(fraExp, prov);

		ExplainMap explain = test.explainPresentValue(fraExp, prov);
		Currency currency = fraExp.Currency;
		int daysBetween = (int) DAYS.between(fraExp.StartDate, fraExp.EndDate);
		assertEquals(explain.get(ExplainKey.ENTRY_TYPE).get(), "FRA");
		assertEquals(explain.get(ExplainKey.PAYMENT_DATE).get(), fraExp.PaymentDate);
		assertEquals(explain.get(ExplainKey.START_DATE).get(), fraExp.StartDate);
		assertEquals(explain.get(ExplainKey.END_DATE).get(), fraExp.EndDate);
		assertEquals(explain.get(ExplainKey.ACCRUAL_YEAR_FRACTION).Value, fraExp.YearFraction);
		assertEquals(explain.get(ExplainKey.DAYS).Value, (int?)(int) daysBetween);
		assertEquals(explain.get(ExplainKey.PAYMENT_CURRENCY).get(), currency);
		assertEquals(explain.get(ExplainKey.NOTIONAL).get().Amount, fraExp.Notional, TOLERANCE);
		assertEquals(explain.get(ExplainKey.TRADE_NOTIONAL).get().Amount, fraExp.Notional, TOLERANCE);

		assertEquals(explain.get(ExplainKey.OBSERVATIONS).get().size(), 1);
		ExplainMap explainObs = explain.get(ExplainKey.OBSERVATIONS).get().get(0);
		IborRateComputation floatingRate = (IborRateComputation) fraExp.FloatingRate;
		assertEquals(explainObs.get(ExplainKey.INDEX).get(), floatingRate.Index);
		assertEquals(explainObs.get(ExplainKey.FIXING_DATE).get(), floatingRate.FixingDate);
		assertEquals(explainObs.get(ExplainKey.INDEX_VALUE).Value, FORWARD_RATE, TOLERANCE);
		assertEquals(explainObs.get(ExplainKey.FROM_FIXING_SERIES).HasValue, false);
		assertEquals(explain.get(ExplainKey.DISCOUNT_FACTOR).Value, DISCOUNT_FACTOR, TOLERANCE);
		assertEquals(explain.get(ExplainKey.FIXED_RATE).Value, fraExp.FixedRate, TOLERANCE);
		assertEquals(explain.get(ExplainKey.PAY_OFF_RATE).Value, FORWARD_RATE, TOLERANCE);
		assertEquals(explain.get(ExplainKey.COMBINED_RATE).Value, FORWARD_RATE, TOLERANCE);
		assertEquals(explain.get(ExplainKey.UNIT_AMOUNT).Value, fvExpected.Amount / fraExp.Notional, TOLERANCE);
		assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().Currency, currency);
		assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().Amount, fvExpected.Amount, TOLERANCE);
		assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().Currency, currency);
		assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().Amount, pvExpected.Amount, TOLERANCE);

		// test via FraTrade
		DiscountingFraTradePricer testTrade = new DiscountingFraTradePricer(test);
		assertEquals(testTrade.explainPresentValue(RFRA_TRADE, prov), test.explainPresentValue(RFRA, prov));
	  }
 //-------------------------------------------------------------------------
 /// <summary>
 /// Calculates the present value of the FRA trade.
 /// <para>
 /// The present value of the trade is the value on the valuation date.
 /// This is the discounted forecast value.
 ///
 /// </para>
 /// </summary>
 /// <param name="trade">  the trade </param>
 /// <param name="provider">  the rates provider </param>
 /// <returns> the present value of the trade </returns>
 public virtual CurrencyAmount presentValue(ResolvedFraTrade trade, RatesProvider provider)
 {
     return(productPricer.presentValue(trade.Product, provider));
 }