多次提前还贷计算器及PMT 函数

最近写了个计算多次提前还贷的计算器,大家可以尝试使用,计算结果仅供参考。

前言

多次提前还贷计算器

网上这样的工具其实不少,不过用起来不是很得劲。比如有的还款时间只能写到月份,有的限制了多次提前还款的次数,不是很自由。

所以我就用 vue 自己写了一个,自认为还挺好用的吧,没有设置什么限制,不过精度问题还需要继续优化。

实现

输入输出

输入:

  • 贷款金额
  • 贷款期限
  • 贷款利率
  • 还款方式(等额本息、等额本金)
  • 首次还款时间
  • 提前还款
    • 还款金额
    • 还款时间
    • 调整期数
    • 调整利率

输出:

  • 累计提前还款
  • 累计调整期数
  • 原累计利息
  • 累计缴息
  • 累计节省利息
  • 每月明细

月明细计算

  • 每月利息: 本月剩余本金 * 年利率 / 12

  • 每月还款额:

    • 等额本息: 用 PMT 函数计算
    • 等额本金: 本月偿还本金 + 本月利息
  • 每月偿还本金:

    • 等额本息: 本月还款额 - 本月利息
    • 等额本金: 本月剩余本金 / 剩余期数

PMT 函数

这个函数本是 Excel 里的,不过 Excel 不开源,只好另外用 js 来实现。这里使用的是网上的大佬实现的版本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
* Copy of Excel's PMT function.
* Credit: http://stackoverflow.com/questions/2094967/excel-pmt-function-in-js
*
* @param ratePerPeriod The interest rate for the loan.
* @param numberOfPayments The total number of payments for the loan in months.
* @param presentValue The present value, or the total amount that a series of future payments is worth now;
* Also known as the principal.
* @param futureValue The future value, or a cash balance you want to attain after the last payment is made.
* If fv is omitted, it is assumed to be 0 (zero), that is, the future value of a loan is 0.
* @param type Optional, defaults to 0. The number 0 (zero) or 1 and indicates when payments are due.
* 0 = At the end of period
* 1 = At the beginning of the period
* @returns {number}
*/
function pmt(ratePerPeriod, numberOfPayments, presentValue, futureValue, type) {
futureValue = typeof futureValue !== "undefined" ? futureValue : 0;
type = typeof type !== "undefined" ? type : 0;

if (ratePerPeriod !== 0.0) {
// Interest rate exists
const q = Math.pow(1 + ratePerPeriod, numberOfPayments);
return (
-(ratePerPeriod * (futureValue + q * presentValue)) /
((-1 + q) * (1 + ratePerPeriod * type))
);
} else if (numberOfPayments !== 0.0) {
// No interest rate, but number of payments exists
return -(futureValue + presentValue) / numberOfPayments;
}

return 0;
}