mirror of https://github.com/apache/poi.git
[github-733] Fix rate order in Mirr function. Thanks to Aleksandrs Jansons. This closes #733
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1922095 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
0d63f9a814
commit
edb9aeaca5
|
@ -56,23 +56,20 @@ public class Mirr extends MultiOperandNumericFunction {
|
||||||
@Override
|
@Override
|
||||||
protected double evaluate(double[] values) throws EvaluationException {
|
protected double evaluate(double[] values) throws EvaluationException {
|
||||||
|
|
||||||
double financeRate = values[values.length-1];
|
double financeRate = values[values.length-2];
|
||||||
double reinvestRate = values[values.length-2];
|
double reinvestRate = values[values.length-1];
|
||||||
|
|
||||||
double[] mirrValues = Arrays.copyOf(values, values.length - 2);
|
double[] mirrValues = Arrays.copyOf(values, values.length - 2);
|
||||||
|
|
||||||
boolean mirrValuesAreAllNegatives = true;
|
boolean mirrValuesAreAllNegatives = true;
|
||||||
|
boolean mirrValuesAreAllPositives = true;
|
||||||
for (double mirrValue : mirrValues) {
|
for (double mirrValue : mirrValues) {
|
||||||
mirrValuesAreAllNegatives &= mirrValue < 0;
|
mirrValuesAreAllNegatives &= mirrValue < 0;
|
||||||
|
mirrValuesAreAllPositives &= mirrValue > 0;
|
||||||
}
|
}
|
||||||
if (mirrValuesAreAllNegatives) {
|
if (mirrValuesAreAllNegatives) {
|
||||||
return -1.0d;
|
return -1.0d;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean mirrValuesAreAllPositives = true;
|
|
||||||
for (double mirrValue : mirrValues) {
|
|
||||||
mirrValuesAreAllPositives &= mirrValue > 0;
|
|
||||||
}
|
|
||||||
if (mirrValuesAreAllPositives) {
|
if (mirrValuesAreAllPositives) {
|
||||||
throw new EvaluationException(ErrorEval.DIV_ZERO);
|
throw new EvaluationException(ErrorEval.DIV_ZERO);
|
||||||
}
|
}
|
||||||
|
@ -87,15 +84,11 @@ public class Mirr extends MultiOperandNumericFunction {
|
||||||
double fv = 0;
|
double fv = 0;
|
||||||
|
|
||||||
int indexN = 0;
|
int indexN = 0;
|
||||||
for (double anIn : in) {
|
|
||||||
if (anIn < 0) {
|
|
||||||
pv += anIn / Math.pow(1 + financeRate + reinvestRate, indexN++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (double anIn : in) {
|
for (double anIn : in) {
|
||||||
if (anIn > 0) {
|
if (anIn > 0) {
|
||||||
fv += anIn * Math.pow(1 + financeRate, numOfYears - indexN++);
|
fv += anIn * Math.pow(1 + reinvestRate, numOfYears - indexN++);
|
||||||
|
} else if (anIn < 0) {
|
||||||
|
pv += anIn / Math.pow(1 + financeRate, indexN++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,43 +44,44 @@ final class TestMirr {
|
||||||
Mirr mirr = new Mirr();
|
Mirr mirr = new Mirr();
|
||||||
double mirrValue;
|
double mirrValue;
|
||||||
|
|
||||||
double financeRate = 0.12;
|
double financeRate = 0.1;
|
||||||
double reinvestRate = 0.1;
|
double reinvestRate = 0.12;
|
||||||
double[] values = {-120000d, 39000d, 30000d, 21000d, 37000d, 46000d, reinvestRate, financeRate};
|
double[] values = {-120000d, 39000d, 30000d, 21000d, 37000d, 46000d, financeRate, reinvestRate};
|
||||||
// MIRR should not failed with these parameters
|
|
||||||
mirrValue = mirr.evaluate(values);
|
mirrValue = mirr.evaluate(values);
|
||||||
assertEquals(0.126094130366, mirrValue, 0.0000000001);
|
assertEquals(0.126094130366, mirrValue, 0.0000000001);
|
||||||
|
|
||||||
reinvestRate = 0.05;
|
financeRate = 0.05;
|
||||||
financeRate = 0.08;
|
reinvestRate = 0.08;
|
||||||
values = new double[]{-7500d, 3000d, 5000d, 1200d, 4000d, reinvestRate, financeRate};
|
values = new double[]{-7500d, 3000d, 5000d, 1200d, 4000d, financeRate, reinvestRate};
|
||||||
// MIRR should not failed with these parameters
|
|
||||||
mirrValue = mirr.evaluate(values);
|
mirrValue = mirr.evaluate(values);
|
||||||
assertEquals(0.18736225093, mirrValue, 0.0000000001);
|
assertEquals(0.18736225093, mirrValue, 0.0000000001);
|
||||||
|
|
||||||
reinvestRate = 0.065;
|
financeRate = 0.065;
|
||||||
financeRate = 0.1;
|
reinvestRate = 0.1;
|
||||||
values = new double[]{-10000, 3400d, 6500d, 1000d, reinvestRate, financeRate};
|
values = new double[]{-10000, 3400d, 6500d, 1000d, financeRate, reinvestRate};
|
||||||
// MIRR should not failed with these parameters
|
|
||||||
mirrValue = mirr.evaluate(values);
|
mirrValue = mirr.evaluate(values);
|
||||||
assertEquals(0.07039493966, mirrValue, 0.0000000001);
|
assertEquals(0.07039493966, mirrValue, 0.0000000001);
|
||||||
|
|
||||||
reinvestRate = 0.07;
|
financeRate = 0.07;
|
||||||
financeRate = 0.01;
|
reinvestRate = 0.01;
|
||||||
values = new double[]{-10000d, -3400d, -6500d, -1000d, reinvestRate, financeRate};
|
values = new double[]{-10000d, -3400d, -6500d, -1000d, financeRate, reinvestRate};
|
||||||
// MIRR should not failed with these parameters
|
|
||||||
mirrValue = mirr.evaluate(values);
|
mirrValue = mirr.evaluate(values);
|
||||||
assertEquals(-1, mirrValue, 0.0);
|
assertEquals(-1, mirrValue, 0.0);
|
||||||
|
|
||||||
|
financeRate = 0.1;
|
||||||
|
reinvestRate = 0.12;
|
||||||
|
values = new double[]{-1000d, -4000d, 5000d, 2000d, financeRate, reinvestRate};
|
||||||
|
mirrValue = mirr.evaluate(values);
|
||||||
|
assertEquals(0.179085686035, mirrValue, 0.0000000001);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testMirrErrors_expectDIV0() {
|
void testMirrErrors_expectDIV0() {
|
||||||
Mirr mirr = new Mirr();
|
Mirr mirr = new Mirr();
|
||||||
|
|
||||||
double reinvestRate = 0.05;
|
|
||||||
double financeRate = 0.08;
|
double financeRate = 0.08;
|
||||||
double[] incomes = {120000d, 39000d, 30000d, 21000d, 37000d, 46000d, reinvestRate, financeRate};
|
double reinvestRate = 0.05;
|
||||||
|
double[] incomes = {120000d, 39000d, 30000d, 21000d, 37000d, 46000d, financeRate, reinvestRate};
|
||||||
|
|
||||||
EvaluationException e = assertThrows(EvaluationException.class, () -> mirr.evaluate(incomes));
|
EvaluationException e = assertThrows(EvaluationException.class, () -> mirr.evaluate(incomes));
|
||||||
assertEquals(ErrorEval.DIV_ZERO, e.getErrorEval());
|
assertEquals(ErrorEval.DIV_ZERO, e.getErrorEval());
|
||||||
|
@ -117,7 +118,7 @@ final class TestMirr {
|
||||||
HSSFSheet sheet = wb.getSheet("Mirr");
|
HSSFSheet sheet = wb.getSheet("Mirr");
|
||||||
HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
|
HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
|
||||||
int failureCount = 0;
|
int failureCount = 0;
|
||||||
int[] resultRows = {9, 19, 29, 45};
|
int[] resultRows = {9, 19, 29, 45, 53};
|
||||||
|
|
||||||
for (int rowNum : resultRows) {
|
for (int rowNum : resultRows) {
|
||||||
HSSFRow row = sheet.getRow(rowNum);
|
HSSFRow row = sheet.getRow(rowNum);
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue