按揭貸款的計算原理與java實現

sunfulv發表於2020-11-09

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);
    }
}

相關文章