Esempio n. 1
0
        private Trade parseNdf(FpmlDocument document, XmlElement fxEl, XmlElement ndfEl, CurrencyAmount curr1Amount, CurrencyAmount curr2Amount, LocalDate valueDate, TradeInfoBuilder tradeInfoBuilder)
        {
            // rate
            XmlElement rateEl = fxEl.getChild("exchangeRate");
            double     rate   = document.parseDecimal(rateEl.getChild("rate"));
            XmlElement pairEl = rateEl.getChild("quotedCurrencyPair");
            Currency   curr1  = document.parseCurrency(pairEl.getChild("currency1"));
            Currency   curr2  = document.parseCurrency(pairEl.getChild("currency2"));
            string     basis  = pairEl.getChild("quoteBasis").Content;
            FxRate     fxRate;

            if ("Currency2PerCurrency1".Equals(basis))
            {
                fxRate = FxRate.of(curr1, curr2, rate);
            }
            else if ("Currency1PerCurrency2".Equals(basis))
            {
                fxRate = FxRate.of(curr2, curr1, rate);
            }
            else
            {
                throw new FpmlParseException("Unknown quote basis: " + basis);
            }
            // settlement currency
            Currency       settleCurr       = document.parseCurrency(ndfEl.getChild("settlementCurrency"));
            CurrencyAmount settleCurrAmount = curr1Amount.Currency.Equals(settleCurr) ? curr1Amount : curr2Amount;
            // index
            XmlElement        fixingEl        = ndfEl.getChild("fixing"); // only support one of these in pricing model
            LocalDate         fixingDate      = document.parseDate(fixingEl.getChild("fixingDate"));
            DaysAdjustment    offset          = DaysAdjustment.ofCalendarDays(Math.toIntExact(valueDate.until(fixingDate, DAYS)));
            XmlElement        sourceEl        = fixingEl.getChild("fxSpotRateSource"); // required for our model
            XmlElement        primarySourceEl = sourceEl.getChild("primaryRateSource");
            string            primarySource   = primarySourceEl.getChild("rateSource").Content;
            string            primaryPage     = primarySourceEl.findChild("rateSourcePage").map(e => e.Content).orElse("");
            LocalTime         time            = document.parseTime(sourceEl.getChild("fixingTime").getChild("hourMinuteTime")); // required for our model
            HolidayCalendarId calendar        = document.parseBusinessCenter(sourceEl.getChild("fixingTime").getChild("businessCenter"));
            FxIndex           index           = ImmutableFxIndex.builder().name(primarySource + "/" + primaryPage + "/" + time).currencyPair(CurrencyPair.of(curr1, curr2)).fixingCalendar(calendar).maturityDateOffset(offset).build();

            return(FxNdfTrade.builder().info(tradeInfoBuilder.build()).product(FxNdf.builder().settlementCurrencyNotional(settleCurrAmount).agreedFxRate(fxRate).index(index).paymentDate(valueDate).build()).build());
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the forecast value of the FRA product.
        /// <para>
        /// The forecast value of the product is the value on the valuation date without present value discounting.
        ///
        /// </para>
        /// </summary>
        /// <param name="fra">  the product </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the forecast value of the product </returns>
        public virtual CurrencyAmount forecastValue(ResolvedFra fra, RatesProvider provider)
        {
            double fv = forecastValue0(fra, provider);

            return(CurrencyAmount.of(fra.Currency, fv));
        }
 public virtual void test_builder_fail()
 {
     assertThrowsIllegalArg(() => BillSecurity.builder().dayCount(DAY_COUNT).info(INFO).legalEntityId(LEGAL_ENTITY).notional(NOTIONAL).settlementDateOffset(DaysAdjustment.ofBusinessDays(-1, USNY, BUSINESS_ADJUST)).yieldConvention(YIELD_CONVENTION).build());
     assertThrowsIllegalArg(() => BillSecurity.builder().dayCount(DAY_COUNT).info(INFO).legalEntityId(LEGAL_ENTITY).notional(AdjustablePayment.of(CurrencyAmount.of(CCY, -2_000_000), MATURITY_DATE_ADJ)).settlementDateOffset(SETTLE).yieldConvention(YIELD_CONVENTION).build());
 }
Esempio n. 4
0
        //-------------------------------------------------------------------------
        public virtual void regression_pv()
        {
            CurrencyAmount pv = PRICER.presentValue(FUTURE_TRADE, RATE_PROVIDER, HW_PROVIDER, LAST_PRICE);

            assertEquals(pv.Amount, 23383.551159035414, NOTIONAL * QUANTITY * TOL);
        }
Esempio n. 5
0
        public virtual void current_cash_vd()
        {
            CurrencyAmount ccTrade = PRICER_TRADE.currentCash(SWAPTION_PRETOD_LONG_REC, VAL_DATE);

            assertEquals(ccTrade.Amount, -PREMIUM_AMOUNT, TOLERANCE_PV);
        }
        internal static FxVanillaOptionTrade sut2()
        {
            AdjustablePayment premium = AdjustablePayment.of(CurrencyAmount.of(EUR, NOTIONAL * 0.01), date(2014, 11, 13));

            return(FxVanillaOptionTrade.builder().product(PRODUCT2).premium(premium).build());
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value theta of the Ibor cap/floor product.
        /// <para>
        /// The present value of the product is the sensitivity value on the valuation date.
        /// </para>
        /// <para>
        /// The cap/floor leg and pay leg are typically in the same currency, thus the
        /// present value gamma is expressed as a single currency amount in most cases.
        ///
        /// </para>
        /// </summary>
        /// <param name="capFloor">  the Ibor cap/floor product </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the volatilities </param>
        /// <returns> the present value theta </returns>
        public virtual MultiCurrencyAmount presentValueTheta(ResolvedIborCapFloor capFloor, RatesProvider ratesProvider, IborCapletFloorletVolatilities volatilities)
        {
            CurrencyAmount pvCapFloorLeg = capFloorLegPricer.presentValueTheta(capFloor.CapFloorLeg, ratesProvider, volatilities);

            return(MultiCurrencyAmount.of(pvCapFloorLeg));
        }
Esempio n. 8
0
        //-------------------------------------------------------------------------
        public virtual void test_parSpreadSensitivity_noFixing()
        {
            PointSensitivities             computedNoFix      = PRICER.parSpreadSensitivity(RDEPOSIT, IMM_PROV_NOFIX);
            CurrencyParameterSensitivities sensiComputedNoFix = IMM_PROV_NOFIX.parameterSensitivity(computedNoFix);
            CurrencyParameterSensitivities sensiExpected      = CAL_FD.sensitivity(IMM_PROV_NOFIX, (p) => CurrencyAmount.of(EUR, PRICER.parSpread(RDEPOSIT, (p))));

            assertTrue(sensiComputedNoFix.equalWithTolerance(sensiExpected, TOLERANCE_RATE_DELTA));
            // Par rate and par spread sensitivities are equal
            PointSensitivities             computedParRateNoFix      = PRICER.parRateSensitivity(RDEPOSIT, IMM_PROV_NOFIX);
            CurrencyParameterSensitivities sensiComputedParRateNoFix = IMM_PROV_NOFIX.parameterSensitivity(computedParRateNoFix);

            assertTrue(sensiComputedNoFix.equalWithTolerance(sensiComputedParRateNoFix, TOLERANCE_RATE_DELTA));
            PointSensitivities             computedFix      = PRICER.parSpreadSensitivity(RDEPOSIT, IMM_PROV_FIX);
            CurrencyParameterSensitivities sensiComputedFix = IMM_PROV_NOFIX.parameterSensitivity(computedFix);

            assertTrue(sensiComputedFix.equalWithTolerance(sensiExpected, TOLERANCE_RATE_DELTA));
        }
Esempio n. 9
0
 public virtual void test_currentCash_past()
 {
     assertEquals(PRICER.currentCash(TRADE_PAST, PROVIDER), CurrencyAmount.zero(USD));
 }
Esempio n. 10
0
        public virtual void test_currentCash_onEndDate()
        {
            RatesProvider prov = ImmutableRatesProvider.builder(RDEPOSIT_TRADE.Product.EndDate).discountCurve(EUR, CURVE).build();

            assertEquals(PRICER_TRADE.currentCash(RDEPOSIT_TRADE, prov), CurrencyAmount.of(EUR, NOTIONAL + INTEREST));
        }
Esempio n. 11
0
 public virtual void test_currentCash_otherDate()
 {
     assertEquals(PRICER_TRADE.currentCash(RDEPOSIT_TRADE, IMM_PROV), CurrencyAmount.zero(EUR));
 }
        public virtual void test_resolve_knownAmountStub()
        {
            // test case
            CurrencyAmount         knownAmount = CurrencyAmount.of(GBP, 150d);
            RateCalculationSwapLeg test        = RateCalculationSwapLeg.builder().payReceive(PAY).accrualSchedule(PeriodicSchedule.builder().startDate(DATE_02_03).endDate(DATE_04_03).firstRegularStartDate(DATE_02_05).lastRegularEndDate(DATE_03_05).frequency(P1M).stubConvention(StubConvention.BOTH).businessDayAdjustment(BusinessDayAdjustment.of(FOLLOWING, GBLO)).build()).paymentSchedule(PaymentSchedule.builder().paymentFrequency(P1M).paymentDateOffset(PLUS_TWO_DAYS).build()).notionalSchedule(NotionalSchedule.of(GBP, 1000d)).calculation(FixedRateCalculation.builder().dayCount(ACT_365F).rate(ValueSchedule.of(0.025d)).initialStub(FixedRateStubCalculation.ofKnownAmount(knownAmount)).finalStub(FixedRateStubCalculation.ofFixedRate(0.1d)).build()).build();
            // expected
            KnownAmountNotionalSwapPaymentPeriod pp1 = KnownAmountNotionalSwapPaymentPeriod.builder().payment(Payment.of(knownAmount, DATE_02_07)).startDate(DATE_02_03).endDate(DATE_02_05).unadjustedStartDate(DATE_02_03).notionalAmount(CurrencyAmount.of(GBP, -1000d)).build();
            RatePaymentPeriod rpp2 = RatePaymentPeriod.builder().paymentDate(DATE_03_07).accrualPeriods(RateAccrualPeriod.builder().startDate(DATE_02_05).endDate(DATE_03_05).yearFraction(ACT_365F.yearFraction(DATE_02_05, DATE_03_05)).rateComputation(FixedRateComputation.of(0.025d)).build()).dayCount(ACT_365F).currency(GBP).notional(-1000d).build();
            RatePaymentPeriod rpp3 = RatePaymentPeriod.builder().paymentDate(DATE_04_07).accrualPeriods(RateAccrualPeriod.builder().startDate(DATE_03_05).endDate(DATE_04_03).unadjustedEndDate(DATE_04_03).yearFraction(ACT_365F.yearFraction(DATE_03_05, DATE_04_03)).rateComputation(FixedRateComputation.of(0.1d)).build()).dayCount(ACT_365F).currency(GBP).notional(-1000d).build();

            // assertion
            assertEquals(test.resolve(REF_DATA), ResolvedSwapLeg.builder().type(FIXED).payReceive(PAY).paymentPeriods(pp1, rpp2, rpp3).build());
        }
        //-------------------------------------------------------------------------
        public virtual void test_resolve()
        {
            // test case
            KnownAmountSwapLeg test = KnownAmountSwapLeg.builder().payReceive(PAY).accrualSchedule(PeriodicSchedule.builder().startDate(DATE_01_05).endDate(DATE_04_05).frequency(P1M).businessDayAdjustment(BusinessDayAdjustment.of(FOLLOWING, GBLO)).build()).paymentSchedule(PaymentSchedule.builder().paymentFrequency(P1M).paymentDateOffset(PLUS_TWO_DAYS).build()).amount(ValueSchedule.builder().initialValue(123d).steps(ValueStep.of(1, ValueAdjustment.ofReplace(234d))).build()).currency(GBP).build();
            // expected
            KnownAmountSwapPaymentPeriod rpp1 = KnownAmountSwapPaymentPeriod.builder().payment(Payment.ofPay(CurrencyAmount.of(GBP, 123d), DATE_02_07)).startDate(DATE_01_06).endDate(DATE_02_05).unadjustedStartDate(DATE_01_05).build();
            KnownAmountSwapPaymentPeriod rpp2 = KnownAmountSwapPaymentPeriod.builder().payment(Payment.ofPay(CurrencyAmount.of(GBP, 234d), DATE_03_07)).startDate(DATE_02_05).endDate(DATE_03_05).build();
            KnownAmountSwapPaymentPeriod rpp3 = KnownAmountSwapPaymentPeriod.builder().payment(Payment.ofPay(CurrencyAmount.of(GBP, 234d), DATE_04_09)).startDate(DATE_03_05).endDate(DATE_04_07).unadjustedEndDate(DATE_04_05).build();

            // assertion
            assertEquals(test.resolve(REF_DATA), ResolvedSwapLeg.builder().type(FIXED).payReceive(PAY).paymentPeriods(rpp1, rpp2, rpp3).build());
        }
 internal static SwaptionTrade sut2()
 {
     return(SwaptionTrade.builder().premium(AdjustablePayment.of(CurrencyAmount.of(Currency.USD, -3050000d), LocalDate.of(2014, 3, 17))).product(SwaptionTest.sut2()).build());
 }
        public virtual void test_dirtyPriceSensitivity()
        {
            PointSensitivityBuilder        point    = PRICER.dirtyPriceSensitivity(PRODUCT, PROVIDER, REF_DATA);
            CurrencyParameterSensitivities computed = PROVIDER.parameterSensitivity(point.build());
            CurrencyParameterSensitivities expected = FD_CAL.sensitivity(PROVIDER, p => CurrencyAmount.of(EUR, PRICER.dirtyPriceFromCurves(PRODUCT, p, REF_DATA)));

            assertTrue(computed.equalWithTolerance(expected, NOTIONAL * EPS));
        }
Esempio n. 16
0
        public virtual void test_presentValue_provider_ended()
        {
            CurrencyAmount computed = PRICER.presentValue(TRADE_PAST, PROVIDER);

            assertEquals(computed, CurrencyAmount.zero(USD));
        }
        public virtual void test_dirtyPriceSensitivityWithZspread_periodic()
        {
            PointSensitivityBuilder        point    = PRICER.dirtyPriceSensitivityWithZspread(PRODUCT, PROVIDER, REF_DATA, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR);
            CurrencyParameterSensitivities computed = PROVIDER.parameterSensitivity(point.build());
            CurrencyParameterSensitivities expected = FD_CAL.sensitivity(PROVIDER, p => CurrencyAmount.of(EUR, PRICER.dirtyPriceFromCurvesWithZSpread(PRODUCT, p, REF_DATA, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR)));

            assertTrue(computed.equalWithTolerance(expected, NOTIONAL * EPS));
        }
Esempio n. 18
0
        //-------------------------------------------------------------------------
        public virtual void test_priceSensitivity()
        {
            PointSensitivities             point    = FUTURE_PRICER.priceSensitivity(FUTURE_PRODUCT, PROVIDER);
            CurrencyParameterSensitivities computed = PROVIDER.parameterSensitivity(point);
            CurrencyParameterSensitivities expected = FD_CAL.sensitivity(PROVIDER, (p) => CurrencyAmount.of(USD, FUTURE_PRICER.price(FUTURE_PRODUCT, (p))));

            assertTrue(computed.equalWithTolerance(expected, EPS * 10.0));
        }
Esempio n. 19
0
 public virtual void test_currentCash_zero()
 {
     assertEquals(PRICER_TRADE.currentCash(OPTION_TRADE, VAL_DATE), CurrencyAmount.zero(PREMIUM.Currency));
 }
Esempio n. 20
0
        public virtual void test_priceSensitivityWithZSpread_continuous()
        {
            PointSensitivities             point    = FUTURE_PRICER.priceSensitivityWithZSpread(FUTURE_PRODUCT, PROVIDER, Z_SPREAD, CONTINUOUS, 0);
            CurrencyParameterSensitivities computed = PROVIDER.parameterSensitivity(point);
            CurrencyParameterSensitivities expected = FD_CAL.sensitivity(PROVIDER, (p) => CurrencyAmount.of(USD, FUTURE_PRICER.priceWithZSpread(FUTURE_PRODUCT, (p), Z_SPREAD, CONTINUOUS, 0)));

            assertTrue(computed.equalWithTolerance(expected, EPS * 10.0));
        }
Esempio n. 21
0
        public virtual void test_parSpreadSensitivity()
        {
            PointSensitivities             point    = PRICER.parSpreadSensitivityRates(FUTURE_TRADE, RATE_PROVIDER, HW_PROVIDER);
            CurrencyParameterSensitivities computed = RATE_PROVIDER.parameterSensitivity(point);
            CurrencyParameterSensitivities expected = FD_CAL.sensitivity(RATE_PROVIDER, p => CurrencyAmount.of(EUR, PRICER.parSpread(FUTURE_TRADE, p, HW_PROVIDER, LAST_PRICE)));

            assertTrue(computed.equalWithTolerance(expected, NOTIONAL * QUANTITY * TOL_FD));
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the currency exposure by discounting each payment in its own currency.
        /// </summary>
        /// <param name="ndf">  the product </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the currency exposure </returns>
        public virtual MultiCurrencyAmount currencyExposure(ResolvedFxNdf ndf, RatesProvider provider)
        {
            if (provider.ValuationDate.isAfter(ndf.PaymentDate))
            {
                return(MultiCurrencyAmount.empty());
            }
            Currency       ccySettle      = ndf.SettlementCurrency;
            CurrencyAmount notionalSettle = ndf.SettlementCurrencyNotional;
            double         dfSettle       = provider.discountFactor(ccySettle, ndf.PaymentDate);
            Currency       ccyOther       = ndf.NonDeliverableCurrency;
            double         agreedRate     = ndf.AgreedFxRate.fxRate(ccySettle, ccyOther);
            double         dfOther        = provider.discountFactor(ccyOther, ndf.PaymentDate);

            return(MultiCurrencyAmount.of(notionalSettle.multipliedBy(dfSettle)).plus(CurrencyAmount.of(ccyOther, -notionalSettle.Amount * agreedRate * dfOther)));
        }
Esempio n. 23
0
        public virtual void test_parSpreadSensitivity()
        {
            PointSensitivities             computed      = PRICER.parSpreadSensitivity(RTERM_DEPOSIT, IMM_PROV);
            CurrencyParameterSensitivities sensiComputed = IMM_PROV.parameterSensitivity(computed);
            CurrencyParameterSensitivities sensiExpected = CAL_FD.sensitivity(IMM_PROV, (p) => CurrencyAmount.of(EUR, PRICER.parSpread(RTERM_DEPOSIT, (p))));

            assertTrue(sensiComputed.equalWithTolerance(sensiExpected, NOTIONAL * EPS_FD));
        }
Esempio n. 24
0
        //-------------------------------------------------------------------------
        public virtual void coverage()
        {
            ResolvedFxSingleBarrierOptionTrade test1 = ResolvedFxSingleBarrierOptionTrade.builder().info(TRADE_INFO).product(PRODUCT).premium(PREMIUM).build();
            ResolvedFxSingleBarrierOptionTrade test2 = ResolvedFxSingleBarrierOptionTrade.builder().product(ResolvedFxSingleBarrierOption.of(VANILLA_OPTION, BARRIER)).premium(Payment.of(CurrencyAmount.of(EUR, NOTIONAL * 0.01), date(2014, 11, 13))).build();

            coverImmutableBean(test1);
            coverBeanEquals(test1, test2);
        }
Esempio n. 25
0
        public virtual void current_cash_past()
        {
            CurrencyAmount ccTrade = PRICER_TRADE.currentCash(SWAPTION_PREPAST_LONG_REC, VAL_DATE);

            assertEquals(ccTrade.Amount, 0, TOLERANCE_PV);
        }
 //-------------------------------------------------------------------------
 public virtual MultiCurrencyAmount currencyExposure(KnownAmountSwapPaymentPeriod period, RatesProvider provider)
 {
     return(MultiCurrencyAmount.of(CurrencyAmount.of(period.Currency, presentValue(period, provider))));
 }
        //-------------------------------------------------------------------------
        public virtual void coverage()
        {
            BillSecurity test1 = BillSecurity.builder().dayCount(DAY_COUNT).info(INFO).legalEntityId(LEGAL_ENTITY).notional(NOTIONAL).settlementDateOffset(SETTLE).yieldConvention(YIELD_CONVENTION).build();

            coverImmutableBean(test1);
            BillSecurity test2 = BillSecurity.builder().dayCount(DayCounts.ACT_365F).info(SecurityInfo.of(SecurityId.of("OG-Test", "ID2"), PRICE_INFO)).legalEntityId(LegalEntityId.of("OG-Ticker", "LE2")).notional(AdjustablePayment.of(CurrencyAmount.of(CCY, 10), MATURITY_DATE_ADJ)).settlementDateOffset(DaysAdjustment.ofBusinessDays(2, EUTA, BUSINESS_ADJUST)).yieldConvention(BillYieldConvention.INTEREST_AT_MATURITY).build();

            coverBeanEquals(test1, test2);
        }
 //-------------------------------------------------------------------------
 /// <summary>
 /// Calculates the current cash of the leg.
 /// </summary>
 /// <param name="cmsLeg">  the CMS leg </param>
 /// <param name="ratesProvider">  the rates provider </param>
 /// <param name="swaptionVolatilities">  the swaption volatilities </param>
 /// <returns> the current cash </returns>
 public virtual CurrencyAmount currentCash(ResolvedCmsLeg cmsLeg, RatesProvider ratesProvider, SabrSwaptionVolatilities swaptionVolatilities)
 {
     validate(ratesProvider, swaptionVolatilities);
     return(cmsLeg.CmsPeriods.Where(x => x.PaymentDate.Equals(ratesProvider.ValuationDate)).Select(x => cmsPeriodPricer.presentValue(x, ratesProvider, swaptionVolatilities)).Aggregate((c1, c2) => c1.plus(c2)).orElse(CurrencyAmount.zero(cmsLeg.Currency)));
 }
Esempio n. 29
0
 public virtual void test_builder_invalid()
 {
     assertThrowsIllegalArg(() => KnownAmountNotionalSwapPaymentPeriod.builder().payment(PAYMENT_2014_10_03).endDate(DATE_2014_10_01).notionalAmount(GBP_P50000).build());
     assertThrowsIllegalArg(() => KnownAmountNotionalSwapPaymentPeriod.builder().payment(PAYMENT_2014_10_03).startDate(DATE_2014_10_01).notionalAmount(GBP_P50000).build());
     assertThrowsIllegalArg(() => KnownAmountNotionalSwapPaymentPeriod.builder().payment(PAYMENT_2014_10_03).startDate(DATE_2014_10_01).endDate(DATE_2014_10_01).notionalAmount(GBP_P50000).build());
     assertThrowsIllegalArg(() => KnownAmountNotionalSwapPaymentPeriod.builder().payment(PAYMENT_2014_10_03).startDate(DATE_2014_03_30).endDate(DATE_2014_10_01).notionalAmount(CurrencyAmount.of(USD, 1000d)).build());
     assertThrowsIllegalArg(() => KnownAmountNotionalSwapPaymentPeriod.builder().payment(PAYMENT_2014_10_03).startDate(DATE_2014_03_30).endDate(DATE_2014_10_01).notionalAmount(CurrencyAmount.of(GBP, 1000d)).fxResetObservation(FX_RESET).build());
     assertThrowsIllegalArg(() => KnownAmountNotionalSwapPaymentPeriod.builder().payment(PAYMENT_2014_10_03).startDate(DATE_2014_03_30).endDate(DATE_2014_10_01).notionalAmount(CurrencyAmount.of(EUR, 1000d)).fxResetObservation(FX_RESET).build());
     assertThrowsIllegalArg(() => KnownAmountNotionalSwapPaymentPeriod.builder().payment(Payment.of(CurrencyAmount.of(EUR, 1000d), DATE_2014_10_03)).startDate(DATE_2014_03_30).endDate(DATE_2014_10_01).notionalAmount(CurrencyAmount.of(USD, 1000d)).fxResetObservation(FX_RESET).build());
 }
Esempio n. 30
0
        private CurrencyAmount presentValueFromProductPresentValue(ResolvedFixedCouponBondTrade trade, LegalEntityDiscountingProvider provider, CurrencyAmount productPresentValue)
        {
            CurrencyAmount pvProduct = productPresentValue.multipliedBy(trade.Quantity);
            CurrencyAmount pvPayment = presentValuePayment(trade, provider);

            return(pvProduct.plus(pvPayment));
        }