-1

I'm working on creating a compound interest formula with monthly contributions in javascript for populating a chartkick.js graph to show the total amount the principal grows to at the end of each year. Here is the formula I'm following.

Compound Interest For Principal
P(1 + r/n) ^ nt
Future Value of a Series
PMT * (((1 + r/n)^nt - 1) / (r/n)) * (1+r/n) 

A = [Compound Interest for Principal] + [Future Value of a Series]

A = the future value of the investment/loan, including interest
P = the principal investment amount (the initial deposit or loan amount)
PMT = the monthly payment
r = the annual interest rate (decimal)
n = the number of times that interest is compounded per year AND additional payment frequency
t = the number of years the money is invested or borrowed for 
*/

Here's my javascript:

P = $("#start-amount").val().replace(/[^\d\.]/g, '');
var t = $("#years").val(); 
var PMT = $("#contributions-amount").val().replace(/[^\d\.]/g, '');  
var n = $("#contribution-rate").val();
//If you choose monthly it is equal to 12 and annually it is equal to 1 
//Convert Interest Rate to Decimal
var r_percentage = $("#interest-rate").val().replace(/[^\d\.]/g, '');
var r = parseFloat(r_percentage) /  100.0;

//Create an arary with list of numbers less than number of years
var t_arr = [];
for (i = 0; i <= t; i++) {
    if (i > 0 && i <= t) {
        t_arr.push(i)
    }
}

//For Chartkick Chart
data = [
{"name": "With interest", "data": {}
},
{"name": "No Interest", "data": {}
}];

/* 
Needs to be like this!
data = [
  {"name":"Workout", "data": {"2013-02-10 00:00:00 -0800": 3, "2013-02-17 00:00:00 -0800": 4}},
  {"name":"Call parents", "data": {"2013-02-10 00:00:00 -0800": 5, "2013-02-17 00:00:00 -0800": 3}}
];*/

/*With Interest
J is equal to each individual year less than the total number of years*/
for (j = 1; j <= t_arr.length; j++) {
    var compound_interest_for_principal = P * (Math.pow(1 + r / n, n * t));
    var value_rounded1 = Math.round(compound_interest_for_principal * 100) /100;
    var future_value_of_series = PMT * (Math.pow(1 + r / n, n * j) - 1) / (r / n) * (1 + r / n);
    var value_rounded2 = Math.round(future_value_of_series * 100) / 100;
    var A = value_rounded1 + value_rounded2;
    var A = A.toFixed(2);
    if (data[0]["data"][j] === undefined) {
        data[0]["data"][j] = A;
    }
}

/*Without Interest */
for (k = 1; k <= t_arr.length; k++) {
    var r = 0;
    var principal_no_interest= P;
    var value_rounded1 = Math.round(principal_no_interest * 100) /100;
    var monthly_no_interest = PMT * n * k;
    var value_rounded2 = Math.round(monthly_no_interest * 100) / 100;
    var A = value_rounded1 + value_rounded2;
    var A = A.toFixed(2);
    if (data[1]["data"][k] === undefined) {
        data[1]["data"][k] = A;
    }
}
new Chartkick.LineChart("savings-chart", data, {"discrete": true});

The values I'm testing are P = $1,000, r = 5% (annual interest), PMT = $100 per month, and n = 12 (number of times interested is compounded per year AND additional payment frequency).

Where the problem is coming in is the values I'm getting.

After 1 year with interest, I get $2,880 and I should get $2,277. After 10 years, I should get $17,065.21, but I'm getting $17,239.94. I don't understand why it's adding about $1,800 to the original vs about $1,200 like it should. Any suggestions?

zasman
  • 446
  • 1
  • 8
  • 28
  • 5
    Replace any `x ^ y` with `Math.pow(x, y)`. What's the problem? – Barmar Aug 30 '16 at 20:17
  • The problem is with nesting the first full half of the formula there... the answer will come out in the millions. – zasman Aug 30 '16 at 20:20
  • No it won't. You keep the nesting, so the `x` in `Math.pow(x, y)` is `(1 + r/n)`... – nnnnnn Aug 30 '16 at 20:21
  • maybe the problem is a missing closing bracket at the end of `var future_value = contributions_amount * (((1 + interest_rate/contribution_rate) ^ (contribution_rate * years) - 1 / (interest_rate/years) * (1 + (interest_rate/years)));` – Nina Scholz Aug 30 '16 at 20:21
  • @JasonBourne IEEE 754 can handle doubles up to 1.7976931348623157e+308. What's the problem? – Derek 朕會功夫 Aug 30 '16 at 20:21
  • @JasonBourne Post what you tried. If you did it wrong, we'll explain your mistake and show you the correction. That's how you learn. – Barmar Aug 30 '16 at 20:22
  • @Derek朕會功夫 It's not supposed to go that high. I'm talking making a calculator where you start out with $1000, put in 100 a month at an interest rate of like 3 percent per year. – zasman Aug 30 '16 at 20:25
  • Just updated post with code – zasman Aug 30 '16 at 20:33
  • Updated the original post with code! – zasman Aug 31 '16 at 17:39
  • which compound interest formula tho. P=e^(rt) is the simplest. These formulas are not hard to implement. Just wait till you need to find integrals... – washcloth Sep 01 '16 at 00:59

2 Answers2

2

You could check this

var result = PMT * (Math.pow(1 + r / n, nt) - 1) / (r / n) * (1 + r / n);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

Thank you all for your help. I found a solution. Here's the incorrect code vs the correct code:

/*
Formula to Implement
P(1 + r/n) ^ nt
Future Value of a Series
PMT * (((1 + r/n)^nt - 1) / (r/n)) * (1+r/n) 

A = [Compound Interest for Principal] + [Future Value of a Series]

A = the future value of the investment/loan, including interest
P = the principal investment amount (the initial deposit or loan amount)
PMT = the monthly payment
r = the annual interest rate (decimal)
n = the number of times that interest is compounded per year AND additional payment frequency
t = the number of years the money is invested or borrowed for 
/*

/*INCORRECT SOLUTION
J is equal to each individual year less than the total number of years*/
for (j = 1; j <= t_arr.length; j++) {
    //Correct
    var compound_interest_for_principal = P * (Math.pow(1 + r / n, n * t));
    //Correct
    var a= Math.round(compound_interest_for_principal * 100) /100;
    //Incorrect
    var future_value_of_series = PMT * (Math.pow(1 + r / n, n * j) - 1) / (r / n) * (1 + r / n);
    var b = Math.round(future_value_of_series * 100) / 100;
    var A = a + b;
    var A = A.toFixed(2);
    if (data[0]["data"][j] === undefined) {
        data[0]["data"][j] = A;
    }
}

//CORRECT SOLUTION
for (j = 1; j <= t_arr.length; j++) {
    //Incorrect
    var compound_interest_for_principal = P * (Math.pow(1 + r / n, n * j));
    var a = Math.round(compound_interest_for_principal * 100) / 100;
    var future_value_of_series = ((PMT * n) / r) * (Math.pow(1 + r / n, n * j) - 1) 
    var b = Math.round(future_value_of_series * 100) / 100;
    var A = a + b
    var A = A.toFixed(2);
    if (data[0]["data"][j] === undefined) {
        data[0]["data"][j] = A;
}
zasman
  • 446
  • 1
  • 8
  • 28