//-------------------------------------------------------------------------
        /// <summary>
        /// Explains the present value of the FRA product.
        /// <para>
        /// This returns explanatory information about the calculation.
        ///
        /// </para>
        /// </summary>
        /// <param name="fra">  the FRA product for which present value should be computed </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the explanatory information </returns>
        public virtual ExplainMap explainPresentValue(ResolvedFra fra, RatesProvider provider)
        {
            ExplainMapBuilder builder  = ExplainMap.builder();
            Currency          currency = fra.Currency;

            builder.put(ExplainKey.ENTRY_TYPE, "FRA");
            builder.put(ExplainKey.PAYMENT_DATE, fra.PaymentDate);
            builder.put(ExplainKey.START_DATE, fra.StartDate);
            builder.put(ExplainKey.END_DATE, fra.EndDate);
            builder.put(ExplainKey.ACCRUAL_YEAR_FRACTION, fra.YearFraction);
            builder.put(ExplainKey.DAYS, (int)DAYS.between(fra.StartDate, fra.EndDate));
            builder.put(ExplainKey.PAYMENT_CURRENCY, currency);
            builder.put(ExplainKey.NOTIONAL, CurrencyAmount.of(currency, fra.Notional));
            builder.put(ExplainKey.TRADE_NOTIONAL, CurrencyAmount.of(currency, fra.Notional));
            if (fra.PaymentDate.isBefore(provider.ValuationDate))
            {
                builder.put(ExplainKey.COMPLETED, true);
                builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.zero(currency));
                builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.zero(currency));
            }
            else
            {
                double rate = rateComputationFn.explainRate(fra.FloatingRate, fra.StartDate, fra.EndDate, provider, builder);
                builder.put(ExplainKey.FIXED_RATE, fra.FixedRate);
                builder.put(ExplainKey.DISCOUNT_FACTOR, provider.discountFactor(currency, fra.PaymentDate));
                builder.put(ExplainKey.PAY_OFF_RATE, rate);
                builder.put(ExplainKey.UNIT_AMOUNT, unitAmount(fra, provider));
                builder.put(ExplainKey.FORECAST_VALUE, forecastValue(fra, provider));
                builder.put(ExplainKey.PRESENT_VALUE, presentValue(fra, provider));
            }
            return(builder.build());
        }
        public virtual void test_before()
        {
            LocalDate startDate = date(2018, 2, 1);
            LocalDate endDate   = date(2018, 2, 28);
            OvernightAveragedDailyRateComputation cmp = OvernightAveragedDailyRateComputation.of(USD_FED_FUND, startDate, endDate, REF_DATA);
            ImmutableRatesProvider rates          = getRatesProvider(date(2018, 1, 24));
            double computedRate                   = FUNCTION.rate(cmp, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, rates);
            PointSensitivityBuilder sensiComputed = FUNCTION.rateSensitivity(cmp, startDate, endDate, rates);
            ExplainMapBuilder       builder       = ExplainMap.builder();
            double explainRate  = FUNCTION.explainRate(cmp, startDate, endDate, rates, builder);
            double expectedRate = 0d;
            PointSensitivityBuilder sensiExpected = PointSensitivityBuilder.none();
            LocalDate date = startDate;

            while (!date.isAfter(endDate))
            {
                OvernightIndexObservation obs = OvernightIndexObservation.of(USD_FED_FUND, date, REF_DATA);
                double rate = rates.overnightIndexRates(USD_FED_FUND).rate(obs);
                PointSensitivityBuilder rateSensi = rates.overnightIndexRates(USD_FED_FUND).ratePointSensitivity(obs);
                LocalDate nextDate = cmp.FixingCalendar.next(date);
                long      days     = DAYS.between(date, nextDate);
                expectedRate += rate * days;
                sensiExpected = sensiComputed.combinedWith(rateSensi.multipliedBy(days));
                date          = nextDate;
            }
            double nDays = 28d;

            expectedRate /= nDays;
            sensiExpected = sensiExpected.multipliedBy(1d / nDays);
            assertEquals(computedRate, expectedRate, TOL);
            assertTrue(sensiComputed.build().equalWithTolerance(sensiExpected.build(), TOL));
            assertEquals(explainRate, computedRate, TOL);
            assertEquals(builder.build().get(ExplainKey.COMBINED_RATE).Value, expectedRate, TOL);
        }
        //-------------------------------------------------------------------------
        public virtual void explainPresentValue(KnownAmountSwapPaymentPeriod period, RatesProvider provider, ExplainMapBuilder builder)
        {
            Currency  currency    = period.Currency;
            LocalDate paymentDate = period.PaymentDate;

            builder.put(ExplainKey.ENTRY_TYPE, "KnownAmountPaymentPeriod");
            builder.put(ExplainKey.PAYMENT_DATE, paymentDate);
            builder.put(ExplainKey.PAYMENT_CURRENCY, currency);
            builder.put(ExplainKey.START_DATE, period.StartDate);
            builder.put(ExplainKey.UNADJUSTED_START_DATE, period.UnadjustedStartDate);
            builder.put(ExplainKey.END_DATE, period.EndDate);
            builder.put(ExplainKey.UNADJUSTED_END_DATE, period.UnadjustedEndDate);
            builder.put(ExplainKey.DAYS, (int)DAYS.between(period.StartDate, period.EndDate));
            if (paymentDate.isBefore(provider.ValuationDate))
            {
                builder.put(ExplainKey.COMPLETED, true);
                builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.zero(currency));
                builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.zero(currency));
            }
            else
            {
                builder.put(ExplainKey.DISCOUNT_FACTOR, provider.discountFactor(currency, paymentDate));
                builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.of(currency, forecastValue(period, provider)));
                builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.of(currency, presentValue(period, provider)));
            }
        }
Example #4
0
        /// <summary>
        /// Explains the present value of a single payment period with z-spread.
        /// <para>
        /// This adds information to the <seealso cref="ExplainMapBuilder"/> to aid understanding of the calculation.
        ///
        /// </para>
        /// </summary>
        /// <param name="period">  the period to price </param>
        /// <param name="ratesProvider">  the rates provider, used to determine price index values </param>
        /// <param name="issuerDiscountFactors">  the discount factor provider </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>
        /// <param name="builder">  the builder to populate </param>
        public virtual void explainPresentValueWithZSpread(CapitalIndexedBondPaymentPeriod period, RatesProvider ratesProvider, IssuerCurveDiscountFactors issuerDiscountFactors, ExplainMapBuilder builder, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear)
        {
            Currency  currency    = period.Currency;
            LocalDate paymentDate = period.PaymentDate;

            builder.put(ExplainKey.ENTRY_TYPE, "CapitalIndexedBondPaymentPeriod");
            builder.put(ExplainKey.PAYMENT_DATE, paymentDate);
            builder.put(ExplainKey.PAYMENT_CURRENCY, currency);
            builder.put(ExplainKey.START_DATE, period.StartDate);
            builder.put(ExplainKey.UNADJUSTED_START_DATE, period.UnadjustedStartDate);
            builder.put(ExplainKey.END_DATE, period.EndDate);
            builder.put(ExplainKey.UNADJUSTED_END_DATE, period.UnadjustedEndDate);
            builder.put(ExplainKey.DAYS, (int)DAYS.between(period.UnadjustedStartDate, period.UnadjustedEndDate));
            if (paymentDate.isBefore(ratesProvider.ValuationDate))
            {
                builder.put(ExplainKey.COMPLETED, true);
                builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.zero(currency));
                builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.zero(currency));
            }
            else
            {
                builder.put(ExplainKey.DISCOUNT_FACTOR, issuerDiscountFactors.discountFactor(paymentDate));
                builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.of(currency, forecastValue(period, ratesProvider)));
                builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.of(currency, presentValueWithZSpread(period, ratesProvider, issuerDiscountFactors, zSpread, compoundedRateType, periodsPerYear)));
            }
        }
Example #5
0
        public virtual void test_explainPresentValue_inPast()
        {
            RatesProvider prov = createProvider(VAL_DATE);

            ExplainMapBuilder builder = ExplainMap.builder();

            PRICER.explainPresentValue(PERIOD_PAST, prov, builder);
            ExplainMap explain = builder.build();

            assertEquals(explain.get(ExplainKey.ENTRY_TYPE).get(), "KnownAmountPaymentPeriod");
            assertEquals(explain.get(ExplainKey.PAYMENT_DATE).get(), PERIOD_PAST.PaymentDate);
            assertEquals(explain.get(ExplainKey.PAYMENT_CURRENCY).get(), PERIOD_PAST.Currency);

            int daysBetween = (int)DAYS.between(DATE_1, DATE_2);

            assertEquals(explain.get(ExplainKey.START_DATE).get(), PERIOD_PAST.StartDate);
            assertEquals(explain.get(ExplainKey.UNADJUSTED_START_DATE).get(), PERIOD_PAST.UnadjustedStartDate);
            assertEquals(explain.get(ExplainKey.END_DATE).get(), PERIOD_PAST.EndDate);
            assertEquals(explain.get(ExplainKey.UNADJUSTED_END_DATE).get(), PERIOD_PAST.UnadjustedEndDate);
            assertEquals(explain.get(ExplainKey.DAYS).Value, (int?)daysBetween);

            assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().Currency, PERIOD_PAST.Currency);
            assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().Amount, 0, TOLERANCE_PV);
            assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().Currency, PERIOD_PAST.Currency);
            assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().Amount, 0 * DISCOUNT_FACTOR, TOLERANCE_PV);
        }
 // common parts of explain
 private void explainBasics(FixedCouponBondPaymentPeriod period, ExplainMapBuilder builder, Currency currency, LocalDate paymentDate)
 {
     builder.put(ExplainKey.ENTRY_TYPE, "FixedCouponBondPaymentPeriod");
     builder.put(ExplainKey.PAYMENT_DATE, paymentDate);
     builder.put(ExplainKey.PAYMENT_CURRENCY, currency);
     builder.put(ExplainKey.START_DATE, period.StartDate);
     builder.put(ExplainKey.UNADJUSTED_START_DATE, period.UnadjustedStartDate);
     builder.put(ExplainKey.END_DATE, period.EndDate);
     builder.put(ExplainKey.UNADJUSTED_END_DATE, period.UnadjustedEndDate);
     builder.put(ExplainKey.ACCRUAL_YEAR_FRACTION, period.YearFraction);
     builder.put(ExplainKey.DAYS, (int)DAYS.between(period.StartDate, period.EndDate));
 }
Example #7
0
        public virtual void test_explainPresentValueWithZSpread_past()
        {
            ExplainMapBuilder builder = ExplainMap.builder();

            PRICER.explainPresentValueWithZSpread(PERIOD_INTERP, IRP_AFTER_PAY, ICDF_AFTER_PAY, builder, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR);
            ExplainMap explain = builder.build();

            assertEquals(explain.get(ExplainKey.ENTRY_TYPE).get(), "CapitalIndexedBondPaymentPeriod");
            assertEquals(explain.get(ExplainKey.PAYMENT_DATE).get(), PERIOD_INTERP.PaymentDate);
            assertEquals(explain.get(ExplainKey.PAYMENT_CURRENCY).get(), PERIOD_INTERP.Currency);
            assertEquals(explain.get(ExplainKey.START_DATE).get(), START);
            assertEquals(explain.get(ExplainKey.UNADJUSTED_START_DATE).get(), START_UNADJ);
            assertEquals(explain.get(ExplainKey.END_DATE).get(), END);
            assertEquals(explain.get(ExplainKey.UNADJUSTED_END_DATE).get(), END_UNADJ);
            assertEquals(explain.get(ExplainKey.DAYS).Value.intValue(), (int)DAYS.between(START_UNADJ, END_UNADJ));
            assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().Amount, 0d, NOTIONAL * TOL);
            assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().Amount, 0d, NOTIONAL * TOL);
        }
	  //-------------------------------------------------------------------------
	  /// <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));
	  }
Example #9
0
        //-------------------------------------------------------------------------
        public virtual void test_explainPresentValue()
        {
            ExplainMapBuilder builder = ExplainMap.builder();

            PRICER.explainPresentValue(PERIOD_INTERP, IRP_BEFORE_START, ICDF_BEFORE_START, builder);
            ExplainMap explain = builder.build();

            assertEquals(explain.get(ExplainKey.ENTRY_TYPE).get(), "CapitalIndexedBondPaymentPeriod");
            assertEquals(explain.get(ExplainKey.PAYMENT_DATE).get(), PERIOD_INTERP.PaymentDate);
            assertEquals(explain.get(ExplainKey.PAYMENT_CURRENCY).get(), PERIOD_INTERP.Currency);
            assertEquals(explain.get(ExplainKey.START_DATE).get(), START);
            assertEquals(explain.get(ExplainKey.UNADJUSTED_START_DATE).get(), START_UNADJ);
            assertEquals(explain.get(ExplainKey.END_DATE).get(), END);
            assertEquals(explain.get(ExplainKey.UNADJUSTED_END_DATE).get(), END_UNADJ);
            assertEquals(explain.get(ExplainKey.DAYS).Value.intValue(), (int)DAYS.between(START_UNADJ, END_UNADJ));
            assertEquals(explain.get(ExplainKey.DISCOUNT_FACTOR).Value, ICDF_BEFORE_START.discountFactor(END));
            assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().Amount, PRICER.forecastValue(PERIOD_INTERP, IRP_BEFORE_START), NOTIONAL * TOL);
            assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().Amount, PRICER.presentValue(PERIOD_INTERP, IRP_BEFORE_START, ICDF_BEFORE_START), NOTIONAL * TOL);
        }
Example #10
0
        // explain PV for an accrual period, ignoring compounding
        private void explainPresentValue(RateAccrualPeriod accrualPeriod, DayCount dayCount, Currency currency, double notional, RatesProvider provider, ExplainMapBuilder builder)
        {
            double rawRate    = rateComputationFn.explainRate(accrualPeriod.RateComputation, accrualPeriod.StartDate, accrualPeriod.EndDate, provider, builder);
            double payOffRate = rawRate * accrualPeriod.Gearing + accrualPeriod.Spread;
            double ua         = unitNotionalAccrual(accrualPeriod, accrualPeriod.Spread, provider);

            // Note that the forecast value is not published since this is potentially misleading when
            // compounding is being applied, and when it isn't then it's the same as the forecast
            // value of the payment period.

            builder.put(ExplainKey.ENTRY_TYPE, "AccrualPeriod");
            builder.put(ExplainKey.START_DATE, accrualPeriod.StartDate);
            builder.put(ExplainKey.UNADJUSTED_START_DATE, accrualPeriod.UnadjustedStartDate);
            builder.put(ExplainKey.END_DATE, accrualPeriod.EndDate);
            builder.put(ExplainKey.UNADJUSTED_END_DATE, accrualPeriod.UnadjustedEndDate);
            builder.put(ExplainKey.ACCRUAL_YEAR_FRACTION, accrualPeriod.YearFraction);
            builder.put(ExplainKey.ACCRUAL_DAYS, dayCount.days(accrualPeriod.StartDate, accrualPeriod.EndDate));
            builder.put(ExplainKey.DAYS, (int)DAYS.between(accrualPeriod.StartDate, accrualPeriod.EndDate));
            builder.put(ExplainKey.GEARING, accrualPeriod.Gearing);
            builder.put(ExplainKey.SPREAD, accrualPeriod.Spread);
            builder.put(ExplainKey.PAY_OFF_RATE, accrualPeriod.NegativeRateMethod.adjust(payOffRate));
            builder.put(ExplainKey.UNIT_AMOUNT, ua);
        }
            /// <summary>
            /// Data is not held for weekends.
            /// </summary>
//JAVA TO C# CONVERTER TODO TASK: Enum value-specific class bodies are not converted by Java to C# Converter:
            public static readonly DenseTimeSeriesCalculation SKIP_WEEKENDS = new DenseTimeSeriesCalculation()
            {
                int calculatePosition(java.time.LocalDate startDate, java.time.LocalDate date)
                {
                    int unadjusted        = (int)DAYS.between(startDate, date);
                    int weekendAdjustment = startDate.getDayOfWeek().compareTo(date.getDayOfWeek()) > 0 ? 1 : 0;
                    int numWeekends       = (unadjusted / 7) + weekendAdjustment;

                    return(unadjusted - (2 * numWeekends));
                }

                java.time.LocalDate calculateDateFromPosition(java.time.LocalDate startDate, int position)
                {
                    int numWeekends        = position / 5;
                    int remaining          = position % 5;
                    int endPointAdjustment = (remaining < (6 - startDate.get(DAY_OF_WEEK))) ? 0 : 2;

                    return(startDate.plusDays((7 * numWeekends) + remaining + endPointAdjustment));
                }

                boolean allowsDate(java.time.LocalDate date)
                {
                    return(!isWeekend(date));
                }
Example #12
0
        //-------------------------------------------------------------------------
        public InterpolatedNodalCurveDefinition filtered(LocalDate valuationDate, ReferenceData refData)
        {
            // mutable list of date-node pairs
//JAVA TO C# CONVERTER TODO TASK: Method reference constructor syntax is not converted by Java to C# Converter:
//JAVA TO C# CONVERTER TODO TASK: Most Java stream collectors are not converted by Java to C# Converter:
            List <Pair <LocalDate, CurveNode> > nodeDates = nodes.Select(node => Pair.of(node.date(valuationDate, refData), node)).collect(toCollection(List <object>::new));

            // delete nodes if clash, but don't throw exceptions yet
            for (int i = 0; i < nodeDates.Count; i++)
            {
                Pair <LocalDate, CurveNode> pair        = nodeDates[i];
                CurveNodeDateOrder          restriction = pair.Second.DateOrder;
                // compare node to previous node
                if (i > 0)
                {
                    Pair <LocalDate, CurveNode> pairBefore = nodeDates[i - 1];
                    if (DAYS.between(pairBefore.First, pair.First) < restriction.MinGapInDays)
                    {
                        switch (restriction.Action)
                        {
                        case DROP_THIS:
                            nodeDates.RemoveAt(i);
                            i = -1;       // restart loop
                            goto loopContinue;

                        case DROP_OTHER:
                            nodeDates.RemoveAt(i - 1);
                            i = -1;       // restart loop
                            goto loopContinue;

                        case EXCEPTION:
                            break;       // do nothing yet
                            break;
                        }
                    }
                }
                // compare node to next node
                if (i < nodeDates.Count - 1)
                {
                    Pair <LocalDate, CurveNode> pairAfter = nodeDates[i + 1];
                    if (DAYS.between(pair.First, pairAfter.First) < restriction.MinGapInDays)
                    {
                        switch (restriction.Action)
                        {
                        case DROP_THIS:
                            nodeDates.Remove(i);
                            i = -1;       // restart loop
                            goto loopContinue;

                        case DROP_OTHER:
                            nodeDates.Remove(i + 1);
                            i = -1;       // restart loop
                            goto loopContinue;

                        case EXCEPTION:
                            break;       // do nothing yet
                            break;
                        }
                    }
                }
                loopContinue :;
            }
            loopBreak :
            // throw exceptions if rules breached
            for (int i = 0; i < nodeDates.Count; i++)
            {
                Pair <LocalDate, CurveNode> pair        = nodeDates[i];
                CurveNodeDateOrder          restriction = pair.Second.DateOrder;
                // compare node to previous node
                if (i > 0)
                {
                    Pair <LocalDate, CurveNode> pairBefore = nodeDates[i - 1];
                    if (DAYS.between(pairBefore.First, pair.First) < restriction.MinGapInDays)
                    {
                        throw new System.ArgumentException(Messages.format("Curve node dates clash, node '{}' and '{}' resolved to dates '{}' and '{}' respectively", pairBefore.Second.Label, pair.Second.Label, pairBefore.First, pair.First));
                    }
                }
                // compare node to next node
                if (i < nodeDates.Count - 1)
                {
                    Pair <LocalDate, CurveNode> pairAfter = nodeDates[i + 1];
                    if (DAYS.between(pair.First, pairAfter.First) < restriction.MinGapInDays)
                    {
                        throw new System.ArgumentException(Messages.format("Curve node dates clash, node '{}' and '{}' resolved to dates '{}' and '{}' respectively", pair.Second.Label, pairAfter.Second.Label, pair.First, pairAfter.First));
                    }
                }
            }
            // return the resolved definition
//JAVA TO C# CONVERTER TODO TASK: Most Java stream collectors are not converted by Java to C# Converter:
            IList <CurveNode> filteredNodes = nodeDates.Select(p => p.Second).collect(toImmutableList());

            return(new InterpolatedNodalCurveDefinition(name, xValueType, yValueType, dayCount, filteredNodes, interpolator, extrapolatorLeft, extrapolatorRight));
        }