讨论

贷款摊销规划器技能

来自 Wikiprompt,自由的提示词百科全书

Fatih Kadir Akın

2026年10月11日

贷款摊销规划器技能 贷款摊销规划器的完整技能定义,包括系统提示、工作流程、参考指南、模板、示例,以及一个经过测试的Python计算器,用于比较还款策略。

提示词内容收藏

🌐
--- name: loan-amortization-planner description: 构建固定利率贷款和抵押贷款的还款摊销计划,显示每笔还款中有多少用于支付利息,并比较不同的还款策略,如每月额外还款、一次性大额还款、更高的固定还款额或更短的期限,包括节省的利息、节省的月份、还清日期,以及在收取费用时的APR估算。当用户询问“我要付多少利息?”、“我应该多还房贷吗?”、“如果我每月多还200会怎样?”或想要汽车、学生、个人或住房贷款的还款计划时使用。包含一个经过测试的stdlib Python计算器。 --- # 贷款摊销规划器 你帮助人们了解贷款的真实成本,以及如何以适合他们预算的方式更快还清贷款。你精确计算数字,用通俗语言解释,并排比较现实可行的选项,并在任何人向贷款机构多付钱之前指出权衡取舍(应急储蓄、其他债务、提前还款规则)。 ## 此技能中的文件 - `scripts/amortize.py` - 固定利率贷款的月度摊销,支持每月额外还款、一次性大额还款、固定还款额、费用和APR估算、年度表格和CSV计划表(仅使用Python 3标准库) - `references/amortization-basics.md` - 摊销如何运作、公式,以及人们容易混淆的术语(利率与APR、期限与还清日期) - `references/prepayment-decision-guide.md` - 何时多还款有意义、贷款合同中需要检查什么,以及优先顺序 - `templates/loan-plan.md` - 要返回的报告 - `examples/example-mortgage-overpayment.md` - 抵押贷款三种多还款策略的完整比较示例 ## 工作流程 ### 1. 收集事实 询问,或假设并说明: - 尚欠金额(或借款金额)、利率、剩余期限,以及已知的当前每月还款额。 - 固定或浮动利率,以及固定期限何时结束。 - 费用:安排费或发起费,以及任何提前还款罚金或年度多还款限额。 - 用户能负担什么:每月额外金额、预期的奖金或一次性金额,以及他们的应急储蓄和其他债务。 - 目标:最低总利息、在某个日期前无债,或最低每月还款额。 ### 2. 运行基准方案 ```bash python3 scripts/amortize.py --principal 300000 --rate 4.5 --years 30 --start 2026-12 python3 scripts/amortize.py --principal 18500 --rate 7.9 --months 48 --fee 400 # 带费用的汽车贷款:APR估算 ``` 检查计算出的还款额与贷款机构的对账单在几分钱内一致。如果不一致,贷款可能有不同的计息天数、余额中包含费用,或还款中包含保险:询问,或使用实际金额配合 `--payment`。 ### 3. 运行情景 ```bash python3 scripts/amortize.py --principal 300000 --rate 4.5 --years 30 --extra 200 python3 scripts/amortize.py --principal 300000 --rate 4.5 --years 30 --lump 12:10000 --lump 24:10000 python3 scripts/amortize.py --principal 300000 --rate 4.5 --years 30 --payment 2000 --yearly python3 scripts/amortize.py --principal 300000 --rate 4.5 --years 20 # 更短期限 python3 scripts/amortize.py ... --schedule plan.csv --json ``` 比较2到4个用户真正能负担的选项。对每个选项,记录每月支出、还清日期、总利息、节省的利息和节省的月份。如果无法运行脚本,使用 `references/amortization-basics.md` 中的公式,并说明数字是近似值。 ### 4. 检查决策,而不仅仅是数学 浏览 `references/prepayment-decision-guide.md`:先应急基金,先高利率债务,提前还款罚金和限额,在当地检查税务影响,以及替代方案(储蓄或投资)的税后回报。永远不要把多还款说成总是正确的。 ### 5. 交付 填写 `templates/loan-plan.md`:一行说明贷款,基准方案,情景比较表,带理由的建议,要问贷款机构的问题,以及后续步骤。遵循 `examples/example-mortgage-overpayment.md` 的风格。 ## 规则 - 每个数字都显示货币并四舍五入到分;将估算标记为估算。 - 计算器假设固定利率、每月还款,额外还款立即用于本金且还款额不变(期限缩短)。要说明这一点,并标记浮动利率或贷款机构重新计算还款额的情况。 - 不提供个人投资或税务建议;解释权衡取舍,并告诉用户向贷款机构或许可顾问咨询什么。 - 如果还款连利息都不够,明确说明并停止:余额会增加。 - 保持解释简短具体:“每多还100可节省约120利息”胜过一段理论。 FILE:references/amortization-basics.md # 摊销基础 ## 固定利率贷款如何还清 每个月贷款机构对尚欠余额收取利息。你的还款首先覆盖该利息;其余部分减少余额(本金)。由于余额下降,利息部分每月减少,本金部分增加,而还款额保持不变。早期还款主要是利息;后期还款主要是本金。 ## 公式 - 月利率:r = 年利率 / 12(例如 4.5% -> 0.00375)。 - 贷款P在n个月内的还款额:M = P * r / (1 - (1 + r)^-n)。当 r = 0 时:M = P / n。 - 本月利息:余额 * r。本月本金:M - 利息。 - 总利息:利息部分之和,或近似 M * n - P。 - 以还款额M还清所需的月份:n = -ln(1 - P * r / M) / ln(1 + r)。如果 P * r >= M,贷款永远不会结束。 快速检查:200,000 按 6% 30年 -> 每月 1,199.10。300,000 按 4.5% 30年 -> 每月 1,520.06。 ## 为什么额外还款能节省这么多 额外还款立即减少余额,因此之后每个月都在较小的金额上计息。节省大约等于额外金额乘以它在贷款剩余期间本应承担的利息。这就是为什么贷款早期支付的款项比后期支付的相同款项节省更多。 ## 人们容易混淆的术语 | 术语 | 含义 | |---|---| | 名义利率 | 合同中的年利率,用于计算每月利息。 | | APR | 包括费用的年百分比率;用于比较报价。利率较低但费用较高的贷款可能有更高的APR。 | | 期限 | 计划的长度(例如30年)。 | | 还清日期 | 余额实际达到零的日期;有额外还款时更早。 | | 缩短期限 vs 降低还款额 | 多还款后,一些贷款机构保持还款额并缩短期限(节省更多利息),其他则重新计算较低的还款额。询问是哪种。 | | 本金 | 尚欠金额,不包括未来利息。 | | 摊销计划表 | 逐月的还款、利息、本金和余额表格。 | ## 四舍五入和小差异 贷款机构每月四舍五入到分,可能使用日利息(实际天数 / 365)而不是利率 / 12。结果可能每月相差几分钱,总利息相差几个单位。最后一笔还款通常吸收四舍五入差异。 ## 固定利率计算器的局限性 - 浮动或跟踪利率:在当前利率以及+1和+2个百分点下运行情景。 - 只付利息期、气球付款、还款假期:单独建模或手工计算。 - 每月还款中包含的保险、托管或账户费用不是利息;在比较前移除。 FILE:references/prepayment-decision-guide.md # 我应该更快还清贷款吗?决策指南 多还款贷款提供有保证的、无风险的“回报”,等于贷款的利率。这很好,但并不总是闲钱的最佳用途。按顺序完成以下步骤。 ## 1. 安全第一 - 应急基金:在多还款前,在易于取用的储蓄中保留约3到6个月的基本开支。寄给贷款机构的钱很难拿回来。 - 稳定收入:如果即将换工作、休产假或有大的开支,先积累现金。 ## 2. 先还最贵的债务 按利率对债务排序(雪崩法):信用卡和透支,然后是个人和汽车贷款,然后是学生贷款和抵押贷款。先多还最高利率的债务。如果动力是问题,先还最小余额(滚雪球法)也可以,但要说明其成本。 ## 3. 阅读合同 - 提前还款罚金或提前还款费用(通常是多还金额的百分比,主要在固定利率期间)。 - 年度多还款额度(例如每年余额的10%免手续费)。 - 多还款是缩短期限还是降低还款额?你能选择吗? - 最低多还款金额以及如何进行(在线、电话、书面指示)。 ## 4. 与替代方案比较 - 雇主的退休金匹配通常优于任何多还款:先拿满匹配。 - 将贷款利率与储蓄能获得的税后、费后回报比较。2%的抵押贷款对比4%的储蓄账户:储蓄在纸面上胜出。7%的汽车贷款对比3%的储蓄账户:多还款胜出。 - 长期来看,投资可能跑赢低利率贷款,但带有风险;多还款的回报是确定的。 - 税务:在一些国家,抵押贷款利息可以抵税,这降低了实际利率。在当地检查;不要假设。 ## 5. 选择策略 | 策略 | 何时适用 | |---|---| | 每月固定额外还款 | 收入稳定;养成习惯;如果尽早开始,相同总额下节省最多。 | | 一次性大额还款(奖金、退税) | 收入不稳定;全年保持灵活性。 | | 更高的固定还款额 | 想要明确的还清日期。 | | 再融资到更短期限 | 有更低利率且更高还款额可负担;比较费用。 | | 保留现金,稍后多还款 | 固定期限即将结束(之后多还款无罚金),或应急基金未满。 | ## 6. 审查 每年、利率变化或收入变化时重新计算数字。提醒用户多还款总是可以暂停;更高的合同还款额通常不能。 FILE:templates/loan-plan.md # 贷款计划:${loan_name} **贷款:** ${balance} 按 ${rate}%(${fixed_or_variable}),剩余 ${remaining_term},每月还款 ${payment},本计划首笔还款 ${start_month} **费用和规则:** ${fees};提前还款限额或罚金:${prepayment_rules} **目标:** ${goal} **额外还款预算:** ${extra_budget} ## 基准方案 - 每月还款: - 从现在起的总利息: - 还清日期: - 首笔还款分配:利息 ... / 本金 ... ## 情景 | 选项 | 每月支出 | 还清日期 | 总利息 | 节省利息 | 节省月份 | |---|---|---|---|---|---| | 基准方案 | | | | - | - | | A: | | | | | | | B: | | | | | | | C: | | | | | | ## 建议 选项 ... 因为: 1. 2. 3. 需要记住的权衡取舍: ## 多还款前 - [ ] 应急基金覆盖 ... 个月 - [ ] 没有更高利率的债务剩余(或优先处理) - [ ] 已向贷款机构确认提前还款罚金/额度 - [ ] 多还款设置为缩短期限(或降低还款额,如果偏好) ## 要问贷款机构的问题 1. 2. ## 后续步骤 1. 2. *假设:固定利率、每月还款、额外还款立即用于本金。这些是估算,不是财务建议。* FILE:examples/example-mortgage-overpayment.md # 示例:比较三种抵押贷款多还款策略 ## 用户请求 “我们的抵押贷款还剩320,000,固定利率4.1%,还有25年,本计划首笔还款在2026年12月。我们可以每月多还约300,或者未来三年每年获得15,000奖金。一个朋友说我们应该直接改为每月2,400。什么最好?我们有6个月的开支储蓄,没有其他债务。银行允许每年多还10%免手续费。” ## 命令 ```bash python3 scripts/amortize.py --principal 320000 --rate 4.1 --years 25 --start 2026-12 python3 scripts/amortize.py --principal 320000 --rate 4.1 --years 25 --start 2026-12 --extra 300 python3 scripts/amortize.py --principal 320000 --rate 4.1 --years 25 --start 2026-12 --lump 12:15000 --lump 24:15000 --lump 36:15000 python3 scripts/amortize.py --principal 320000 --rate 4.1 --years 25 --start 2026-12 --payment 2400 ``` 输出(缩短): ``` 基准方案:每月 1,706.80,利息 192,038.38,总支付 512,038.38,还清于 2051-11(300次还款) 计划(+300.00/月):还清于 2046-02(231次还款),利息 143,068.39 节省 48,969.99 利息和 69 个月(5年9个月);每多还100节省 70.97 计划(第12次还款一次性15,000.00,第24次还款15,000.00,第36次还款15,000.00):还清于 2046-11(240次还款),利息 133,018.73 节省 59,019.65 利息和 60 个月(5年0个月);每多还100节省 131.15 计划(固定还款 2,400.00):还清于 2041-10(179次还款),利息 107,805.37 节省 84,233.01 利息和 121 个月(10年1个月) ``` ## 贷款计划(填好的模板,缩短) **贷款:** 320,000.00 按 4.1% 固定利率,剩余25年,每月还款 1,706.80,首笔还款2026年12月 **费用和规则:** 每年多还余额的10%以内免费 **目标:** 在不失去灵活性的情况下减少利息 | 选项 | 每月支出 | 还清日期 | 总利息 | 节省利息 | 节省月份 | |---|---|---|---|---|---| | 基准方案 | 1,706.80 | 2051-11 | 192,038.38 | - | - | | A:每月+300 | 2,006.80 | 2046-02 | 143,068.39 | 48,969.99 | 69 | | B:第1至3年15,000奖金 | 1,706.80 + 总计45,000 | 2046-11 | 133,018.73 | 59,019.65 | 60 | | C:固定每月2,400 | 2,400.00 | 2041-10 | 107,805.37 | 84,233.01 | 121 | **建议:** 选项B,如果预算允许再加A。奖金在贷款早期支付,因此每多还100节省约131利息,几乎是月度计划的两倍(每100约71,因为大部分钱在后期支付)。它不需要改变每月预算,每次15,000都在免费10%额度内(第1年32,000)。选项C节省最多,因为它在15年内多付约124,000,但它将固定支出每月提高693;只有在你舒适地负担得起时才这样做,并将其设置为自愿多还款而不是新的合同还款额,以便可以暂停。 **权衡取舍:** 多付的钱很难拿回来;保持6个月应急基金不动。如果你的储蓄账户税后收益超过4.1%,储蓄可能在纸面上胜过多还款;在当地检查利率和任何税务规则。 **要问贷款机构的问题:** 1. 多还款会缩短期限且还款额不变(如上假设),还是重新计算还款额? 2. 10%额度是按日历年还是按贷款年度重置? *假设:整个期限固定利率、每月还款、多还款立即用于本金。估算,不是财务建议。* FILE:scripts/amortize.py #!/usr/bin/env python3 """固定利率贷款摊销,支持额外还款和情景比较。 用法: python3 amortize.py --principal 250000 --rate 4.2 --years 30 [选项] python3 amortize.py --principal 18000 --rate 7.9 --months 60 --extra 150 选项: --principal N 借款金额(必填) --rate PCT 名义年利率百分比,例如 4.2(必填;允许0) --years N | --months N 期限(两者之一必填) --start YYYY-MM 首笔还款月份(默认:下个月) --extra N 每笔每月还款中增加的额外金额 --extra-from N --extra 开始的还款编号(默认 1) --lump N:AMOUNT 第N次还款中的一次性额外还款(可重复) --payment N 支付此固定每月金额而不是计算出的金额 --fee N 一次性前期费用,用于成本和APR估算 --schedule FILE 将完整月度计划表写入CSV --yearly 打印逐年表格 --json 以JSON格式打印结果 额外还款假设立即减少本金,无提前还款罚金,且每月还款额不变(期限缩短)。利率为名义年利率,按月复利(每月利率 / 12)。每月金额四舍五入到分。 退出代码:0 正常,2 用法或输入错误。仅使用Python 3标准库。 """ import argparse import csv import datetime as dt import json import sys def monthly_payment(principal, annual_rate, n): r = annual_rate / 100 / 12 if r == 0: return principal / n return principal * r / (1 - (1 + r) ** -n) def add_months(ym, k): y, m = ym m0 = m - 1 + k return (y + m0 // 12, m0 % 12 + 1) def schedule(principal, annual_rate, n, payment=None, extra=0.0, extra_from=1, lumps=None): r = annual_rate / 100 / 12 base = round(payment if payment else monthly_payment(principal, annual_rate, n), 2) lumps = lumps or {} bal = round(principal, 2) rows = [] k = 0 while bal > 0.005: k += 1 if k > 1200: raise ValueError("贷款在100年内未还清;还款额对利息来说太小") interest = round(bal * r, 2) if base + (extra if k >= extra_from else 0) <= interest and not lumps.get(k): raise ValueError(f"还款 {base:.2f} 不足以覆盖每月利息 {interest:.2f};余额会增加") sched = min(base, bal + interest) if payment is None and k == n: sched = bal + interest # 最后一次计划还款吸收四舍五入差异 ext = min(extra if k >= extra_from else 0.0, max(bal + interest - sched, 0)) lump = min(lumps.get(k, 0.0), max(bal + interest - sched - ext, 0)) principal_paid = round(sched + ext + lump - interest, 2) bal = round(bal - principal_paid, 2) rows.append({"n": k, "payment": round(sched, 2), "extra": round(ext + lump, 2), "interest": interest, "principal": principal_paid, "balance": max(bal, 0.0)}) return base, rows def summarize(rows): return {"months": len(rows), "total_interest": round(sum(x["interest"] for x in rows), 2), "total_paid": round(sum(x["payment"] + x["extra"] for x in rows), 2), "total_extra": round(sum(x["extra"] for x in rows), 2)} def apr_estimate(principal, fee, payment, n): """使还款现值等于本金减去费用的年利率(二分法)。""" target = principal - fee lo, hi = 0.0, 1.0 for _ in range(100): mid = (lo + hi) / 2 r = mid / 12 pv = payment * n if r == 0 else payment * (1 - (1 + r) ** -n) / r lo, hi = (mid, hi) if pv > target else (lo, mid) return round(lo * 100, 3) def fmt_ym(ym): return f"{ym[0]:04d}-{ym[1]:02d}" def main(argv): p = argparse.ArgumentParser(add_help=True, description="带额外还款的贷款摊销") p.add_argument("--principal", type=float, required=True) p.add_argument("--rate", type=float, required=True) g = p.add_mutually_exclusive_group(required=True) g.add_argument("--years", type=float) g.add_argument("--months", type=int) p.add_argument("--start") p.add_argument("--extra", type=float, default=0.0) p.add_argument("--extra-from", type=int, default=1) p.add_argument("--lump", action="append", default=[]) p.add_argument("--payment", type=float) p.add_argument("--fee", type=float, default=0.0) p.add_argument("--schedule") p.add_argument("--yearly", action="store_true") p.add_argument("--json", action="store_true") try: a = p.parse_args(argv) except SystemExit as e: return 0 if e.code == 0 else 2 try: n = a.months if a.months else round(a.years * 12) if a.principal <= 0 or n <= 0 or a.rate < 0 or a.extra < 0 or a.fee < 0: raise ValueError("本金和期限必须为正;利率、额外还款和费用不能为负") if a.rate > 100: raise ValueError("利率以年百分比表示,例如 4.2 表示 4.2%") lumps = {} for item in a.lump: num, _, amt = item.partition(":") try: if not num.isdigit(): raise ValueError value = float(amt) except ValueError: raise ValueError(f"--lump 必须形如 24:5000(还款编号:金额),得到 {item!r}") from None lumps[int(num)] = lumps.get(int(num), 0.0) + value if a.start: try: y, m = a.start.split("-") start = (int(y), int(m)) except ValueError: raise ValueError(f"--start 必须形如 2026-11,得到 {a.start!r}") from None if not 1 <= start[1] <= 12: raise ValueError("--start 月份必须在 01 到 12 之间") else: t = dt.date.today() start = add_months((t.year, t.month), 1) base_pay, base_rows = schedule(a.principal, a.rate, n, payment=None) scenario = bool(a.extra or lumps or a.payment) pay, rows = schedule(a.principal, a.rate, n, payment=a.payment, extra=a.extra, extra_from=a.extra_from, lumps=lumps) if scenario else (base_pay, base_rows) except ValueError as e: print(f"错误:{e}", file=sys.stderr) return 2 base_sum, plan_sum = summarize(base_rows), summarize(rows) result = { "inputs": {"principal": a.principal, "annual_rate_pct": a.rate, "term_months": n, "first_payment": fmt_ym(start), "extra_monthly": a.extra, "extra_from_payment": a.extra_from, "lumps": lumps, "fixed_payment": a.payment, "fees": a.fee}, "baseline": {"monthly_payment": base_pay, **base_sum, "payoff": fmt_ym(add_months(start, base_sum["months"] - 1))}, } if a.fee: result["baseline"]["apr_estimate_pct"] = apr_estimate(a.principal, a.fee, base_pay, n) result["baseline"]["total_cost_incl_fees"] = round(base_sum["total_interest"] + a.fee, 2) if scenario: result["plan"] = {"monthly_payment": pay, **plan_sum, "payoff": fmt_ym(add_months(start, plan_sum["months"] - 1)), "months_saved": base_sum["months"] - plan_sum["months"], "interest_saved": round(base_sum["total_interest"] - plan_sum["total_interest"], 2)} if plan_sum["total_extra"]: result["plan"]["interest_saved_per_100_extra"] = round(100 * result["plan"]["interest_saved"] / plan_sum["total_extra"], 2) yearly = [] for i in range(0, len(rows), 12): chunk = rows[i:i + 12] yearly.append({"year": i // 12 + 1, "paid": round(sum(x["payment"] + x["extra"] for x in chunk), 2), "interest": round(sum(x["interest"] for x in chunk), 2), "principal": round(sum(x["principal"] for x in chunk), 2), "end_balance": chunk[-1]["balance"]}) result["yearly"] = yearly first = base_rows[0] result["baseline"]["first_payment_split"] = {"interest": first["interest"], "principal": first["principal"]} if a.schedule: try: with open(a.schedule, "w", newline="", encoding="utf-8") as f: w = csv.writer(f) w.writerow(["n", "month", "payment", "extra", "interest", "principal", "balance"]) for x in rows: w.writerow([x["n"], fmt_ym(add_months(start, x["n"] - 1)), f"{x['payment']:.2f}", f"{x['extra']:.2f}", f"{x['interest']:.2f}", f"{x['principal']:.2f}", f"{x['balance']:.2f}"]) except OSError as e: print(f"错误:无法写入计划表 {a.schedule}:{e.strerror}", file=sys.stderr) return 2 if a.json: print(json.dumps(result, indent=2)) return 0 b = result["baseline"] print(f"贷款 {a.principal:,.2f} 按 {a.rate}% 期限 {n} 个月,首笔还款 {fmt_ym(start)}") print(f"基准方案:每月 {b['monthly_payment']:,.2f},利息 {b['total_interest']:,.2f}," f"总支付 {b['total_paid']:,.2f},还清于 {b['payoff']}({b['months']}次还款)") if a.fee: print(f" 含费用 {a.fee:,.2f}:借款总成本 {b['total_cost_incl_fees']:,.2f},APR 约 {b['apr_estimate_pct']}%") print(f" 首笔还款:{first['interest']:,.2f} 利息,{first['principal']:,.2f} 本金") if scenario: pl = result["plan"] what = [] if a.payment: what.append(f"固定还款 {a.payment:,.2f}") if a.extra: what.append(f"+{a.extra:,.2f}/月" + (f" 从第 {a.extra_from} 次还款开始" if a.extra_from > 1 else "")) if lumps: what.append("一次性还款 " + ", ".join(f"第{k}次还款 {v:,.2f}" for k, v in sorted(lumps.items()))) print(f"计划({'; '.join(what)}):还清于 {pl['payoff']}({pl['months']}次还款)," f"利息 {pl['total_interest']:,.2f}") ms = pl["months_saved"] if ms >= 0 and pl["interest_saved"] >= 0: print(f" 节省 {pl['interest_saved']:,.2f} 利息和 {ms} 个月({ms // 12}年{ms % 12}个月)" + (f";每多还100节省 {pl['interest_saved_per_100_extra']:,.2f}" if pl.get("interest_saved_per_100_extra") else "")) else: print(f" 警告:此计划比基准方案多花费 {-pl['interest_saved']:,.2f} 利息,且多花 {-ms} 个月") if a.yearly: print(f"\n逐年({'计划' if scenario else '基准方案'}):") print(f"{'年份':>4} {'已支付':>12} {'利息':>12} {'本金':>12} {'余额':>12}") for y in yearly: print(f"{y['year']:>4} {y['paid']:>12,.2f} {y['interest']:>12,.2f} {y['principal']:>12,.2f} {y['end_balance']:>12,.2f}") if a.schedule: print(f"\n计划表已写入 {a.schedule}({len(rows)} 行)") return 0 if __name__ == "__main__": sys.exit(main(sys.argv[1:]))

登录以查看完整提示词

继续使用:

登录即表示你同意我们的 使用条款 和 隐私政策

用法

此提示词专为 personal 设计。复制上方内容并粘贴到你常用的 AI 工具中。

为获得最佳效果,可将占位符(方括号或大写字母标示)替换为你的具体需求。

参考资料

分类:personal| prompts.chat| loan-amortization| mortgage-calculator

讨论