多个贷方的利率

时间:2018-04-29 19:44:01

标签: java math finance amortization

我想创建一个Amortisation calculator来获取贷款人数 N 的报价36个月贷款,其中每个贷款人的利率不同。目标是提供尽可能的费率,并提供每月还款金额和总还款金额。我的代码的结果是关闭但不完全

我正在使用公式formula

i(利率)计算为total amount lended / requested amount,其中,每个贷方的借出金额乘以贷方的利率。

    BigDecimal requestedAmountP = new BigDecimal("" + requestedAmount);
    BigDecimal minLendersRate = calculateRate(requestedAmount, lenders);

    // https://en.wikipedia.org/wiki/Mortgage_calculator#Monthly_payment_formula
    // r*P/(1 - (1+r)^(-N))         if r != 0
    // P/N                          if r == 0
    BigDecimal monthlyRepayment;
    if (minLendersRate.compareTo(BigDecimal.ZERO) == 0) {
        monthlyRepayment = requestedAmountP.divide(DURATION_MONTHS, MathContext.DECIMAL128);
    } else {
        BigDecimal r = calculateEffectiveInterestInMonths(minLendersRate);
        BigDecimal tmp = r.add(BigDecimal.ONE).pow(-DURATION_MONTHS.intValue(), MathContext.DECIMAL128);
        BigDecimal dividend = BigDecimal.ONE.subtract(tmp);
        monthlyRepayment = r.multiply(requestedAmountP).divide(dividend, MathContext.DECIMAL128);
    }
    BigDecimal totalRepayment = monthlyRepayment.multiply(DURATION_MONTHS);

计算费率:

private BigDecimal calculateRate(double requestedAmount, List<Lender> lenders) {
    List<Lender> sortedLenders = lenders.stream().sorted(Comparator.comparing(Lender::getRate)).collect(toList());
    List<BigDecimal> moneyLended = moneyLended(requestedAmount, sortedLenders);

    BigDecimal totalMoneyLended = IntStream.range(0, moneyLended.size())
            .mapToObj(index -> moneyLended.get(index).multiply(sortedLenders.get(index).getRate()))
            .reduce(BigDecimal.ZERO, BigDecimal::add);

    return totalMoneyLended.divide(new BigDecimal("" + requestedAmount), MathContext.DECIMAL128);
}

private List<BigDecimal> moneyLended(double requestedAmount, List<Lender> sortedLenders) {
    List<BigDecimal> moneyLended = new ArrayList<>(sortedLenders.size());

    int i = 0;
    Double remaining = requestedAmount;
    while (remaining > 0) {
        if (remaining - sortedLenders.get(i).getAvailable().doubleValue() >= 0) {
            remaining = remaining - sortedLenders.get(i).getAvailable().doubleValue();

        } else {
            remaining = 0d;
        }
        moneyLended.add(sortedLenders.get(i).getAvailable());
        i++;
    }
    return moneyLended;
}

计算Effective Interest in Months

private BigDecimal calculateEffectiveInterestInMonths(BigDecimal nominalInterest) {
    // Formula: ((1+nominalInterest)^(1/12))-1
    BigDecimal exp = BigDecimal.ONE.divide(new BigDecimal("12"), MathContext.DECIMAL128);
    return BigDecimalMath.pow(BigDecimal.ONE.add(nominalInterest), exp, MathContext.DECIMAL128)
            .subtract(BigDecimal.ONE);
}

似乎十进制操作存在问题,但我无法找到位置。

0 个答案:

没有答案