├── README.md └── algorithm.php /README.md: -------------------------------------------------------------------------------- 1 | # PHP-P2P-Algorithm 2 | 金融P2P常见还款算法 3 | -------------------------------------------------------------------------------- /algorithm.php: -------------------------------------------------------------------------------- 1 | getRepamentTime($borrow_time, $i, 'yxb'); 70 | $_result[$i]['interest'] = $minterest; 71 | $_result[$i]['capital'] = $mcapital; 72 | $surplus = $surplus - $mcapital; 73 | 74 | $scapital += $mcapital; 75 | //最后一期平账 76 | if ($i + 1 == $times) { 77 | $_result[$i]['capital'] = round($mcapital + ($account - $scapital), 2); 78 | $_result[$i]['interest'] = round($minterest + ($scapital - $account), 2); 79 | } 80 | } 81 | // 返回总数据 82 | if ($type == "all") { 83 | return array( 84 | 'repayment_account' => $repayment_account, 85 | 'monthly_repayment' => $monthly_repayment, 86 | 'month_apr' => round($year_apr / 12, 2), 87 | 'profit_fee' => $tProfitFee, 88 | ); 89 | } 90 | return $_result; 91 | } 92 | 93 | /** 94 | * 按月付息到期还本 95 | * @param int $account 借款金额 96 | * @param double $year_apr 借款年利率 97 | * @param int $month_times 借款天数(目前只支持30的倍数) 98 | * @param int $borrow_style 还款方式 99 | * @param int $borrow_time 借款时间 100 | * @param string $type all=返回一次性还款数据,留空为返回还款每月还款详细数据 101 | * @return Array 102 | */ 103 | private function EqualEndMonth($account, $year_apr, $month_times, $borrow_style, $borrow_time, $type) 104 | { 105 | $times = ($month_times < 30) ? 1 : $month_times / 30; 106 | $tInterest = ceil($account * $times * ($year_apr / 12)) / 100; 107 | $interest = round($tInterest / $times, 2); 108 | $tAccount = $tInterest + $account; 109 | // 返回总数据 110 | if ($type == "all") { 111 | return array( 112 | 'repayment_account' => $tAccount, 113 | 'monthly_repayment' => $interest, 114 | 'month_apr' => round($year_apr / 12, 2), 115 | ); 116 | } 117 | // 计算每月利息 118 | $_result = array(); 119 | // 本金 120 | for ($i = 0; $i < $times; $i++) { 121 | $_result[$i]['repayment_account'] = $interest; 122 | //@todo 按月付息到期还本新算法计算还款时间 123 | $_result[$i]['repayment_time'] = $this->getRepamentTime($borrow_time, $i, 'yx_eb'); 124 | $_result[$i]['interest'] = $interest; 125 | $_result[$i]['capital'] = 0; 126 | if ($i + 1 == $times) { 127 | $_result[$i]['capital'] = $account; 128 | $_result[$i]['repayment_account'] = $account + $tInterest - $interest * ($times - 1); 129 | $_result[$i]['interest'] = $tInterest - $interest * ($times - 1); 130 | } 131 | } 132 | return $_result; 133 | } 134 | 135 | /** 136 | * 到期还本付息 137 | * @param int $account 借款金额 138 | * @param double $year_apr 借款年利率 139 | * @param int $month_times 借款天数(目前只支持30的倍数) 140 | * @param int $borrow_style 还款方式 141 | * @param int $borrow_time 借款时间 142 | * @param string $type all=返回一次性还款数据,留空为返回还款每月还款详细数据 143 | * @return Array 144 | */ 145 | private function EqualEnd($account, $year_apr, $month_times, $borrow_style, $borrow_time, $type) 146 | { 147 | 148 | $times = ($month_times < 30) ? 1 : $month_times / 30; 149 | $tInterest = ceil($account * $times * ($year_apr / 12)) / 100; 150 | $interest = round($tInterest / $times, 2); 151 | $tAccount = $tInterest + $account; 152 | // 返回总数据 153 | if ($type == "all") { 154 | return array( 155 | 'repayment_account' => $tAccount, 156 | 'monthly_repayment' => $tAccount, 157 | 'month_apr' => round($year_apr / 12, 2), 158 | ); 159 | } 160 | $_result = array(); 161 | $_result['repayment_account'] = $tAccount; 162 | if ($month_times % 30 == 0) { 163 | $month_times = ceil($month_times / 30) - 1; 164 | //@todo 到期还本付息新算法计算还款时间 165 | $_result['repayment_time'] = $this->getRepamentTime($borrow_time, $month_times, 'ebx'); 166 | } else { 167 | //@todo 到期还本付息新算法计算还款时间 168 | $time = $this->formatTime($borrow_time); 169 | $_result['repayment_time'] = strtotime($month_times . ' day', $time); 170 | } 171 | $_result['interest'] = $tInterest; 172 | $_result['capital'] = $account; 173 | return array($_result); 174 | } 175 | 176 | /** 177 | * 根据放款时间获取具体期数还款截止时间 178 | * @todo 新规则还款时间精确到天,解决30号、31号、1号时间问题 179 | * @param int $debitTime 放款时间 180 | * @param int $order 期数 181 | * @param int $borrowStyle 融资还款方式 [yxb按月等额本息 | yx_eb按月付息到期还本 | ebx到期还本付息 | jx_eb按季付息到期还本] 182 | * @author xiebin 183 | */ 184 | function getRepamentTime($debitTime, $order, $borrowStyle) 185 | { 186 | $repayment_time = 0; 187 | if ("yxb" == $borrowStyle || "yx_eb" == $borrowStyle) { 188 | $repayment_time = $this->formatTime($debitTime, $order + 1); 189 | } elseif ("ebx" == $borrowStyle) { 190 | $repayment_time = $this->formatTime($debitTime, $order + 1); 191 | } elseif ("jx_eb" == $borrowStyle) { 192 | $repayment_time = $this->formatTime($debitTime, ($order + 1) * 3); 193 | } 194 | return $repayment_time; 195 | } 196 | 197 | /** 198 | * 格式化时间并判断 199 | * @param int $time 时间戳 200 | * @param int $order 期数[取值范围1-12] 201 | * @author xiebin 202 | */ 203 | function formatTime($time, $order = 1) 204 | { 205 | //格式化时间并判断 206 | list($y, $m, $d, $h, $i, $s) = explode(' ', date('Y m d H i s', $time)); 207 | if ($d == 30 || $d == 31) { //如果是30号或者31号放款 208 | /** 209 | * @todo 解决还款计划2月跨年问题 210 | */ 211 | $diff = intval(($m + $order) / 12); 212 | $month = ($m + $order) > 12 ? ($m + $order - $diff * 12) : $m + $order; //获取月份 213 | if ($month == 2) { //如果是2月 214 | $day = date('t', mktime(0, 0, 0, 2, 1, $y + $diff)); //获取2月天数 215 | $timestamp = mktime(23, 59, 59, 2, $day, $y + $diff); 216 | } else { 217 | $timestamp = mktime(0, 0, 0, $m + $order, $d, $y) - 1; 218 | } 219 | } else { 220 | $timestamp = mktime(0, 0, 0, $m + $order, $d, $y) - 1; 221 | } 222 | return $timestamp; 223 | } 224 | } --------------------------------------------------------------------------------