UNPKG

jexl-functions-fork

Version:
289 lines (288 loc) 13.5 kB
"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, }; });