import math import numpy as np import matplotlib.pyplot as plt from matplotlib.ticker import MultipleLocator, FormatStrFormatter def averageCapitalInterest(monthRate, total, monthNum): x = total * math.pow(1 + monthRate, monthNum) * monthRate / (math.pow(1 + monthRate, monthNum) - 1) debtRest = [0] * (monthNum + 1) refundPerMonth = [x] * (monthNum + 1) refundInterestPerMonth = [0] * (monthNum + 1) refundCapitalPerMonth = [0] * (monthNum + 1) debtRest[0] = total refundPerMonth[0] = 0 for monthSeq in range(1, monthNum + 1, 1): debtRest[monthSeq] = total * math.pow(1 + monthRate, monthSeq) - x * (math.pow(1 + monthRate, monthSeq) - 1) / monthRate refundInterestPerMonth[monthSeq] = debtRest[monthSeq - 1] * monthRate refundCapitalPerMonth[monthSeq] = x - refundInterestPerMonth[monthSeq] totalInterest = sum(refundInterestPerMonth) totalRefund = total + totalInterest capitalRest = debtRest assert((totalRefund-1<sum(refundPerMonth) and totalRefund+1>sum(refundPerMonth)) == True) return [totalRefund, totalInterest, debtRest, capitalRest, refundPerMonth, refundInterestPerMonth, refundCapitalPerMonth] def averageCapital(monthRate, total, monthNum): debtRest = [0] * (monthNum + 1) refundPerMonth = [0] * (monthNum + 1) refundInterestPerMonth = [0] * (monthNum + 1) refundCapitalPerMonth = [total/monthNum] * (monthNum + 1) debtRest[0] = total refundCapitalPerMonth[0] = 0 for monthSeq in range(1, monthNum + 1, 1): debtRest[monthSeq] = debtRest[monthSeq-1] - refundCapitalPerMonth[monthSeq] refundInterestPerMonth[monthSeq] = debtRest[monthSeq-1] * monthRate refundPerMonth[monthSeq] = refundCapitalPerMonth[monthSeq] + refundInterestPerMonth[monthSeq] totalInterest = sum(refundInterestPerMonth) totalRefund = total + totalInterest capitalRest = debtRest assert((totalRefund-1<sum(refundPerMonth) and totalRefund+1>sum(refundPerMonth)) == True) return [totalRefund, totalInterest, debtRest, capitalRest, refundPerMonth, refundInterestPerMonth, refundCapitalPerMonth] if __name__ == "__main__": monthRate = 0.049*0.9/12 total = 1800000 monthNum = 12 * 30 investRate = math.pow(1+0.06,1/12) -1 # investRate = 0.08/12 [totalRefund, totalInterest, debtRest, capitalRest, refundPerMonth, refundInterestPerMonth,refundCapitalPerMonth] = averageCapitalInterest(monthRate, total, monthNum) [totalRefund1, totalInterest1,debtRest1, capitalRest1, refundPerMonth1, refundInterestPerMonth1, refundCapitalPerMonth1] = averageCapital(monthRate, total, monthNum) print("等額本息:總共還款:"+str(totalRefund)+" 其中利息:"+str(totalInterest)) print("等額本金:總共還款:" + str(totalRefund1) + " 其中利息:" + str(totalInterest1)) print("等額本息比等額本金多付利息:" + str(totalRefund -totalRefund1)) cashDiff = [0]*(monthNum + 1) investProfit= [0]*(monthNum + 1) for i in range(1, monthNum+1, 1): cashDiff[i] = refundPerMonth1[i] - refundPerMonth[i] for i in range(1, monthNum, 1): investProfit[i] = cashDiff[i] * math.pow(1+investRate,monthNum-i) print("等額本息月供比等額本金多出的現金投資收益爲:" + str(sum(investProfit))) print("等額本息比等額本金,在還完貸款後:" + str(sum(investProfit)-(totalRefund -totalRefund1))) for i in range(1,monthNum+1,1): print("第"+str(i) +"月 等額本息:月供:"+str(refundPerMonth[i])+" 每月還本金:"+str(refundCapitalPerMonth[i])+" 剩餘未還本金:"+str(debtRest[i])) print("第" + str(i) + "月 等額本金:月供:" + str(refundPerMonth1[i]) + " 每月還本金:" + str(refundCapitalPerMonth1[i]) + " 剩餘未還本金:" + str(debtRest1[i])) pic = r"E:\loan.png" xmajorLocator = MultipleLocator(6) # 將x主刻度標籤設置爲20的倍數 xmajorFormatter = FormatStrFormatter('%d') # 設置x軸標籤文本的格式 xminorLocator = MultipleLocator(3) # 將x軸次刻度標籤設置爲的倍數 ymajorLocator = MultipleLocator(50000) # 將y軸主刻度標籤設置爲的倍數 ymajorFormatter = FormatStrFormatter('%1.1f') # 設置y軸標籤文本的格式 yminorLocator = MultipleLocator(25000) # 將此y軸次刻度標籤設置爲的倍數 x = np.linspace(0, monthNum, monthNum+1) plt.figure(1) ax1 = plt.subplot(111) plt.plot(x, debtRest, 'r') plt.plot(x, debtRest1, 'b') # 設置主刻度標籤的位置,標籤文本的格式 ax1.xaxis.set_major_locator(xmajorLocator) ax1.xaxis.set_major_formatter(xmajorFormatter) ax1.yaxis.set_major_locator(ymajorLocator) ax1.yaxis.set_major_formatter(ymajorFormatter) # 顯示次刻度標籤的位置,沒有標籤文本 ax1.xaxis.set_minor_locator(xminorLocator) ax1.yaxis.set_minor_locator(yminorLocator) ax1.xaxis.grid(True, which='major') # x座標軸的網格使用主刻度 ax1.yaxis.grid(True, which='major') # y座標軸的網格使用次刻度 plt.legend(["debtRestCI", "debtRest"], loc=0) plt.xlabel("month") plt.ylabel("amount") plt.xlim(0, monthNum) plt.figure(2) ax2 = plt.subplot(111) plt.plot(x, refundPerMonth, 'r') plt.plot(x, refundCapitalPerMonth, 'm') plt.plot(x, refundPerMonth1, 'c') plt.plot(x, refundCapitalPerMonth1, 'g') xmajorLocator = MultipleLocator(6) # 將x主刻度標籤設置爲20的倍數 xmajorFormatter = FormatStrFormatter('%d') # 設置x軸標籤文本的格式 xminorLocator = MultipleLocator(3) # 將x軸次刻度標籤設置爲的倍數 ymajorLocator = MultipleLocator(500) # 將y軸主刻度標籤設置爲的倍數 ymajorFormatter = FormatStrFormatter('%1.1f') # 設置y軸標籤文本的格式 yminorLocator = MultipleLocator(100) # 將此y軸次刻度標籤設置爲的倍數 # 設置主刻度標籤的位置,標籤文本的格式 ax2.xaxis.set_major_locator(xmajorLocator) ax2.xaxis.set_major_formatter(xmajorFormatter) ax2.yaxis.set_major_locator(ymajorLocator) ax2.yaxis.set_major_formatter(ymajorFormatter) # 顯示次刻度標籤的位置,沒有標籤文本 ax2.xaxis.set_minor_locator(xminorLocator) ax2.yaxis.set_minor_locator(yminorLocator) ax2.xaxis.grid(True, which='major') # x座標軸的網格使用主刻度 ax2.yaxis.grid(True, which='major') # y座標軸的網格使用次刻度 plt.legend(["refundPerMonthCI", "refundCapitalPerMonthCI", "refundPerMonth", "refundCapitalPerMonth"], loc = 0) plt.xlabel("month") plt.ylabel("amount") plt.xlim(0, monthNum) plt.show() plt.close(1) plt.close(2)