27#include "kspread_functions_helper.h"
29#include "valueconverter.h"
32#include <kcalendarsystem.h>
40Value func_continuous (valVector args,
ValueCalc *calc, FuncExtra *);
48Value func_effective (valVector args,
ValueCalc *calc, FuncExtra *);
51Value func_fv_annuity (valVector args,
ValueCalc *calc, FuncExtra *);
55Value func_level_coupon (valVector args,
ValueCalc *calc, FuncExtra *);
61Value func_pv_annuity (valVector args,
ValueCalc *calc, FuncExtra *);
66Value func_tbillprice (valVector args,
ValueCalc *calc, FuncExtra *);
67Value func_tbillyield (valVector args,
ValueCalc *calc, FuncExtra *);
68Value func_zero_coupon (valVector args,
ValueCalc *calc, FuncExtra *);
71void RegisterFinancialFunctions()
73 FunctionRepository* repo = FunctionRepository::self();
76 f =
new Function (
"ACCRINT", func_accrint);
77 f->setParamCount (6, 7);
79 f =
new Function (
"ACCRINTM", func_accrintm);
80 f->setParamCount (3, 5);
82 f =
new Function (
"COMPOUND", func_compound);
85 f =
new Function (
"CONTINUOUS", func_continuous);
88 f =
new Function (
"COUPNUM", func_coupnum);
89 f->setParamCount (3, 5);
91 f =
new Function (
"DB", func_db);
92 f->setParamCount (4, 5);
94 f =
new Function (
"DDB", func_ddb);
95 f->setParamCount (4, 5);
97 f =
new Function (
"DISC", func_disc);
98 f->setParamCount (4, 5);
100 f =
new Function (
"DOLLARDE", func_dollarde);
101 f->setParamCount (2);
103 f =
new Function (
"DOLLARFR", func_dollarfr);
104 f->setParamCount (2);
106 f =
new Function (
"DURATION", func_duration);
107 f->setParamCount (3);
109 f =
new Function (
"EFFECT", func_effective);
110 f->setParamCount (2);
112 f =
new Function (
"EFFECTIVE", func_effective);
113 f->setParamCount (2);
115 f =
new Function (
"EURO", func_euro);
116 f->setParamCount (1);
118 f =
new Function (
"FV", func_fv);
119 f->setParamCount (3);
121 f =
new Function (
"FV_ANNUITY", func_fv_annuity);
122 f->setParamCount (3);
124 f =
new Function (
"INTRATE", func_intrate);
125 f->setParamCount (4, 5);
127 f =
new Function (
"IPMT", func_ipmt);
128 f->setParamCount (4, 6);
130 f =
new Function (
"ISPMT", func_ispmt);
131 f->setParamCount (4);
133 f =
new Function (
"LEVEL_COUPON", func_level_coupon);
134 f->setParamCount (5);
136 f =
new Function (
"NOMINAL", func_nominal);
137 f->setParamCount (2);
139 f =
new Function (
"NPER", func_nper);
140 f->setParamCount (3, 5);
142 f =
new Function (
"PMT", func_pmt);
143 f->setParamCount (3, 5);
145 f =
new Function (
"PPMT", func_ppmt);
146 f->setParamCount (4, 6);
148 f =
new Function (
"PV", func_pv);
149 f->setParamCount (3);
151 f =
new Function (
"PV_ANNUITY", func_pv_annuity);
152 f->setParamCount (3);
154 f =
new Function (
"RECEIVED", func_received);
155 f->setParamCount (4, 5);
157 f =
new Function (
"SLN", func_sln);
158 f->setParamCount (3);
160 f =
new Function (
"SYD", func_syd);
161 f->setParamCount (4);
163 f =
new Function (
"TBILLEQ", func_tbilleq);
164 f->setParamCount (3);
166 f =
new Function (
"TBILLPRICE", func_tbillprice);
167 f->setParamCount (3);
169 f =
new Function (
"TBILLYIELD", func_tbillyield);
170 f->setParamCount (3);
172 f =
new Function (
"ZERO_COUPON", func_zero_coupon);
173 f->setParamCount (3);
186 pvif = calc->pow (calc->
add (rate, 1), nper);
187 fvifa = calc->div (calc->sub (pvif, 1), rate);
190 Value val1 = calc->sub (calc->mul (calc->mul (-1, pv), pvif), fv);
191 Value val2 = calc->mul (calc->
add (1.0, calc->mul (rate, type)),
193 return calc->div (val1, val2);
200 Value val1 = calc->pow (calc->
add (rate, 1), period);
202 Value val2 = calc->mul (start, val1);
204 Value val3 = calc->mul (pay, calc->div (calc->sub (val1, 1), rate));
206 return calc->
add (val2, val3);
213 TQDate settlement = calc->conv()->asDate (args[0]).
asDate();
214 TQDate maturity = calc->conv()->asDate (args[1]).
asDate();
215 int frequency = calc->conv()->asInteger (args[2]).
asInteger();
218 if (args.count() > 3)
219 basis = calc->conv()->asInteger (args[3]).
asInteger();
220 if (args.count() == 5)
221 eom = calc->conv()->asBoolean (args[4]).
asBoolean();
223 if (basis < 0 || basis > 5 || ( frequency == 0 ) || ( 12 % frequency != 0 )
224 || settlement.daysTo( maturity ) <= 0)
228 TQDate cDate( maturity );
230 int months = maturity.month() - settlement.month()
231 + 12 * ( maturity.year() - settlement.year() );
233 cDate = calc->conv()->locale()->calendar()->addMonths (cDate, -months);
235 if ( eom && maturity.daysInMonth() == maturity.day() )
237 while( cDate.daysInMonth() != cDate.day() )
241 if ( settlement.day() >= cDate.day() )
244 result = ( 1 + months / ( 12 / frequency ) );
246 return Value (result);
252 TQDate maturity = calc->conv()->asDate (args[0]).
asDate();
253 TQDate firstInterest = calc->conv()->asDate (args[1]).
asDate();
254 TQDate settlement = calc->conv()->asDate (args[2]).
asDate();
256 Value rate = args[3];
258 int frequency = calc->conv()->asInteger (args[5]).
asInteger();
261 if (args.count() == 7)
262 basis = calc->conv()->asInteger (args[6]).
asInteger();
264 if ( basis < 0 || basis > 4 || (calc->
isZero (frequency)) ||
265 (12 % frequency != 0))
268 if ( ( settlement.daysTo( firstInterest ) < 0 )
269 || ( firstInterest.daysTo( maturity ) > 0 ) )
272 double d = daysBetweenDates (maturity, settlement, basis);
273 double y = daysPerYear (maturity, basis);
275 if ( d < 0 || y <= 0 || calc->lower (par, 0) || calc->
lower (rate, 0) ||
279 Value coeff = calc->div (calc->mul (par, rate), frequency);
282 return calc->mul (coeff, n * frequency);
288 TQDate issue = calc->conv()->asDate (args[0]).
asDate();
289 TQDate maturity = calc->conv()->asDate (args[1]).
asDate();
290 Value rate = args[2];
294 if (args.count() > 3)
296 if (args.count() == 5)
297 basis = calc->conv()->asInteger (args[4]).
asInteger ();
299 double d = daysBetweenDates (issue, maturity, basis);
300 double y = daysPerYear (issue, basis);
302 if (d < 0 || y <= 0 || calc->isZero (par) || calc->
isZero (rate) ||
303 calc->
lower (par, 0) || calc->
lower (rate, 0) || basis < 0 || basis > 4)
307 return calc->mul (calc->mul (par, rate), d / y);
313 TQDate settlement = calc->conv()->asDate (args[0]).
asDate();
314 TQDate maturity = calc->conv()->asDate (args[1]).
asDate();
317 Value redemp = args[3];
320 if (args.count() == 5)
321 basis = calc->conv()->asInteger (args[4]).
asInteger();
323 double y = daysPerYear (settlement, basis);
324 double d = daysBetweenDates (settlement, maturity, basis);
326 if ( y <= 0 || d <= 0 || basis < 0 || basis > 4 || calc->
isZero (redemp) )
330 return calc->mul (calc->div (calc->sub (redemp, par), redemp), y / d);
335Value func_tbillprice (valVector args,
ValueCalc *calc, FuncExtra *)
337 TQDate settlement = calc->conv()->asDate (args[0]).
asDate();
338 TQDate maturity = calc->conv()->asDate (args[1]).
asDate();
340 Value discount = args[2];
342 double days = settlement.daysTo( maturity );
344 if (settlement > maturity || calc->
lower (discount, 0) || days > 265)
348 Value val = calc->div (calc->mul (discount, days), 360.0);
350 return calc->mul (calc->sub (1.0, val), 100);
354Value func_tbillyield (valVector args,
ValueCalc *calc, FuncExtra *)
356 TQDate settlement = calc->conv()->asDate (args[0]).
asDate();
357 TQDate maturity = calc->conv()->asDate (args[1]).
asDate();
359 Value rate = args[2];
361 double days = settlement.daysTo( maturity );
363 if (settlement > maturity || calc->
isZero (rate) || calc->
lower (rate, 0)
368 return calc->mul (calc->div (calc->sub (100.0, rate), rate), 360.0 / days);
374 TQDate settlement = calc->conv()->asDate (args[0]).
asDate();
375 TQDate maturity = calc->conv()->asDate (args[1]).
asDate();
377 Value discount = args[2];
379 double days = settlement.daysTo( maturity );
381 if (settlement > maturity || calc->
lower (discount, 0) || days > 265)
385 Value divisor = calc->sub (360.0, calc->mul (discount, days));
386 if (calc->
isZero (divisor))
390 return calc->mul (calc->div (discount, divisor), 356.0);
397 TQDate settlement = calc->conv()->asDate (args[0]).
asDate();
398 TQDate maturity = calc->conv()->asDate (args[1]).
asDate();
400 Value investment = args[2];
401 Value discount = args[3];
404 if (args.count() == 5)
405 basis = calc->conv()->asInteger (args[4]).
asInteger();
407 double d = daysBetweenDates( settlement, maturity, basis );
408 double y = daysPerYear( settlement, basis );
410 if ( d <= 0 || y <= 0 || basis < 0 || basis > 4 )
414 Value x = calc->sub (1.0, (calc->mul (discount, d / y)));
418 return calc->div (investment, x);
434 tmp = calc->div (tmp, 10);
439 Value r = calc->sub (d, fl);
442 return calc->
add (fl, calc->div (calc->mul (r, pow (10.0, n)), f));
458 tmp = calc->div (tmp, 10);
463 Value r = calc->sub (d, fl);
466 return calc->
add (fl, calc->div (calc->mul (r, f), pow (10.0, n)));
474 TQDate settlement = calc->conv()->asDate (args[0]).
asDate();
475 TQDate maturity = calc->conv()->asDate (args[1]).
asDate();
477 Value invest = args[2];
478 Value redemption = args[3];
481 if (args.count() == 5)
482 basis = calc->conv()->asInteger (args[4]).
asInteger();
484 double d = daysBetweenDates (settlement, maturity, basis);
485 double y = daysPerYear (settlement, basis);
487 if ( d <= 0 || y <= 0 || calc->isZero (invest) || basis < 0 || basis > 4 )
491 return calc->mul (calc->div (calc->sub (redemption, invest), invest), y/d);
498 Value rate = args[0];
502 if (!calc->
greater (rate, 0.0))
507 if (calc->
lower (calc->div (fv, pv), 0))
511 return calc->div (calc->ln (calc->div (fv, pv)),
512 calc->ln (calc->
add (rate, 1.0)));
518 Value rate = args[0];
519 Value nper = args[1];
523 if (args.count() > 3) fv = args[3];
524 if (args.count() == 5) type = args[4];
526 return getPay (calc, rate, nper, pv, fv, type);
532 Value rate = args[0];
537 if (args.count() > 3) fv = args[3];
538 if (args.count() == 5) type = args[4];
540 if (!calc->
greater (rate, 0.0))
548 Value v = calc->
add (calc->mul (rate, type), 1.0);
549 Value d1 = calc->sub (calc->mul (pmt, v), calc->mul (fv, rate));
550 Value d2 = calc->
add (calc->mul (pmt, v), calc->mul (pv, rate));
551 Value res = calc->div (d1, d2);
557 return calc->div (calc->ln (res), calc->ln (calc->
add (rate, 1.0)));
563 Value rate = args[0];
565 Value nper = args[2];
572 Value d = calc->mul (calc->mul (pv, -1), rate);
575 return calc->sub (d, calc->mul (calc->div (d, nper), per));
581 Value rate = args[0];
583 Value nper = args[2];
588 if (args.count() > 4) fv = args[4];
589 if (args.count() == 6) type = args[5];
591 Value payment = getPay (calc, rate, nper, pv, fv, type);
592 Value ineg = getPrinc (calc, pv, payment, rate, calc->sub (per, 1));
595 return calc->mul (calc->mul (ineg, -1), rate);
615 Value rate = args[0];
617 Value nper = args[2];
621 if (args.count() > 4) fv = args[4];
622 if (args.count() == 6) type = args[5];
624 Value pay = getPay (calc, rate, nper, pv, fv, type);
625 Value ipmt = func_ipmt (args, calc, 0);
626 return calc->sub (pay, ipmt);
633 Value present = args[0];
634 Value interest = args[1];
635 Value periods = args[2];
638 return calc->mul (present, calc->pow (calc->
add (interest, 1), periods));
644 Value func_compound (valVector args,
ValueCalc *calc, FuncExtra *)
646 Value principal = args[0];
647 Value interest = args[1];
648 Value periods = args[2];
649 Value years = args[3];
652 Value base = calc->
add (calc->div (interest, periods), 1);
653 return calc->mul (principal, calc->pow (base, calc->mul (periods, years)));
659Value func_continuous (valVector args,
ValueCalc *calc, FuncExtra *)
662 Value principal = args[0];
663 Value interest = args[1];
664 Value years = args[2];
667 return calc->mul (principal, calc->exp (calc->mul (interest, years)));
674 Value future = args[0];
675 Value interest = args[1];
676 Value periods = args[2];
679 return calc->div (future, calc->pow (calc->
add (interest, 1), periods));
683Value func_pv_annuity (valVector args,
ValueCalc *calc, FuncExtra *)
685 Value amount = args[0];
686 Value interest = args[1];
687 Value periods = args[2];
692 recpow = calc->div (1, calc->pow (calc->
add (interest, 1), periods));
693 return calc->mul (amount, calc->div (calc->sub (1, recpow), interest));
697Value func_fv_annuity (valVector args,
ValueCalc *calc, FuncExtra *)
702 Value amount = args[0];
703 Value interest = args[1];
704 Value periods = args[2];
708 Value pw = calc->pow (calc->
add (interest, 1), periods);
709 return calc->mul (amount, calc->div (calc->sub (pw, 1), interest));
713Value func_effective (valVector args,
ValueCalc *calc, FuncExtra *)
717 Value nominal = args[0];
718 Value periods = args[1];
722 Value base = calc->
add (calc->div (nominal, periods), 1);
723 return calc->sub (calc->pow (base, periods), 1);
727Value func_zero_coupon (valVector args,
ValueCalc *calc, FuncExtra *)
731 Value face = args[0];
732 Value rate = args[1];
733 Value years = args[2];
736 return calc->div (face, calc->pow (calc->
add (rate, 1), years));
740Value func_level_coupon (valVector args,
ValueCalc *calc, FuncExtra *)
743 Value face = args[0];
744 Value coupon_rate = args[1];
745 Value coupon_year = args[2];
746 Value years = args[3];
747 Value market_rate = args[4];
749 Value coupon, interest, pw, pv_annuity;
755 coupon = calc->mul (coupon_rate, calc->div (face, coupon_year));
756 interest = calc->div (market_rate, coupon_year);
757 pw = calc->pow (calc->
add (interest, 1), calc->mul (years, coupon_year));
758 pv_annuity = calc->div (calc->sub (1, calc->div (1, pw)), interest);
759 return calc->
add (calc->mul (coupon, pv_annuity), calc->div (face, pw));
765 Value effective = args[0];
766 Value periods = args[1];
768 if (calc->
isZero (periods))
774 pw = calc->pow (calc->
add (effective, 1), calc->div (1, periods));
775 return calc->mul (periods, calc->sub (pw, 1));
782 Value cost = args[0];
783 Value salvage_value = args[1];
784 Value life = args[2];
787 if (!calc->
greater (life, 0.0))
791 return calc->div (calc->sub (cost, salvage_value), life);
798 Value cost = args[0];
799 Value salvage_value = args[1];
800 Value life = args[2];
801 Value period = args[3];
804 if (!calc->
greater (life, 0.0))
812 v1 = calc->sub (cost, salvage_value);
813 v2 = calc->
add (calc->sub (life, period), 1);
814 v3 = calc->mul (life, calc->
add (life, 1.0));
815 return calc->div (calc->mul (calc->mul (v1, v2), 2), v3);
825 double cost = calc->conv()->asFloat (args[0]).
asFloat();
826 double salvage = calc->conv()->asFloat (args[1]).
asFloat();
827 double life = calc->conv()->asFloat (args[2]).
asFloat();
828 double period = calc->conv()->asFloat (args[3]).
asFloat();
830 if (args.count() == 5)
831 month = calc->conv()->asFloat (args[4]).
asFloat();
834 if (cost == 0 || life <= 0.0)
837 if (calc->
lower (calc->div (salvage, cost), 0))
840 double rate = 1000 * (1 - pow( (salvage/cost), (1/life) ));
841 rate = floor( rate + 0.5 ) / 1000;
843 double total = cost * rate * month / 12;
846 return Value (total);
848 for (
int i = 1; i < life; ++i)
850 return Value (rate * (cost-total));
851 else total += rate * (cost-total);
853 return Value ((cost-total) * rate * (12-month)/12);
860 double cost = calc->conv()->asFloat (args[0]).
asFloat();
861 double salvage = calc->conv()->asFloat (args[1]).
asFloat();
862 double life = calc->conv()->asFloat (args[2]).
asFloat();
863 double period = calc->conv()->asFloat (args[3]).
asFloat();
865 if (args.count() == 5)
866 factor = calc->conv()->asFloat (args[4]).
asFloat();
870 if ( cost < 0.0 || salvage < 0.0 || life <= 0.0 || period < 0.0 || factor < 0.0 )
873 for(
int i = 0; i < life-1; ++i )
875 double periodDep = ( cost - total ) * ( factor / life );
876 if ( i == period - 1 )
877 return Value (periodDep);
882 return Value (cost - total - salvage);
888 TQString currency = calc->conv()->asString (args[0]).
asString().upper();
891 if( currency ==
"ATS" ) result = 13.7603;
892 else if( currency ==
"BEF" ) result = 40.3399;
893 else if( currency ==
"DEM" ) result = 1.95583;
894 else if( currency ==
"ESP" ) result = 166.386;
895 else if( currency ==
"FIM" ) result = 5.94573;
896 else if( currency ==
"FRF" ) result = 6.55957;
897 else if( currency ==
"GRD" ) result = 340.75;
898 else if( currency ==
"IEP" ) result = 0.787564;
899 else if( currency ==
"ITL" ) result = 1936.27;
900 else if( currency ==
"LUX" ) result = 40.3399;
901 else if( currency ==
"NLG" ) result = 2.20371;
902 else if( currency ==
"PTE" ) result = 200.482;
906 return Value (result);
The ValueCalc class is used to perform all sorts of calculations.
bool greater(const Value &a, const Value &b)
numerical comparison
bool isZero(const Value &a)
comparison and related
Value roundDown(const Value &a, const Value &digits)
rounding
bool lower(const Value &a, const Value &b)
numerical comparison
Value add(const Value &a, const Value &b)
basic arithmetic operations
Provides a wrapper for cell value.
static const Value & errorDIV0()
Returns constant reference to DIV/0!
TQDate asDate() const
Returns the date representation of this value.
double asFloat() const
Returns the floating-point value of this value.
long asInteger() const
Returns the integer value of this value.
TQString asString() const
Returns the string value of this value.
static const Value & errorVALUE()
Returns constant reference to VALUE!
bool asBoolean() const
Returns the boolean value of this value.