som-exp-sdk
Version:
Evaluate the User Expression
137 lines (136 loc) • 6.07 kB
JavaScript
;
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;