moneyfunx 1.2.3 → 1.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,10 +6,8 @@
6
6
  /**
7
7
  * Calculates the minimum payment to pay the principal back in the number of periods at the periodic rate
8
8
  *
9
- * balance = principal + interest
10
- *
11
9
  * @param {number} principal The amount borrowed
12
- * @param {number} periodicRate The rate the balance accrues interest at per period
10
+ * @param {number} periodicRate The rate the principal accrues interest at per period
13
11
  * @param {number [int]} periods The number of periods the principal is repaid over
14
12
  * @returns {number} The minimum payment
15
13
  */
@@ -17,11 +15,9 @@ export declare function calculateMinPayment(principal: number, periodicRate: num
17
15
  /**
18
16
  * Calculates the principal remaining after a certain number of payments from a beginning principal at a periodic rate
19
17
  *
20
- * balance = principal + interest
21
- *
22
18
  * @param {number} principal The amount borrowed
23
19
  * @param {number} payment The amount paid at each period
24
- * @param {number} periodicRate The rate the balance accrues interest at per period
20
+ * @param {number} periodicRate The rate the princpal accrues interest at per period
25
21
  * @param {number [int]} periods The number of periods paid to compute the desired principal remaining
26
22
  * @returns {number} The remaining principal
27
23
  */
@@ -29,11 +25,9 @@ export declare function principalRemaining(principal: number, payment: number, p
29
25
  /**
30
26
  * Calculates the total interest paid after a certain number of payments from a beginning principal at a periodic rate
31
27
  *
32
- * balance = principal + interest
33
- *
34
28
  * @param {number} principal The amount borrowed
35
29
  * @param {number} payment The amount paid at each period
36
- * @param {number} periodicRate The rate the balance accrues interest at per period
30
+ * @param {number} periodicRate The rate the princpal accrues interest at per period
37
31
  * @param {number [int]} periods The number of periods paid to compute the desired principal remaining
38
32
  * @returns {number} The total interest paid
39
33
  */
@@ -41,11 +35,9 @@ export declare function interestPaid(principal: number, payment: number, periodi
41
35
  /**
42
36
  * Calculates the number of payments required to pay off a principal
43
37
  *
44
- * balance = principal + interest
45
- *
46
38
  * @param {number} principal The amount borrowed
47
39
  * @param {number} payment The amount paid at each period
48
- * @param {number} periodicRate The rate the balance accrues interest at per period
40
+ * @param {number} periodicRate The rate the princpal accrues interest at per period
49
41
  * @returns The number of payments needed to pay off the principal
50
42
  */
51
43
  export declare function numPaymentsToZero(principal: number, payment: number, periodicRate: number): number;
@@ -6,10 +6,8 @@
6
6
  /**
7
7
  * Calculates the minimum payment to pay the principal back in the number of periods at the periodic rate
8
8
  *
9
- * balance = principal + interest
10
- *
11
9
  * @param {number} principal The amount borrowed
12
- * @param {number} periodicRate The rate the balance accrues interest at per period
10
+ * @param {number} periodicRate The rate the principal accrues interest at per period
13
11
  * @param {number [int]} periods The number of periods the principal is repaid over
14
12
  * @returns {number} The minimum payment
15
13
  */
@@ -23,26 +21,22 @@ export function calculateMinPayment(principal, periodicRate, periods) {
23
21
  /**
24
22
  * Calculates the principal remaining after a certain number of payments from a beginning principal at a periodic rate
25
23
  *
26
- * balance = principal + interest
27
- *
28
24
  * @param {number} principal The amount borrowed
29
25
  * @param {number} payment The amount paid at each period
30
- * @param {number} periodicRate The rate the balance accrues interest at per period
26
+ * @param {number} periodicRate The rate the princpal accrues interest at per period
31
27
  * @param {number [int]} periods The number of periods paid to compute the desired principal remaining
32
28
  * @returns {number} The remaining principal
33
29
  */
34
30
  export function principalRemaining(principal, payment, periodicRate, periods) {
35
- return Math.max(principal * Math.pow((1 + periodicRate), periods) -
36
- payment * ((Math.pow((1 + periodicRate), periods) - 1) / periodicRate), 0);
31
+ return Math.max((principal * Math.pow((1 + periodicRate), periods)) -
32
+ (payment * (Math.pow((1 + periodicRate), periods) - 1) / periodicRate), 0);
37
33
  }
38
34
  /**
39
35
  * Calculates the total interest paid after a certain number of payments from a beginning principal at a periodic rate
40
36
  *
41
- * balance = principal + interest
42
- *
43
37
  * @param {number} principal The amount borrowed
44
38
  * @param {number} payment The amount paid at each period
45
- * @param {number} periodicRate The rate the balance accrues interest at per period
39
+ * @param {number} periodicRate The rate the princpal accrues interest at per period
46
40
  * @param {number [int]} periods The number of periods paid to compute the desired principal remaining
47
41
  * @returns {number} The total interest paid
48
42
  */
@@ -53,11 +47,9 @@ export function interestPaid(principal, payment, periodicRate, periods) {
53
47
  /**
54
48
  * Calculates the number of payments required to pay off a principal
55
49
  *
56
- * balance = principal + interest
57
- *
58
50
  * @param {number} principal The amount borrowed
59
51
  * @param {number} payment The amount paid at each period
60
- * @param {number} periodicRate The rate the balance accrues interest at per period
52
+ * @param {number} periodicRate The rate the princpal accrues interest at per period
61
53
  * @returns The number of payments needed to pay off the principal
62
54
  */
63
55
  export function numPaymentsToZero(principal, payment, periodicRate) {
@@ -10,7 +10,7 @@ import type { AmortizationRecord, LoansPaymentSchedule } from './paymentTypes';
10
10
  * Calculates the extra amount in a payment after all loans' minimum payments are met
11
11
  * Throws an exception if the payment provided is less than the collective minimum payments for all loans
12
12
  *
13
- * @param {Array<Loan>} loans The loans to allocate minimum payments
13
+ * @param {ILoan[]} loans The loans to allocate minimum payments
14
14
  * @param {number} payment The amount to pay across all loans
15
15
  * @returns {number} The extra amount of payment
16
16
  */
@@ -25,14 +25,14 @@ export declare function determineExtraPayment(loans: ILoan[], payment: number):
25
25
  * @param {number} numPayments The number of periods to make payments to the loan
26
26
  * @param {number} startPeriod An initial offset of periods to 'fast-forward' the state of the loan to prior to calculation of each period
27
27
  * @param {number} carryover An additional amount to pay towards a loan, used when a residual amount is available from paying off the previous loan this period
28
- * @returns {Array<AmortizationRecord>} The amortization schdule for the number of payments of payment made to the loan from the provided start period
28
+ * @returns {AmortizationRecord[]} The amortization schdule for the number of payments of payment made to the loan from the provided start period
29
29
  */
30
30
  export declare function amortizePayments(loan: Loan, principal: number, payment: number, numPayments: number, startPeriod?: number, carryover?: number): AmortizationRecord[];
31
31
  /**
32
32
  *
33
33
  * Calculates a wealth of information about paying of a set of loans with a total payment amount
34
34
  *
35
- * @param {Array<Loans>} loans The loans to pay off
35
+ * @param {Loan[]} loans The loans to pay off
36
36
  * @param {number} payment The total amount of money budgeted to pay all loans each period
37
37
  * @param {boolean} reduceMinimum Flag to reduce the total payment amount by a loan's minimum when that loan is paid off
38
38
  * @returns {LoansPaymentSchedule} Various totals and series of data regarding paying off the loans at the payment amount
@@ -4,13 +4,12 @@
4
4
  *
5
5
  */
6
6
  import * as errors from './errors';
7
- import * as helpers from './helperFunctions';
8
7
  /**
9
8
  *
10
9
  * Calculates the extra amount in a payment after all loans' minimum payments are met
11
10
  * Throws an exception if the payment provided is less than the collective minimum payments for all loans
12
11
  *
13
- * @param {Array<Loan>} loans The loans to allocate minimum payments
12
+ * @param {ILoan[]} loans The loans to allocate minimum payments
14
13
  * @param {number} payment The amount to pay across all loans
15
14
  * @returns {number} The extra amount of payment
16
15
  */
@@ -32,7 +31,7 @@ export function determineExtraPayment(loans, payment) {
32
31
  * @param {number} numPayments The number of periods to make payments to the loan
33
32
  * @param {number} startPeriod An initial offset of periods to 'fast-forward' the state of the loan to prior to calculation of each period
34
33
  * @param {number} carryover An additional amount to pay towards a loan, used when a residual amount is available from paying off the previous loan this period
35
- * @returns {Array<AmortizationRecord>} The amortization schdule for the number of payments of payment made to the loan from the provided start period
34
+ * @returns {AmortizationRecord[]} The amortization schdule for the number of payments of payment made to the loan from the provided start period
36
35
  */
37
36
  export function amortizePayments(loan, principal, payment, numPayments, startPeriod = 0, carryover = 0) {
38
37
  if (payment === null) {
@@ -63,7 +62,7 @@ export function amortizePayments(loan, principal, payment, numPayments, startPer
63
62
  *
64
63
  * Calculates a wealth of information about paying of a set of loans with a total payment amount
65
64
  *
66
- * @param {Array<Loans>} loans The loans to pay off
65
+ * @param {Loan[]} loans The loans to pay off
67
66
  * @param {number} payment The total amount of money budgeted to pay all loans each period
68
67
  * @param {boolean} reduceMinimum Flag to reduce the total payment amount by a loan's minimum when that loan is paid off
69
68
  * @returns {LoansPaymentSchedule} Various totals and series of data regarding paying off the loans at the payment amount
@@ -71,10 +70,10 @@ export function amortizePayments(loan, principal, payment, numPayments, startPer
71
70
  */
72
71
  export function payLoans(loans, payment, reduceMinimum = false) {
73
72
  let monthlyPayment = payment;
74
- const paymentData = {};
73
+ const paymentSchedule = {};
75
74
  const loanPrincipalsRemaining = {};
76
75
  loans.forEach((loan) => {
77
- paymentData[loan.id] = {
76
+ paymentSchedule[loan.id] = {
78
77
  lifetimeInterest: 0,
79
78
  lifetimePrincipal: loan.currentBalance,
80
79
  amortizationSchedule: []
@@ -91,29 +90,33 @@ export function payLoans(loans, payment, reduceMinimum = false) {
91
90
  const firstLoanPayment = firstLoan.minPayment +
92
91
  determineExtraPayment(loans.slice(paidLoans), monthlyPayment);
93
92
  const firstLoanPrincipalRemaining = loanPrincipalsRemaining[firstLoan.id];
94
- const periodsToPay = helpers.numPaymentsToZero(firstLoanPrincipalRemaining, firstLoanPayment, firstLoan.periodicRate);
95
- const firstLoanPaidPeriods = amortizePayments(firstLoan, firstLoanPrincipalRemaining, firstLoanPayment, periodsToPay, periodsElapsed);
93
+ const periodsToPay = firstLoan.numPaymentsToZero(firstLoanPayment, firstLoanPrincipalRemaining);
94
+ const firstLoanAmortizedPayments = amortizePayments(firstLoan, firstLoanPrincipalRemaining, firstLoanPayment, periodsToPay, periodsElapsed);
96
95
  const firstLoanCarryover = firstLoanPayment - (firstLoan.principalRemaining(periodsToPay - 1, firstLoanPayment, firstLoanPrincipalRemaining) + firstLoan.accrueInterest(firstLoan.principalRemaining(periodsToPay - 1, firstLoanPayment, firstLoanPrincipalRemaining)));
97
- paymentData[firstLoan.id].amortizationSchedule = [
98
- ...paymentData[firstLoan.id].amortizationSchedule,
99
- ...firstLoanPaidPeriods
96
+ paymentSchedule[firstLoan.id].amortizationSchedule = [
97
+ ...paymentSchedule[firstLoan.id].amortizationSchedule,
98
+ ...firstLoanAmortizedPayments
100
99
  ];
101
100
  totalAmortizationSchedule = [
102
101
  ...totalAmortizationSchedule,
103
- ...firstLoanPaidPeriods
102
+ ...firstLoanAmortizedPayments
104
103
  ];
105
104
  paidLoans += 1;
106
105
  // handle calculating information for the rest of the loans
107
106
  loans.slice(paidLoans).forEach((loan, index) => {
108
107
  const loanPrincipalRemaining = loanPrincipalsRemaining[loan.id];
109
- const paidPeriods = amortizePayments(loan, loanPrincipalRemaining, loan.minPayment, Math.min(periodsToPay, helpers.numPaymentsToZero(loanPrincipalRemaining, loan.minPayment, loan.periodicRate)), periodsElapsed, (index === 0 && !reduceMinimum) ? firstLoanCarryover : 0);
110
- paymentData[loan.id].amortizationSchedule = [
111
- ...paymentData[loan.id].amortizationSchedule,
112
- ...paidPeriods,
108
+ const loanAmortizedPayments = amortizePayments(loan, loanPrincipalRemaining, loan.minPayment, Math.min(periodsToPay, loan.numPaymentsToZero(loan.minPayment, loanPrincipalRemaining)), periodsElapsed,
109
+ // bug
110
+ // when loan 1 is paid off with overkill on the final payment,
111
+ // loan 2 is not getting the extra over the global minimum for that payment
112
+ // i.e. needs to trickle down to #2
113
+ (index === 0 && !reduceMinimum) ? firstLoanCarryover : 0);
114
+ paymentSchedule[loan.id].amortizationSchedule = [
115
+ ...paymentSchedule[loan.id].amortizationSchedule,
116
+ ...loanAmortizedPayments,
113
117
  ];
114
- loanPrincipalsRemaining[loan.id] = paymentData[loan.id].amortizationSchedule[paymentData[loan.id].amortizationSchedule.length - 1].principalRemaining;
115
118
  totalAmortizationSchedule = totalAmortizationSchedule.map((element) => {
116
- const matchedInnerElement = paidPeriods.find((innerElement) => innerElement.period === element.period);
119
+ const matchedInnerElement = loanAmortizedPayments.find((innerElement) => innerElement.period === element.period);
117
120
  return (matchedInnerElement != null)
118
121
  ? {
119
122
  period: element.period,
@@ -124,6 +127,7 @@ export function payLoans(loans, payment, reduceMinimum = false) {
124
127
  }
125
128
  : element;
126
129
  });
130
+ loanPrincipalsRemaining[loan.id] = paymentSchedule[loan.id].amortizationSchedule[paymentSchedule[loan.id].amortizationSchedule.length - 1].principalRemaining;
127
131
  });
128
132
  if (reduceMinimum) {
129
133
  monthlyPayment -= firstLoan.minPayment;
@@ -131,16 +135,16 @@ export function payLoans(loans, payment, reduceMinimum = false) {
131
135
  periodsElapsed += periodsToPay;
132
136
  }
133
137
  for (const loan of loans) {
134
- const loanLifetimeInterest = (paymentData[loan.id].amortizationSchedule.reduce((lifetimeInterest, curval) => lifetimeInterest + curval.interest, 0));
135
- paymentData[loan.id].lifetimeInterest = loanLifetimeInterest;
136
- paymentData[loan.id].lifetimePrincipal = loan.principal;
138
+ const loanLifetimeInterest = (paymentSchedule[loan.id].amortizationSchedule.reduce((lifetimeInterest, curval) => lifetimeInterest + curval.interest, 0));
139
+ paymentSchedule[loan.id].lifetimeInterest = loanLifetimeInterest;
140
+ paymentSchedule[loan.id].lifetimePrincipal = loan.principal;
137
141
  totalLifetimeInterest += loanLifetimeInterest;
138
- totalLifetimePrincipal += loan.principal;
142
+ totalLifetimePrincipal += loan.currentBalance;
139
143
  }
140
- paymentData.totals = {
144
+ paymentSchedule.totals = {
141
145
  lifetimeInterest: totalLifetimeInterest,
142
146
  lifetimePrincipal: totalLifetimePrincipal,
143
147
  amortizationSchedule: totalAmortizationSchedule
144
148
  };
145
- return paymentData;
149
+ return paymentSchedule;
146
150
  }
@@ -1,31 +1,31 @@
1
1
  /**
2
2
  *
3
- * This file contains functions for sorting Arrays of Loans on certain attributes
3
+ * This file contains functions for sorting Arrays of ILoans on certain attributes
4
4
  *
5
5
  */
6
- import { Loan } from './loan';
7
- type avalanche = (loan1: Loan, loan2: Loan) => number;
8
- type snowball = (loan1: Loan, loan2: Loan) => number;
6
+ import { ILoan } from './loan';
7
+ type avalanche = (loan1: ILoan, loan2: ILoan) => number;
8
+ type snowball = (loan1: ILoan, loan2: ILoan) => number;
9
9
  type sortFunction = avalanche | snowball;
10
10
  /**
11
11
  * Sorts loans descending by interest rate
12
- * @param {Loan} loan1 A loan to be comapred
13
- * @param {Loan} loan2 A loan to be comapred
12
+ * @param {ILoan} loan1 A loan to be compared
13
+ * @param {ILoan} loan2 A loan to be comapred
14
14
  * @returns {number} the order in which to sort the loans in descending interest rate
15
15
  */
16
- export declare function avalanche(loan1: Loan, loan2: Loan): number;
16
+ export declare function avalanche(loan1: ILoan, loan2: ILoan): number;
17
17
  /**
18
18
  * Sorts loans ascending by principal
19
- * @param {Loan} loan1 A loan to be compared
20
- * @param {Loan} loan2 A loan to be compared
19
+ * @param {ILoan} loan1 A loan to be compared
20
+ * @param {ILoan} loan2 A loan to be compared
21
21
  * @returns {number} the order in which to sort the loans in ascending princpal
22
22
  */
23
- export declare function snowball(loan1: Loan, loan2: Loan): number;
23
+ export declare function snowball(loan1: ILoan, loan2: ILoan): number;
24
24
  /**
25
- * Sorts an array of loans using the provided sortFunc
26
- * @param {Array<Loan>} loans The loans to sort
27
- * @param {function} sortFunc The algorithm to sort the loans with
25
+ * Sorts an array of loans using the provided sortFunction
26
+ * @param {ILoan[]} loans The loans to sort
27
+ * @param {function} sortFunction The algorithm to sort the loans with
28
28
  * @returns The sorted array loans
29
29
  */
30
- export declare function sortLoans(loans: Loan[], sortFunction: sortFunction): Loan[];
30
+ export declare function sortLoans(loans: ILoan[], sortFunction: sortFunction): ILoan[];
31
31
  export {};
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  *
3
- * This file contains functions for sorting Arrays of Loans on certain attributes
3
+ * This file contains functions for sorting Arrays of ILoans on certain attributes
4
4
  *
5
5
  */
6
6
  /**
7
7
  * Sorts loans descending by interest rate
8
- * @param {Loan} loan1 A loan to be comapred
9
- * @param {Loan} loan2 A loan to be comapred
8
+ * @param {ILoan} loan1 A loan to be compared
9
+ * @param {ILoan} loan2 A loan to be comapred
10
10
  * @returns {number} the order in which to sort the loans in descending interest rate
11
11
  */
12
12
  export function avalanche(loan1, loan2) {
@@ -14,17 +14,17 @@ export function avalanche(loan1, loan2) {
14
14
  }
15
15
  /**
16
16
  * Sorts loans ascending by principal
17
- * @param {Loan} loan1 A loan to be compared
18
- * @param {Loan} loan2 A loan to be compared
17
+ * @param {ILoan} loan1 A loan to be compared
18
+ * @param {ILoan} loan2 A loan to be compared
19
19
  * @returns {number} the order in which to sort the loans in ascending princpal
20
20
  */
21
21
  export function snowball(loan1, loan2) {
22
22
  return loan1.currentBalance - loan2.currentBalance;
23
23
  }
24
24
  /**
25
- * Sorts an array of loans using the provided sortFunc
26
- * @param {Array<Loan>} loans The loans to sort
27
- * @param {function} sortFunc The algorithm to sort the loans with
25
+ * Sorts an array of loans using the provided sortFunction
26
+ * @param {ILoan[]} loans The loans to sort
27
+ * @param {function} sortFunction The algorithm to sort the loans with
28
28
  * @returns The sorted array loans
29
29
  */
30
30
  export function sortLoans(loans, sortFunction) {