• 住房贷款等额本息(等额本金)还款计划计算


    一、等额本息

    也就是本金+利息每月是相等的,即每月还款额是等额的。

    随着占用资金成本的减少所产生的每月利息也会对应减少,在每月还款额不变的情况下,每月需还款本金是递增的。

    计算步骤如下:

    1.按照推导公式优先计算每月还款额。

    每月还款额=(贷款本金月利率*(1+月利率)^还款月数))/((1+月利率)^还款月数-1)

    2.根据剩余本金计算当期利息。

    利息=剩余本金*月利率

    3.计算当期本金。

    本金=每月还款额-利息。

    4.最后一期使用倒推法先计算本金。

    本金=贷款金额-前期合计本金

    二、等额本金

    本金每月是等额的,随着占用资金成本的减少所产生的每月利息也会对应减少,在本金不变的情况下,每月还款额是逐月递减的。

    计算步骤如下:
    1.按照推导公式优先计算每月本金。
    本金=贷款金额/贷款期数
    2.根据剩余本金计算当期利息。
    利息=剩余本金*月利率
    3.计算每月还款额。
    每月还款额=本金+利息
    4.最后一期使用倒推法先计算本金。
    本金=贷款金额-前期合计本金
    5.计算最后一期利息。
    利息=剩余本金*月利率
    6.计算最后一期还款额。
    每月还款额=本金+利息

    三、代码实现

    计算工具类

    1. public class LoanCalculator {
    2. /**
    3. * 等额本息计算公式
    4. *
    5. * @param param - 贷款信息
    6. */
    7. public static Map calcEqCapitalAndInterest(Param param) {
    8. Map result = new TreeMap<>(Comparator.comparingInt(o -> o));
    9. // 总贷款期限
    10. int loanPeriods = param.getLoanPeriods();
    11. // 贷款月利率
    12. BigDecimal monthRate = param.getMonthRate();
    13. // 每月还款金额
    14. BigDecimal monthAmount = calMonthRepayment(param);
    15. // 剩余本金
    16. BigDecimal balance = param.getLoanAmount();
    17. // 出最后一期本金和
    18. BigDecimal noneLastCapitalTotal = BigDecimal.ZERO;
    19. Loan loan;
    20. LocalDate date = ObjectsUtil.isNull(param.getStartRepaymentDate()) ? LocalDate.now() : param.getStartRepaymentDate();// 还款日
    21. for (int i = 1; i <= loanPeriods; i++) {
    22. loan = new Loan().setPeriod(i).setAmount(monthAmount);// 每月还款金额
    23. loan.setInterest(calMonthInterest(balance, monthRate));// 利息=剩余本金*月利率
    24. loan.setCapital(monthAmount.subtract(loan.getInterest()));// 本金=每月还款额-利息
    25. loan.setCapitalBalance(balance = balance.subtract(loan.getCapital()));// 当期剩余本金
    26. loan.setRepaymentDate(date.plusMonths(i - 1));// 还款日
    27. result.put(i, loan);
    28. if (i != loanPeriods) {
    29. noneLastCapitalTotal = noneLastCapitalTotal.add(loan.getCapital());
    30. }
    31. }
    32. // 修正最后一期的数值
    33. Loan lastLoan = result.get(loanPeriods);
    34. lastLoan.setCapital(param.getLoanAmount().subtract(noneLastCapitalTotal));// 最后一期使用倒推法先计算本金,本金=贷款金额-前期合计本金。
    35. lastLoan.setInterest(monthAmount.subtract(lastLoan.getCapital()));// 计算最后一期利息,当期利息=每月还款额-本金。
    36. lastLoan.setCapitalBalance(BigDecimal.ZERO);// 最后一期剩余本金为零,剩余的全部加在最后一期本金计算利息
    37. return result;
    38. }
    39. /**
    40. * 等额本金计算公式
    41. *
    42. * @param param - 贷款信息
    43. */
    44. public static Map calcEqCapital(Param param) {
    45. Map result = new TreeMap<>(Comparator.comparingInt(o -> o));
    46. // 总贷款期限
    47. int loanPeriods = param.getLoanPeriods();
    48. // 贷款月利率
    49. BigDecimal monthRate = param.getMonthRate();
    50. // 每月还款本金
    51. BigDecimal monthCapital = calMonthCapital(param);
    52. // 剩余本金
    53. BigDecimal balance = param.getLoanAmount();
    54. Loan loan;
    55. LocalDate date = ObjectsUtil.isNull(param.getStartRepaymentDate()) ? LocalDate.now() : param.getStartRepaymentDate();// 还款日
    56. for (int i = 1; i <= loanPeriods; i++) {
    57. loan = new Loan().setPeriod(i).setCapital(monthCapital);// 本金
    58. loan.setInterest(calMonthInterest(balance, monthRate));// 利息=剩余本金*月利率
    59. loan.setAmount(loan.getCapital().add(loan.getInterest()));// 每月还款额=本金+利息
    60. loan.setCapitalBalance(balance = balance.subtract(monthCapital));// 当期剩余本金
    61. loan.setRepaymentDate(date.plusMonths(i - 1));// 还款日
    62. result.put(i, loan);
    63. }
    64. // 修正最后一期的数值
    65. Loan lastLoan = result.get(loanPeriods);
    66. lastLoan.setCapital(param.getLoanAmount().subtract(monthCapital.multiply(BigDecimal.valueOf(loanPeriods - 1))));// 最后一期使用倒推法先计算本金,本金=贷款金额-前期合计本金。
    67. lastLoan.setInterest(calMonthInterest(lastLoan.getCapital(), monthRate));// 计算最后一期利息,利息=剩余本金*月利率。
    68. lastLoan.setAmount(lastLoan.getCapital().add(lastLoan.getInterest()));// 计算最后一期还款额,每月还款额=本金+利息。
    69. lastLoan.setCapitalBalance(BigDecimal.ZERO);// 最后一期剩余本金为零,剩余的全部加在最后一期本金计算利息
    70. return result;
    71. }
    72. /**
    73. * 计算等额本息还款月供
    74. *
    75. * @param param 贷款信息包含贷款金额、年利率、期限
    76. * @return 等额本息还款月供
    77. */
    78. private static BigDecimal calMonthRepayment(Param param) {
    79. BigDecimal totalRate = param.getMonthRate().add(BigDecimal.ONE);
    80. return fromMetadata(param.getLoanAmount().multiply((param.getMonthRate().multiply(totalRate.pow(param.getLoanPeriods()))).divide(totalRate.pow(param.getLoanPeriods()).subtract(BigDecimal.ONE), RoundingMode.HALF_EVEN)), 2);
    81. }
    82. /**
    83. * 计算等额本金每月还款本金
    84. *
    85. * @param param 贷款信息包含贷款金额、年利率
    86. * @return 等额本金每月还款本金
    87. */
    88. private static BigDecimal calMonthCapital(Param param) {
    89. return fromMetadata(param.getLoanAmount().divide(new BigDecimal(param.getLoanPeriods()), 2, RoundingMode.HALF_EVEN), 2);
    90. }
    91. /**
    92. * 计算利息
    93. *
    94. * @param restCapital 剩余本金
    95. * @param monthRate 月利率
    96. * @return 当期利息
    97. */
    98. private static BigDecimal calMonthInterest(BigDecimal restCapital, BigDecimal monthRate) {
    99. return fromMetadata(restCapital.multiply(monthRate), 2);
    100. }
    101. /**
    102. * 银行家算法截取指定位数
    103. *
    104. * @param bigDecimal 待格式化数据
    105. * @param digit 截取位数
    106. */
    107. static BigDecimal fromMetadata(BigDecimal bigDecimal, int digit) {
    108. return bigDecimal.setScale(digit, RoundingMode.HALF_EVEN);
    109. }
    110. }

    辅助类

    1. /**
    2. * 贷款数据计算参数
    3. */
    4. @Getter
    5. @Setter
    6. public class Param {
    7. private final static BigDecimal monthTimes = new BigDecimal("12");
    8. /**
    9. * 贷款金额
    10. */
    11. private BigDecimal loanAmount;
    12. /**
    13. * 贷款年利率
    14. */
    15. private BigDecimal yearRate;
    16. /**
    17. * 贷款期限(月)
    18. */
    19. private int loanPeriods;
    20. /**
    21. * 首期还款日
    22. */
    23. private LocalDate startRepaymentDate = LocalDate.now();
    24. public BigDecimal getMonthRate() {
    25. return LoanCalculator.fromMetadata(yearRate.divide(monthTimes, 8, RoundingMode.HALF_EVEN), 8);
    26. }
    27. }
    1. /**
    2. * 贷款信息
    3. */
    4. @ToString
    5. @Getter
    6. @Setter
    7. @Accessors(chain = true)
    8. public class Loan implements Serializable {
    9. private static final long serialVersionUID = 1L;
    10. /**
    11. * 期数
    12. */
    13. private Integer period;
    14. /**
    15. * 还款日
    16. */
    17. private LocalDate repaymentDate;
    18. /**
    19. * 月还款金额
    20. */
    21. private BigDecimal amount;
    22. /**
    23. * 月还款本金
    24. */
    25. private BigDecimal capital;
    26. /**
    27. * 月还款利息
    28. */
    29. private BigDecimal interest;
    30. /**
    31. * 剩余应还本金
    32. */
    33. private BigDecimal capitalBalance;
    34. }

  • 相关阅读:
    ModStartCMS v4.9.0 用户注册IP,后台登录优化
    详解Java的static关键字
    SELF-INSTRUCT: Aligning Language Models with Self-Generated Instructions
    CAD Exchanger SDK for Win and Linux Crack
    Jmeter连接mysql数据库详细步骤
    【网络安全产品】---下一代防火墙
    Linux使用netstat查看网络状态
    招投标系统软件源码,招投标全流程在线化管理
    Redis Pipelining 底层原理分析及实践
    【24种设计模式】装饰器模式(Decorator Pattern(Wrapper))
  • 原文地址:https://blog.csdn.net/gengzhy/article/details/127455461