jexl-functions-fork
Version:
Package with available JEXL functions
289 lines (288 loc) • 13.5 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var jexl_1 = require("@digifi/jexl");
var module_1 = require("../utils/module");
var dayjs_1 = __importDefault(require("../dayjs"));
var date_and_time_1 = __importDefault(require("./date-and-time"));
exports.default = (0, module_1.createModule)(function (_a, options) {
var safeFlatten = _a.safeFlatten, coerceToNumber = _a.coerceToNumber;
var dateTimeModule = (0, date_and_time_1.default)(options);
var FV = function (rate, periods, payment, value, type) {
var coercedRate = coerceToNumber(rate);
var coercedPeriods = coerceToNumber(periods);
var coercedPayment = coerceToNumber(payment);
var coercedValue = value ? coerceToNumber(value) : 0;
var coercedType = type ? coerceToNumber(type) : 0;
if (coercedRate === 0) {
return -(coercedValue + coercedPayment * coercedPeriods);
}
var term = Math.pow(1 + coercedRate, coercedPeriods);
if (coercedType === 1) {
return -(coercedValue * term + (coercedPayment * (1 + coercedRate) * (term - 1)) / coercedRate);
}
return -(coercedValue * term + (coercedPayment * (term - 1)) / coercedRate);
};
var PMT = function (rate, periods, present, future, type) {
var coercedRate = coerceToNumber(rate);
var coercedPeriods = coerceToNumber(periods);
var coercedPresent = coerceToNumber(present);
var coercedFuture = future ? coerceToNumber(future) : 0;
var coercedType = type ? coerceToNumber(type) : 0;
if (coercedRate === 0) {
return -(coercedPresent + coercedFuture) / coercedPeriods;
}
var term = Math.pow(1 + coercedRate, coercedPeriods);
if (coercedType === 1) {
return -(((coercedFuture * coercedRate) / (term - 1) + (coercedPresent * coercedRate) / (1 - 1 / term)) / (1 + coercedRate));
}
return -((coercedFuture * coercedRate) / (term - 1) + (coercedPresent * coercedRate) / (1 - 1 / term));
};
var ACCRINT = function (issue, first, settlement, rate, par, frequency, basis) {
var coercedRate = coerceToNumber(rate);
var coercedPar = par ? coerceToNumber(par) : 0;
var coercedFrequency = coerceToNumber(frequency);
var issueDate = (0, dayjs_1.default)(issue);
var firstDate = (0, dayjs_1.default)(first);
var settlementDate = (0, dayjs_1.default)(settlement);
if (!issueDate.isValid()) {
throw new jexl_1.ExecutionError('Issue date is not valid.');
}
if (!firstDate.isValid()) {
throw new jexl_1.ExecutionError('First date is not valid.');
}
if (!settlementDate.isValid()) {
throw new jexl_1.ExecutionError('Settlement date is not valid.');
}
if (coercedRate <= 0) {
throw new jexl_1.ExecutionError('Rate is lower or equal 0.');
}
if (coercedPar <= 0) {
throw new jexl_1.ExecutionError('Par is lower or equal 0');
}
if (![1, 2, 4].includes(coercedFrequency)) {
throw new jexl_1.ExecutionError('Frequency should be equal to [1, 2, 4]');
}
if (settlementDate <= issueDate) {
throw new jexl_1.ExecutionError('Settlement date should be greater than issue date');
}
return coercedPar * coercedRate * dateTimeModule.YEARFRAC(issue, settlement, basis);
};
var CUMIPMT = function (rate, periods, value, start, end, type) {
var coercedRate = coerceToNumber(rate);
var coercedPeriods = Math.abs(coerceToNumber(periods));
var coercedValue = coerceToNumber(value);
var coercedEnd = Math.abs(coerceToNumber(end));
var coercedStart = Math.abs(coerceToNumber(start));
if (coercedRate <= 0) {
throw new jexl_1.ExecutionError('Rate should be more than 0.');
}
if (coercedPeriods <= 0) {
throw new jexl_1.ExecutionError('Periods should be more than 0.');
}
if (coercedValue <= 0) {
throw new jexl_1.ExecutionError('Value should be more than 0.');
}
if (coercedEnd < coercedStart) {
throw new jexl_1.ExecutionError('End should be more than start.');
}
var differenceBetweenEndAndStart = coercedEnd - coercedStart;
if (differenceBetweenEndAndStart > options.defaultMaxArraySize) {
throw new jexl_1.ExecutionError("Difference between end and start should be not more than: ".concat(options.defaultMaxArraySize));
}
if (type !== 0 && type !== 1) {
throw new jexl_1.ExecutionError('Type should be equal 0 or 1.');
}
var payment = PMT(coercedRate, coercedPeriods, coercedValue, 0, type);
var interest = coercedStart === 1 && type === 0 ? -coercedValue : 0;
var startFrom = coercedStart === 1 ? coercedStart + 1 : coercedStart;
for (var i = startFrom; i <= coercedEnd; i++) {
if (type === 1) {
interest = interest + FV(coercedRate, i - 2, payment, coercedValue, 1) - payment;
}
else {
interest = interest + FV(coercedRate, i - 1, payment, coercedValue, 0);
}
}
return interest * coercedRate;
};
var CUMPRINC = function (rate, periods, value, start, end, type) {
var coercedRate = coerceToNumber(rate);
var coercedPeriods = Math.abs(coerceToNumber(periods));
var coercedValue = coerceToNumber(value);
var coercedEnd = Math.abs(coerceToNumber(end));
var coercedStart = Math.abs(coerceToNumber(start));
var coercedType = type ? coerceToNumber(type) : 0;
if (coercedRate <= 0) {
throw new jexl_1.ExecutionError('Rate should be more than 0.');
}
if (coercedPeriods <= 0) {
throw new jexl_1.ExecutionError('Periods should be more than 0.');
}
if (coercedValue <= 0) {
throw new jexl_1.ExecutionError('Value should be more than 0.');
}
if (coercedEnd < coercedStart) {
throw new jexl_1.ExecutionError('End should be more than start.');
}
var principal = 0;
var payment = PMT(coercedRate, coercedPeriods, coercedValue, 0, coercedType);
var startFrom = coercedStart === 1 ? coercedStart + 1 : coercedStart;
if (startFrom === 1) {
principal = coercedType === 0
? payment + coercedValue * coercedRate
: payment;
}
for (var i = startFrom; i <= coercedEnd; i++) {
if (coercedType > 0) {
principal = principal + payment - (FV(coercedRate, i - 2, payment, coercedValue, 1) - payment) * coercedRate;
}
else {
principal = principal + payment - FV(coercedRate, i - 1, payment, coercedValue, 0) * coercedRate;
}
}
return principal;
};
var IPMT = function (rate, period, periods, present, future, type) {
var coercedRate = coerceToNumber(rate);
var coercedPeriod = coerceToNumber(period);
var coercedPresent = coerceToNumber(present);
var coercedType = type ? coerceToNumber(type) : 0;
var payment = PMT(rate, periods, present, future, type);
if (coercedPeriod === 1) {
return type === 1
? 0
: (-coercedPresent * coercedRate);
}
return coercedType === 1
? (FV(coercedRate, coercedPeriod - 2, payment, coercedPresent, 1) - payment) * coercedRate
: (FV(coercedRate, coercedPeriod - 1, payment, coercedPresent, 0)) * coercedRate;
};
var EFFECT = function (rate, periods) {
var coercedRate = coerceToNumber(rate);
var coercedPeriods = coerceToNumber(periods);
if (coercedRate <= 0 || coercedPeriods < 1) {
throw new jexl_1.ExecutionError('Incorrect incoming arguments.');
}
var flooredPeriods = Math.trunc(coercedPeriods);
return Math.pow(1 + coercedRate / flooredPeriods, flooredPeriods) - 1;
};
var RATE = function (periods, payment, present, future, type, guess) {
var coercedGuess = guess === undefined ? 0.01 : coerceToNumber(guess);
var coercedFuture = future ? coerceToNumber(future) : 0;
var coercedType = type ? 1 : 0;
var coercedPeriods = coerceToNumber(periods);
var coercedPayment = coerceToNumber(payment);
var coercedPresent = coerceToNumber(present);
var epsMax = 1e-10;
var maxIterations = 20;
var rate = coercedGuess;
for (var i = 0; i < maxIterations; i++) {
if (rate <= -1) {
throw new jexl_1.ExecutionError('Incorrect rate.');
}
var y = void 0;
var f = void 0;
if (Math.abs(rate) < epsMax) {
y = coercedPresent * (1 + coercedPeriods * rate) + coercedPayment * (1 + rate * coercedType) * coercedPeriods + coercedFuture;
}
else {
f = Math.pow(1 + rate, coercedPeriods);
y = coercedPresent * f + coercedPayment * (1 / rate + coercedType) * (f - 1) + coercedFuture;
}
if (Math.abs(y) < epsMax) {
return rate;
}
var dy = void 0;
if (Math.abs(rate) < epsMax) {
dy = coercedPresent * coercedPeriods + coercedPayment * coercedType * coercedPeriods;
}
else {
var df = coercedPeriods * Math.pow(1 + rate, coercedPeriods - 1);
f = Math.pow(1 + rate, coercedPeriods);
dy = coercedPresent * df + coercedPayment * (1 / rate + coercedType) * df + coercedPayment * (-1 / (rate * rate)) * (f - 1);
}
rate = rate - y / dy;
}
return rate;
};
var ISPMT = function (rate, period, periods, value) {
return coerceToNumber(value) * coerceToNumber(rate) * (coerceToNumber(period) / coerceToNumber(periods) - 1);
};
var NOMINAL = function (rate, periods) {
var coercedRate = coerceToNumber(rate);
var coercedPeriods = coerceToNumber(periods);
if (coercedRate <= 0 || coercedPeriods < 1) {
throw new jexl_1.ExecutionError('Incorrect arguments.');
}
var flooredPeriods = Math.trunc(coercedPeriods);
return (Math.pow(coercedRate + 1, 1 / flooredPeriods) - 1) * flooredPeriods;
};
var NPER = function (rate, payment, present, future, type) {
var coercedType = type ? coerceToNumber(type) : 0;
var coercedFuture = future ? coerceToNumber(future) : 0;
var coercedRate = coerceToNumber(rate);
var coercedPayment = coerceToNumber(payment);
var coercedPresent = coerceToNumber(present);
if (coercedRate === 0) {
return -(coercedPresent + coercedFuture) / coercedPayment;
}
var num = coercedPayment * (1 + coercedRate * coercedType) - coercedFuture * coercedRate;
var den = coercedPresent * coercedRate + coercedPayment * (1 + coercedRate * coercedType);
return Math.log(num / den) / Math.log(1 + coercedRate);
};
var NPV = function (rate) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
var coercedRate = coerceToNumber(rate);
return safeFlatten(args).reduce(function (result, arg, index) {
return result + coerceToNumber(arg) / Math.pow(1 + coercedRate, index + 1);
}, 0);
};
var PDURATION = function (rate, present, future) {
var coercedRate = coerceToNumber(rate);
if (coercedRate <= 0) {
throw new jexl_1.ExecutionError('Invalid arguments.');
}
return (Math.log(coerceToNumber(future)) - Math.log(coerceToNumber(present))) / Math.log(1 + coercedRate);
};
var PPMT = function (rate, period, periods, present, future, type) {
return PMT(rate, periods, present, future, type) - IPMT(rate, period, periods, present, future, type);
};
var PV = function (rate, periods, payment, future, type) {
var coercedRate = coerceToNumber(rate);
var coercedPeriods = coerceToNumber(periods);
var coercedPayment = coerceToNumber(payment);
var coercedFuture = future ? coerceToNumber(future) : 0;
var coercedType = type ? coerceToNumber(type) : 0;
if (coercedRate === 0) {
return -coercedPayment * coercedPeriods - coercedFuture;
}
return ((((1 - Math.pow(1 + coercedRate, coercedPeriods)) / coercedRate) * coercedPayment * (1 + coercedRate * coercedType) - coercedFuture) / Math.pow(1 + coercedRate, coercedPeriods));
};
var DELTA = function (firstValue, secondValue) {
return firstValue === secondValue ? 1 : 0;
};
return {
EFFECT: EFFECT,
FV: FV,
PMT: PMT,
IPMT: IPMT,
RATE: RATE,
ISPMT: ISPMT,
NOMINAL: NOMINAL,
NPER: NPER,
NPV: NPV,
PDURATION: PDURATION,
PPMT: PPMT,
PV: PV,
DELTA: DELTA,
ACCRINT: ACCRINT,
CUMPRINC: CUMPRINC,
CUMIPMT: CUMIPMT,
};
});