某呗提前还款模拟
Posted 葫芦一生
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了某呗提前还款模拟相关的知识,希望对你有一定的参考价值。
- /**
- * 阿里借呗计息还款规则说明实现
- *
- * 测试阿里案例和韩哥案例通过
- * @return
- */
- package jdongtech.jiebaiUtils;
- import java.util.Arrays;
- import java.util.Calendar;
- import java.util.HashMap;
- import java.util.Map;
- import jdongtech.interestUtils.AverageCapitalPlusInterestUtils;
- public class advanceRepayMore {
- public static void main(String[] args) {
- Calendar lendDay = Calendar.getInstance(); // 借款日期
- Calendar rebackDay = Calendar.getInstance();// 还款日期
- double rebackInvest = 0; // 还款金额
- double invest = 0; // 借款本金
- int month = 0; // 期数
- double yearRate = 0; // 年利率
- int acctOffsetDay = 15; // 平移日期
- int accountDay = 25; // 账单日,蚂蚁会把账单日设置成借款当日
- // 文件示例
- lendDay.set(Calendar.MONTH, 9);
- lendDay.set(Calendar.DAY_OF_MONTH, 13);
- rebackInvest = 100.24;
- // rebackInvest = 60.04;
- rebackDay.set(Calendar.MONTH, 9);
- rebackDay.set(Calendar.DAY_OF_MONTH, 14);
- invest = 1200; // 本金
- month = 12; // 期数
- yearRate = 7.2 / 100; // 年利率
- acctOffsetDay = 15;
- accountDay = 25;
- // 韩哥示例
- lendDay.set(Calendar.MONTH, 4);
- lendDay.set(Calendar.DAY_OF_MONTH, 13);
- rebackInvest = 60.04;
- rebackDay.set(Calendar.MONTH, 4);
- rebackDay.set(Calendar.DAY_OF_MONTH, 13);
- invest = 120; // 本金
- month = 6; // 期数
- yearRate = 14.4 / 100; // 年利率
- acctOffsetDay = 15;
- accountDay = 13; // 账单日,蚂蚁会把账单日设置成借款当日
- double dateRate = yearRate / 360;
- int[] daysCount = new int[month];
- int IncreaseFlag = 0;
- Calendar lendCalOffset = (Calendar) lendDay.clone();
- lendCalOffset.add(Calendar.DATE, acctOffsetDay);
- Calendar accCal = (Calendar) lendDay.clone();
- accCal.set(Calendar.DAY_OF_MONTH, accountDay);
- Calendar accCalBegin = (Calendar) accCal.clone();
- if (lendCalOffset.before(accCal)) {
- } else {
- accCalBegin.add(Calendar.MONTH, 1);
- IncreaseFlag = 1;
- }
- Calendar accCalEnd = (Calendar) accCal.clone();
- accCalEnd.add(Calendar.MONTH, month - 1);
- System.out.println(lendDay.getTime() + "借款日期");
- System.out.println(accCalBegin.getTime() + "开始");
- System.out.println(accCalEnd.getTime() + "结束");
- int daysLending = RepayUtils.daysOffset(lendDay, accCalEnd);
- System.out.println("借款经历" + daysLending + "天");
- Calendar accCalPerEnd = (Calendar) accCalBegin.clone();
- for (int i = 0; i < month; i++) {
- Calendar accCalPerBeg;
- if (i == 0) {
- accCalPerBeg = (Calendar) lendDay.clone();
- } else {
- accCalPerBeg = (Calendar) accCalPerEnd.clone();
- accCalPerBeg.add(Calendar.MONTH, -1);
- }
- int daysPer = RepayUtils.daysOffset(accCalPerBeg, accCalPerEnd);
- daysCount[i] = daysPer;
- accCalPerEnd.add(Calendar.MONTH, 1);
- }
- System.out.println("部分还款前计划:");
- normalRepay.getPerMonthPrincipalInterestBig(invest, dateRate, month, daysCount, IncreaseFlag);
- System.out.println("提前还款日期:" + rebackDay.getTime());
- int curPeriod = 0;
- int daysCurPeriod = RepayUtils.daysOffset(lendDay, rebackDay);
- for (int i = 0; i < daysCount.length; i++) {
- daysCurPeriod = daysCurPeriod - daysCount[i];
- if (daysCurPeriod <= 0) { // 账单日算当前期
- curPeriod = i;
- daysCurPeriod = daysCurPeriod + daysCount[i];
- i = daysCount.length;
- }
- }
- System.out.println("提前还款当期期数:" + curPeriod);
- System.out.println("提前还款当期天数:" + daysCurPeriod);
- System.out.println("部分还款后计划:");
- getPerMonthPrincipalInterestBigRebackSome(invest, dateRate, month, daysCount, IncreaseFlag, rebackInvest,
- curPeriod, daysCurPeriod);
- }
- /**
- * 计算实际等额本息每月额度
- *
- * @return
- */
- public static double getPerMonthPrincipalInterestBigRebackSome(double invest, double dateRate, int totalmonth,
- int[] daysCount, int IncreaseFlag, double rebackInvest, int curPeriod, int daysCurPeriod) {
- IncreaseFlag = 1;
- if (daysCurPeriod == 0) {
- daysCurPeriod = 1;
- }
- double perMonthStandard = AverageCapitalPlusInterestUtils.getPerMonthPrincipalInterest(invest, dateRate * 360,
- totalmonth);
- double perMonthMax = perMonthStandard * 1.01;
- double[] PRperMonth = new double[totalmonth];
- double[] PperMonth = new double[totalmonth];
- double[] RperMonth = new double[totalmonth];
- double[] PLeftperMonth = new double[totalmonth];
- Map<Double, Double> lastCheckMap = new HashMap<Double, Double>();
- Map<Double, double[]> PLeftperMonthMap = new HashMap<Double, double[]>();
- Map<Double, double[]> PRperMonthMap = new HashMap<Double, double[]>();
- Map<Double, double[]> PperMonthMap = new HashMap<Double, double[]>();
- Map<Double, double[]> RperMonthMap = new HashMap<Double, double[]>();
- Map<Double, Double> sumPRMap = new HashMap<Double, Double>();
- Map<Double, Double> sumPMap = new HashMap<Double, Double>();
- Map<Double, Double> sumRMap = new HashMap<Double, Double>();
- if (IncreaseFlag == 1) {
- while (perMonthStandard < perMonthMax) {
- PRperMonth = new double[totalmonth];
- PperMonth = new double[totalmonth];
- RperMonth = new double[totalmonth];
- PLeftperMonth = new double[totalmonth];
- PRperMonth[0] = RepayUtils.num2second(perMonthStandard);
- PLeftperMonth[0] = RepayUtils.num2second(invest);
- RperMonth[0] = RepayUtils.num2secondDown(PLeftperMonth[0] * daysCount[0] * dateRate);
- PperMonth[0] = RepayUtils.num2second(PRperMonth[0] - RperMonth[0]);
- for (int j = 1; j < totalmonth; j++) {
- PRperMonth[j] = RepayUtils.num2second(perMonthStandard);
- PLeftperMonth[j] = RepayUtils.num2second(PLeftperMonth[j - 1] - PperMonth[j - 1]);
- RperMonth[j] = RepayUtils.num2secondDown(PLeftperMonth[j] * dateRate * daysCount[j]);
- PperMonth[j] = RepayUtils.num2second(PRperMonth[j] - RperMonth[j]);
- if (j == totalmonth - 1) {
- PperMonth[j] = RepayUtils.num2second(PLeftperMonth[j]);
- PRperMonth[j] = RepayUtils.num2second(PperMonth[j] + RperMonth[j]);
- }
- }
- double sumP = 0;
- double sumR = 0;
- double sumPR = 0;
- for (int i = 0; i < PLeftperMonth.length; i++) {
- sumP = sumP + PperMonth[i];
- sumR = sumR + RperMonth[i];
- sumPR = sumPR + PRperMonth[i];
- }
- lastCheckMap.put(RepayUtils.num2second(perMonthStandard),
- Math.abs(PRperMonth[totalmonth - 1] - PRperMonth[totalmonth - 2]));
- PLeftperMonthMap.put(RepayUtils.num2second(perMonthStandard), PLeftperMonth);
- PRperMonthMap.put(RepayUtils.num2second(perMonthStandard), PRperMonth);
- PperMonthMap.put(RepayUtils.num2second(perMonthStandard), PperMonth);
- RperMonthMap.put(RepayUtils.num2second(perMonthStandard), RperMonth);
- sumPRMap.put(RepayUtils.num2second(perMonthStandard), RepayUtils.num2second(sumPR));
- sumPMap.put(RepayUtils.num2second(perMonthStandard), RepayUtils.num2second(sumP));
- sumRMap.put(RepayUtils.num2second(perMonthStandard), RepayUtils.num2second(sumR));
- perMonthStandard = perMonthStandard + 0.01;
- }
- }
- Double resultKey = RepayUtils.getKeyByMinValue(lastCheckMap);
- // 当期剩余天数
- int remainDaysCurPeriod = daysCount[curPeriod] - daysCurPeriod;
- double rebackPCurPeriod = RepayUtils.num2second(
- rebackInvest - RepayUtils.num2secondDown(PLeftperMonth[curPeriod] * dateRate * daysCurPeriod));
- if (rebackPCurPeriod < PperMonthMap.get(resultKey)[curPeriod]) { // 还款小于当前期本金
- PLeftperMonthMap.get(resultKey)[curPeriod] = RepayUtils
- .num2second(PLeftperMonthMap.get(resultKey)[curPeriod] - rebackPCurPeriod);
- PperMonthMap.get(resultKey)[curPeriod] = RepayUtils
- .num2second(PperMonthMap.get(resultKey)[curPeriod] - rebackPCurPeriod);
- RperMonthMap.get(resultKey)[curPeriod] = RepayUtils
- .num2secondDown(PLeftperMonthMap.get(resultKey)[curPeriod] * dateRate * remainDaysCurPeriod);
- PRperMonthMap.get(resultKey)[curPeriod] = RepayUtils
- .num2second(RperMonthMap.get(resultKey)[curPeriod] + PperMonthMap.get(resultKey)[curPeriod]);
- System.out.println("等额本息每月还款额:" + resultKey);
- System.out.println("每期经历" + Arrays.toString(daysCount));
- System.out.println("每月余本金:" + Arrays.toString(PLeftperMonthMap.get(resultKey)));
- System.out.println("每月还款额:" + Arrays.toString(PRperMonthMap.get(resultKey)));
- System.out.println("每月还本金:" + Arrays.toString(PperMonthMap.get(resultKey)));
- System.out.println("每月还利息:" + Arrays.toString(RperMonthMap.get(resultKey)));
- double sumP = 0;
- double sumR = 0;
- double sumPR = 0;
- for (int i = 0; i < PLeftperMonth.length; i++) {
- sumP = sumP + PperMonthMap.get(resultKey)[i];
- sumR = sumR + RperMonthMap.get(resultKey)[i];
- sumPR = sumPR + PRperMonthMap.get(resultKey)[i];
- }
- sumPRMap.put(RepayUtils.num2second(resultKey), RepayUtils.num2second(sumPR));
- sumPMap.put(RepayUtils.num2second(resultKey), RepayUtils.num2second(sumP));
- sumRMap.put(RepayUtils.num2second(resultKey), RepayUtils.num2second(sumR));
- System.out.println("总还款额:" + sumPRMap.get(resultKey));
- System.out.println("总还本金:" + sumPMap.get(resultKey));
- System.out.println("总还利息:" + sumRMap.get(resultKey));
- } else { // 还款本金大于当期本金
- int[] dayCountsAfter = new int[totalmonth - curPeriod];
- double[] PRperMonthAfter = new double[totalmonth - curPeriod];
- double[] PperMonthAfter = new double[totalmonth - curPeriod];
- double[] RperMonthAfter = new double[totalmonth - curPeriod];
- double[] PLeftperMonthAfter = new double[totalmonth - curPeriod];
- // P本金0的阶段 第一个月
- double remainInvest = RepayUtils.num2second(PLeftperMonthMap.get(resultKey)[curPeriod] - rebackPCurPeriod);
- PperMonthAfter[0] = RepayUtils.num2second(0);
- PLeftperMonthAfter[0] = remainInvest;
- RperMonthAfter[0] = RepayUtils.num2secondDown(PLeftperMonthAfter[0] * dateRate * remainDaysCurPeriod);
- PRperMonthAfter[0] = RperMonthAfter[0];
- // P本金非0的再平衡阶段
- int remainMonth = totalmonth - curPeriod - 1;
- double perMonthStandardRec = AverageCapitalPlusInterestUtils.getPerMonthPrincipalInterest(remainInvest,
- dateRate * 360, remainMonth);
- int[] daysCountRec = Arrays.copyOfRange(daysCount, curPeriod + 1, totalmonth); // 剩余天数数组
- for (int i = 0; i < remainMonth; i++) {
- dayCountsAfter[i + 1] = daysCountRec[i];
- dayCountsAfter[0] = remainDaysCurPeriod;
- }
- double perMonthMaxRec = perMonthStandardRec * 1.1;
- double[] PRperMonthRec = new double[remainMonth];
- double[] PperMonthRec = new double[remainMonth];
- double[] RperMonthRec = new double[remainMonth];
- double[] PLeftperMonthRec = new double[remainMonth];
- Map<Double, Double> lastCheckMapRec = new HashMap<Double, Double>();
- Map<Double, double[]> PLeftperMonthMapRec = new HashMap<Double, double[]>();
- Map<Double, double[]> PRperMonthMapRec = new HashMap<Double, double[]>();
- Map<Double, double[]> PperMonthMapRec = new HashMap<Double, double[]>();
- Map<Double, double[]> RperMonthMapRec = new HashMap<Double, double[]>();
- while (perMonthStandardRec < perMonthMaxRec) {
- PRperMonthRec = new double[remainMonth];
- PperMonthRec = new double[remainMonth];
- RperMonthRec = new double[remainMonth];
- PLeftperMonthRec = new double[remainMonth];
- PRperMonthRec[0] = RepayUtils.num2second(perMonthStandardRec);
- PLeftperMonthRec[0] = RepayUtils.num2second(remainInvest);
- RperMonthRec[0] = RepayUtils.num2secondDown(PLeftperMonthRec[0] * daysCountRec[0] * dateRate);
- PperMonthRec[0] = RepayUtils.num2second(PRperMonthRec[0] - RperMonthRec[0]);
- for (int j = 1; j < remainMonth; j++) {
- PRperMonthRec[j] = RepayUtils.num2second(perMonthStandardRec);
- PLeftperMonthRec[j] = RepayUtils.num2second(PLeftperMonthRec[j - 1] - PperMonthRec[j - 1]);
- RperMonthRec[j] = RepayUtils.num2secondDown(PLeftperMonthRec[j] * dateRate * daysCountRec[j]);
- PperMonthRec[j] = RepayUtils.num2second(PRperMonthRec[j] - RperMonthRec[j]);
- if (j == remainMonth - 1) {
- PperMonthRec[j] = RepayUtils.num2second(PLeftperMonthRec[j]);
- PRperMonthRec[j] = RepayUtils.num2second(PperMonthRec[j] + RperMonthRec[j]);
- }
- }
- lastCheckMapRec.put(RepayUtils.num2second(perMonthStandardRec),
- Math.abs(PRperMonthRec[remainMonth - 1] - PRperMonthRec[remainMonth - 2]));
- PLeftperMonthMapRec.put(RepayUtils.num2second(perMonthStandardRec), PLeftperMonthRec);
- PRperMonthMapRec.put(RepayUtils.num2second(perMonthStandardRec), PRperMonthRec);
- PperMonthMapRec.put(RepayUtils.num2second(perMonthStandardRec), PperMonthRec);
- RperMonthMapRec.put(RepayUtils.num2secondDown(perMonthStandardRec), RperMonthRec);
- perMonthStandardRec = perMonthStandardRec + 0.01;
- }
- Double resultKeyRec = RepayUtils.getKeyByMinValue(lastCheckMapRec);
- for (int i = 1; i < totalmonth; i++) {
- PperMonthAfter[i] = RepayUtils.num2second(PperMonthMapRec.get(resultKeyRec)[i - 1]);
- PLeftperMonthAfter[i] = RepayUtils.num2second(PLeftperMonthMapRec.get(resultKeyRec)[i - 1]);
- RperMonthAfter[i] = RepayUtils.num2second(RperMonthMapRec.get(resultKeyRec)[i - 1]);
- PRperMonthAfter[i] = RepayUtils.num2second(PRperMonthMapRec.get(resultKeyRec)[i - 1]);
- }
- System.out.println("重新等额本息每月还款额:" + resultKeyRec);
- System.out.println("重新每期经历" + Arrays.toString(dayCountsAfter));
- System.out.println("重新每月余本金:" + Arrays.toString(PLeftperMonthAfter));
- System.out.println("重新每月还款额:" + Arrays.toString(PRperMonthAfter));
- System.out.println("重新每月还本金:" + Arrays.toString(PperMonthAfter));
- System.out.println("重新每月还利息:" + Arrays.toString(RperMonthAfter));
- double sumP = 0;
- double sumR = 0;
- double sumPR = 0;
- for (int i = 0; i < PLeftperMonth.length; i++) {
- sumP = sumP + PperMonthAfter[i];
- sumR = sumR + RperMonthAfter[i];
- sumPR = sumPR + PRperMonthAfter[i];
- }
- sumPRMap.put(RepayUtils.num2second(resultKey), RepayUtils.num2second(sumPR));
- sumPMap.put(RepayUtils.num2second(resultKey), RepayUtils.num2second(sumP));
- sumRMap.put(RepayUtils.num2second(resultKey), RepayUtils.num2second(sumR));
- System.out.println("总还款额:" + sumPRMap.get(resultKey));
- System.out.println("总还本金:" + sumPMap.get(resultKey));
- System.out.println("总还利息:" + sumRMap.get(resultKey));
- }
- return resultKey;
- }
- }
以上是关于某呗提前还款模拟的主要内容,如果未能解决你的问题,请参考以下文章