貸款計算公式——java實現

廢話說在前頭,本人公司作銀行APP,每次寫到貸款計算器老是一遍又一遍研究計算公式。N次事後,仍是決定寫一篇blog分享給你們。html

注:利率一概按照4.9計算。全部計算結果參照在線貸款計算公式java

等額本息

每個月還款本金+利息同樣。
貸款本金100萬,貸款期限30年,貸款利息91萬元(近似值),那麼月供191萬元/360月。測試

/**
     * 計算等額本息還款
     *
     * @param principal 貸款總額
     * @param months    貸款期限
     * @param rate      貸款利率
     * @return
     */
    public static String[] calculateEqualPrincipalAndInterest(double principal, int months, double rate) {
        ArrayList<String> data = new ArrayList<String>();
        double monthRate = rate / (100 * 12);//月利率
        double preLoan = (principal * monthRate * Math.pow((1 + monthRate), months)) / (Math.pow((1 + monthRate), months) - 1);//每個月還款金額
        double totalMoney = preLoan * months;//還款總額
        double interest = totalMoney - principal;//還款總利息
        data.add(FORMAT.format(totalMoney));//還款總額
        data.add(FORMAT.format(principal));//貸款總額
        data.add(FORMAT.format(interest));//還款總利息
        data.add(FORMAT.format(preLoan));//每個月還款金額
        data.add(String.valueOf(months));//還款期限
        return data.toArray(new String[data.size()]);
    }

運行結果:spa

這裏寫圖片描述

在線計算結果:
這裏寫圖片描述.net

等額本金

貸款本金100萬,貸款期限30年。每個月還款本金=100萬/360月,每個月還款利息=剩餘貸款金額*月利率。因此每個月利息遞減。3d

/**
     * 計算等額本金還款
     *
     * @param principal 貸款總額
     * @param months    貸款期限
     * @param rate      貸款利率
     * @return
     */
    public static String[] calculateEqualPrincipal(double principal, int months, double rate) {
        ArrayList<String> data = new ArrayList<String>();
        double monthRate = rate / (100 * 12);//月利率
        double prePrincipal = principal / months;//每個月還款本金
        double firstMonth = prePrincipal + principal * monthRate;//第一個月還款金額
        double decreaseMonth = prePrincipal * monthRate;//每個月利息遞減
        double interest = (months + 1) * principal * monthRate / 2;//還款總利息
        double totalMoney = principal + interest;//還款總額
        data.add(FORMAT.format(totalMoney));//還款總額
        data.add(FORMAT.format(principal));//貸款總額
        data.add(FORMAT.format(interest));//還款總利息
        data.add(FORMAT.format(firstMonth));//首月還款金額
        data.add(FORMAT.format(decreaseMonth));//每個月遞減利息
        data.add(String.valueOf(months));//還款期限
        return data.toArray(new String[data.size()]);
    }

運行結果:rest

這裏寫圖片描述

在線計算結果:code

這裏寫圖片描述

提早還款

當客戶有足夠的錢償還貸款本金時,能夠向銀行申請提早還款。orm

所有提早還款

一次性結清貸款htm

等額本息

扣除以前每個月還款的本金(前期還款時,利息佔月供很大的比例),剩餘貸款金額加上一個月利息即支付金額。

/**
     * 一次性提早還款計算(等額本息)
     *
     * @param principal 貸款總額
     * @param months    貸款期限
     * @param payTimes  已還次數
     * @param rate      貸款利率
     * @return
     */
    public static String[] calculateEqualPrincipalAndInterest(double principal, int months, int payTimes, double rate) {
        ArrayList<String> data = new ArrayList<String>();
        double monthRate = rate / (100 * 12);//月利率
        double preLoan = (principal * monthRate * Math.pow((1 + monthRate), months)) / (Math.pow((1 + monthRate), months) - 1);//每個月還款金額
        double totalMoney = preLoan * months;//還款總額
        double interest = totalMoney - principal;//還款總利息
        double leftLoan = principal * Math.pow(1 + monthRate, payTimes) - preLoan * (Math.pow(1 + monthRate, payTimes) - 1) / monthRate;//n個月後欠銀行的錢
        double payLoan = principal - leftLoan;//已還本金
        double payTotal = preLoan * payTimes;//已還總金額
        double payInterest = payTotal - payLoan;//已還利息
        double totalPayAhead = leftLoan * (1 + monthRate);//剩餘一次還清
        double saveInterest = totalMoney - payTotal - totalPayAhead;
        data.add(FORMAT.format(totalMoney));//原還款總額
        data.add(FORMAT.format(principal));//貸款總額
        data.add(FORMAT.format(interest));//原還款總利息
        data.add(FORMAT.format(preLoan));//原還每個月還款金額
        data.add(FORMAT.format(payTotal));//已還總金額
        data.add(FORMAT.format(payLoan));//已還本金
        data.add(FORMAT.format(payInterest));//已還利息
        data.add(FORMAT.format(totalPayAhead));//一次還清支付金額
        data.add(FORMAT.format(saveInterest));//節省利息
        data.add(String.valueOf(0));//剩餘還款期限
        return data.toArray(new String[data.size()]);
    }

已還款10次,運行結果:

這裏寫圖片描述

在線計算運行結果:
這裏寫圖片描述

由此能夠看出,前10次還款,扣除本金只佔20%左右。

等額本金

/**
     * 一次性提早還款計算(等額本金)
     *
     * @param principal 貸款總額
     * @param months    貸款期限
     * @param payTimes  已還次數
     * @param rate      貸款利率
     * @return
     */
    public static String[] calculateEqualPrincipal(double principal, int months, int payTimes, double rate) {
        ArrayList<String> data = new ArrayList<String>();
        double monthRate = rate / (100 * 12);//月利率
        double prePrincipal = principal / months;//每個月還款本金
        double firstMonth = prePrincipal + principal * monthRate;//第一個月還款金額
        double decreaseMonth = prePrincipal * monthRate;//每個月利息遞減
        double interest = (months + 1) * principal * monthRate / 2;//還款總利息
        double totalMoney = principal + interest;//還款總額
        double payLoan = prePrincipal * payTimes;//已還本金
        double payInterest = (principal * payTimes - prePrincipal * (payTimes - 1) * payTimes / 2) * monthRate;//已還利息
        double payTotal = payLoan + payInterest;//已還總額
        double totalPayAhead = (principal - payLoan) * (1 + monthRate);//提早還款金額(剩餘本金加上剩餘本金當月利息)
        double saveInterest = totalMoney - payTotal - totalPayAhead;
        data.add(FORMAT.format(totalMoney));//原還款總額
        data.add(FORMAT.format(principal));//貸款總額
        data.add(FORMAT.format(interest));//原還款總利息
        data.add(FORMAT.format(firstMonth));//原首月還款金額
        data.add(FORMAT.format(decreaseMonth));//原每個月遞減利息
        data.add(FORMAT.format(payTotal));//已還總金額
        data.add(FORMAT.format(payLoan));//已還本金
        data.add(FORMAT.format(payInterest));//已還利息
        data.add(FORMAT.format(totalPayAhead));//一次還清支付金額
        data.add(FORMAT.format(saveInterest));//節省利息
        data.add(String.valueOf(0));//剩餘還款期限
        return data.toArray(new String[data.size()]);
    }

已還款10次,運行結果:
這裏寫圖片描述

在線計算運行結果:
這裏寫圖片描述

對比等額本息,已償還本金佔還款金額30%左右。

部分提早還款

保持月供不變

等額本息

/**
     * 部分提早還款計算(等額本息、月供不變)
     *
     * @param principal      貸款總額
     * @param months         貸款期限
     * @param aheadPrincipal 提早還款金額
     * @param payTimes       已還次數
     * @param rate           貸款利率
     * @return
     */
    public static String[] calculateEqualPrincipalAndInterestApart(double principal, int months, double aheadPrincipal, int payTimes, double rate) {
        ArrayList<String> data = new ArrayList<String>();
        double monthRate = rate / (100 * 12);//月利率
        double preLoan = (principal * monthRate * Math.pow((1 + monthRate), months)) / (Math.pow((1 + monthRate), months) - 1);//每個月還款金額
        double totalMoney = preLoan * months;//還款總額
        double interest = totalMoney - principal;//還款總利息
        double leftLoanBefore = principal * Math.pow(1 + monthRate, payTimes) - preLoan * (Math.pow(1 + monthRate, payTimes) - 1) / monthRate;//提早還款前欠銀行的錢
        double leftLoan = principal * Math.pow(1 + monthRate, payTimes + 1) - preLoan * (Math.pow(1 + monthRate, payTimes + 1) - 1) / monthRate-aheadPrincipal;//提早還款後欠銀行的錢
        double payLoan = principal - leftLoanBefore;//已還本金
        double payTotal = preLoan * payTimes ;//已還總金額
        double payInterest = payTotal - payLoan;//已還利息
        double aheadTotalMoney = aheadPrincipal + preLoan;//提早還款總額
        //計算剩餘還款期限
        int leftMonth = (int) Math.floor(Math.log(preLoan / (preLoan - leftLoan * monthRate)) / Math.log(1 + monthRate));
        double newPreLoan = (leftLoan * monthRate * Math.pow((1 + monthRate), leftMonth)) / (Math.pow((1 + monthRate), leftMonth) - 1);//剩餘貸款每個月還款金額
        double leftTotalMoney = newPreLoan * leftMonth;//剩餘還款總額
        double leftInterest = leftTotalMoney - (leftLoan-aheadPrincipal);
        double saveInterest = totalMoney - aheadTotalMoney - leftTotalMoney-payTotal;
        data.add(FORMAT.format(totalMoney));//原還款總額
        data.add(FORMAT.format(principal));//貸款總額
        data.add(FORMAT.format(interest));//原還款總利息
        data.add(FORMAT.format(preLoan));//原還每個月還款金額
        data.add(FORMAT.format(payTotal));//已還總金額
        data.add(FORMAT.format(payLoan));//已還本金
        data.add(FORMAT.format(payInterest));//已還利息
        data.add(FORMAT.format(aheadTotalMoney));//提早還款總額
        data.add(FORMAT.format(leftTotalMoney));//剩餘還款總額
        data.add(FORMAT.format(leftInterest));//剩餘還款總利息
        data.add(FORMAT.format(newPreLoan));//剩餘每個月還款金額
        data.add(FORMAT.format(saveInterest));//節省利息
        data.add(String.valueOf(leftMonth));//剩餘還款期限
        return data.toArray(new String[data.size()]);
    }

貸款100萬,提早還款50萬。首次還款:17年8月,提早還款:18年6月。已還次數10次是截止到18年5月。剩餘貸款,保持月供不變(大體維持不變),後續需還款114期(9年零6月),因此提早還款後還款日期:18年7月~27年12月。

運行結果:

這裏寫圖片描述

在線計算結果:(這裏有1個月的偏差

這裏寫圖片描述

等額本金

/**
     *  部分提早還款計算(等額本金、月供不變)
     * @param principal      貸款總額
     * @param months         貸款期限
     * @param aheadPrincipal 提早還款金額
     * @param payTimes       已還次數
     * @param rate           貸款利率
     * @return
     */
    public static String[] calculateEqualPrincipalApart(double principal, int months, double aheadPrincipal, int payTimes, double rate) {
        ArrayList<String> data = new ArrayList<String>();
        double monthRate = rate / (100 * 12);//月利率
        double prePrincipal = principal / months;//每個月還款本金
        double firstMonth = prePrincipal + principal * monthRate;//第一個月還款金額
        double decreaseMonth = prePrincipal * monthRate;//每個月利息遞減
        double interest = (months + 1) * principal * monthRate / 2;//還款總利息
        double totalMoney = principal + interest;//還款總額
        double payLoan = prePrincipal * payTimes;//已還本金
        double payInterest = (principal * payTimes - prePrincipal * (payTimes - 1) * payTimes / 2) * monthRate;//已還利息
        double payTotal = payLoan + payInterest;//已還總額
        double aheadTotalMoney = (principal - payLoan) *  monthRate+aheadPrincipal+prePrincipal;//提早還款金額
        double leftLoan = principal - aheadPrincipal - payLoan-prePrincipal;//剩餘金額
        int leftMonth = (int) Math.floor(leftLoan / prePrincipal);
        double newPrePrincipal = leftLoan / leftMonth;//新的每個月還款本金
        double newFirstMonth = newPrePrincipal + leftLoan * monthRate;//新的第一個月還款金額
        double newDecreaseMonth = newPrePrincipal * monthRate;//新的每個月利息遞減
        double leftInterest = (leftMonth + 1) * leftLoan * monthRate / 2;//還款總利息
        double leftTotalMoney = leftLoan + leftInterest;//還款總額
        double saveInterest = totalMoney-payTotal-aheadTotalMoney-leftTotalMoney;
        data.add(FORMAT.format(totalMoney));//原還款總額
        data.add(FORMAT.format(principal));//貸款總額
        data.add(FORMAT.format(interest));//原還款總利息
        data.add(FORMAT.format(firstMonth));//原還首月還款金額
        data.add(FORMAT.format(decreaseMonth));//原每個月遞減利息
        data.add(FORMAT.format(payTotal));//已還總金額
        data.add(FORMAT.format(payLoan));//已還本金
        data.add(FORMAT.format(payInterest));//已還利息
        data.add(FORMAT.format(aheadTotalMoney));//提早還款總額
        data.add(FORMAT.format(leftTotalMoney));//剩餘還款總額
        data.add(FORMAT.format(leftInterest));//剩餘還款總利息
        data.add(FORMAT.format(newFirstMonth));//剩餘首月還款金額
        data.add(FORMAT.format(newDecreaseMonth));//剩餘月遞減利息
        data.add(FORMAT.format(saveInterest));//節省利息
        data.add(String.valueOf(leftMonth));//剩餘還款期限
        return data.toArray(new String[data.size()]);
    }

貸款100萬,還款10期後,提早還款50萬。

運行結果:

這裏寫圖片描述

在線計算結果:

這裏寫圖片描述

保持期數不變

等額本息

/**
     * 部分提早還款計算(等額本息、期限不變)
     * @param principal      貸款總額
     * @param months         貸款期限
     * @param aheadPrincipal 提早還款金額
     * @param payTimes       已還次數
     * @param rate           貸款利率
     * @return
     */
    public static String[] calculateEqualPrincipalAndInterestApart2(double principal, int months, double aheadPrincipal, int payTimes, double rate) {
        ArrayList<String> data = new ArrayList<String>();
        double monthRate = rate / (100 * 12);//月利率
        double preLoan = (principal * monthRate * Math.pow((1 + monthRate), months)) / (Math.pow((1 + monthRate), months) - 1);//每個月還款金額
        double totalMoney = preLoan * months;//還款總額
        double interest = totalMoney - principal;//還款總利息
        double leftLoanBefore = principal * Math.pow(1 + monthRate, payTimes ) - preLoan * (Math.pow(1 + monthRate, payTimes ) - 1) / monthRate;//提早還款前欠銀行的錢
        double leftLoan = principal * Math.pow(1 + monthRate, payTimes + 1) - preLoan * (Math.pow(1 + monthRate, payTimes + 1) - 1) / monthRate;//提早還款後銀行的錢
        double payLoan = principal - leftLoanBefore;//已還本金
        double payTotal = preLoan * payTimes;//已還總金額
        double payInterest = payTotal - payLoan;//已還利息
        double aheadTotalMoney = preLoan + aheadPrincipal;//下個月還款金額
        double newPreLoan = ((leftLoan - aheadPrincipal) * monthRate * Math.pow((1 + monthRate), months - payTimes - 1)) / (Math.pow((1 + monthRate), months - payTimes - 1) - 1);//下個月起每個月還款金額
        double leftTotalMoney = newPreLoan*(months-payTimes);
        double leftInterest =leftTotalMoney -(leftLoan - aheadPrincipal);
        double saveInterest = totalMoney-payTotal-aheadTotalMoney-leftTotalMoney;
        data.add(FORMAT.format(totalMoney));//原還款總額
        data.add(FORMAT.format(principal));//貸款總額
        data.add(FORMAT.format(interest));//原還款總利息
        data.add(FORMAT.format(preLoan));//原還每個月還款金額
        data.add(FORMAT.format(payTotal));//已還總金額
        data.add(FORMAT.format(payLoan));//已還本金
        data.add(FORMAT.format(payInterest));//已還利息
        data.add(FORMAT.format(aheadTotalMoney));//提早還款總額
        data.add(FORMAT.format(leftTotalMoney));//剩餘還款總額
        data.add(FORMAT.format(leftInterest));//剩餘還款總利息
        data.add(FORMAT.format(newPreLoan));//剩餘每個月還款金額
        data.add(FORMAT.format(saveInterest));//節省利息
        data.add(String.valueOf(months));//剩餘還款期限
        return data.toArray(new String[data.size()]);
    }

運行結果:

這裏寫圖片描述

在線計算結果:

這裏寫圖片描述

等額本金

/**
     * 部分提早還款計算(等額本金、期限不變)
     * @param principal      貸款總額
     * @param months         貸款期限
     * @param aheadPrincipal 提早還款金額
     * @param payTimes       已還次數
     * @param rate           貸款利率
     * @return
     */
    public static String[] calculateEqualPrincipalApart2(double principal, int months, double aheadPrincipal, int payTimes, double rate) {
        ArrayList<String> data = new ArrayList<String>();
        double monthRate = rate / (100 * 12);//月利率
        double prePrincipal = principal / months;//每個月還款本金
        double firstMonth = prePrincipal + principal * monthRate;//第一個月還款金額
        double decreaseMonth = prePrincipal * monthRate;//每個月利息遞減
        double interest = (months + 1) * principal * monthRate / 2;//還款總利息
        double totalMoney = principal + interest;//還款總額
        double payLoan = prePrincipal * payTimes;//已還本金
        double payInterest = (principal * payTimes - prePrincipal * (payTimes - 1) * payTimes / 2) * monthRate;//已還利息
        double payTotal = payLoan + payInterest;//已還總額
        double aheadTotalMoney = (principal - payLoan) *  monthRate+aheadPrincipal+prePrincipal;//提早還款金額
        int leftMonth = months - payTimes-1;
        double leftLoan = principal - aheadPrincipal - payLoan-prePrincipal;
        double newPrePrincipal = leftLoan / leftMonth;//新的每個月還款本金
        double newFirstMonth = newPrePrincipal + leftLoan * monthRate;//新的第一個月還款金額
        double newDecreaseMonth = newPrePrincipal * monthRate;//新的每個月利息遞減
        double leftInterest = (leftMonth + 1) * leftLoan * monthRate / 2;//還款總利息
        double leftTotalMoney = leftLoan + leftInterest;//還款總額
        double saveInterest = totalMoney-payTotal-aheadTotalMoney-leftTotalMoney;
        data.add(FORMAT.format(totalMoney));//原還款總額
        data.add(FORMAT.format(principal));//貸款總額
        data.add(FORMAT.format(interest));//原還款總利息
        data.add(FORMAT.format(firstMonth));//原還首月還款金額
        data.add(FORMAT.format(decreaseMonth));//原每個月遞減利息
        data.add(FORMAT.format(payTotal));//已還總金額
        data.add(FORMAT.format(payLoan));//已還本金
        data.add(FORMAT.format(payInterest));//已還利息
        data.add(FORMAT.format(aheadTotalMoney));//提早還款總額
        data.add(FORMAT.format(leftTotalMoney));//剩餘還款總額
        data.add(FORMAT.format(leftInterest));//剩餘還款總利息
        data.add(FORMAT.format(newFirstMonth));//剩餘首月還款金額
        data.add(FORMAT.format(newDecreaseMonth));//剩餘月遞減利息
        data.add(FORMAT.format(saveInterest));//節省利息
        data.add(String.valueOf(months));//剩餘還款期限
        return data.toArray(new String[data.size()]);
    }

運行結果:

這裏寫圖片描述

在線計算結果:

這裏寫圖片描述

測試數據:

貸款100萬 部分提早還款50萬 已償還10期 貸款利率4.9 貸款期限30年

相關文章
相關標籤/搜索