Number部分(6) Mortgage Calculator--按揭贷款计算器

题目描述:

Mortgage Calculator – Calculate the monthly payments of a fixed term mortgage over given Nth terms at a given interest rate. Also figure out how long it will take the user to pay back the loan.

题目翻译:

按揭贷款计算器——在给定利率下,计算固定期限按揭贷款在第N期的月还款。同时计算用户需要多长时间来偿还贷款。

按揭贷款的相关概念(Mortgage)

  1. 什么是按揭贷款
    抵押贷款是指提供私人资产作为债务担保进行借款,多发生于购买房地产时英航借出的抵押贷款。

  2. 抵押贷款的类型
    抵押贷款的类型有多种,主要通过一下几个因素来定义抵押贷款的类型。

    • 利率(interest) :分为固定利率和浮动利率
    • 期限(Term) :按揭贷款通常拥有最大还款期限
    • 还款数额与还款频率(Payment amount and frequency) :规定两次还款之间的时间间隔以及在每个周期内需要还款的数目
    • 预付款(PrePayment):贷款方提前支付的预付款
  3. 还款方式
    按揭贷款一般采用分期还款,在固定汇率的情况下,规定一个还款期限,然后每月按时还一定数额。
    常见的两种还款方式:等额本息还款和等额本金还款
    两种还款方案每月还款金额计算如下:
    假定贷款的年利率为r,还款年限为Y年,贷款本金为P,每月还款金额为A
    贷款的月利率\(R =r/12\), 还款期数为\(N=12Y\)

    • 等额本息还款:
      等额本息还款是指在还款时,每个月总的还款金额是相同的。每月所还本金和所还利息是变化的
      假定第t个还款月还款后,剩余的总还款金额为 \(p(t)\).

      \[\begin{aligned}&p(0)=P\\&p(1)=p(0)(1+R)-A=P(1+R)-A\\&p(2)=P(1)(1+R)-A=[P(1+R)-A](1+R)-A=P(1+R)^2-(1+R)A-A\\&...\\&p(t)=P(1+R)^t-A(1+R)^{t-1}-A(1+R)^{t-2}-...-A(1+R)-A\\\end{aligned}\]

      我们可以得到每月还款后剩余还款金额\(p(t)\)的表达式:

      \[\begin{aligned}p(t)&=P(1+R)^t-A\sum_{i=0}^{t-1}(1+R)^i\\&=P(1+R)^t-A\frac{1-(1+R)^t}{1-(1+R)}\\&=P(1+R)^t-A\frac{(1+R)^t-1}{R}\end{aligned}\]

      我们给定的还款期数为N,也就是说\(p(N)=0\),我们可以求出每月还款数额A。
      由方程

      \[\begin{aligned}P(n)=P(1+R)^N-A\frac{(1+R)^N-1}{R}=0\\\end{aligned}\]

      可以得到

      \[\begin{aligned}A&=\frac{PR(1+R)^N}{(1+R)^N-1}\\\end{aligned}\]

      也就是说,如果采用等额本息的方式来还款,每月需要还款的数额为\(\frac{PR(1+R)^N}{(1+R)^N-1}\)

      虽然每个月的还款数额相同,每月所还得利息和本金是变化的
      第t+1个还款月需要还的利息\(i(t+1)\),为该月还款前的剩余还款金额\(p(t)\)乘以月利率R

      \[\begin{aligned}i(t+1)&=p(t)R\\&=PR(1+R)^t-A(1+R)^t+A\\&=(PR-A)(1+R)^t+A\\&=((PR-A)(1+R)^{t-1}+A)(1+R)-A(1+R)+A\\&=i(t)(1+R)-AR\\\end{aligned}\]

      因为\((PR-A)<0\),所以\(i(t)\)是关于t的减函数,也就是说每个月的还款金额中,利息所占的比重是降低的,而本金所占的比重是上升的

    • 等额本金还款:
      在等额本金还款方式中,每个月还款的本金是相同,但是每个月所还的利息不同,所以每个月的还款总金额是变化的。
      每个月需要还得本金pr为总本金除以总的还款月数。

      \[\begin{aligned}pr = \frac{P}{N}\end{aligned}\]

      每个月需要还得利息\(pi(t)\) = (本金-已归还的本金之和)*每月利率

      \[\begin{aligned}pi(t)& = (P-pr(t-1))R\\&=-prAt+(A+P)R\\&=-\frac{PR}{N}t+(\frac{P}{N}+P)R\\\end{aligned}\]

      可以看到,每个月所还利息\(pi(t)\)是关于t的减函数,说明每个月所还的利息是逐渐减少的。由于每个月所还的本金数额不变,所以每个月所还贷款总额是递减的。

程序实现

用户输入贷款汇率,贷款总金额,还款的年限和选择的还款方式。
程序输出用户每个月需要还款的总金额以及需要偿还的本金和利息数额。

import java.util.Scanner;

public class MortgageCalculator{

    public static void mortgageCalcute(double P,double interest,int Y,int type){

        //输入参数贷款总额P,贷款利率interest,还款年限Y,还款类型type(0表示等额本息还款方式,1表示等额本金还款方式)
        switch(type){
            case 0:
                equalLoanPayment(P,interest,Y);
                break;
            case 1:
                equalPrincipalPayment(P,interest,Y);
                break;
        }
    }

    public static void equalLoanPayment(double P,double interest,int Y){ //等额本息还款计算函数
        int N = Y*12;
        double R = interest/12;
        double A = P*R*Math.pow(1+R,N)/(Math.pow(1+R,N)-1);
        System.out.printf("每月偿还的本息%7.2f\n",A*10000);
        double[] pi = new double[N];
        pi[0] = P*R;
        System.out.printf("第1个月需要偿还的利息:%8.2f  第1个月需要偿还的本金为:%7.2f\n",pi[0]*10000,(A-pi[0])*10000);
        for(int i=1;i<N;i++){
            pi[i] = pi[i-1]*(1+R)-A*R;
            System.out.printf("第%d个月需要偿还的利息:%7.2f  第%d个月需要偿还的本金为:%7.2f\n",i+1,pi[i]*10000,i+1,(A-pi[i])*10000);

        }

    }
    public static void equalPrincipalPayment(double P,double interest,int Y){ //等额本金还款计算函数

        int N = Y*12; //还款的总月份
        double R = interest/12; //还款的月利率
        double A = P*1.0/N; //每月需要还得本金
        System.out.printf("每月需要偿还的本金%7.2f\n",A*10000);
        double[] pi = new double[N+1];
        for(int i=1;i<=N;i++){
            pi[i] = -P*R*1.0/N*i+(P/N+P)*R;
            System.out.printf("第%d个月需要偿还的利息:%7.2f.第%d个月需要偿还的本息:%7.2f\n",i+1,pi[i]*10000,i+1,(pi[i]+A)*10000);
        }


    }
    public static void main(String[] args){
        //equalPrincipalPayment(45.4, 3.25/100, 15);
        Scanner sc = new Scanner(System.in);
        System.out.println("选择还款方式: 0 等额本息,1 等额本金");
        int PaymentType = sc.nextInt();
        System.out.println("输入还款总额(单位:万),还款年利率(百分数)与还款年限,用空格隔开");
        double Payment = sc.nextDouble();
        double interest = sc.nextDouble();
        int years = sc.nextInt();
        sc.close();
        System.out.println("还款总额:"+Payment+"还款年利率:"+interest+"% "+"还款年限:"+years+"年");
        mortgageCalcute(Payment,interest/100,years,PaymentType);
    }
}
11-10 06:52