了解过贷款的小伙伴都知道,贷款有等额本金和等额本息这两种方式,前者每月还款的本金相同,利息逐月递减;后者每月还款额相同,刚开始还款时利息还的多,后面本金还的逐渐增多。参考网上讨论利息计算的诸多文章,两个模型理论上,都有下列共同特点:
- 利息按月利率计算,一月一期
- 按期还款情况下当月应还利息只由未还完的本金决定
- 每月还款额除了未还本金产生的全部利息外,剩下的金额应该全部用于偿还本金
像最近部分银行提出的先息后本(先还利息若干年,最后一次性偿还本金)则不符合这个条件。
还款额的计算知乎文章为什么买房贷款,最好选择等额本金?中提到了一个例子:
前阵子,院长有位朋友在惠州买了套120平米的房,总价125万左右,大约贷了87.5万。
办房贷的时候,他听从销售的建议,选了【等额本息】的还款方式。每个月固定还5726.39元。这个还款额度在他的承受范围之内,因此就选了。
那假如选择等额本金呢?第一个月要还的金额为7218.75元,此后每个月少还14.89元,直至20年后还完。
通过描述可知,贷款87.5万,贷20年,等额本息每月还款5726.39元,等额本金首月还款7218.75元。假设文中的贷款未使用公积金,计算时利率为固定利率,根据网上的贷款计算器可知此时的贷款年利率为4.9%。
以这个例子为例,简单说明等额本金和等额本息的计算方法:
首先贷20年,按月分期,贷款为
20∗12=240期。
年利率4.9%,月利率为
0.049÷12=0.004983 即0.4083%。
等额本金 情况下:
每月应还本金=总本金÷期数
每月应还利息=剩余本金×月利率
每月还款额=每月应还本金 每月应还利息
在这个例子中:
- 每月应还本金为
875000÷240=3645.83元 - 首月应还利息为
875000×0.4083元 - 首月应还:
3645.83 3572.92=7218.75元。 - 第2月剩余本金为
875000−3645.83=871354.17元。 - 第2月应还利息为
871354.17×0.4083元。 - 第2月应还:
3645.83 3558.03=7203.86元。
将这段逻辑抽象为代码有:
import matplotlib.pyplot as plt
import numpy as np
def averageCapital(months, principal, rate):
month_rate = rate / 12
monthly_capital = principal / months
interests = [0] * months
capitals = [0] * months
left_principal = [0] * months
left_principal[0] = principal
total_payment = [0] * months
for i in range(0, months):
interests[i] = left_principal[i] * month_rate
capitals[i] = monthly_capital
total_payment[i] = monthly_capital interests[i]
if i 1 < months:
left_principal[i 1] = left_principal[i] - monthly_capital
return capitals, interests, total_payment
为了便于查看再封装一个打印成表格的函数:
import pandas as pd
def drawTable(months, fn, *args, **kwargs):
capitals, interests, total_payment = fn(months, *args, **kwargs)
paid_capital = [0] * months
paid_interests = [0] * months
paid_capital[0] = capitals[0]
paid_interests[0] = interests[0]
for x in range(1, months):
paid_capital[x] = paid_capital[x - 1] capitals[x]
paid_interests[x] = paid_interests[x - 1] interests[x]
origin = pd.DataFrame([total_payment, capitals, interests, paid_capital, paid_interests])
return pd.DataFrame(origin.values.T, columns=['还款额','还款本金','还款利息','已还本金','已还利息'], index=np.arange(1, months 1))
我们运行一下知乎上的例子,看看头几年还款的本金、利息等:
pd.options.display.float_format = '{:.2f}'.format
drawTable(12 * 20, averageCapital, 875000, 0.049)[0:10]
可以看到和文中描述一致,使用微信房小团小程序,也可以打印出一致的结果。
等额本息 的计算方法有些复杂,参考用python深度解读房贷利率文中的解法,设A为本金,第i个月月末所欠银行本金为Ai,每月所还贷款总额为X,月利率为β, 则有:
由于最后一期时剩余本金为0,可反解得:
这里m为总期数(在刚刚的例子中,m=240)。而后就可以使用与等额本金计算中类似的逻辑,从第一期所还利息开始,反推每期的利息与本金。具体代码如下:
def averageCapitalPlusInterest(months, principal, rate):
month_rate = rate / 12
monthly_payment = principal * month_rate * (1 month_rate) ** months / ((1 month_rate) ** months - 1)
interests = [0] * months
capitals = [0] * months
left_principal = [0] * months
left_principal[0] = principal
total_payment = [0] * months
for i in range(0, months):
total_payment[i] = monthly_payment
interests[i] = left_principal[i] * month_rate
capitals[i] = total_payment[i] - interests[i]
if i 1 < months:
left_principal[i 1] = left_principal[i] - capitals[i]
return capitals, interests, total_payment
我们运行一下知乎上的例子,看看等额本息模式下第8年附近,到底还了多少利息和本金:
drawTable(12 * 20, averageCapitalPlusInterest, 875000, 0.049)[90:100]