随笔- 310  文章- 1  评论- 0  阅读- 85559 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
#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 #已全部还完<br>        if pay_way==1 and mod_principal1<=0:break<br>        if pay_way==2 and mod_principal2<=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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
+-------+----------+----------+----------+-----------+------------+--------------+------------+
| 期数  | 月还款   | 还款本金 | 还款利息 | 总还款    | 总还款本金 | 剩余还款本金 | 总还款利息 |
+-------+----------+----------+----------+-----------+------------+--------------+------------+
| 金-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   |
+-------+----------+-----------+----------+-----------+------------+--------------+------------+

  

 

 posted on   boye169  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示