support other interest compounding types (#24)
Co-authored-by: Chris Weiss <chrwei@users.noreply.github.com>
This commit is contained in:
@@ -165,6 +165,11 @@ As an example, if your loan is at 4.5% interest and you want to insert an
|
|||||||
interest transaction on the 28th of the month, set the account note to
|
interest transaction on the 28th of the month, set the account note to
|
||||||
`interestRate:0.045 interestDay:28`.
|
`interestRate:0.045 interestDay:28`.
|
||||||
|
|
||||||
|
By default, interest is calculated using the 30/360 method where interest is
|
||||||
|
computed monthly using 30/360 (or 1/12) of the interest rate. If you need to
|
||||||
|
compute interest using the ACTUAL/ACTUAL method, set `interest:actual` in the
|
||||||
|
note. If you need to compute interest daily, set `interest:daily`.
|
||||||
|
|
||||||
You can optionally change the payee used for the interest transactions by
|
You can optionally change the payee used for the interest transactions by
|
||||||
setting `INTEREST_PAYEE_NAME` in the `.env` file.
|
setting `INTEREST_PAYEE_NAME` in the `.env` file.
|
||||||
|
|
||||||
|
|||||||
+27
-5
@@ -2,6 +2,11 @@ const api = require('@actual-app/api');
|
|||||||
const { closeBudget, ensurePayee, getAccountBalance, getAccountNote, getLastTransactionDate, getTagValue, openBudget, showPercent } = require('./utils');
|
const { closeBudget, ensurePayee, getAccountBalance, getAccountNote, getLastTransactionDate, getTagValue, openBudget, showPercent } = require('./utils');
|
||||||
require("dotenv").config();
|
require("dotenv").config();
|
||||||
|
|
||||||
|
function daysInYear(year) {
|
||||||
|
// Check if the year is a leap year
|
||||||
|
return ((year % 4 === 0 && year % 100 > 0) || year %400 == 0) ? 366 : 365;
|
||||||
|
}
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
await openBudget();
|
await openBudget();
|
||||||
|
|
||||||
@@ -16,9 +21,12 @@ require("dotenv").config();
|
|||||||
const note = await getAccountNote(account);
|
const note = await getAccountNote(account);
|
||||||
|
|
||||||
if (note) {
|
if (note) {
|
||||||
if (note.indexOf('interestRate:') > -1 && note.indexOf('interestDay:') > -1) {
|
let interestRate = parseFloat(getTagValue(note, 'interestRate', 0.0));
|
||||||
let interestRate = parseFloat(getTagValue(note, 'interestRate'));
|
const interestDay = parseInt(getTagValue(note, 'interestDay', 0));
|
||||||
const interestDay = parseInt(getTagValue(note, 'interestDay'));
|
|
||||||
|
if (interestRate && interestDay) {
|
||||||
|
const kind = getTagValue(note, 'interest', 'monthly');
|
||||||
|
const isDaily = kind == 'daily';
|
||||||
|
|
||||||
const interestTransactionDate = new Date();
|
const interestTransactionDate = new Date();
|
||||||
if (interestTransactionDate.getDate() < interestDay) {
|
if (interestTransactionDate.getDate() < interestDay) {
|
||||||
@@ -35,8 +43,22 @@ require("dotenv").config();
|
|||||||
if (!lastDate) continue;
|
if (!lastDate) continue;
|
||||||
const daysPassed = Math.floor((interestTransactionDate - new Date(lastDate)) / 86400000);
|
const daysPassed = Math.floor((interestTransactionDate - new Date(lastDate)) / 86400000);
|
||||||
|
|
||||||
|
let period = 12;
|
||||||
|
let numPeriods = 1
|
||||||
|
switch (kind) {
|
||||||
|
case 'daily':
|
||||||
|
period = daysInYear(interestTransactionDate.getFullYear());
|
||||||
|
numPeriods = daysPassed;
|
||||||
|
break;
|
||||||
|
case 'actual':
|
||||||
|
period = daysInYear(interestTransactionDate.getFullYear()) / daysPassed;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
const balance = await getAccountBalance(account, interestTransactionDate);
|
const balance = await getAccountBalance(account, interestTransactionDate);
|
||||||
const compoundedInterest = Math.round(balance * (Math.pow(1 + interestRate / 12, 1) - 1));
|
const compoundedInterest = Math.round(balance * (Math.pow(1 + interestRate / period, numPeriods) - 1));
|
||||||
|
|
||||||
interestRate = showPercent(interestRate);
|
interestRate = showPercent(interestRate);
|
||||||
|
|
||||||
@@ -52,7 +74,7 @@ require("dotenv").config();
|
|||||||
payee: payeeId,
|
payee: payeeId,
|
||||||
amount: compoundedInterest,
|
amount: compoundedInterest,
|
||||||
cleared: true,
|
cleared: true,
|
||||||
notes: `Interest for 1 month at ${interestRate}`,
|
notes: `Interest for ${daysPassed} days, ${balance / 100.0} at ${interestRate} (${isDaily ? "daily" : "monthly"})`,
|
||||||
}]);
|
}]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user