I am get a formula to calculate the Net Present Value using Rent, Number of periods, Discount Rate and Future Value.I am able to get the Present Value however, I need a formula to calculate the Net Present Value on today's date or any date a user inputs. My code is as below:
function PV() {
var future = 5000;
var type = 1;
periods = 12;
rate = document.getElementById("rate").value;
var ratePercent = periods * 100;
rate = Math.pow(1 + rate / 100, 1 / 365) - 1;
rate = eval(rate);
periods = eval(periods);
// Return present value
if (rate === 0) {
document.getElementById("presentResultValue").value = -payment * periods - future;
} else {
document.getElementById("presentResultValue").value = (
(((1 - Math.pow(1 + rate, periods)) / rate) * payment * (1 + rate * type) - future) /
Math.pow(1 + rate, periods)
).toFixed(2);
}
}
I am also using Excel to calculate this but need a way to convert it to Javascript. I am also attaching my work with excel. ExcelNPV I am still learning JavaScript so any help will be greatly appreciated. Thank you.
Came across NPV formula on my project and had to create a function for it. Finance.js is great but I didn't want to clutter my code with it because my problem was just getting this formula.
ES5 Function
/**
* Calculates the Net Present Value of a given initial investment
* cost and an array of cash flow values with the specified discount rate.
*
* #param {number} rate - The discount rate percentage
* #param {number} initialCost - The initial investment
* #param {array} cashFlows - An array of future payment amounts
* #return {number} The calculated Net Present Value
*/
function getNPV(rate, initialCost, cashFlows) {
var npv = initialCost;
for (var i = 0; i < cashFlows.length; i++) {
npv += cashFlows[i] / Math.pow(rate / 100 + 1, i + 1);
}
return npv;
}
Using the function:
var rate = 10;
var initialCost = -25000;
var cashFlows = [-10000, 0, 10000, 30000, 100000];
console.log(getNPV(rate, initialCost, cashFlows));
// expected output: 56004.77488497429
JavaScript ES6 Function:
https://www.evermade.fi/net-present-value-npv-formula-for-javascript/
/**
* Calculates the Net Present Value of a given initial investment
* cost and an array of cash flow values with the specified discount rate.
* #param {number} rate - The discount rate percentage
* #param {number} initialCost - The initial investment
* #param {array} cashFlows - An array of future payment amounts
* #return {number} The calculated Net Present Value
*/
function getNPV(rate, initialCost, cashFlows) {
return cashFlows.reduce(
(accumulator, currentValue, index) =>
accumulator + currentValue / Math.pow(rate / 100 + 1, index + 1),
initialCost
);
}
I've explained most of it on my blogpost.
Hope this helps :)
One big thing you are missing with this is the cost.
You have periods, you have rate, you have rate percent. But there is nothing there for the "cost".
You say you have this in Excel, and other languages. If you understand the calculations in Excel, then you may understand how you should do it in JavaScript.
In Excel you use the nifty function =NPV(.... where it takes 2 arguments. The first is the "RATE" and the second is the "VALUE" which can be multiple values. When you do this in Excel, one of the values you pass in would be the total cost. So you have something like this....
=NPV(2%,[total cost],[Year1Value],[Year2Value],[Year3Value],....) or =NPV(A1,A2:A12)
The "Total Cost" would go where you spend the money....assuming its at the end of Year 1, it would go before the "value" / return from year one.
With that being said, another thing to consider is determining WHEN the cost was needed.
If the cost is upfront, then it would be taken out of the "array" of values section and added to the NPV calculations such as....
=NPV(A1,A3:A12) + A2
Where cell A2 is the Cost (upfront) and A1 is the rate and A3-A12 are all the returns.
As a simple example, if you have the rate somewhere on the page, you can loop through the arguments that are going to be passed to it such as below....
function NPV() {
var args = [];
for (i = 0; i < arguments.length; i++) {
args = args.concat(arguments[i]);
}
var rate = document.getElementById("rate").value;
var value = 0;
// loop through each argument, and calculate the value
// based on the rate, and add it to the "value" variable
// creating a running total
for (var i = 1; i < args.length; i++) {
value = value + ((args[i])/(Math.pow(1 + rate, i)));
}
return value;
}
Additionally, you could also look for a library such as Finanace.JS http://financejs.org/
This worked for me
function getNPV(rate, a, payment) {
var npv = 0;
for (var i = 0; i < a.length; i++) {
npv += payment / Math.pow(1 + rate, a[i]);
console.log(payment / Math.pow(1 + rate, a[i]))
}
return npv;
}
Related
I am trying to calculate the Exponential Moving Average (EMA) of stock. I found this formula:
=AVERAGE(INDEX(GoogleFinance("GOOG","all",WORKDAY(TODAY(),-200),TODAY()),,3))
But it is a function just to calculate Simple Moving Average. I researched more and found a script from this thread that was supposed to be the solution:
/**
* Calculates the EMA of the range.
*
* #param {range} range The range of cells to calculate.
* #param {number} n The number of trailing samples to give higer weight to, e.g. 30.
* #return The EMA of the range.
* #customfunction
*/
function EMA(range, n) {
if (!range.reduce) {
return range;
}
n = Math.min(n, range.length);
var a = 2 / (n + 1);
return range.reduce(function(accumulator, currentValue, index, array) {
return currentValue != "" ? (currentValue * a + accumulator * (1-a)) : accumulator;
}, 0);
}
But when I run it, it is no way near the actual value. Kindly can you guide me on how to calculate accurate EMA of stock after 200 days with a script or formula without iterating each previous day's value or as a next option can we calculate EMA from the Simple Moving Average of the last 200 days?
Here is the link to Sample Data. In Column U, I am calculating EMA step by step, while Column B is the Simple Moving Average of 'GOOG' stock, can we get EMA using the data of Column B by creating some formula or script?
Issue:
I think the referenced formula is not handling the first element in the series properly. The value of the EMA at time period 0 matches the value of the series itself. And since all the rest of the values depend on that one, the end result is wrong (ref):
Solution:
Therefore, the reduce function should take the first value in the series as the initial value:
function EMA(range, n) {
if (!range.reduce) {
return range;
}
n = Math.min(n, range.length);
const a = 2 / (n + 1);
const first = range.shift();
return range.reduce((accumulator, currentValue) => {
return currentValue != "" ? (currentValue * a + accumulator * (1-a)) : accumulator;
}, first);
}
I am trying to calculate the consistency of an array of values which output a percentage. So for example an array of [1,1,1,1,1] would output 100% consistency, and array of [1,12,23,5,2] would output something like 25% consistency.
I have tried a simple percentage difference calculation but is only for two numbers whereas this needs to work for a dynamic array and this only outputs the difference. Any help would be appreciated so thanks in advance.
function getPercentage(n1, n2){
var newValue = n1 - n2;
return (newValue / n1) * 100;
}
getPercentage(1, 12)
Based on your comments, I refined the base value used in calculating the overall consistency between members of the array.
The new results calculated (which on visual inspection seems plausible, again it depends on the definition of consistency over all members but I think this is getting closer):
$ node jsscratch.js
Consistency for 1,1,1,1,1 is 100.000% fixed to 3 decimal places
Consistency for 1,12,23,5,2 is 33.360% fixed to 3 decimal places
Consistency for 1,12,23,15,12 is 50.160% fixed to 3 decimal places
Consistency for 1,2,10 is 83.778% fixed to 3 decimal places
/**
* Calculate the expected value
*/
function expectancy(arrayOfValues) {
let sumTotal = function(previousValue, currentValue) {
return previousValue + currentValue;
};
let u = arrayOfValues.reduce(sumTotal);
// Assume each member carries an equal weight in expected value
u = u / arrayOfValues.length;
return u;
}
/**
* Calculate consistency of the members in the vector
* #param {Array<number>} The vector of members to inspect for similarity
* #return {number} The percentage of members that are the same
*/
var similarity = function(arrayOfValues) {
let sumTotal = function(previousValue, currentValue) {
return previousValue + currentValue;
};
// Step 1: Calculate the mean value u
let u = expectancy(arrayOfValues); // Calculate the average
// Step 2: Calculate the standard deviation sig
let sig = [];
let N = 1/arrayOfValues.length;
for (let i = 0; i < arrayOfValues.length; i++) {
sig.push(N*(arrayOfValues[i] - u) * (arrayOfValues[i] - u));
}
// This only works in mutable type, such as found in JavaScript, else sum it up
sig = sig.reduce(sumTotal);
// Step 3: Offset from 100% to get the similarity
return 100 - sig;
}
answer = similarity(ar1);
console.log(`Consistency for ${ar1} is ${answer.toFixed(3)}% fixed to 3 decimal places`);
answer = similarity(ar2);
console.log(`Consistency for ${ar2} is ${answer.toFixed(3)}% fixed to 3 decimal places`);
answer = similarity(ar3);
console.log(`Consistency for ${ar3} is ${answer.toFixed(3)}% fixed to 3 decimal places`);
answer = similarity(ar4);
console.log(`Consistency for ${ar4} is ${answer.toFixed(3)}% fixed to 3 decimal places`);
Ok this is my first stab I'll take at it, tried to brake it up into smaller units of code to make it easier to work through. If I had enough time this could be further refined but then the readability goes south ;-)
Tried to avoid using TypeScript and to keep it as ECMAScript 5 friendly as possible. (Sorry about the messy formatting)
let ar100 = [1,1,1,1,1];
let ar25 = [1,12,23,5,2];
/**
* Calculate the lack of difference between two values (ie consistency)
* #param {number} valA
* #param {number} valB
* #returns {number} The consistency as a decimal
* where 1 is '100% consistent'
* and 0.5 is '50% consistent'
*/
var calcConsistency = function( valA, valB) {
let diff = Math.abs(valA - valB);
let consistency = (valA - diff) / valA;
// assumption: you can't be less than zero consistent
return consistency < 0 ? 0 : consistency;
}
/**
* A predicate used by the map operation in 'overallConsistency'
* #param {*} val
* #param {*} index
* #param {*} values
* #return {number} the average consistency of the current 'val' to the other 'values'
*/
var mapEachConsistency = function(val, index, values) {
let predicateGetOnlyOthers = function(currentValue, othersIndex) {
return index !== othersIndex;
};
let others = values.filter(predicateGetOnlyOthers);
const otherCount = others.length;
let totalConsistency = others.reduce(function(previousValue, currentValue) {
return previousValue + calcConsistency(val, currentValue);
});
return (totalConsistency / otherCount);
}
/**
* Calculate the overall average consistency of an array of numbers
* #param {Array<number>} arrayOfValues
* #return {number} The average consistency score as percentage
*/
var overallConsistency = function(arrayOfValues) {
let consists = arrayOfValues.map(mapEachConsistency);
let sumTotal = function(previous, current){ return previous + current; };
let avgAnswer = consists.reduce(sumTotal);
return (avgAnswer / consists.length) * 100;
};
// Here's using it to see the results
var answer = overallConsistency(ar100);
console.log(`Consistency: ${answer.toFixed(3)}% (fixed to 3 dicimal place)`);
answer = overallConsistency(ar25);
console.log(`Consistency: ${answer.toFixed(3)}% (fixed to 3 dicimal place)`);
I would like get a random number in a range excluding one number (e.g. from 1 to 1000 exclude 577). I searched for a solution, but never solved my issue.
I want something like:
Math.floor((Math.random() * 1000) + 1).exclude(577);
I would like to avoid for loops creating an array as much as possible, because the length is always different (sometimes 1 to 10000, sometimes 685 to 888555444, etc), and the process of generating it could take too much time.
I already tried:
Javascript - Generating Random numbers in a Range, excluding certain numbers
How can I generate a random number within a range but exclude some?
How could I achieve this?
The fastest way to obtain a random integer number in a certain range [a, b], excluding one value c, is to generate it between a and b-1, and then increment it by one if it's higher than or equal to c.
Here's a working function:
function randomExcluded(min, max, excluded) {
var n = Math.floor(Math.random() * (max-min) + min);
if (n >= excluded) n++;
return n;
}
This solution only has a complexity of O(1).
One possibility is not to add 1, and if that number comes out, you assign the last possible value.
For example:
var result = Math.floor((Math.random() * 100000));
if(result==577) result = 100000;
In this way, you will not need to re-launch the random method, but is repeated. And meets the objective of being a random.
As #ebyrob suggested, you can create a function that makes a mapping from a smaller set to the larger set with excluded values by adding 1 for each value that it is larger than or equal to:
// min - integer
// max - integer
// exclusions - array of integers
// - must contain unique integers between min & max
function RandomNumber(min, max, exclusions) {
// As #Fabian pointed out, sorting is necessary
// We use concat to avoid mutating the original array
// See: http://stackoverflow.com/questions/9592740/how-can-you-sort-an-array-without-mutating-the-original-array
var exclusionsSorted = exclusions.concat().sort(function(a, b) {
return a - b
});
var logicalMax = max - exclusionsSorted.length;
var randomNumber = Math.floor(Math.random() * (logicalMax - min + 1)) + min;
for(var i = 0; i < exclusionsSorted.length; i++) {
if (randomNumber >= exclusionsSorted[i]) {
randomNumber++;
}
}
return randomNumber;
}
Example Fiddle
Also, I think #JesusCuesta's answer provides a simpler mapping and is better.
Update: My original answer had many issues with it.
To expand on #Jesus Cuesta's answer:
function RandomNumber(min, max, exclusions) {
var hash = new Object();
for(var i = 0; i < exclusions.length; ++i ) { // TODO: run only once as setup
hash[exclusions[i]] = i + max - exclusions.length;
}
var randomNumber = Math.floor((Math.random() * (max - min - exclusions.length)) + min);
if (hash.hasOwnProperty(randomNumber)) {
randomNumber = hash[randomNumber];
}
return randomNumber;
}
Note: This only works if max - exclusions.length > maximum exclusion. So close.
You could just continue generating the number until you find it suits your needs:
function randomExcluded(start, end, excluded) {
var n = excluded
while (n == excluded)
n = Math.floor((Math.random() * (end-start+1) + start));
return n;
}
myRandom = randomExcluded(1, 10000, 577);
By the way this is not the best solution at all, look at my other answer for a better one!
Generate a random number and if it matches the excluded number then add another random number(-20 to 20)
var max = 99999, min = 1, exclude = 577;
var num = Math.floor(Math.random() * (max - min)) + min ;
while(num == exclude || num > max || num < min ) {
var rand = Math.random() > .5 ? -20 : 20 ;
num += Math.floor((Math.random() * (rand));
}
import random
def rng_generator():
a = random.randint(0, 100)
if a == 577:
rng_generator()
else:
print(a)
#main()
rng_generator()
Exclude the number from calculations:
function toggleRand() {
// demonstration code only.
// this algorithm does NOT produce random numbers.
// return `0` - `576` , `578` - `n`
return [Math.floor((Math.random() * 576) + 1)
,Math.floor(Math.random() * (100000 - 578) + 1)
]
// select "random" index
[Math.random() > .5 ? 0 : 1];
}
console.log(toggleRand());
Alternatively, use String.prototype.replace() with RegExp /^(577)$/ to match number that should be excluded from result; replace with another random number in range [0-99] utilizing new Date().getTime(), isNaN() and String.prototype.slice()
console.log(
+String(Math.floor(Math.random()*(578 - 575) + 575))
.replace(/^(577)$/,String(isNaN("$1")&&new Date().getTime()).slice(-2))
);
Could also use String.prototype.match() to filter results:
console.log(
+String(Math.floor(Math.random()*10))
.replace(/^(5)$/,String(isNaN("$1")&&new Date().getTime()).match(/[^5]/g).slice(-1)[0])
);
I have read quite a few back prop algorithms and i have no idea why mine is doing what it is doing.
Some notes before reading
No-hidden layer can "learn" all linear equations given a training set. Using 5 / 2 training it will even learn as accurate as 0.01% average error (fairly low)
When a hidden layer is used. The network will only output 2 values. One if both inputs are positive one if both inputs are negative.
The activation function of inputs -> hiddens -> (up to) outputs is f(x) = 1 / (1 + e^-x)
The activation function of outputs is linear (f(x) = x)
Error calculations
I believe this is where my possible error is at!
Outputs: E(k) = (target(k) - O(k).output) * f'(O(k).output) = (target - actual) * 1 linear activation fn gets 1 as derivative
Inputs and hiddens: E(j) = sum(w(kj) * E(k)) * f'(N(j).output) = sum(w(kj) * E(k) * N(j).output * (1 - N(j).output)
The full source code can be found here
http://www.github.com/primeagen/neural-js
The Source! Its in javascript!
Remember: Feedforward and output error seems to be correct since a non hidden layer network can learn any linear function and extrapolate well beyond its training set with a 0.01%. So i believe that is correct
Back prop error calculation
// Output layer
for (var i = 0; i < this._outputs.length; i++) {
var o = this._outputs[i];
o.error = targetOutputs[i] - o.output;
this._mse += o.error * o.error;
}
// Go through hidden layers
for (var cIdx = this._layers.length - 2; cIdx > 0; cIdx--) {
var curr = this._layers[cIdx];
var next = this._layers[cIdx + 1];
// Go through hidden neurons
for (var hN = 0, hLen = curr.length; hN < hLen; hN++) {
var h = curr[hN];
var sum = 0;
for (var nN = 0, nLen = next.length; nN < nLen; nN++) {
var n = next[nN];
sum += n.w[hN] * n.error;
}
h.error = sum * h.dActivationFn(h.output);
}
}
The activation function and its derivative
/**
* The logisticFunction function is 1 / (1 + e ^ (-x))
* #param x
*/
function logisticFunction(x) {
return 1 / (1 + Math.pow(Math.E, -x));
}
/**
* The derivative of the logistic function
* #param {Number} x
* #returns {Number}
*/
function dLogisticFunction(x) {
return x * (1 - x);
}
Neuron.dActivation = dLogisticFunction
My network just converges onto an answer (its random) and no matter the input (when positive) the value will not change when trained with 100+ data points...
Any idea?
I am wondering how in javascript if i was given a number (say 10000) and then was given a percentage (say 35.8%)
how would I work out how much that is (eg 3580)
var result = (35.8 / 100) * 10000;
(Thank you jball for this change of order of operations. I didn't consider it).
This is what I would do:
// num is your number
// amount is your percentage
function per(num, amount){
return num*amount/100;
}
...
<html goes here>
...
alert(per(10000, 35.8));
Your percentage divided by 100 (to get the percentage between 0 and 1) times by the number
35.8/100*10000
Best thing is to memorize balance equation in natural way.
Amount / Whole = Percentage / 100
usually You have one variable missing, in this case it is Amount
Amount / 10000 = 35.8 / 100
then you have high school math (proportion) to multiple outer from both sides and inner from both sides.
Amount * 100 = 358 000
Amount = 3580
It works the same in all languages and on paper. JavaScript is no exception.
I use two very useful JS functions:
http://blog.bassta.bg/2013/05/rangetopercent-and-percenttorange/
function rangeToPercent(number, min, max){
return ((number - min) / (max - min));
}
and
function percentToRange(percent, min, max) {
return((max - min) * percent + min);
}
If you want to pass the % as part of your function you should use the following alternative:
<script>
function fpercentStr(quantity, percentString)
{
var percent = new Number(percentString.replace("%", ""));
return fpercent(quantity, percent);
}
function fpercent(quantity, percent)
{
return quantity * percent / 100;
}
document.write("test 1: " + fpercent(10000, 35.873))
document.write("test 2: " + fpercentStr(10000, "35.873%"))
</script>
In order to fully avoid floating point issues, the amount whose percent is being calculated and the percent itself need to be converted to integers. Here's how I resolved this:
function calculatePercent(amount, percent) {
const amountDecimals = getNumberOfDecimals(amount);
const percentDecimals = getNumberOfDecimals(percent);
const amountAsInteger = Math.round(amount + `e${amountDecimals}`);
const percentAsInteger = Math.round(percent + `e${percentDecimals}`);
const precisionCorrection = `e-${amountDecimals + percentDecimals + 2}`; // add 2 to scale by an additional 100 since the percentage supplied is 100x the actual multiple (e.g. 35.8% is passed as 35.8, but as a proper multiple is 0.358)
return Number((amountAsInteger * percentAsInteger) + precisionCorrection);
}
function getNumberOfDecimals(number) {
const decimals = parseFloat(number).toString().split('.')[1];
if (decimals) {
return decimals.length;
}
return 0;
}
calculatePercent(20.05, 10); // 2.005
As you can see, I:
Count the number of decimals in both the amount and the percent
Convert both amount and percent to integers using exponential notation
Calculate the exponential notation needed to determine the proper end value
Calculate the end value
The usage of exponential notation was inspired by Jack Moore's blog post. I'm sure my syntax could be shorter, but I wanted to be as explicit as possible in my usage of variable names and explaining each step.
It may be a bit pedantic / redundant with its numeric casting, but here's a safe function to calculate percentage of a given number:
function getPerc(num, percent) {
return Number(num) - ((Number(percent) / 100) * Number(num));
}
// Usage: getPerc(10000, 25);
var number = 10000;
var result = .358 * number;
Harder Way (learning purpose) :
var number = 150
var percent= 10
var result = 0
for (var index = 0; index < number; index++) {
const calculate = index / number * 100
if (calculate == percent) result += index
}
return result