• 某呗提前还款模拟


    1. /** 
    2.  * 阿里借呗计息还款规则说明实现 
    3.  *  
    4.  * 测试阿里案例和韩哥案例通过 
    5.  * @return 
    6.  */  
    7. package jdongtech.jiebaiUtils;  
    8.   
    9. import java.util.Arrays;  
    10. import java.util.Calendar;  
    11. import java.util.HashMap;  
    12. import java.util.Map;  
    13.   
    14. import jdongtech.interestUtils.AverageCapitalPlusInterestUtils;  
    15.   
    16. public class advanceRepayMore {  
    17.     public static void main(String[] args) {  
    18.   
    19.         Calendar lendDay = Calendar.getInstance(); // 借款日期  
    20.         Calendar rebackDay = Calendar.getInstance();// 还款日期  
    21.         double rebackInvest = 0; // 还款金额  
    22.         double invest = 0; // 借款本金  
    23.         int month = 0; // 期数  
    24.         double yearRate = 0; // 年利率  
    25.         int acctOffsetDay = 15; // 平移日期  
    26.         int accountDay = 25; // 账单日,蚂蚁会把账单日设置成借款当日  
    27.   
    28.         // 文件示例  
    29.         lendDay.set(Calendar.MONTH, 9);  
    30.         lendDay.set(Calendar.DAY_OF_MONTH, 13);  
    31.         rebackInvest = 100.24;  
    32.         // rebackInvest = 60.04;  
    33.         rebackDay.set(Calendar.MONTH, 9);  
    34.         rebackDay.set(Calendar.DAY_OF_MONTH, 14);  
    35.         invest = 1200; // 本金  
    36.         month = 12; // 期数  
    37.         yearRate = 7.2 / 100; // 年利率  
    38.         acctOffsetDay = 15;  
    39.         accountDay = 25;  
    40.   
    41.         // 韩哥示例  
    42.         lendDay.set(Calendar.MONTH, 4);  
    43.         lendDay.set(Calendar.DAY_OF_MONTH, 13);  
    44.         rebackInvest = 60.04;  
    45.         rebackDay.set(Calendar.MONTH, 4);  
    46.         rebackDay.set(Calendar.DAY_OF_MONTH, 13);  
    47.         invest = 120; // 本金  
    48.         month = 6; // 期数  
    49.         yearRate = 14.4 / 100; // 年利率  
    50.         acctOffsetDay = 15;  
    51.         accountDay = 13; // 账单日,蚂蚁会把账单日设置成借款当日  
    52.   
    53.         double dateRate = yearRate / 360;  
    54.         int[] daysCount = new int[month];  
    55.         int IncreaseFlag = 0;  
    56.         Calendar lendCalOffset = (Calendar) lendDay.clone();  
    57.         lendCalOffset.add(Calendar.DATE, acctOffsetDay);  
    58.         Calendar accCal = (Calendar) lendDay.clone();  
    59.         accCal.set(Calendar.DAY_OF_MONTH, accountDay);  
    60.         Calendar accCalBegin = (Calendar) accCal.clone();  
    61.         if (lendCalOffset.before(accCal)) {  
    62.         } else {  
    63.             accCalBegin.add(Calendar.MONTH, 1);  
    64.             IncreaseFlag = 1;  
    65.         }  
    66.         Calendar accCalEnd = (Calendar) accCal.clone();  
    67.         accCalEnd.add(Calendar.MONTH, month - 1);  
    68.   
    69.         System.out.println(lendDay.getTime() + "借款日期");  
    70.         System.out.println(accCalBegin.getTime() + "开始");  
    71.         System.out.println(accCalEnd.getTime() + "结束");  
    72.         int daysLending = RepayUtils.daysOffset(lendDay, accCalEnd);  
    73.         System.out.println("借款经历" + daysLending + "天");  
    74.   
    75.         Calendar accCalPerEnd = (Calendar) accCalBegin.clone();  
    76.         for (int i = 0; i < month; i++) {  
    77.             Calendar accCalPerBeg;  
    78.             if (i == 0) {  
    79.                 accCalPerBeg = (Calendar) lendDay.clone();  
    80.             } else {  
    81.                 accCalPerBeg = (Calendar) accCalPerEnd.clone();  
    82.                 accCalPerBeg.add(Calendar.MONTH, -1);  
    83.             }  
    84.   
    85.             int daysPer = RepayUtils.daysOffset(accCalPerBeg, accCalPerEnd);  
    86.             daysCount[i] = daysPer;  
    87.             accCalPerEnd.add(Calendar.MONTH, 1);  
    88.         }  
    89.   
    90.         System.out.println("部分还款前计划:");  
    91.         normalRepay.getPerMonthPrincipalInterestBig(invest, dateRate, month, daysCount, IncreaseFlag);  
    92.   
    93.         System.out.println("提前还款日期:" + rebackDay.getTime());  
    94.         int curPeriod = 0;  
    95.         int daysCurPeriod = RepayUtils.daysOffset(lendDay, rebackDay);  
    96.         for (int i = 0; i < daysCount.length; i++) {  
    97.             daysCurPeriod = daysCurPeriod - daysCount[i];  
    98.             if (daysCurPeriod <= 0) { // 账单日算当前期  
    99.                 curPeriod = i;  
    100.                 daysCurPeriod = daysCurPeriod + daysCount[i];  
    101.                 i = daysCount.length;  
    102.             }  
    103.         }  
    104.         System.out.println("提前还款当期期数:" + curPeriod);  
    105.         System.out.println("提前还款当期天数:" + daysCurPeriod);  
    106.         System.out.println("部分还款后计划:");  
    107.         getPerMonthPrincipalInterestBigRebackSome(invest, dateRate, month, daysCount, IncreaseFlag, rebackInvest,  
    108.                 curPeriod, daysCurPeriod);  
    109.     }  
    110.   
    111.     /** 
    112.      * 计算实际等额本息每月额度 
    113.      *  
    114.      * @return 
    115.      */  
    116.     public static double getPerMonthPrincipalInterestBigRebackSome(double invest, double dateRate, int totalmonth,  
    117.             int[] daysCount, int IncreaseFlag, double rebackInvest, int curPeriod, int daysCurPeriod) {  
    118.         IncreaseFlag = 1;  
    119.         if (daysCurPeriod == 0) {  
    120.             daysCurPeriod = 1;  
    121.         }  
    122.         double perMonthStandard = AverageCapitalPlusInterestUtils.getPerMonthPrincipalInterest(invest, dateRate * 360,  
    123.                 totalmonth);  
    124.   
    125.         double perMonthMax = perMonthStandard * 1.01;  
    126.         double[] PRperMonth = new double[totalmonth];  
    127.         double[] PperMonth = new double[totalmonth];  
    128.         double[] RperMonth = new double[totalmonth];  
    129.         double[] PLeftperMonth = new double[totalmonth];  
    130.         Map<Double, Double> lastCheckMap = new HashMap<Double, Double>();  
    131.         Map<Double, double[]> PLeftperMonthMap = new HashMap<Double, double[]>();  
    132.         Map<Double, double[]> PRperMonthMap = new HashMap<Double, double[]>();  
    133.         Map<Double, double[]> PperMonthMap = new HashMap<Double, double[]>();  
    134.         Map<Double, double[]> RperMonthMap = new HashMap<Double, double[]>();  
    135.         Map<Double, Double> sumPRMap = new HashMap<Double, Double>();  
    136.         Map<Double, Double> sumPMap = new HashMap<Double, Double>();  
    137.         Map<Double, Double> sumRMap = new HashMap<Double, Double>();  
    138.   
    139.         if (IncreaseFlag == 1) {  
    140.             while (perMonthStandard < perMonthMax) {  
    141.                 PRperMonth = new double[totalmonth];  
    142.                 PperMonth = new double[totalmonth];  
    143.                 RperMonth = new double[totalmonth];  
    144.                 PLeftperMonth = new double[totalmonth];  
    145.   
    146.                 PRperMonth[0] = RepayUtils.num2second(perMonthStandard);  
    147.                 PLeftperMonth[0] = RepayUtils.num2second(invest);  
    148.                 RperMonth[0] = RepayUtils.num2secondDown(PLeftperMonth[0] * daysCount[0] * dateRate);  
    149.                 PperMonth[0] = RepayUtils.num2second(PRperMonth[0] - RperMonth[0]);  
    150.                 for (int j = 1; j < totalmonth; j++) {  
    151.                     PRperMonth[j] = RepayUtils.num2second(perMonthStandard);  
    152.                     PLeftperMonth[j] = RepayUtils.num2second(PLeftperMonth[j - 1] - PperMonth[j - 1]);  
    153.                     RperMonth[j] = RepayUtils.num2secondDown(PLeftperMonth[j] * dateRate * daysCount[j]);  
    154.                     PperMonth[j] = RepayUtils.num2second(PRperMonth[j] - RperMonth[j]);  
    155.                     if (j == totalmonth - 1) {  
    156.                         PperMonth[j] = RepayUtils.num2second(PLeftperMonth[j]);  
    157.                         PRperMonth[j] = RepayUtils.num2second(PperMonth[j] + RperMonth[j]);  
    158.                     }  
    159.                 }  
    160.                 double sumP = 0;  
    161.                 double sumR = 0;  
    162.                 double sumPR = 0;  
    163.                 for (int i = 0; i < PLeftperMonth.length; i++) {  
    164.                     sumP = sumP + PperMonth[i];  
    165.                     sumR = sumR + RperMonth[i];  
    166.                     sumPR = sumPR + PRperMonth[i];  
    167.                 }  
    168.                 lastCheckMap.put(RepayUtils.num2second(perMonthStandard),  
    169.                         Math.abs(PRperMonth[totalmonth - 1] - PRperMonth[totalmonth - 2]));  
    170.                 PLeftperMonthMap.put(RepayUtils.num2second(perMonthStandard), PLeftperMonth);  
    171.                 PRperMonthMap.put(RepayUtils.num2second(perMonthStandard), PRperMonth);  
    172.                 PperMonthMap.put(RepayUtils.num2second(perMonthStandard), PperMonth);  
    173.                 RperMonthMap.put(RepayUtils.num2second(perMonthStandard), RperMonth);  
    174.                 sumPRMap.put(RepayUtils.num2second(perMonthStandard), RepayUtils.num2second(sumPR));  
    175.                 sumPMap.put(RepayUtils.num2second(perMonthStandard), RepayUtils.num2second(sumP));  
    176.                 sumRMap.put(RepayUtils.num2second(perMonthStandard), RepayUtils.num2second(sumR));  
    177.   
    178.                 perMonthStandard = perMonthStandard + 0.01;  
    179.             }  
    180.         }  
    181.   
    182.         Double resultKey = RepayUtils.getKeyByMinValue(lastCheckMap);  
    183.         // 当期剩余天数  
    184.         int remainDaysCurPeriod = daysCount[curPeriod] - daysCurPeriod;  
    185.         double rebackPCurPeriod = RepayUtils.num2second(  
    186.                 rebackInvest - RepayUtils.num2secondDown(PLeftperMonth[curPeriod] * dateRate * daysCurPeriod));  
    187.   
    188.         if (rebackPCurPeriod < PperMonthMap.get(resultKey)[curPeriod]) { // 还款小于当前期本金  
    189.             PLeftperMonthMap.get(resultKey)[curPeriod] = RepayUtils  
    190.                     .num2second(PLeftperMonthMap.get(resultKey)[curPeriod] - rebackPCurPeriod);  
    191.             PperMonthMap.get(resultKey)[curPeriod] = RepayUtils  
    192.                     .num2second(PperMonthMap.get(resultKey)[curPeriod] - rebackPCurPeriod);  
    193.             RperMonthMap.get(resultKey)[curPeriod] = RepayUtils  
    194.                     .num2secondDown(PLeftperMonthMap.get(resultKey)[curPeriod] * dateRate * remainDaysCurPeriod);  
    195.             PRperMonthMap.get(resultKey)[curPeriod] = RepayUtils  
    196.                     .num2second(RperMonthMap.get(resultKey)[curPeriod] + PperMonthMap.get(resultKey)[curPeriod]);  
    197.   
    198.             System.out.println("等额本息每月还款额:" + resultKey);  
    199.             System.out.println("每期经历" + Arrays.toString(daysCount));  
    200.             System.out.println("每月余本金:" + Arrays.toString(PLeftperMonthMap.get(resultKey)));  
    201.             System.out.println("每月还款额:" + Arrays.toString(PRperMonthMap.get(resultKey)));  
    202.             System.out.println("每月还本金:" + Arrays.toString(PperMonthMap.get(resultKey)));  
    203.             System.out.println("每月还利息:" + Arrays.toString(RperMonthMap.get(resultKey)));  
    204.             double sumP = 0;  
    205.             double sumR = 0;  
    206.             double sumPR = 0;  
    207.             for (int i = 0; i < PLeftperMonth.length; i++) {  
    208.                 sumP = sumP + PperMonthMap.get(resultKey)[i];  
    209.                 sumR = sumR + RperMonthMap.get(resultKey)[i];  
    210.                 sumPR = sumPR + PRperMonthMap.get(resultKey)[i];  
    211.             }  
    212.             sumPRMap.put(RepayUtils.num2second(resultKey), RepayUtils.num2second(sumPR));  
    213.             sumPMap.put(RepayUtils.num2second(resultKey), RepayUtils.num2second(sumP));  
    214.             sumRMap.put(RepayUtils.num2second(resultKey), RepayUtils.num2second(sumR));  
    215.   
    216.             System.out.println("总还款额:" + sumPRMap.get(resultKey));  
    217.             System.out.println("总还本金:" + sumPMap.get(resultKey));  
    218.             System.out.println("总还利息:" + sumRMap.get(resultKey));  
    219.   
    220.         } else { // 还款本金大于当期本金  
    221.             int[] dayCountsAfter = new int[totalmonth - curPeriod];  
    222.             double[] PRperMonthAfter = new double[totalmonth - curPeriod];  
    223.             double[] PperMonthAfter = new double[totalmonth - curPeriod];  
    224.             double[] RperMonthAfter = new double[totalmonth - curPeriod];  
    225.             double[] PLeftperMonthAfter = new double[totalmonth - curPeriod];  
    226.   
    227.             // P本金0的阶段 第一个月  
    228.             double remainInvest = RepayUtils.num2second(PLeftperMonthMap.get(resultKey)[curPeriod] - rebackPCurPeriod);  
    229.             PperMonthAfter[0] = RepayUtils.num2second(0);  
    230.             PLeftperMonthAfter[0] = remainInvest;  
    231.             RperMonthAfter[0] = RepayUtils.num2secondDown(PLeftperMonthAfter[0] * dateRate * remainDaysCurPeriod);  
    232.             PRperMonthAfter[0] = RperMonthAfter[0];  
    233.   
    234.             // P本金非0的再平衡阶段  
    235.             int remainMonth = totalmonth - curPeriod - 1;  
    236.             double perMonthStandardRec = AverageCapitalPlusInterestUtils.getPerMonthPrincipalInterest(remainInvest,  
    237.                     dateRate * 360, remainMonth);  
    238.             int[] daysCountRec = Arrays.copyOfRange(daysCount, curPeriod + 1, totalmonth); // 剩余天数数组  
    239.             for (int i = 0; i < remainMonth; i++) {  
    240.                 dayCountsAfter[i + 1] = daysCountRec[i];  
    241.                 dayCountsAfter[0] = remainDaysCurPeriod;  
    242.             }  
    243.   
    244.             double perMonthMaxRec = perMonthStandardRec * 1.1;  
    245.             double[] PRperMonthRec = new double[remainMonth];  
    246.             double[] PperMonthRec = new double[remainMonth];  
    247.             double[] RperMonthRec = new double[remainMonth];  
    248.             double[] PLeftperMonthRec = new double[remainMonth];  
    249.             Map<Double, Double> lastCheckMapRec = new HashMap<Double, Double>();  
    250.             Map<Double, double[]> PLeftperMonthMapRec = new HashMap<Double, double[]>();  
    251.             Map<Double, double[]> PRperMonthMapRec = new HashMap<Double, double[]>();  
    252.             Map<Double, double[]> PperMonthMapRec = new HashMap<Double, double[]>();  
    253.             Map<Double, double[]> RperMonthMapRec = new HashMap<Double, double[]>();  
    254.             while (perMonthStandardRec < perMonthMaxRec) {  
    255.                 PRperMonthRec = new double[remainMonth];  
    256.                 PperMonthRec = new double[remainMonth];  
    257.                 RperMonthRec = new double[remainMonth];  
    258.                 PLeftperMonthRec = new double[remainMonth];  
    259.   
    260.                 PRperMonthRec[0] = RepayUtils.num2second(perMonthStandardRec);  
    261.                 PLeftperMonthRec[0] = RepayUtils.num2second(remainInvest);  
    262.                 RperMonthRec[0] = RepayUtils.num2secondDown(PLeftperMonthRec[0] * daysCountRec[0] * dateRate);  
    263.                 PperMonthRec[0] = RepayUtils.num2second(PRperMonthRec[0] - RperMonthRec[0]);  
    264.                 for (int j = 1; j < remainMonth; j++) {  
    265.                     PRperMonthRec[j] = RepayUtils.num2second(perMonthStandardRec);  
    266.                     PLeftperMonthRec[j] = RepayUtils.num2second(PLeftperMonthRec[j - 1] - PperMonthRec[j - 1]);  
    267.                     RperMonthRec[j] = RepayUtils.num2secondDown(PLeftperMonthRec[j] * dateRate * daysCountRec[j]);  
    268.                     PperMonthRec[j] = RepayUtils.num2second(PRperMonthRec[j] - RperMonthRec[j]);  
    269.                     if (j == remainMonth - 1) {  
    270.                         PperMonthRec[j] = RepayUtils.num2second(PLeftperMonthRec[j]);  
    271.                         PRperMonthRec[j] = RepayUtils.num2second(PperMonthRec[j] + RperMonthRec[j]);  
    272.                     }  
    273.                 }  
    274.   
    275.                 lastCheckMapRec.put(RepayUtils.num2second(perMonthStandardRec),  
    276.                         Math.abs(PRperMonthRec[remainMonth - 1] - PRperMonthRec[remainMonth - 2]));  
    277.   
    278.                 PLeftperMonthMapRec.put(RepayUtils.num2second(perMonthStandardRec), PLeftperMonthRec);  
    279.                 PRperMonthMapRec.put(RepayUtils.num2second(perMonthStandardRec), PRperMonthRec);  
    280.                 PperMonthMapRec.put(RepayUtils.num2second(perMonthStandardRec), PperMonthRec);  
    281.                 RperMonthMapRec.put(RepayUtils.num2secondDown(perMonthStandardRec), RperMonthRec);  
    282.                 perMonthStandardRec = perMonthStandardRec + 0.01;  
    283.             }  
    284.   
    285.             Double resultKeyRec = RepayUtils.getKeyByMinValue(lastCheckMapRec);  
    286.   
    287.             for (int i = 1; i < totalmonth; i++) {  
    288.                 PperMonthAfter[i] = RepayUtils.num2second(PperMonthMapRec.get(resultKeyRec)[i - 1]);  
    289.                 PLeftperMonthAfter[i] = RepayUtils.num2second(PLeftperMonthMapRec.get(resultKeyRec)[i - 1]);  
    290.                 RperMonthAfter[i] = RepayUtils.num2second(RperMonthMapRec.get(resultKeyRec)[i - 1]);  
    291.                 PRperMonthAfter[i] = RepayUtils.num2second(PRperMonthMapRec.get(resultKeyRec)[i - 1]);  
    292.             }  
    293.   
    294.             System.out.println("重新等额本息每月还款额:" + resultKeyRec);  
    295.             System.out.println("重新每期经历" + Arrays.toString(dayCountsAfter));  
    296.             System.out.println("重新每月余本金:" + Arrays.toString(PLeftperMonthAfter));  
    297.             System.out.println("重新每月还款额:" + Arrays.toString(PRperMonthAfter));  
    298.             System.out.println("重新每月还本金:" + Arrays.toString(PperMonthAfter));  
    299.             System.out.println("重新每月还利息:" + Arrays.toString(RperMonthAfter));  
    300.   
    301.             double sumP = 0;  
    302.             double sumR = 0;  
    303.             double sumPR = 0;  
    304.             for (int i = 0; i < PLeftperMonth.length; i++) {  
    305.                 sumP = sumP + PperMonthAfter[i];  
    306.                 sumR = sumR + RperMonthAfter[i];  
    307.                 sumPR = sumPR + PRperMonthAfter[i];  
    308.             }  
    309.             sumPRMap.put(RepayUtils.num2second(resultKey), RepayUtils.num2second(sumPR));  
    310.             sumPMap.put(RepayUtils.num2second(resultKey), RepayUtils.num2second(sumP));  
    311.             sumRMap.put(RepayUtils.num2second(resultKey), RepayUtils.num2second(sumR));  
    312.   
    313.             System.out.println("总还款额:" + sumPRMap.get(resultKey));  
    314.             System.out.println("总还本金:" + sumPMap.get(resultKey));  
    315.             System.out.println("总还利息:" + sumRMap.get(resultKey));  
    316.         }  
    317.         return resultKey;  
    318.     }  
    319.   
    320. }  
  • 相关阅读:
    网络流
    Link-Cut-Tree题集
    动态点分治
    斜率优化DP
    【Python学习之旅】---继承的方式完成包装(授权、item系列、str&repr、format 自定义格式方法)
    【Python学习之旅】---动态导入模块
    【Python学习之旅】---封装与反射(类的相关知识,面向对象三大特性:继承-多态-封装)
    【Python学习之旅】---多态(类的相关知识,面向对象三大特性:继承-多态-封装)
    【Python学习之旅】---多态(类的相关知识)
    【Python学习之旅】---继承(类的相关知识)
  • 原文地址:https://www.cnblogs.com/huluyisheng/p/6866415.html
Copyright © 2020-2023  润新知