-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add financial package, moved from amd-utils. see millermedeiros/amd-u…
- Loading branch information
1 parent
46118ce
commit 45531fe
Showing
12 changed files
with
421 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
# amd-utils / financial # | ||
|
||
Financial math helpers. | ||
|
||
|
||
|
||
## compoundInterest(interestRate, nPeriods, presentValue):Number | ||
|
||
Calculates [compount | ||
interest](http://en.wikipedia.org/wiki/Future_value#Compound_interest) over | ||
a period. | ||
|
||
```js | ||
compoundInterest(0.1, 3, 100); // 133.1 | ||
``` | ||
|
||
|
||
|
||
## futureValue(rate, nPeriods, payment[, presentValue, isDue]):Number | ||
|
||
Calculate the future value of an investment based on periodic, constant | ||
payments at a constant interest rate. (aka. | ||
[annuity](http://en.wikipedia.org/wiki/Annuity_%28finance_theory%29)) - Works | ||
similarly to Microsoft Excel `FV()` function. | ||
|
||
Payments are made at the end of each period by default, set `isDue` to `true` | ||
if payments should be made at the beginning of each period. | ||
|
||
See: [`presentValue()`](#presentValue) | ||
|
||
```js | ||
futureValue(0.12, 12, 1000); // 24133.13 | ||
futureValue(0.12, 12, 1000, 0, true); // 27029.11 | ||
futureValue(0.12, 12, 1000, 500); // 26081.12 | ||
futureValue(0.12, 12, 1000, 500, true); // 28977.10 | ||
``` | ||
|
||
|
||
|
||
## npv(discountRate, values):Number | ||
|
||
Calculates the [net present value](http://en.wikipedia.org/wiki/Net_present_value). | ||
|
||
```js | ||
npv(0.1, [-100, 30, 35, 28, 46]); // 7.867073163159489 | ||
npv(0.1, [30, 35, 28, 46]) - 100; // 8.653780479475415 | ||
``` | ||
|
||
|
||
|
||
## payment(rate, nPeriods, presentValue, futureValue, isDue):Number | ||
|
||
Calculates the payment for a loan based on constant payments and a constant | ||
interest rate. Similar to Microsoft Excel `PMT()` function. (aka. mortgage or | ||
[annuity](http://en.wikipedia.org/wiki/Annuity_%28finance_theory%29)) | ||
|
||
```js | ||
payment(0.05, 10, 1000); // 129.50457496545667 | ||
payment(0.05, 10, 0, 1000); // 79.50457496545668 | ||
``` | ||
|
||
|
||
|
||
## presentValue(rate, nPeriods, payment[, futurevalue, isDue]):Number | ||
|
||
Returns the present value of an investment. The present value is the total | ||
amount that a series of future payments is worth now (aka. | ||
[annuity](http://en.wikipedia.org/wiki/Annuity_%28finance_theory%29)). - Works | ||
similarly to Microsoft Excel `PV()` function. | ||
|
||
Payments are made at the end of each period by default, set `isDue` to `true` | ||
if payments should be made at the beginning of each period. | ||
|
||
See: [`futureValue()`](#futureValue) | ||
|
||
```js | ||
presentValue(0.12, 12, 1000); // 6194.37 | ||
presentValue(0.12, 12, 1000, 0, true); // 6937.70 | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
define(function () { | ||
|
||
/** | ||
* Basic compound interest | ||
* @version 0.2.0 (2012/03/20) | ||
*/ | ||
function compoundInterest(interestRate, nPeriods, presentValue) { | ||
return presentValue * Math.pow(1 + interestRate, nPeriods); | ||
} | ||
|
||
return compoundInterest; | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
define(['./compoundInterest'], function (compoundInterest) { | ||
|
||
/** | ||
* Calculate future value of an investment. | ||
* http://en.wikipedia.org/wiki/Annuity_%28finance_theory%29 | ||
* @version 0.2.0 (2012/03/20) | ||
*/ | ||
function futureValue(rate, nPeriods, payment, presentValue, isDue){ | ||
if (rate === 0) { | ||
//isDue makes no difference since rate is zero.. | ||
return payment * nPeriods; | ||
} else { | ||
var s = payment * ((Math.pow(1 + rate, nPeriods) - 1) / rate); | ||
if (isDue) { | ||
s *= (1 + rate); | ||
} | ||
if (presentValue) { | ||
s += presentValue * Math.pow(1 + rate, nPeriods); | ||
} | ||
return s; | ||
} | ||
} | ||
|
||
return futureValue; | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
define(function () { | ||
|
||
|
||
/** | ||
* Net present value | ||
* http://en.wikipedia.org/wiki/Net_present_value | ||
* @version 0.1.0 (2011/12/30) | ||
*/ | ||
function npv(discountRate, values) { | ||
var val = 0, | ||
n = values.length; | ||
|
||
while (n--) { | ||
val += values[n] / Math.pow(1 + discountRate, n + 1); | ||
} | ||
|
||
return val; | ||
} | ||
|
||
return npv; | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
define(['./compoundInterest'], function (compoundInterest) { | ||
|
||
/** | ||
* Calculates the payment for a loan based on constant payments and | ||
* a constant interest rate. | ||
* http://en.wikipedia.org/wiki/Annuity_%28finance_theory%29 | ||
* @version 0.1.1 (2012/03/20) | ||
*/ | ||
function payment(rate, nPeriods, presentValue, futureValue, isDue){ | ||
futureValue = futureValue || 0; | ||
if (!presentValue && !futureValue) { | ||
return 0; | ||
} else if (rate === 0) { | ||
return (presentValue + futureValue) / nPeriods; | ||
} else { | ||
var r; | ||
r = (rate / (1 - Math.pow(1 + rate, -nPeriods))) * presentValue; | ||
if (futureValue) { | ||
//the "opposite" of financial/futureValue | ||
r += futureValue / ((Math.pow(1 + rate, nPeriods) -1) / rate); | ||
} | ||
return isDue? r / (1 + rate) : r; | ||
} | ||
} | ||
|
||
return payment; | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
define(function () { | ||
|
||
/** | ||
* Returns the present value of an investment. | ||
* http://en.wikipedia.org/wiki/Annuity_%28finance_theory%29 | ||
* @version 0.2.0 (2012/03/20) | ||
*/ | ||
function presentValue(rate, nPeriods, payment, futureValue, isDue){ | ||
if (rate === 0) { | ||
return payment * nPeriods; | ||
} else { | ||
var p = ((1 - Math.pow(1 + rate, - nPeriods)) / rate) * payment; | ||
if (isDue) { | ||
p *= (1 + rate); | ||
} | ||
if (futureValue) { | ||
p += futureValue / Math.pow(1 + rate, nPeriods); | ||
} | ||
return p; | ||
} | ||
} | ||
|
||
return presentValue; | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
define(['src/financial/compoundInterest', 'amd-utils/number/enforcePrecision'], function (compoundInterest, enforcePrecision) { | ||
|
||
describe('financial/compoundInterest()', function () { | ||
|
||
beforeEach(function(){ | ||
this.addMatchers({ | ||
toFinanciallyEqual : function(val){ | ||
return (enforcePrecision(this.actual, 2) === val); | ||
} | ||
}); | ||
}); | ||
|
||
|
||
it('should calculate the compound interest', function () { | ||
|
||
expect( compoundInterest(0.1, 20, 100) ).toFinanciallyEqual( 672.75 ); | ||
expect( compoundInterest(0.1, 3, 100) ).toFinanciallyEqual( 133.1 ); | ||
|
||
}); | ||
|
||
}); | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
define(['src/financial/futureValue', 'amd-utils/number/enforcePrecision'], function (futureValue, enforcePrecision) { | ||
|
||
describe('financial/futureValue()', function () { | ||
|
||
beforeEach(function(){ | ||
this.addMatchers({ | ||
toFinanciallyEqual : function(val){ | ||
return (enforcePrecision(this.actual, 2) === val); | ||
} | ||
}); | ||
}); | ||
|
||
|
||
it('should calculate the future value of an investment based on periodic, constant payments at a constant interest rate.', function () { | ||
|
||
expect( futureValue(0.12, 12, 1000) ).toFinanciallyEqual( 24133.13 ); | ||
expect( futureValue(0.12, 12, 1000, null, true) ).toFinanciallyEqual( 27029.11 ); | ||
|
||
expect( futureValue(0.06, 40, 2000) ).toFinanciallyEqual( 309523.93 ); | ||
expect( futureValue(0.06, 40, 2000, null, true) ).toFinanciallyEqual( 328095.37 ); | ||
|
||
expect( futureValue(0.06, 25, 2400) ).toFinanciallyEqual( 131674.83 ); | ||
expect( futureValue(0.06, 25, 2400, null, true) ).toFinanciallyEqual( 139575.32 ); | ||
|
||
}); | ||
|
||
it('presentValue should compound over the periods', function () { | ||
|
||
expect( futureValue(0.12, 12, 1000, 500) ).toFinanciallyEqual( 26081.12 ); | ||
expect( futureValue(0.12, 12, 1000, 500, true) ).toFinanciallyEqual( 28977.10 ); | ||
|
||
expect( futureValue(0.06, 25, 2400, 10000) ).toFinanciallyEqual( 174593.54 ); | ||
expect( futureValue(0.06, 25, 2400, 10000, true) ).toFinanciallyEqual( 182494.03 ); | ||
|
||
}); | ||
|
||
it('should return sum of payments if rate is zero', function () { | ||
expect( futureValue(0.0, 25, 2400) ).toFinanciallyEqual( 60000 ); | ||
expect( futureValue(0.0, 25, 2400, null, true) ).toFinanciallyEqual( 60000 ); | ||
}); | ||
|
||
it('should decrement the value if rate is negative (deflation)', function () { | ||
expect( futureValue(-0.06, 25, 2400) ).toFinanciallyEqual( 31483.59 ); | ||
expect( futureValue(-0.06, 25, 2400, null, true) ).toFinanciallyEqual( 29594.58 ); | ||
}); | ||
|
||
}); | ||
|
||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
define(['src/financial/npv', 'amd-utils/number/enforcePrecision'], function (npv, enforcePrecision) { | ||
|
||
describe('financial/npv()', function () { | ||
|
||
beforeEach(function(){ | ||
this.addMatchers({ | ||
toFinanciallyEqual : function(val){ | ||
return (enforcePrecision(this.actual, 2) === val); | ||
} | ||
}); | ||
}); | ||
|
||
|
||
it('should return the net present value', function () { | ||
|
||
var vals = [-100, 5, 10, 12, 20, 30]; | ||
|
||
expect( npv(0.06, vals) ).toFinanciallyEqual( -35.89 ); | ||
expect( npv(0.10, vals) ).toFinanciallyEqual( -41.71 ); | ||
|
||
vals.push(40, 55); | ||
|
||
expect( npv(0.06, vals) ).toFinanciallyEqual( 25.22 ); | ||
expect( npv(0.10, vals) ).toFinanciallyEqual( 4.47 ); | ||
|
||
|
||
// based on wikipedia example | ||
// http://en.wikipedia.org/wiki/Net_present_value#Example | ||
vals = [25000, 25000, 25000, 25000, 25000, 25000]; | ||
|
||
expect( npv(0.1, vals) - 100000 ).toFinanciallyEqual( 8881.52 ); | ||
}); | ||
|
||
it('should work if rate is zero', function () { | ||
expect( npv(0, [100, 100, 100]) ).toFinanciallyEqual( 300 ); | ||
}); | ||
|
||
}); | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
define(['src/financial/payment', 'amd-utils/number/enforcePrecision'], function (payment, enforcePrecision) { | ||
|
||
describe('financial/payment()', function () { | ||
|
||
beforeEach(function(){ | ||
this.addMatchers({ | ||
toFinanciallyEqual : function(val){ | ||
return (enforcePrecision(this.actual, 2) === val); | ||
} | ||
}); | ||
}); | ||
|
||
|
||
it('payment should be based on a constant interest rate', function () { | ||
expect( payment(0.05, 10, 1000) ).toFinanciallyEqual( 129.50 ); | ||
expect( payment(6.5/100/12, 30*12, 200000) ).toFinanciallyEqual( 1264.14 ); | ||
}); | ||
|
||
it('isDue should change behavior', function () { | ||
expect( payment(0.05, 10, 1000, null, true) ).toFinanciallyEqual( 123.34 ); | ||
expect( payment(6.5/100/12, 30*12, 200000, null, true) ).toFinanciallyEqual( 1257.33 ); | ||
}); | ||
|
||
it('futureValue should be computed into the result', function () { | ||
expect( payment(0.05, 10, 1000, 500) ).toFinanciallyEqual( 169.26 ); | ||
expect( payment(0.05, 10, 1000, 500, true) ).toFinanciallyEqual( 161.20 ); | ||
}); | ||
|
||
it('should be zero if presentValue is zero', function () { | ||
expect( payment(0.05, 10, 0) ).toFinanciallyEqual( 0 ); | ||
}); | ||
|
||
it('shouldn\'t be zero if futureValue is specified', function () { | ||
expect( payment(0.05, 10, 0, 500) ).toFinanciallyEqual( 39.75 ); | ||
}); | ||
|
||
it('should work with negative rate', function () { | ||
expect( payment(-0.05, 10, 1000) ).toFinanciallyEqual( 74.61 ); | ||
expect( payment(-0.05, 10, 1000, 500) ).toFinanciallyEqual( 136.91 ); | ||
expect( payment(-0.05, 10, 1000, 500, true) ).toFinanciallyEqual( 144.12 ); | ||
expect( payment(-0.05, 10, 0, 500) ).toFinanciallyEqual( 62.30 ); | ||
expect( payment(-0.05, 10, 0, 500, true) ).toFinanciallyEqual( 65.58 ); | ||
}); | ||
|
||
it('should work with zero rate', function () { | ||
expect( payment(0, 10, 1000) ).toFinanciallyEqual( 100 ); | ||
expect( payment(0, 10, 1000, 500) ).toFinanciallyEqual( 150 ); | ||
}); | ||
|
||
it('should work with negative values', function () { | ||
expect( payment(0.05, 10, 1000, -500) ).toFinanciallyEqual( 89.75 ); | ||
expect( payment(0.05, 10, -1000, 500) ).toFinanciallyEqual( -89.75 ); | ||
expect( payment(0.05, 10, -1000, -500) ).toFinanciallyEqual( -169.26 ); | ||
}); | ||
|
||
}); | ||
|
||
}); |
Oops, something went wrong.