#coding:utf-8 import sys from prettytable import PrettyTable import math ''' 月利率 = 年利率/12 1.等额本息计算公式:每月还款金额 =〔贷款本金×月利率×(1+月利率)^还款月数〕÷〔(1+月利率)^还款月数 - 1〕 每月利息 = 每月还款金额 - (1 + 月利率 )^(还款期数-1) * (每月还款金额 - 月利率*贷款本金) 每月偿还本金 = ( 1 + 月利率)^(还款期数-1) * (每月还款金额 - 月利率*贷款本金) 2.等额本金计算公式:每月还款金额 =(贷款本金 / 还款月数)+(本金 — 已归还本金累计额)* 每月利率 每月偿还本金=贷款本金/还款月数 每月利息=(本金-累计已还本金)×月利率 ''' YEAR_LPR=0.0385 #年利率 MONTH_LPR=round(YEAR_LPR/12,12) #月利率 UNIT= 10000 #单位万元 ''' 月供计算 periods:第n期还款 pay_month:总还款月数 total:单位(万元) 等额本息:pay_way=1 等额本金:pay_way=2 ''' #月供 def get_month_pay(total,periods=1,pay_month=360,pay_way=1): result=0 if pay_way==1: result = (total*UNIT*MONTH_LPR*((MONTH_LPR+1)**pay_month))/((MONTH_LPR+1)**pay_month-1) elif pay_way==2: result=(total*UNIT/pay_month)+(total*UNIT - (total*UNIT/pay_month)*(periods-1) )*MONTH_LPR return round(result,6) # 每月还款利息 def get_month_interest(total,periods=1,pay_month=360,pay_way=1): result=0 if pay_way==1: month_pay = round((total*UNIT*MONTH_LPR*((MONTH_LPR+1)**pay_month))/((MONTH_LPR+1)**pay_month-1),6) #每月还款金额 result = month_pay-((1 + MONTH_LPR)**(periods-1)) * (month_pay - MONTH_LPR * total * UNIT) elif pay_way==2: result = (total*UNIT - (total*UNIT/pay_month)*(periods-1) )*MONTH_LPR return round(result,6) #每月还款本金 def get_month_principal(total,periods=1,pay_month=360,pay_way=1): result=0 if pay_way==1: month_pay = round((total*UNIT*MONTH_LPR*((MONTH_LPR+1)**pay_month))/((MONTH_LPR+1)**pay_month-1),6) #每月还款金额 result = ((1 + MONTH_LPR)**(periods-1)) * (month_pay - MONTH_LPR * total* UNIT) elif pay_way==2: result = total*UNIT/pay_month return round(result,6) #获取剩余还款期数(还款周期,还款金额不变,缩短剩余期数) #pay_month:月供 #total:上期本金 #total_new:新的还款本金 #periods:上期还款周期 def get_month_periods1(total_new,pay_month): period = math.log10(pay_month/(pay_month-total_new*MONTH_LPR))/math.log10(1+MONTH_LPR) # return math.ceil(period) return int(period) #尽力缩短还款期数 def get_month_periods2(total,total_new,periods): period = total_new/(total*UNIT) * periods # return math.ceil(period) return int(period) ''' sum_total:还款本金 pay_month:总还款期数 pay_way:还款方式 等额本息:pay_way=1 等额本金:pay_way=2 before_pay_dict:提前还款参数,值:{key(第几期):value(提前还款金额)} ''' def main(sum_total,pay_month,pay_way,before_pay_dict=dict()): titiles = ["期数", "月还款", "还款本金","还款利息","总还款","总还款本金","剩余还款本金","总还款利息"] tb = PrettyTable(titiles) for i in titiles:tb._align[i] = 'l' sum_month_pay1 = 0 #总还款金额 sum_month_pay2 = 0 sum_month_principal1= 0 #总还款本金 sum_month_principal2 = 0 sum_month_interest1 = 0 #总还款利息 sum_month_interest2 = 0 mod_principal1 = sum_total * UNIT #剩余本金 mod_principal2 = sum_total * UNIT remaining_pay_month = pay_month ##提前还款后,剩余还款期数 total = sum_total periods =0 #第n期 for i,_ in enumerate(range(1,pay_month+1),1): periods += 1 month_pay1=get_month_pay(total,periods,remaining_pay_month,pay_way=1) #月供 month_pay2=get_month_pay(total,periods,remaining_pay_month,pay_way=2) month_interest1 = get_month_interest(total,periods,remaining_pay_month,pay_way=1) #利息 month_interest2 = get_month_interest(total,periods,remaining_pay_month,pay_way=2) month_principal1 = get_month_principal(total,periods,remaining_pay_month,pay_way=1) #本金 month_principal2 = get_month_principal(total,periods,remaining_pay_month,pay_way=2) sum_month_pay1 += month_pay1 #总还款数 sum_month_pay2 += month_pay2 sum_month_principal1 += month_principal1 #总还款本金 sum_month_principal2 += month_principal2 sum_month_interest1 += month_interest1 #总还款利息 sum_month_interest2 += month_interest2 mod_principal1 = (sum_total*UNIT) -sum_month_principal1 #剩余本金 mod_principal2 = (sum_total*UNIT) -sum_month_principal2 #提前还款 if before_pay_dict.keys().__contains__(i): pay_money = before_pay_dict[i] #提前还款金额 month_principal1 += pay_money month_principal2 += pay_money sum_month_pay1 += pay_money sum_month_pay2 += pay_money sum_month_principal1 += pay_money sum_month_principal2 += pay_money mod_principal1 -= pay_money mod_principal2 -= pay_money periods = 0 remaining_pay_month = pay_month - i if pay_way==1 and mod_principal1>0: total = mod_principal1/10000 if pay_way==2 and mod_principal2>0: total = mod_principal2/10000 row1=['息-{}'.format(i),round(month_pay1,2),round(month_principal1,2),round(month_interest1,2),round(sum_month_pay1,2), round(sum_month_principal1,2),abs(round(mod_principal1,2)),round(sum_month_interest1,2)] row2=['金-{}'.format(i),round(month_pay2,2),round(month_principal2,2),round(month_interest2,2),round(sum_month_pay2,2), round(sum_month_principal2,2),abs(round(mod_principal2,2)),round(sum_month_interest2,2)] if pay_way==1 :tb.add_row(row1) if pay_way==2 :tb.add_row(row2) if before_pay_dict.keys().__contains__(i): tb.add_row(["---", "---", "---","---","---","---","---","---"]) print(tb) #提前还贷,保持月供,缩短剩余期数方式 def mainv2(sum_total,pay_month,pay_way,before_pay_dict=dict()): titiles = ["期数", "月还款", "还款本金","还款利息","总还款","总还款本金","剩余还款本金","总还款利息"] tb = PrettyTable(titiles) for i in titiles:tb._align[i] = 'l' sum_month_pay1 = 0 #总还款金额 sum_month_pay2 = 0 sum_month_principal1= 0 #总还款本金 sum_month_principal2 = 0 sum_month_interest1 = 0 #总还款利息 sum_month_interest2 = 0 mod_principal1 = sum_total * UNIT #剩余本金 mod_principal2 = sum_total * UNIT remaining_pay_month = pay_month #提前还款后,从新计算的还款周期 remaining_periods = pay_month #剩余还款期数 total = sum_total periods =0 #第n期 for i,_ in enumerate(range(1,pay_month+1),1): periods += 1 remaining_periods -= 1 month_pay1 = get_month_pay(total,periods,remaining_pay_month,pay_way=1) #月供 month_pay2 = get_month_pay(total,periods,remaining_pay_month,pay_way=2) month_interest1 = get_month_interest(total,periods,remaining_pay_month,pay_way=1) #利息 month_interest2 = get_month_interest(total,periods,remaining_pay_month,pay_way=2) month_principal1 = get_month_principal(total,periods,remaining_pay_month,pay_way=1) #本金 month_principal2 = get_month_principal(total,periods,remaining_pay_month,pay_way=2) sum_month_pay1 += month_pay1 #总还款数 sum_month_pay2 += month_pay2 sum_month_principal1 += month_principal1 #总还款本金 sum_month_principal2 += month_principal2 sum_month_interest1 += month_interest1 #总还款利息 sum_month_interest2 += month_interest2 mod_principal1 = (sum_total*UNIT) - sum_month_principal1 #剩余本金 mod_principal2 = (sum_total*UNIT) - sum_month_principal2 #提前还款 if before_pay_dict.keys().__contains__(i): pay_money = before_pay_dict[i] #提前还款金额 month_principal1 += pay_money month_principal2 += pay_money sum_month_pay1 += pay_money sum_month_pay2 += pay_money sum_month_principal1 += pay_money sum_month_principal2 += pay_money mod_principal1 -= pay_money mod_principal2 -= pay_money periods = 0 # remaining_pay_month = pay_month - i if pay_way==1 and mod_principal1>0: total = mod_principal1/10000 if pay_way==2 and mod_principal2>0: total = mod_principal2/10000 if pay_way==1:remaining_pay_month = get_month_periods1(mod_principal1,month_pay1) if pay_way==2:remaining_pay_month = get_month_periods2(sum_total,mod_principal2,pay_month) # print('remaining_pay_month=',remaining_pay_month,mod_principal1,mod_principal2) remaining_periods = remaining_pay_month row1=['息-{}'.format(i),round(month_pay1,2),round(month_principal1,2),round(month_interest1,2),round(sum_month_pay1,2), round(sum_month_principal1,2),abs(round(mod_principal1,2)),round(sum_month_interest1,2)] row2=['金-{}'.format(i),round(month_pay2,2),round(month_principal2,2),round(month_interest2,2),round(sum_month_pay2,2), round(sum_month_principal2,2),abs(round(mod_principal2,2)),round(sum_month_interest2,2)] if pay_way==1 :tb.add_row(row1) if pay_way==2 :tb.add_row(row2) if before_pay_dict.keys().__contains__(i): tb.add_row(["---", "---", "---","---","---","---","---","---"]) if remaining_periods==0:break #已全部还完 print(tb) if __name__ == "__main__": pay_way = 1 #还款方式:1为等额本息,2为等额本金 before_pay_dict={ 4:10000, #提前还款期数:提前还款金额 5:30000, 8:80000, } mainv2(50,15,pay_way,before_pay_dict) #提前还款,月供不变,还款期数减少 main(50,15,pay_way,before_pay_dict) #提前还款,月供减少,还款期数不变
+-------+----------+----------+----------+-----------+------------+--------------+------------+ | 期数 | 月还款 | 还款本金 | 还款利息 | 总还款 | 总还款本金 | 剩余还款本金 | 总还款利息 | +-------+----------+----------+----------+-----------+------------+--------------+------------+ | 金-1 | 34937.5 | 33333.33 | 1604.17 | 34937.5 | 33333.33 | 466666.67 | 1604.17 | | 金-2 | 34830.56 | 33333.33 | 1497.22 | 69768.06 | 66666.67 | 433333.33 | 3101.39 | | 金-3 | 34723.61 | 33333.33 | 1390.28 | 104491.67 | 100000.0 | 400000.0 | 4491.67 | | 金-4 | 34616.67 | 43333.33 | 1283.33 | 149108.33 | 143333.33 | 356666.67 | 5775.0 | | --- | --- | --- | --- | --- | --- | --- | --- | | 金-5 | 36810.97 | 65666.67 | 1144.31 | 215919.31 | 209000.0 | 291000.0 | 6919.31 | | --- | --- | --- | --- | --- | --- | --- | --- | | 金-6 | 37308.62 | 36375.0 | 933.62 | 253227.93 | 245375.0 | 254625.0 | 7852.93 | | 金-7 | 37191.92 | 36375.0 | 816.92 | 290419.85 | 281750.0 | 218250.0 | 8669.85 | | 金-8 | 37075.22 | 116375.0 | 700.22 | 407495.07 | 398125.0 | 101875.0 | 9370.07 | | --- | --- | --- | --- | --- | --- | --- | --- | | 金-9 | 34285.18 | 33958.33 | 326.85 | 441780.25 | 432083.33 | 67916.67 | 9696.92 | | 金-10 | 34176.23 | 33958.33 | 217.9 | 475956.49 | 466041.67 | 33958.33 | 9914.82 | | 金-11 | 34067.28 | 33958.33 | 108.95 | 510023.77 | 500000.0 | 0.0 | 10023.77 | +-------+----------+----------+----------+-----------+------------+--------------+------------+ +-------+----------+-----------+----------+-----------+------------+--------------+------------+ | 期数 | 月还款 | 还款本金 | 还款利息 | 总还款 | 总还款本金 | 剩余还款本金 | 总还款利息 | +-------+----------+-----------+----------+-----------+------------+--------------+------------+ | 金-1 | 34937.5 | 33333.33 | 1604.17 | 34937.5 | 33333.33 | 466666.67 | 1604.17 | | 金-2 | 34830.56 | 33333.33 | 1497.22 | 69768.06 | 66666.67 | 433333.33 | 3101.39 | | 金-3 | 34723.61 | 33333.33 | 1390.28 | 104491.67 | 100000.0 | 400000.0 | 4491.67 | | 金-4 | 34616.67 | 43333.33 | 1283.33 | 149108.33 | 143333.33 | 356666.67 | 5775.0 | | --- | --- | --- | --- | --- | --- | --- | --- | | 金-5 | 33568.55 | 62424.24 | 1144.31 | 212676.88 | 205757.58 | 294242.42 | 6919.31 | | --- | --- | --- | --- | --- | --- | --- | --- | | 金-6 | 30368.27 | 29424.24 | 944.03 | 243045.15 | 235181.82 | 264818.18 | 7863.33 | | 金-7 | 30273.87 | 29424.24 | 849.62 | 273319.02 | 264606.06 | 235393.94 | 8712.96 | | 金-8 | 30179.46 | 109424.24 | 755.22 | 383498.48 | 374030.3 | 125969.7 | 9468.18 | | --- | --- | --- | --- | --- | --- | --- | --- | | 金-9 | 18399.82 | 17995.67 | 404.15 | 401898.31 | 392025.97 | 107974.03 | 9872.33 | | 金-10 | 18342.09 | 17995.67 | 346.42 | 420240.4 | 410021.65 | 89978.35 | 10218.75 | | 金-11 | 18284.35 | 17995.67 | 288.68 | 438524.75 | 428017.32 | 71982.68 | 10507.43 | | 金-12 | 18226.62 | 17995.67 | 230.94 | 456751.36 | 446012.99 | 53987.01 | 10738.37 | | 金-13 | 18168.88 | 17995.67 | 173.21 | 474920.24 | 464008.66 | 35991.34 | 10911.58 | | 金-14 | 18111.14 | 17995.67 | 115.47 | 493031.38 | 482004.33 | 17995.67 | 11027.06 | | 金-15 | 18053.41 | 17995.67 | 57.74 | 511084.79 | 500000.0 | 0.0 | 11084.79 | +-------+----------+-----------+----------+-----------+------------+--------------+------------+
标签:pay,sum,month,---,还款,计算,total,提前 From: https://www.cnblogs.com/boye169/p/18099086