计算还款计划表并核对利息
目标
亲自使用两种方式计算贷款还款计划,并手工核实存款利息与税款、逾期利息、资产质量分类和拨备,弄清银行存贷款业务中的数字从何而来。
为什么重要
银行系统需求中有一半都在追问“这个数字为什么会这样得出”。等额本息还款方式每月支付相同金额,等额本金还款方式每月偿还相同本金。同一笔贷款采用不同方式时,总利息、首月还款额和提前还款时的剩余本金都会不同。如果不理解这些差异,就无法区分还款计划界面上的缺陷与正常行为。
利息计算有一套惯例。月利率是年利率除以 12;存款利息按实际天数计算后除以 365;不足 1 韩元的金额在哪个阶段、以何种方式舍去,也由各家公司自行规定。本实验把这些惯例明确规定为本实验的规则——在实际工作中,相应规则会写在贵公司的产品定义文档中。规则不同,数字就可能相差 1 韩元,而这 1 韩元会在总账核对时暴露出来。
逾期既是利息问题,也是分类问题。根据逾期天数,贷款会被分为正常、关注和次级,而分类又决定银行必须计提多少拨备。拨备会直接计入损益,因此一项分类就可能改变该季度的业绩。
本实验的规则
- 月利率 = 年利率 ÷ 12(直接使用,不进行四舍五入)。每月利息 = 上期余额 × 月利率,不足 1 韩元四舍五入。
- 等额本息的月还款额为
P × r ÷ (1 − (1 + r)^−n)对不足 1 韩元部分四舍五入后的值,最后一个月偿清全部剩余本金。 - 等额本金的月本金为
P ÷ n的商(向下取整),不能整除的余数计入最后一个月。 - 存款利息 = 本金 × 年利率 × 天数 ÷ 365,不足 1 韩元舍去。天数为到期日减去开户日所得天数。所得税为利息的 14%,地方所得税为所得税的 10%,两项税款都舍去不足 10 韩元的部分。
- 逾期利息 = 逾期当期的约定还款额 ×(约定利率 + 3.0)% × 逾期天数 ÷ 365,不足 1 韩元舍去。基准日为
2026-08-31,未还款期次的逾期天数为基准日减去应还款日所得天数。 - 资产质量分类以最早的未还款期次为准:0~29 天为
NORMAL,30~89 天为PRECAUTIONARY,90 天或以上为SUBSTANDARD。相应拨备率分别为 1.0%、10.0% 和 20.0%;拨备 = 余额 × 比率,不足 1 韩元舍去。
步骤
- 将右侧示例中的生成器保存为
/root/bank/make_loans.py,并运行python3 make_loans.py。将生成loans.csv(6 笔贷款)、payments.csv(32 个还款期次)和deposits.csv(3 笔存款)。 - 将
L001的等额本息还款计划写入/root/bank/schedule_L001.csv,表头为n,payment,interest,principal,balance,共写 360 行。 - 将
L002的等额本金还款计划写入/root/bank/schedule_L002.csv,使用相同表头,共写 36 行。 - 分别用两种方式计算
L003,并在/root/bank/compare_L003.txt中写入六行:annuity_payment=,annuity_total_interest=,equal_first_payment=,equal_last_payment=,equal_total_interest=,interest_diff=。interest_diff等于等额本息的总利息减去等额本金的总利息。 - 将 3 笔存款的到期利息和税款写入
/root/bank/deposit_interest.csv,表头为dep_id,principal,days,interest,income_tax,local_tax,net。net等于本金加利息,再减去两项税款。 - 从
payments.csv中找出迟还或尚未偿还的期次,写入/root/bank/overdue.csv,表头为loan_id,seq,due_date,days_late,late_interest;并在/root/bank/overdue.txt中写入四行:overdue_rows=,late_interest_total=,max_days_late=,max_loan=。 - 将全部 6 笔贷款写入
/root/bank/provision.csv,表头为loan_id,days_overdue,class,outstanding,rate_pct,provision;并在/root/bank/provision.txt中写入三行:total_outstanding=,total_provision=,substandard_count=。outstanding使用loans.csv中的outstanding_20260831。 - 在
/root/bank/loan_report.md中撰写报告,包含## Repayment comparison(还款方式比较)、## Deposit interest and tax(存款利息与税金)、## Overdue and classification(逾期与资产质量分类)、## What the system must keep(系统必须保留的内容)四个章节。
参考
- 使用 Python 计算会更快。用
csv模块读取数据,再用datetime.date.fromisoformat处理日期相减,即可得到天数。 - Python 的
round()会把 .5 舍入到相邻的偶数。对不足 1 韩元的数值四舍五入时使用int(x + 0.5),舍去时使用int(x)。 - 常见错误 1:一开始就把月利率四舍五入到小数点后四位。
L001的 4.50 ÷ 12 = 0.00375 缩成四位小数后,第一个月的利息就相差 15,000 韩元;如果写成 0.0037,360 个月的总利息会少 3,843,336 韩元。L002的 7.50 ÷ 12 = 0.00625 缩成四位小数后,第一个月的利息也会相差 1,500 韩元。 - 常见错误 2:按今天的日期而不是基准日计算逾期天数。评分程序采用
2026-08-31作为基准。 - 常见错误 3:对利息总额一次性计税。必须逐笔存款分别计算,并分别进行舍去处理。
生成贷款与存款数据
将右侧示例中的生成器保存为 /root/bank/make_loans.py,并运行 python3 make_loans.py。将生成 loans.csv(6 笔贷款)、payments.csv(32 个还款期次)和 deposits.csv(3 笔存款)。
请将实验说明中的生成器保存为 /root/bank/make_loans.py,并使用 python3 运行。如果手工修改,后续步骤中的所有数字都会出现偏差。
生成等额本息还款计划
将 L001 的等额本息还款计划写入 /root/bank/schedule_L001.csv,表头为 n,payment,interest,principal,balance,共写 360 行。
月利率 r = 4.50 ÷ 100 ÷ 12。还款额 = P × r ÷ (1 − (1 + r)^−360),对不足 1 韩元部分四舍五入。每月利息 = 上期余额 × r 后四舍五入;本金 = 还款额 − 利息;最后一个月偿清全部剩余余额。使用 int(x + 0.5) 进行四舍五入。
生成等额本金还款计划
将 L002 的等额本金还款计划写入 /root/bank/schedule_L002.csv,使用相同表头,共写 36 行。
月本金 = 30,000,000 // 36(向下取整)。每月利息 = 上期余额 × (7.50 ÷ 100 ÷ 12) 后四舍五入。还款额 = 利息 + 本金。最后一个月的本金为全部剩余余额,因此余下的 12 韩元会计入该月。
用两种方式比较同一笔贷款
分别用两种方式计算 L003,并在 /root/bank/compare_L003.txt 中写入六行:annuity_payment=, annuity_total_interest=, equal_first_payment=, equal_last_payment=, equal_total_interest=, interest_diff=。interest_diff 等于等额本息的总利息减去等额本金的总利息。
把第 2、3 步的计算程序原样应用于 L003(50,000,000、3.75%、36 个月),分别对两份还款计划的利息列求和。等额本息的结果更大。
计算存款利息和代扣税款
将 3 笔存款的到期利息和税款写入 /root/bank/deposit_interest.csv,表头为 dep_id,principal,days,interest,income_tax,local_tax,net。net 等于本金加利息,再减去两项税款。
days = 到期日 − 开户日(两个 datetime.date 相减后取 .days)。interest = int(P × rate/100 × days/365)。income_tax = int(interest × 0.14) 后舍去不足 10 韩元的部分;local_tax = 所得税的 10%,同样舍去不足 10 韩元的部分。
计算逾期期次和逾期利息
从 payments.csv 中找出迟还或尚未偿还的期次,写入 /root/bank/overdue.csv,表头为 loan_id,seq,due_date,days_late,late_interest;并在 /root/bank/overdue.txt 中写入四行:overdue_rows=, late_interest_total=, max_days_late=, max_loan=。
如果存在 paid_date,逾期天数为 paid_date − due_date;否则为 2026-08-31 − due_date。结果小于或等于 0 时不属于逾期。逾期利息 = int(amount_due × (rate + 3.0)/100 × days/365)。请从 loans.csv 中按贷款取得约定利率。
计算资产质量分类和拨备
将全部 6 笔贷款写入 /root/bank/provision.csv,表头为 loan_id,days_overdue,class,outstanding,rate_pct,provision;并在 /root/bank/provision.txt 中写入三行:total_outstanding=, total_provision=, substandard_count=。outstanding 使用 loans.csv 中的 outstanding_20260831。
对每笔贷款,在 paid_date 为空的期次中找出最早的 due_date,再用 2026-08-31 减去该日期。没有未还款期次时为 0 天。0~29 为 NORMAL,30~89 为 PRECAUTIONARY,90 或以上为 SUBSTANDARD。拨备 = int(outstanding × 比率/100)。
撰写存贷款验证报告
在 /root/bank/loan_report.md 中撰写报告,包含 ## Repayment comparison(还款方式比较)、## Deposit interest and tax(存款利息与税金)、## Overdue and classification(逾期与资产质量分类)、## What the system must keep(系统必须保留的内容)四个章节。
把 task 中的四个章节标题(反引号中的英文标题,或括号中意思相同的中文标题;韩文、日文标题也可以)分别写成以 ## 开头的一行。在还款方式比较章节中写入 L003 的总利息差额(interest_diff);在存款章节中写入税率(tax rate);在逾期章节中写出降为 SUBSTANDARD 的全部贷款编号,并用数字写明拨备(provision)总额。