drawTable(12 * 20, normalPaid, 875000, 0.049, True)[10:14]
可以看到抽象出公共结构后,前后的计算结果并没有发生变化。
考虑年限不变提前还款的情况,这里将每次提前还款的时间和金额组成python的元组,若干个(账期,还款金额)元组组成一个list输入函数。函数首先计算正常情况下的还款信息,而后根据提前还款信息,修改提前还款日的剩余本金,并从各个提前还款日重新计算剩余还款。
def extraPaidWithFixedPeriod(months, principal, rate, capitalAveraged, extraPaidList :list):
capitals, interests, total_payment = normalPaid(months, principal, rate, capitalAveraged)
extraPaidList.sort(key=lambda x:x[0])
originCapital, originInterests, originTotal = capitals.copy(), interests.copy(), total_payment.copy()
left_principal = [0] * months
left_principal[0] = principal
for x in range(0,months):
if x < months - 1:
left_principal[x 1] = left_principal[x] - capitals[x]
def normalPaidOffset(left_months, principal, rate, capitalAveraged, offset):
month_rate = rate / 12
monthly_capital = left_principal[offset] / left_months
monthly_payment = left_principal[offset] * month_rate * (1 month_rate) ** left_months / ((1 month_rate) ** left_months - 1)
for i in range(0, left_months):
interests[offset i] = left_principal[offset i] * month_rate
if capitalAveraged:
capitals[offset i] = monthly_capital
total_payment[offset i] = monthly_capital interests[offset i]
else:
total_payment[offset i] = monthly_payment
capitals[offset i] = total_payment[offset i] - interests[offset i]
if i == 0:
print("次月还款 %.2f" % total_payment[offset i])
if offset i 1 < months:
left_principal[offset i 1] = left_principal[offset i] - capitals[offset i]
return
for x,y in extraPaidList:
capitals[x] = capitals[x] y
left_principal[x 1] = left_principal[x] - capitals[x]
total_payment[x] = capitals[x] interests[x]
print("当月需还 %.f 剩余本金 %.f" %(total_payment[x], left_principal[x 1]))
normalPaidOffset(months - x - 1, left_principal[x 1], rate, capitalAveraged, x 1)
printStatistics(originCapital, originInterests, originTotal, months)
print("")
printStatistics(capitals, interests, total_payment, months)
print("节省利息 %.2f" % (np.sum(originInterests) - np.sum(interests)))
return capitals, interests, total_payment, originTotal, originInterests
再定义几个函数对提前还款节省的利息进行可视化。
def drawDiagramExtraPaid(months, capitals, interests, originalTotal, originalInterests, showOriginTotal=True):
month_array = np.arange(1, months 1, 1)
capital_with_origin_interest = [0] * months
height = interests
for x in range(1, months):
capital_with_origin_interest[x] = capitals[x] originalInterests[x]
l1 = plt.bar(month_array, originalTotal if showOriginTotal else capital_with_origin_interest, width=0.2, align='center', color='yellow')
l2 = plt.bar(month_array, capitals, width=0.2, align='center', color='red')
l3 = plt.bar(month_array, interests, width=0.2, align='center', color='blue', bottom=capitals)
# plt.legend(handles = [l1, l2,l3], labels = ['每月少还' if showOriginTotal else '节省利息', '本金','利息'], loc = 'best',fontsize=20)
plt.ylim(0, (capitals[0] interests[0])*1.1)
plt.show()
def drawTableExtraPaid(months, capitals, interests, total_payment, originalTotal, originalInterests):
paid_capital = [0] * months
paid_interests = [0] * months
saved_money = [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]
saved_money[x] = saved_money[x - 1] (originalInterests[x] - interests[x] )
origin = pd.DataFrame([total_payment, capitals, interests, paid_capital, paid_interests,saved_money])
return pd.DataFrame(origin.values.T, columns=['还款额','还款本金','还款利息','已还本金','已还利息','累计节省'], index=np.arange(1, months 1))
通过参数showOriginTotal的取值,可以分别绘制每月少还的钱与当月节省利息的情况。下面分别绘制了等额本金和等额本息情况下,87.5万贷20年,在第一年还10万后还款和利息的变化情况。
a, b, c, d, e = extraPaidWithFixedPeriod(12 * 20, 875000, 0.049, True, [(13,100000)])
drawDiagramExtraPaid(12 * 20, a, b, d, e)
drawDiagramExtraPaid(12 * 20, a, b, d, e, False)
drawTableExtraPaid(12 * 20, a, b, c, d, e)[10:20]