可以看到第96期(第8年年终)时,本金还了25万,但利息已经还了近30万了,和之前文中例子的数据是可以对得上的。
刚刚我们已经将还款的各项数据以表格的形式打印。此外我们还可以借助python的能力,打印还款的柱状图。
import numpy as np
def printStatistics(capitals, interests, total_payment, months):
print("总本金:" str(np.sum(capitals)))
print("总利息:" str(np.sum(interests)))
print("总利息/总本金" str(np.sum(interests)/np.sum(capitals)))
print("首月还款 %.2f 末月还款: %.2f" % (total_payment[0], total_payment[months - 1]))
def drawDiagram(months, fn, *args, **kwargs):
capitals, interests, total_payment = fn(months, *args, **kwargs)
printStatistics(capitals, interests, total_payment, months)
month_array = np.arange(1, months 1, 1)
height = interests
plt.bar(month_array, capitals, width=0.2, align='center', color='red')
plt.bar(month_array, interests, width=0.2, align='center', color='blue', bottom=capitals)
plt.show()
再跑一下知乎的例子,绘制等额本金和等额本息的还款柱状图:
drawDiagram(12 * 20, averageCapital, 875000, 0.049)
如图,蓝色是所还利息,红色是所还本金。可以看出本金每月不变,利息逐月递减的特征。
等额本息情况下:
drawDiagram(12 * 20, averageCapitalPlusInterest, 875000, 0.049)
也能看出所绘图形和等额本息的含义基本一致。
另外部分城市可以公积金贷款,以杭州为例,目前杭州公积金充足情况下可贷50w-60w,这里考虑一下公积金的情况:
def averageCapitalWithPublicFund(months, principal1, rate1, principal2, rate2):
a, b, c = averageCapital(months, principal1, rate1)
a1, b1, c1 = averageCapital(months, principal2, rate2)
return np.sum([a,a1],axis=0).tolist(), np.sum([b,b1],axis=0).tolist(), np.sum([c,c1],axis=0).tolist()
drawTable(12 * 20, averageCapitalWithPublicFund, 700000, 0.041, 300000, 0.031)[0:10]
这里算了下商贷70w(利率4.1%),公积金贷30w(利率3.1%)下组合贷款的情况,和微信小程序房小团的计算是一致的。
再来讨论下提前还款。如果知乎文中买房的那位,在贷款1年后提前还款10w会怎样呢?了解一点背景知识的朋友,都知晓提前还款分两种情况:
- 年限不变,月供减少
- 年限缩短,月供不变
现在分情况讨论,并给出计算函数。
注:notebook中所有计算结果均在微信房小团小程序上得到互相验证。
年限不变,月供减少这种情况下,相当于在提前还款月之后重新做了一次贷款。我们首先对刚刚的计算函数进行一定的简化,抽象一下公共的部分。
def normalPaid(months, principal, rate, capitalAveraged):
month_rate = rate / 12
monthly_capital = principal / months
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):
interests[i] = left_principal[i] * month_rate
if capitalAveraged:
capitals[i] = monthly_capital
total_payment[i] = monthly_capital interests[i]
else:
total_payment[i] = monthly_payment
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
drawTable(12 * 20, normalPaid, 875000, 0.049, False)[10:14]