irr以及apr利率计算 php代码

2020-12-17 09:22:49   工作备份

 

  1. class InterestRateService
  2. {
  3. private $precision = 0.001; //夹逼准则 精度范围
  4. private $principal = 0; //本金
  5. private $flow = []; //还款数据
  6. private $payment_method = 0; //还款方式 0按月还款 1按年还款
  7. private $i = 100; //最大循环次数
  8. public static function getInstance()
  9. {
  10. return new self();
  11. }
  12. /**
  13. * @param $principal//本金
  14. * @param array $flow//还款数据
  15. * @param int $payment_method//还款方式 0按月还款 1按年还款
  16. *
  17. * @return $this
  18. */
  19. public function setPrecision($principal, $flow = [], $payment_method = 0)
  20. {
  21. $this->principal = $principal;
  22. $this->flow = $flow;
  23. $this->payment_method = $payment_method;
  24. return $this;
  25. }
  26. /**
  27. * irr利率计算.
  28. *
  29. * @return string
  30. */
  31. public function irrCalculate()
  32. {
  33. $principal = $this->principal;
  34. $precision = $this->precision;
  35. $i = $this->i;
  36. $flow = $this->flow;
  37. $net_present_value = 1;
  38. $min = -10;
  39. $max = 10;
  40. $guess = 0;
  41. $k = 0;
  42. while (abs($net_present_value - $principal) > $precision && $k <= $i) {
  43. ++$k;
  44. $net_present_value = 0;
  45. $guess = ($min + $max) / 2;
  46. foreach ($flow as $period=>$cash_flow) {
  47. $net_present_value += $cash_flow / pow(1 + $guess, $period + 1);
  48. }
  49. if ($net_present_value - $principal > 0) {
  50. $min = $guess;
  51. } else {
  52. $max = $guess;
  53. }
  54. }
  55. return ($guess * 100) . '%';
  56. }
  57. /**
  58. * 还款数据返回.
  59. *
  60. * @return array
  61. */
  62. public function remainingAmount()
  63. {
  64. $principal = $this->principal;
  65. $flow = $this->flow;
  66. $array = [];
  67. foreach ($flow as $i=>$value) {
  68. $array[] = [
  69. 'key' => $i + 1,
  70. 'money'=> $value,
  71. 'left' => $principal - $value,
  72. ];
  73. $principal = $principal - $value;
  74. }
  75. return $array;
  76. }
  77. /**
  78. * apr利率计算.
  79. *
  80. * @return string
  81. */
  82. public function aprCalculate()
  83. {
  84. $periods = $this->getPeriods();
  85. $principal = $this->principal;
  86. $flow = $this->flow;
  87. return (((array_sum($flow) - $principal) / $principal) / ($periods / 12) * 100) . '%';
  88. }
  89. /**
  90. * @return float|int
  91. */
  92. private function getPeriods()
  93. {
  94. if (0 == $this->payment_method) {
  95. //按月还款
  96. return count($this->flow);
  97. }
  98. return 12 * count($this->flow);
  99. }
  100. }