You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

FinanceLib.java 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /* ====================================================================
  2. Licensed to the Apache Software Foundation (ASF) under one or more
  3. contributor license agreements. See the NOTICE file distributed with
  4. this work for additional information regarding copyright ownership.
  5. The ASF licenses this file to You under the Apache License, Version 2.0
  6. (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.ss.formula.functions;
  16. /**
  17. * This class is a function library for common fiscal functions.
  18. * <b>Glossary of terms/abbreviations:</b>
  19. * <br>
  20. * <ul>
  21. * <li><em>FV:</em> Future Value</li>
  22. * <li><em>PV:</em> Present Value</li>
  23. * <li><em>NPV:</em> Net Present Value</li>
  24. * <li><em>PMT:</em> (Periodic) Payment</li>
  25. *
  26. * </ul>
  27. * For more info on the terms/abbreviations please use the references below
  28. * (hyperlinks are subject to change):
  29. * <p>
  30. * Online References:
  31. * <ol>
  32. * <li>GNU Emacs Calc 2.02 Manual: http://theory.uwinnipeg.ca/gnu/calc/calc_203.html</li>
  33. * <li>Yahoo Financial Glossary: http://biz.yahoo.com/f/g/nn.html#y</li>
  34. * <li>MS Excel function reference: http://office.microsoft.com/en-us/assistance/CH062528251033.aspx</li>
  35. * </ol>
  36. *
  37. * Implementation Notes:<p>
  38. *
  39. * Symbols used in the formulae that follow:<br>
  40. * <ul>
  41. * <li>p: present value</li>
  42. * <li>f: future value</li>
  43. * <li>n: number of periods</li>
  44. * <li>y: payment (in each period)</li>
  45. * <li>r: rate</li>
  46. * <li>^: the power operator (NOT the java bitwise XOR operator!)</li>
  47. * </ul>
  48. * [From MS Excel function reference] Following are some of the key formulas
  49. * that are used in this implementation:
  50. * <pre>
  51. * p(1+r)^n + y(1+rt)((1+r)^n-1)/r + f=0 ...{when r!=0}
  52. * ny + p + f=0 ...{when r=0}
  53. * </pre>
  54. */
  55. public final class FinanceLib {
  56. private FinanceLib() {
  57. // no instances of this class
  58. }
  59. /**
  60. * Future value of an amount given the number of payments, rate, amount
  61. * of individual payment, present value and boolean value indicating whether
  62. * payments are due at the beginning of period
  63. * (false =&gt; payments are due at end of period)
  64. * @param r rate
  65. * @param n num of periods
  66. * @param y pmt per period
  67. * @param p present value
  68. * @param t type (true=pmt at beginning of period, false=pmt at end of period)
  69. */
  70. public static double fv(double r, double n, double y, double p, boolean t) {
  71. if (r == 0) {
  72. return -1*(p+(n*y));
  73. } else {
  74. double r1 = r + 1;
  75. return ((1-Math.pow(r1, n)) * (t ? r1 : 1) * y ) / r
  76. -
  77. p*Math.pow(r1, n);
  78. }
  79. }
  80. /**
  81. * Present value of an amount given the number of future payments, rate, amount
  82. * of individual payment, future value and boolean value indicating whether
  83. * payments are due at the beginning of period
  84. * (false =&gt; payments are due at end of period)
  85. * @param r rate
  86. * @param n num of periods
  87. * @param y pmt per period
  88. * @param f future value
  89. * @param t type (true=pmt at beginning of period, false=pmt at end of period)
  90. */
  91. public static double pv(double r, double n, double y, double f, boolean t) {
  92. if (r == 0) {
  93. return -1*((n*y)+f);
  94. } else {
  95. double r1 = r + 1;
  96. return (( ( 1 - Math.pow(r1, n) ) / r ) * (t ? r1 : 1) * y - f)
  97. /
  98. Math.pow(r1, n);
  99. }
  100. }
  101. /**
  102. * calculates the Net Present Value of a principal amount
  103. * given the discount rate and a sequence of cash flows
  104. * (supplied as an array). If the amounts are income the value should
  105. * be positive, else if they are payments and not income, the
  106. * value should be negative.
  107. * @param r rate
  108. * @param cfs cashflow amounts
  109. */
  110. public static double npv(double r, double[] cfs) {
  111. double npv = 0;
  112. for (int i=0;i<arr.length;i++)
  113. {
  114. npv+=cfs[i]/Math.pow(1+r,i);
  115. }
  116. return npv;
  117. }
  118. /**
  119. *
  120. * @param r rate
  121. * @param n num of periods
  122. * @param p present value
  123. * @param f future value
  124. * @param t type (true=pmt at beginning of period, false=pmt at end of period)
  125. */
  126. public static double pmt(double r, double n, double p, double f, boolean t) {
  127. if (r == 0) {
  128. return -1*(f+p)/n;
  129. } else {
  130. double r1 = r + 1;
  131. return ( f + p * Math.pow(r1, n) ) * r
  132. /
  133. ((t ? r1 : 1) * (1 - Math.pow(r1, n)));
  134. }
  135. }
  136. /**
  137. *
  138. * @param r rate
  139. * @param y pmt per period
  140. * @param p present value
  141. * @param f future value
  142. * @param t type (true=pmt at beginning of period, false=pmt at end of period)
  143. */
  144. public static double nper(double r, double y, double p, double f, boolean t) {
  145. if (r == 0) {
  146. return -1 * (f + p) / y;
  147. } else {
  148. double r1 = r + 1;
  149. double ryr = (t ? r1 : 1) * y / r;
  150. double a1 = ((ryr - f) < 0)
  151. ? Math.log(f - ryr)
  152. : Math.log(ryr - f);
  153. double a2 = ((ryr - f) < 0)
  154. ? Math.log(-p - ryr)
  155. : Math.log(p + ryr);
  156. double a3 = Math.log(r1);
  157. return (a1 - a2) / a3;
  158. }
  159. }
  160. }