示例#1
0
        //-------------------------------------------------------------------------
        private CurrencyAmount presentValuePayment(ResolvedFixedCouponBondTrade trade, LegalEntityDiscountingProvider provider)
        {
            RepoCurveDiscountFactors repoDf = DiscountingFixedCouponBondProductPricer.repoCurveDf(trade.Product, provider);
            Payment upfrontPayment          = this.upfrontPayment(trade);

            return(paymentPricer.presentValue(upfrontPayment, repoDf.DiscountFactors));
        }
示例#2
0
        public virtual void test_resolve()
        {
            FixedCouponBond         @base    = sut();
            ResolvedFixedCouponBond resolved = @base.resolve(REF_DATA);

            assertEquals(resolved.LegalEntityId, LEGAL_ENTITY);
            assertEquals(resolved.SettlementDateOffset, DATE_OFFSET);
            assertEquals(resolved.YieldConvention, YIELD_CONVENTION);
            ImmutableList <FixedCouponBondPaymentPeriod> periodicPayments = resolved.PeriodicPayments;
            int expNum = 20;

            assertEquals(periodicPayments.size(), expNum);
            LocalDate unadjustedEnd = END_DATE;
            Schedule  unadjusted    = PERIOD_SCHEDULE.createSchedule(REF_DATA).toUnadjusted();

            for (int i = 0; i < expNum; ++i)
            {
                FixedCouponBondPaymentPeriod payment = periodicPayments.get(expNum - 1 - i);
                assertEquals(payment.Currency, EUR);
                assertEquals(payment.Notional, NOTIONAL);
                assertEquals(payment.FixedRate, FIXED_RATE);
                assertEquals(payment.UnadjustedEndDate, unadjustedEnd);
                assertEquals(payment.EndDate, BUSINESS_ADJUST.adjust(unadjustedEnd, REF_DATA));
                assertEquals(payment.PaymentDate, payment.EndDate);
                LocalDate unadjustedStart = unadjustedEnd.minusMonths(6);
                assertEquals(payment.UnadjustedStartDate, unadjustedStart);
                assertEquals(payment.StartDate, BUSINESS_ADJUST.adjust(unadjustedStart, REF_DATA));
                assertEquals(payment.YearFraction, unadjusted.getPeriod(expNum - 1 - i).yearFraction(DAY_COUNT, unadjusted));
                assertEquals(payment.DetachmentDate, EX_COUPON.adjust(payment.PaymentDate, REF_DATA));
                unadjustedEnd = unadjustedStart;
            }
            Payment expectedPayment = Payment.of(CurrencyAmount.of(EUR, NOTIONAL), BUSINESS_ADJUST.adjust(END_DATE, REF_DATA));

            assertEquals(resolved.NominalPayment, expectedPayment);
        }
示例#3
0
        //-------------------------------------------------------------------------
        public virtual void test_resolve()
        {
            Payment           settle   = Payment.of(PRODUCT.Notional.Value.multipliedBy(-PRICE * QUANTITY), SETTLEMENT_DATE);
            ResolvedBillTrade expected = ResolvedBillTrade.builder().info(TRADE_INFO).product(PRODUCT.resolve(REF_DATA)).quantity(QUANTITY).settlement(settle).build();

            assertEquals(sut_price().resolve(REF_DATA), expected);
        }
示例#4
0
        public virtual void test_resolve_receive()
        {
            BulletPayment         test     = BulletPayment.builder().payReceive(PayReceive.RECEIVE).value(GBP_P1000).date(AdjustableDate.of(DATE_2015_06_30)).build();
            ResolvedBulletPayment expected = ResolvedBulletPayment.of(Payment.of(GBP_P1000, DATE_2015_06_30));

            assertEquals(test.resolve(REF_DATA), expected);
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the currency exposure of the FX barrier option trade.
        /// <para>
        /// The trinomial tree is first calibrated to Black volatilities,
        /// then the price is computed based on the calibrated tree.
        ///
        /// </para>
        /// </summary>
        /// <param name="trade">  the option trade </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the Black volatility provider </param>
        /// <returns> the currency exposure </returns>
        public virtual MultiCurrencyAmount currencyExposure(ResolvedFxSingleBarrierOptionTrade trade, RatesProvider ratesProvider, BlackFxOptionVolatilities volatilities)
        {
            Payment        premium   = trade.Premium;
            CurrencyAmount pvPremium = paymentPricer.presentValue(premium, ratesProvider);
            ResolvedFxSingleBarrierOption product = trade.Product;

            return(productPricer.currencyExposure(product, ratesProvider, volatilities).plus(pvPremium));
        }
 //-------------------------------------------------------------------------
 /// <summary>
 /// Computes the forecast value of the payment.
 /// <para>
 /// The present value is zero if the payment date is before the valuation date.
 ///
 /// </para>
 /// </summary>
 /// <param name="payment">  the payment </param>
 /// <param name="provider">  the provider </param>
 /// <returns> the forecast value </returns>
 public virtual CurrencyAmount forecastValue(Payment payment, BaseProvider provider)
 {
     if (provider.ValuationDate.isAfter(payment.Date))
     {
         return(CurrencyAmount.zero(payment.Currency));
     }
     return(payment.Value);
 }
 /// <summary>
 /// Calculates the current cash.
 /// </summary>
 /// <param name="payment">  the payment </param>
 /// <param name="provider">  the provider </param>
 /// <returns> the current cash </returns>
 public virtual CurrencyAmount currentCash(Payment payment, BaseProvider provider)
 {
     if (payment.Date.isEqual(provider.ValuationDate))
     {
         return(payment.Value);
     }
     return(CurrencyAmount.zero(payment.Currency));
 }
 /// <summary>
 /// Computes the forecast value of the payment.
 /// <para>
 /// The present value is zero if the payment date is before the valuation date.
 ///
 /// </para>
 /// </summary>
 /// <param name="payment">  the payment </param>
 /// <param name="provider">  the provider </param>
 /// <returns> the forecast value </returns>
 public virtual double forecastValueAmount(Payment payment, BaseProvider provider)
 {
     if (provider.ValuationDate.isAfter(payment.Date))
     {
         return(0d);
     }
     return(payment.Amount);
 }
 /// <summary>
 /// Compute the present value curve sensitivity of the payment.
 /// <para>
 /// The present value sensitivity of the payment is the sensitivity of the
 /// present value to the discount factor curve.
 /// There is no sensitivity if the payment date is before the valuation date.
 /// </para>
 /// <para>
 /// The specified discount factors should be for the payment currency, however this is not validated.
 ///
 /// </para>
 /// </summary>
 /// <param name="payment">  the payment </param>
 /// <param name="discountFactors">  the discount factors to price against </param>
 /// <returns> the point sensitivity of the present value </returns>
 public virtual PointSensitivityBuilder presentValueSensitivity(Payment payment, DiscountFactors discountFactors)
 {
     if (discountFactors.ValuationDate.isAfter(payment.Date))
     {
         return(PointSensitivityBuilder.none());
     }
     return(discountFactors.zeroRatePointSensitivity(payment.Date).multipliedBy(payment.Amount));
 }
 /// <summary>
 /// Computes the present value of the payment by discounting.
 /// <para>
 /// The present value is zero if the payment date is before the valuation date.
 /// </para>
 /// <para>
 /// The specified discount factors should be for the payment currency, however this is not validated.
 ///
 /// </para>
 /// </summary>
 /// <param name="payment">  the payment </param>
 /// <param name="discountFactors">  the discount factors to price against </param>
 /// <returns> the present value </returns>
 public virtual CurrencyAmount presentValue(Payment payment, DiscountFactors discountFactors)
 {
     if (discountFactors.ValuationDate.isAfter(payment.Date))
     {
         return(CurrencyAmount.zero(payment.Currency));
     }
     return(payment.Value.multipliedBy(discountFactors.discountFactor(payment.Date)));
 }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value sensitivity of the FX vanilla option trade.
        /// <para>
        /// The present value sensitivity of the trade is the sensitivity of the present value to
        /// the underlying curves.
        /// </para>
        /// <para>
        /// The volatility is fixed in this sensitivity computation.
        ///
        /// </para>
        /// </summary>
        /// <param name="trade">  the option trade </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the Black volatility provider </param>
        /// <returns> the present value curve sensitivity of the trade </returns>
        public virtual PointSensitivities presentValueSensitivityRatesStickyStrike(ResolvedFxVanillaOptionTrade trade, RatesProvider ratesProvider, BlackFxOptionSmileVolatilities volatilities)
        {
            ResolvedFxVanillaOption product     = trade.Product;
            PointSensitivities      pvcsProduct = productPricer.presentValueSensitivityRatesStickyStrike(product, ratesProvider, volatilities).build();
            Payment            premium          = trade.Premium;
            PointSensitivities pvcsPremium      = paymentPricer.presentValueSensitivity(premium, ratesProvider).build();

            return(pvcsProduct.combinedWith(pvcsPremium));
        }
        //-------------------------------------------------------------------------
        public virtual void test_resolve()
        {
            FxSingle         fwd  = sut();
            ResolvedFxSingle test = fwd.resolve(REF_DATA);

            assertEquals(test.BaseCurrencyPayment, Payment.of(GBP_P1000, DATE_2015_06_30));
            assertEquals(test.CounterCurrencyPayment, Payment.of(USD_M1600, DATE_2015_06_30));
            assertEquals(test.PaymentDate, DATE_2015_06_30);
        }
示例#13
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the forward exchange rate.
        /// </summary>
        /// <param name="fx">  the product </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the forward rate </returns>
        public virtual FxRate forwardFxRate(ResolvedFxSingle fx, RatesProvider provider)
        {
            FxForwardRates fxForwardRates = provider.fxForwardRates(fx.CurrencyPair);
            Payment        basePayment    = fx.BaseCurrencyPayment;
            Payment        counterPayment = fx.CounterCurrencyPayment;
            double         forwardRate    = fxForwardRates.rate(basePayment.Currency, fx.PaymentDate);

            return(FxRate.of(basePayment.Currency, counterPayment.Currency, forwardRate));
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value of the FX vanilla option trade.
        /// <para>
        /// The present value of the trade is the value on the valuation date.
        ///
        /// </para>
        /// </summary>
        /// <param name="trade">  the option trade </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the Black volatility provider </param>
        /// <returns> the present value of the trade </returns>
        public virtual MultiCurrencyAmount presentValue(ResolvedFxVanillaOptionTrade trade, RatesProvider ratesProvider, BlackFxOptionSmileVolatilities volatilities)
        {
            ResolvedFxVanillaOption product   = trade.Product;
            CurrencyAmount          pvProduct = productPricer.presentValue(product, ratesProvider, volatilities);
            Payment        premium            = trade.Premium;
            CurrencyAmount pvPremium          = paymentPricer.presentValue(premium, ratesProvider);

            return(MultiCurrencyAmount.of(pvProduct, pvPremium));
        }
        public virtual void test_of_Payment()
        {
            NotionalExchange test = NotionalExchange.of(Payment.of(GBP_1000, DATE_2014_06_30));

            assertEquals(test.Payment, Payment.of(GBP_1000, DATE_2014_06_30));
            assertEquals(test.PaymentDate, DATE_2014_06_30);
            assertEquals(test.PaymentAmount, GBP_1000);
            assertEquals(test.Currency, GBP);
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value sensitivity of the swaption product.
        /// <para>
        /// The present value sensitivity of the product is the sensitivity of the present value to
        /// the underlying curves.
        ///
        /// </para>
        /// </summary>
        /// <param name="trade">  the swaption trade </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="hwProvider">  the Hull-White model parameter provider </param>
        /// <returns> the point sensitivity to the rate curves </returns>
        public virtual PointSensitivities presentValueSensitivityRates(ResolvedSwaptionTrade trade, RatesProvider ratesProvider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider)
        {
            ResolvedSwaption        product     = trade.Product;
            PointSensitivityBuilder pvcsProduct = PRICER_PRODUCT.presentValueSensitivityRates(product, ratesProvider, hwProvider);
            Payment premium = trade.Premium;
            PointSensitivityBuilder pvcsPremium = PRICER_PREMIUM.presentValueSensitivity(premium, ratesProvider);

            return(pvcsProduct.combinedWith(pvcsPremium).build());
        }
        /// <summary>
        /// Calculates the present value of the swaption trade.
        /// <para>
        /// The result is expressed using the currency of the swapion.
        ///
        /// </para>
        /// </summary>
        /// <param name="trade">  the swaption trade </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="hwProvider">  the Hull-White model parameter trade </param>
        /// <returns> the present value </returns>
        public virtual CurrencyAmount presentValue(ResolvedSwaptionTrade trade, RatesProvider ratesProvider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider)
        {
            ResolvedSwaption product   = trade.Product;
            CurrencyAmount   pvProduct = PRICER_PRODUCT.presentValue(product, ratesProvider, hwProvider);
            Payment          premium   = trade.Premium;
            CurrencyAmount   pvPremium = PRICER_PREMIUM.presentValue(premium, ratesProvider);

            return(pvProduct.plus(pvPremium));
        }
        public virtual void test_of_rate_switchOrder()
        {
            ResolvedFxSingle test = ResolvedFxSingle.of(USD_M1600, FxRate.of(USD, GBP, 1d / 1.6d), DATE_2015_06_30);

            assertEquals(test.BaseCurrencyPayment, Payment.of(GBP_P1000, DATE_2015_06_30));
            assertEquals(test.CounterCurrencyPayment, Payment.of(USD_M1600, DATE_2015_06_30));
            assertEquals(test.PaymentDate, DATE_2015_06_30);
            assertEquals(test.CurrencyPair, CurrencyPair.of(GBP, USD));
            assertEquals(test.ReceiveCurrencyAmount, GBP_P1000);
        }
        public virtual void test_of_amounts_bothZero()
        {
            ResolvedFxSingle test = ResolvedFxSingle.of(CurrencyAmount.zero(GBP), CurrencyAmount.zero(USD), DATE_2015_06_30);

            assertEquals(test.BaseCurrencyPayment, Payment.of(CurrencyAmount.zero(GBP), DATE_2015_06_30));
            assertEquals(test.CounterCurrencyPayment, Payment.of(CurrencyAmount.zero(USD), DATE_2015_06_30));
            assertEquals(test.PaymentDate, DATE_2015_06_30);
            assertEquals(test.CurrencyPair, CurrencyPair.of(GBP, USD));
            assertEquals(test.ReceiveCurrencyAmount, CurrencyAmount.zero(USD));
        }
        /// <summary>
        /// Computes the present value of the payment with z-spread by discounting.
        /// <para>
        /// The present value is zero if the payment date is before the valuation date.
        /// </para>
        /// <para>
        /// The specified discount factors should be for the payment currency, however this is not validated.
        /// </para>
        /// <para>
        /// The z-spread is a parallel shift applied to continuously compounded rates or periodic
        /// compounded rates of the discounting curve.
        ///
        /// </para>
        /// </summary>
        /// <param name="payment">  the payment </param>
        /// <param name="discountFactors">  the discount factors to price against </param>
        /// <param name="zSpread">  the z-spread </param>
        /// <param name="compoundedRateType">  the compounded rate type </param>
        /// <param name="periodsPerYear">  the number of periods per year </param>
        /// <returns> the present value </returns>
        public virtual CurrencyAmount presentValueWithSpread(Payment payment, DiscountFactors discountFactors, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear)
        {
            if (discountFactors.ValuationDate.isAfter(payment.Date))
            {
                return(CurrencyAmount.zero(payment.Currency));
            }
            double df = discountFactors.discountFactorWithSpread(payment.Date, zSpread, compoundedRateType, periodsPerYear);

            return(payment.Value.multipliedBy(df));
        }
示例#21
0
        //-------------------------------------------------------------------------
        private PointSensitivities presentValueSensitivitySettlement(Payment settlement, RepoCurveDiscountFactors repoDf)
        {
            PointSensitivityBuilder pointSettle = paymentPricer.presentValueSensitivity(settlement, repoDf.DiscountFactors);

            if (pointSettle is ZeroRateSensitivity)
            {
                return(RepoCurveZeroRateSensitivity.of((ZeroRateSensitivity)pointSettle, repoDf.RepoGroup).build());
            }
            return(pointSettle.build());    // NoPointSensitivity
        }
        /// <summary>
        /// Compute the present value curve sensitivity of the payment with z-spread.
        /// <para>
        /// The present value sensitivity of the payment is the sensitivity of the
        /// present value to the discount factor curve.
        /// There is no sensitivity if the payment date is before the valuation date.
        /// </para>
        /// <para>
        /// The specified discount factors should be for the payment currency, however this is not validated.
        /// </para>
        /// <para>
        /// The z-spread is a parallel shift applied to continuously compounded rates or periodic
        /// compounded rates of the discounting curve.
        ///
        /// </para>
        /// </summary>
        /// <param name="payment">  the payment </param>
        /// <param name="discountFactors">  the discount factors to price against </param>
        /// <param name="zSpread">  the z-spread </param>
        /// <param name="compoundedRateType">  the compounded rate type </param>
        /// <param name="periodsPerYear">  the number of periods per year </param>
        /// <returns> the point sensitivity of the present value </returns>
        public virtual PointSensitivityBuilder presentValueSensitivityWithSpread(Payment payment, DiscountFactors discountFactors, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear)
        {
            if (discountFactors.ValuationDate.isAfter(payment.Date))
            {
                return(PointSensitivityBuilder.none());
            }
            ZeroRateSensitivity sensi = discountFactors.zeroRatePointSensitivityWithSpread(payment.Date, zSpread, compoundedRateType, periodsPerYear);

            return(sensi.multipliedBy(payment.Amount));
        }
示例#23
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the par spread.
        /// <para>
        /// The par spread is the spread that should be added to the FX forward points to have a zero value.
        ///
        /// </para>
        /// </summary>
        /// <param name="swap">  the product </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the spread </returns>
        public virtual double parSpread(ResolvedFxSwap swap, RatesProvider provider)
        {
            Payment             counterPaymentNear = swap.NearLeg.CounterCurrencyPayment;
            MultiCurrencyAmount pv = presentValue(swap, provider);
            double pvCounterCcy    = pv.convertedTo(counterPaymentNear.Currency, provider).Amount;
            double dfEnd           = provider.discountFactor(counterPaymentNear.Currency, swap.FarLeg.PaymentDate);
            double notionalBaseCcy = swap.NearLeg.BaseCurrencyPayment.Amount;

            return(-pvCounterCcy / (notionalBaseCcy * dfEnd));
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value sensitivity of the FX barrier option trade.
        /// <para>
        /// The present value sensitivity of the trade is the sensitivity of the present value to
        /// the underlying curves.
        /// </para>
        /// <para>
        /// The sensitivity is computed by bump and re-price, returning <seealso cref="CurrencyParameterSensitivities"/>,
        /// not <seealso cref="PointSensitivities"/>.
        /// </para>
        /// <para>
        /// The trinomial tree is first calibrated to Black volatilities,
        /// then the price is computed based on the calibrated tree.
        ///
        /// </para>
        /// </summary>
        /// <param name="trade">  the option trade </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the Black volatility provider </param>
        /// <returns> the present value curve sensitivity of the trade </returns>
        public virtual CurrencyParameterSensitivities presentValueSensitivityRates(ResolvedFxSingleBarrierOptionTrade trade, RatesProvider ratesProvider, BlackFxOptionVolatilities volatilities)
        {
            ResolvedFxSingleBarrierOption  product     = trade.Product;
            CurrencyParameterSensitivities sensProduct = productPricer.presentValueSensitivityRates(product, ratesProvider, volatilities);
            Payment premium = trade.Premium;
            PointSensitivityBuilder        pvcsPremium = paymentPricer.presentValueSensitivity(premium, ratesProvider);
            CurrencyParameterSensitivities sensPremium = ratesProvider.parameterSensitivity(pvcsPremium.build());

            return(sensProduct.combinedWith(sensPremium));
        }
示例#25
0
        /// <summary>
        /// Calculates the current cash of the swaption trade.
        /// <para>
        /// Only the premium is contributing to the current cash for non-cash settle swaptions.
        ///
        /// </para>
        /// </summary>
        /// <param name="trade">  the swaption trade </param>
        /// <param name="valuationDate">  the valuation date </param>
        /// <returns> the current cash amount </returns>
        public virtual CurrencyAmount currentCash(ResolvedSwaptionTrade trade, LocalDate valuationDate)
        {
            Payment premium = trade.Premium;

            if (premium.Date.Equals(valuationDate))
            {
                return(CurrencyAmount.of(premium.Currency, premium.Amount));
            }
            return(CurrencyAmount.of(premium.Currency, 0d));
        }
        public virtual void test_of_switchOrderPayments()
        {
            FxSingle test = FxSingle.of(Payment.of(USD_M1600, DATE_2015_06_30), Payment.of(GBP_P1000, DATE_2015_06_30));

            assertEquals(test.BaseCurrencyAmount, GBP_P1000);
            assertEquals(test.CounterCurrencyAmount, USD_M1600);
            assertEquals(test.PaymentDate, DATE_2015_06_30);
            assertEquals(test.CurrencyPair, CurrencyPair.of(GBP, USD));
            assertEquals(test.PayCurrencyAmount, USD_M1600);
            assertEquals(test.ReceiveCurrencyAmount, GBP_P1000);
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Compute the present value curve sensitivity of the payment.
        /// <para>
        /// The present value sensitivity of the payment is the sensitivity of the
        /// present value to the discount factor curve.
        /// There is no sensitivity if the payment date is before the valuation date.
        ///
        /// </para>
        /// </summary>
        /// <param name="payment">  the payment </param>
        /// <param name="provider">  the provider </param>
        /// <returns> the point sensitivity of the present value </returns>
        public virtual PointSensitivityBuilder presentValueSensitivity(Payment payment, BaseProvider provider)
        {
            // duplicated code to avoid looking up in the provider when not necessary
            if (provider.ValuationDate.isAfter(payment.Date))
            {
                return(PointSensitivityBuilder.none());
            }
            DiscountFactors discountFactors = provider.discountFactors(payment.Currency);

            return(discountFactors.zeroRatePointSensitivity(payment.Date).multipliedBy(payment.Amount));
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the future cash flow of the payment.
        /// <para>
        /// The cash flow is returned, empty if the payment has already occurred.
        ///
        /// </para>
        /// </summary>
        /// <param name="payment">  the payment </param>
        /// <param name="provider">  the provider </param>
        /// <returns> the cash flow, empty if the payment has occurred </returns>
        public virtual CashFlows cashFlows(Payment payment, BaseProvider provider)
        {
            if (provider.ValuationDate.isAfter(payment.Date))
            {
                return(CashFlows.NONE);
            }
            double   df   = provider.discountFactor(payment.Currency, payment.Date);
            CashFlow flow = CashFlow.ofForecastValue(payment.Date, payment.Currency, payment.Amount, df);

            return(CashFlows.of(flow));
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Computes the present value of the payment by discounting.
        /// <para>
        /// The present value is zero if the payment date is before the valuation date.
        ///
        /// </para>
        /// </summary>
        /// <param name="payment">  the payment </param>
        /// <param name="provider">  the provider </param>
        /// <returns> the present value </returns>
        public virtual CurrencyAmount presentValue(Payment payment, BaseProvider provider)
        {
            // duplicated code to avoid looking up in the provider when not necessary
            if (provider.ValuationDate.isAfter(payment.Date))
            {
                return(CurrencyAmount.zero(payment.Currency));
            }
            double df = provider.discountFactor(payment.Currency, payment.Date);

            return(payment.Value.multipliedBy(df));
        }
        /// <summary>
        /// Computes the present value of the payment by discounting.
        /// <para>
        /// The present value is zero if the payment date is before the valuation date.
        ///
        /// </para>
        /// </summary>
        /// <param name="payment">  the payment </param>
        /// <param name="provider">  the provider </param>
        /// <returns> the present value </returns>
        public virtual double presentValueAmount(Payment payment, BaseProvider provider)
        {
            // duplicated code to avoid looking up in the provider when not necessary
            if (provider.ValuationDate.isAfter(payment.Date))
            {
                return(0d);
            }
            double df = provider.discountFactor(payment.Currency, payment.Date);

            return(payment.Amount * df);
        }