[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    koffice/kspread/functions
From:       Marijn Kruisselbrink <m.kruisselbrink () student ! tue ! nl>
Date:       2010-06-13 14:24:25
Message-ID: 20100613142425.D43D6AC8D4 () svn ! kde ! org
[Download RAW message or body]

SVN commit 1137561 by mkruisselbrink:

Add support for the IRR function. Unit tests still need to be added


 M  +49 -4     financial.cpp  
 M  +18 -0     financial.xml  


--- trunk/koffice/kspread/functions/financial.cpp #1137560:1137561
@@ -73,7 +73,7 @@
 Value func_fv_annuity(valVector args, ValueCalc *calc, FuncExtra *);
 Value func_intrate(valVector args, ValueCalc *calc, FuncExtra *);
 Value func_ipmt(valVector args, ValueCalc *calc, FuncExtra *);
-// Value func_irr (valVector args, ValueCalc *calc, FuncExtra *);
+Value func_irr (valVector args, ValueCalc *calc, FuncExtra *);
 Value func_ispmt(valVector args, ValueCalc *calc, FuncExtra *);
 Value func_level_coupon(valVector args, ValueCalc *calc, FuncExtra *);
 Value func_mduration(valVector args, ValueCalc *calc, FuncExtra *);
@@ -227,9 +227,10 @@
     f = new Function("IPMT", func_ipmt);
     f->setParamCount(4, 6);
   add(f);
-//   f = new Function ("IRR", func_irr);
-//   f->setParamCount (1, 2);
-//   add(f);
+    f = new Function ("IRR", func_irr);
+    f->setParamCount (1, 2);
+    f->setAcceptArray();
+  add(f);
     f = new Function("ISPMT", func_ispmt);
     f->setParamCount(4);
   add(f);
@@ -1362,8 +1363,52 @@
     return helper_ipmt(calc, rate, per, nper, pv, fv, type);
 }
 
+static double irrResult(Value sec, ValueCalc *calc, double rate)
+{
+    double res = 0;
+    for (unsigned i = 0; i < sec.count(); i++) {
+        double val = calc->conv()->asFloat(sec.element(i)).asFloat();
+        res += val / pow(1.0 + rate, double(i));
+    }
+    return res;
+}
 
+static double irrResultDerive(Value sec, ValueCalc *calc, double rate)
+{
+    double res = 0;
+    for (unsigned i = 0; i < sec.count(); i++) {
+        double val = calc->conv()->asFloat(sec.element(i)).asFloat();
+        res += -double(i) * val / pow(1.0 + rate, double(i + 1));
+    }
+    return res;
+}
+
 //
+// Function: IRR
+//
+Value func_irr(valVector args, ValueCalc *calc, FuncExtra *)
+{
+    static const double maxEpsilon = 1e-10;
+    static const int maxIter = 50;
+
+    Value seq = args[0];
+
+    double rate = 0.1;
+    if (args.count() > 1) rate = calc->conv()->asFloat(args[1]).asFloat();
+
+    bool contLoop;
+    int i = 0;
+    do {
+        double newRate = rate - irrResult(seq, calc, rate) / irrResultDerive(seq, calc, rate);
+        double rateEpsilon = fabs(newRate - rate);
+        rate = newRate;
+        contLoop = (rateEpsilon > maxEpsilon) && (fabs(rate) > maxEpsilon);
+    } while (contLoop && (++i < maxIter));
+
+    return Value(rate);
+}
+
+//
 // Function: ISPMT
 //
 Value func_ispmt(valVector args, ValueCalc *calc, FuncExtra *)
--- trunk/koffice/kspread/functions/financial.xml #1137560:1137561
@@ -672,6 +672,24 @@
     </Function>
 
     <Function>
+      <Name>IRR</Name>
+      <Type>Float</Type>
+      <Parameter>
+        <Comment>Values</Comment>
+        <Type>Float</Type>
+      </Parameter>
+      <Parameter>
+        <Comment>Guess</Comment>
+        <Type>Float</Type>
+      </Parameter>
+      <Help>
+        <Text>The IRR function calculates the internal rate of return for a series of cash flows.</Text>
+        <Syntax>IRR( Values[; Guess = 0.1 ] )</Syntax>
+        <Related>XIRR</Related>
+      </Help>
+    </Function>
+
+    <Function>
       <Name>ISPMT</Name>
       <Type>Float</Type>
       <Parameter>
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic