UNPKG

som-exp-sdk

Version:

Evaluate the User Expression

137 lines (136 loc) 6.07 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FinancialExpression = void 0; const constants_1 = require("./constants"); class FinancialExpression { constructor() { this.pv = (interestRate, loanTerm, monthlyPayment) => { // Ex: pv(4.5/100/12, 10*12, 4000) // returns "385957.29" let output = this.const.INVALID_INPUT_VALUE; try { if (interestRate && interestRate > 0 && monthlyPayment && monthlyPayment > 0 && loanTerm && loanTerm > 0) { const onePlusRWholePowerN = (1 + interestRate) ** loanTerm; if (onePlusRWholePowerN && onePlusRWholePowerN > 0) { const numerator = monthlyPayment * (1 - (1 / onePlusRWholePowerN)); const denominator = interestRate; const pv = numerator / denominator; output = pv.toFixed(2).toString(); } } else { console.log(`Input values are invalid to calculate pv`); } } catch (e) { console.log(`Error while calculating pv. Error is ${e}`); } return output; }; this.fv = (interestRate, loanTerm, monthlyPayment) => { // Ex: fv(4.5/100/12, 10*12, 4000) // returns "604792.29" let output = this.const.INVALID_INPUT_VALUE; try { if (interestRate && interestRate > 0 && monthlyPayment && monthlyPayment > 0 && loanTerm && loanTerm > 0) { const onePlusRWholePowerN = (1 + interestRate) ** loanTerm; if (onePlusRWholePowerN && onePlusRWholePowerN > 0) { const numerator = monthlyPayment * (onePlusRWholePowerN - 1); const denominator = interestRate; const fv = numerator / denominator; output = fv.toFixed(2).toString(); } } else { console.log(`Input values are invalid to calculate to fv`); } } catch (e) { console.log(`Error while calculating fv. Error is ${e}`); } return output; }; this.pmt = (interestRate, loanTerm, loanAmount) => { // Ex: pmt(5/100/12, 5*12, 100000) // returns "1887" let output = this.const.INVALID_INPUT_VALUE; try { if (interestRate && interestRate > 0 && loanAmount && loanAmount > 0 && loanTerm && loanTerm > 0) { const onePlusRWholePowerN = (1 + interestRate) ** loanTerm; if (onePlusRWholePowerN && onePlusRWholePowerN > 0) { const numerator = loanAmount * (interestRate * onePlusRWholePowerN); const denominator = onePlusRWholePowerN - 1; const pmt = numerator / denominator; output = Math.floor(pmt).toString(); } } else { console.log(`Input values are invalid to calculate pmt`); } } catch (e) { console.log(`Error while calculating pmt. Error is ${e}`); } return output; }; this.rate = (period, pmt, pv) => { // Ex: rate(10*12, -1061, 100000) // returns 0.004172545 if (period && period > 0 && pmt && pv && pv > 0) { // Sets default values for parameters const fv = 0; const type = 0; let guess = 0.1; // Sets the limits for possible guesses to any // number between 0% and 100% let lowLimit = 0; let highLimit = 1; // Defines a tolerance of up to +/- 0.00005% of pmt, to accept // the solution as valid. const tolerance = Math.abs(this.const.TOLERANCE_LEVEL * pmt); // Tries at most 40 times to find a solution within the tolerance. for (let tl = 0; tl < 40; tl++) { // Resets the balance to the original pv. let balance = pv; // Calculates the balance at the end of the loan, based // on loan conditions. for (let pr = 0; pr < period; pr++) { balance = (type == 0) ? balance * (1 + guess) + pmt : (balance + pmt) * (1 + guess); } // Returns the guess if balance is within tolerance. If not, adjusts // the limits and starts with a new guess. if (Math.abs(balance + fv) < tolerance) { return guess; } else if (balance + fv > 0) { // Sets a new highLimit knowing that // the current guess was too big. highLimit = guess; } else { // Sets a new lowLimit knowing that // the current guess was too small. lowLimit = guess; } // Calculates the new guess. guess = (highLimit + lowLimit) / 2; } } // Returns 0 if no acceptable result was found after 40 tries. return 0; }; this.const = new constants_1.Constants(); } } exports.FinancialExpression = FinancialExpression;