/**
* 阿里借呗计息还款规则说明实现
*
* 测试阿里案例和韩哥案例通过
* @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;
}
}
分享到:
相关推荐
提前还款涉及到的算法则更为复杂,因为需要重新计算剩余贷款的利息和还款计划。通常,提前还款可以减少总的利息支出,但可能需要支付一定的手续费。具体计算涉及剩余本金、剩余期限、提前还款金额以及银行对于提前...
通过对各种可能的提前还款时间和金额进行计算,可以找到最经济的提前还款策略。 此外,文章还探讨了投资股票和基金的收益模型,以模拟投资风险和收益的不确定性。通过计算机模拟,可以预测不同投资组合可能带来的...
然后,可以使用MATLAB的内置函数或者自定义算法来模拟提前还款行为,计算每个时间段内的CPR值。对于SMM,我们可以设置循环结构,逐月计算每笔贷款的还款额,并累加到总还款现金流中。 MATLAB的Financial Toolbox...
3. 提前还款分析:模拟不同提前还款策略,分析节省的利息和缩短的还款期限。 三、房贷计算器核心算法 房贷计算器的核心算法通常采用等额本息还款法,该方法下,每月还款额固定,包括部分本金和剩余贷款的利息。...
实验报告详细记录了三年内的各项战略决策,包括贷款、土地分配、建筑、价格设定、广告投放、景观费用、个人消费贷款、存款、提前还款、股票发行和国债购买等,通过对这些决策的分析和评价,评估企业经营效果。...
5. **提前还款功能**:在代码中,可能会有允许用户预付部分或全部贷款的函数,这会影响到总的利息支出和还款期限。 6. **还款计划生成**:这部分代码将生成详细的还款计划,显示每月的还款额、利息和剩余本金,帮助...
4. **提前还款**:用户可能希望在贷款期限内提前还清部分或全部贷款,MATLAB 可以帮助计算提前还款后的节省利息和新的还款计划。 5. **利率变动影响**:对于浮动利率贷款,MATLAB 可以用于模拟未来利率变化对贷款...
- **提前还款**:用户可以模拟提前还款的情景,查看提前还款后节省的总利息和剩余月数。 - **利率变动**:模拟未来利率变化对贷款成本的影响。 - **货币时间价值**:考虑资金的时间价值,显示现值和未来值的对比。 -...
- **提前还款模拟**:用户可以设定提前还款的金额和时间,看看这将如何影响总的利息支出和还款周期。 - **公积金贷款计算**:除了商业贷款,部分计算器还能处理公积金贷款的计算,考虑到不同的利率和政策。 - **税费...
4. **提前还款分析**:对于贷款,用户可以查看提前还款对总利息支出的影响。 在实际应用中,"復利計算器"可能还会包含以下特性: - **多种货币选择**:支持不同国家的货币计算,适应全球化投资需求。 - **税率计算*...
在MATLAB环境中,"Simplemortgagecalculator"是一个用于计算房贷的简单工具...此外,根据`license.txt`的条款,如果允许,可以将这个工具作为基础,扩展为更复杂的房贷计算器,比如加入提前还款、利率变动等复杂功能。
最后,通过数据分析和优化算法(如线性规划、动态规划等),模型可以找到最优的贷款策略,这可能包括最佳贷款期限、最优初始利率、最合理的提前还款时间点等。 总结来说,数学建模在住房贷款问题中扮演了关键角色,...
数学建模是应用数学的一种方法,它利用数学工具和理论来模拟真实世界的问题,以便进行预测、决策和理解复杂系统。 首先,我们来了解什么是不良贷款。在银行术语中,不良贷款指的是那些借款人无法按时偿还本金或利息...
3. 提前还款:抵押贷款可能允许提前还款,C#可以设计一个模块来模拟提前还款的影响,包括节省的利息和可能的罚款计算。 四、C#的金融库与框架 在C#生态系统中,有多个金融计算相关的库和框架,如NodaTime用于处理...
审计人员依据专家的经验和对业务的理解,构建模型来检测潜在的风险点,例如,可能通过分析贷款客户的信用评分、还款记录等数据,预测违约风险,从而提前采取防范措施。 在实际操作中,审计人员会结合各种模型,根据...
通过迭代方法,我们可以逐步更新贷款余额,考虑利息的积累,以及可能的额外还款或提前还款,以预测未来的贷款状况。迭代计算允许我们模拟不同场景,比如调整利率、还款期和每月还款额,以找出最佳的偿还策略。 ...
3. **提前还款分析**:允许用户模拟提前还款的情况,计算出提前还款节省的总利息和剩余的贷款余额。 4. **退休储蓄规划**:根据用户的收入、支出和预期的退休年龄,为用户提供一个退休储蓄的目标和进度。 5. **...
为了有效管理流动性风险,银行可以利用数值模拟技术构建现金流量预测模型,通过对各类资产负债项目现金流变动情况进行仿真模拟,提前识别可能出现的资金缺口,并采取相应措施予以应对。 ### 结语 综上所述,“CS-...
6. 还款管理:自动扣款、提前还款、逾期处理等功能。 7. 风险控制:实时监控交易数据,预警潜在风险。 五、开发工具 1. IDEA:IntelliJ IDEA,Java开发的集成开发环境,提供强大的代码编辑、调试和版本控制功能。 2...
4. 遗传算法:受生物进化启发,通过模拟自然选择过程寻找最优解。在信用卡业务中,可能用于优化信用卡产品设计或定价策略。 综上所述,数据挖掘技术在信用卡业务中扮演着至关重要的角色,它能够帮助金融机构更准确...