Link to home
Start Free TrialLog in
Avatar of selpmet
selpmet

asked on

I need a javascript formula that calculates daily, weekly, monthly compound interest accurately

I need a very accurate calculator formula, right now my formula works for monthly contributions with monthly compounding, but when you use weekly contributions with monthly compounding, I don't know how to adjust the formula. You can see my calculator in action at by downloading and unzipping the attached files.

So far, this is the most accurate calculator I've found on the web (I'd be happy if you could get a javascript formula to match the values generated by this calculator):
http://tiny.cc/kmhGP

Here is the problem with weekly contributions and monthly compounding:
1. there are 52 weeks in a year, but some months have 5 weeks while others have 4, however I don't think their calc takes this into account, I think they simply base their calculation on 52 weeks and every 4 weeks they compound the interest.

Anyway, here is the formula I'm using:

var P = startingAmount;
    var Y = yearsOfInvesting;
    var c = getAdditionalContributionsPerPeriod;
    var t = getTermsPerPeriod;
    var n = t * Y;
    var r = interestRate / 100 / t; // interestRate [%]
    var z = 1 + r;
 total = P * Math.pow(z, n) + c * (Math.pow(z, n + 1) - z) / r;

For a scenario:
1. $1000 principal
2. $50 per week contribution
3. 10 years
4. monthly compounding
The total according to: http://tiny.cc/kmhGP should be $30,007 rounding the decimals up.

The closest I've come to this is by this formula is by weekly contributions & weekly compounding (but I want to change it to monthly compounding):
<script>
var P = 1000;//startingAmount;
    var Y = 0;//yearsOfInvesting;
    var c = 50;//
    var n = 520;//t * Y;
    var r = .02/52;
    var z = 1 + r;

mz=  P * Math.pow(z, n) + c * (Math.pow(z, n + 1) - z) / r;
document.write(mz);
</script>
How can I make my formula work for weekly and daily contributions?
 
// Savings calculator formulas
 
// Parameters:
//startingAmount
//years
//additionalContributions
//interestRate
//aditionalContributionsPeriod: 1 - per week; 2 - bi-weekly; 3 - per month; 4 - per quarter; 5 - per year
//interestRatePeriod, Compound: 1 - Daily; 2 - monthly; 3 - quarterly; 4 - annually
 
 
function getDataForChart(startingAmount, yearsOfInvesting, additionalContributions, interestRate, 
    aditionalContributionsPeriod, interestRatePeriod) {
   // Map to one - letter variables
   //var P = startingAmount;
   var Y = yearsOfInvesting;
  // var c = getAdditionalContributionsPerPeriod(startingAmount, yearsOfInvesting, 
      // additionalContributions, interestRate, aditionalContributionsPeriod, interestRatePeriod);
  // var t = getTermsPerPeriod(startingAmount, yearsOfInvesting, 
      // additionalContributions, interestRate, aditionalContributionsPeriod, interestRatePeriod);
  // var n = t * Y;
  // var r = interestRate / 100 / t; // interestRate [%]
  // var z = 1 + r;
   
   var data1 = new Array();
   var data2 = new Array();
   for (var i = 1; i <= Y; i++) {
       // Base amount:
       var B = calculatePrincipal(startingAmount, i, additionalContributions, interestRate, 
                 aditionalContributionsPeriod, interestRatePeriod);
       data1[i - 1] = [i, B];
       // Compound contributions:
       var Cc = calculateTotal(startingAmount, i, additionalContributions, interestRate, 
                aditionalContributionsPeriod, interestRatePeriod);
       // var Cc = P * Math.pow(z, i) + c * (Math.pow(z, i + 1) - z) / r;
       data2[i - 1] = [i, Cc];
   } 
   
   var series = new Array();
   series[0] = data1;
   series[1] = data2;
   return series;
}
 
function calculatePrincipal(startingAmount, yearsOfInvesting, additionalContributions, interestRate, 
    aditionalContributionsPeriod, interestRatePeriod) {
   
    var P = startingAmount;
    var Y = yearsOfInvesting;
    var c = getAdditionalContributionsPerPeriod(startingAmount, yearsOfInvesting, 
       additionalContributions, interestRate, aditionalContributionsPeriod, interestRatePeriod);
    var t = getTermsPerPeriod(startingAmount, yearsOfInvesting, 
       additionalContributions, interestRate, aditionalContributionsPeriod, interestRatePeriod);
    var n = t * Y;
    var r = interestRate / 100 / t; // interestRate [%]
    var z = 1 + r;
    var coeff = 1;
    if (aditionalContributionsPeriod == 1) {
	coeff = 52;
    }
    else if (aditionalContributionsPeriod == 2) {
	coeff = 26;
    }
    else if (aditionalContributionsPeriod == 3) {
	coeff = 12;
    }
    else if (aditionalContributionsPeriod == 4) {
	coeff = 4;
    }
    return startingAmount + coeff * additionalContributions * yearsOfInvesting;
}
 
function calculateTotal(startingAmount, yearsOfInvesting, additionalContributions, interestRate, 
    aditionalContributionsPeriod, interestRatePeriod) {
    
    var P = startingAmount;
    var Y = yearsOfInvesting;
    var c = getAdditionalContributionsPerPeriod(startingAmount, yearsOfInvesting, 
       additionalContributions, interestRate, aditionalContributionsPeriod, interestRatePeriod);
    var t = getTermsPerPeriod(startingAmount, yearsOfInvesting, 
       additionalContributions, interestRate, aditionalContributionsPeriod, interestRatePeriod);
    var n = t * Y;
    var r = interestRate / 100 / t; // interestRate [%]
    var z = 1 + r;
    return P * Math.pow(z, n) + c * (Math.pow(z, n + 1) - z) / r;
}
 
function getTermsPerPeriod(startingAmount, yearsOfInvesting, additionalContributions, interestRate, 
      aditionalContributionsPeriod, interestRatePeriod) {	
  
      if (interestRatePeriod == 1) {
	  return 365;
      }
      else if (interestRatePeriod == 2) {
	  return 12;
      }
      else if (interestRatePeriod == 3) {
	  return 4;
      }
      else {
	  return 1;
      }
      return 1;
}
 
function getAdditionalContributionsPerPeriod(startingAmount, yearsOfInvesting, 
    additionalContributions, interestRate, aditionalContributionsPeriod, interestRatePeriod) {
  
  var divideFactor = 1;
  if (interestRatePeriod == 1) {
      // Additional contributions per day
      if (aditionalContributionsPeriod == 1) {
	  // Week => factor = 7
          divideFactor = 7;
      }
      else if (aditionalContributionsPeriod == 2) {
	  // Biweekly => factor = 14
          divideFactor = 7;
      }
      else if (aditionalContributionsPeriod == 3) {
	  // Monthly => factor = 30
          divideFactor = 30;
      }
      else if (aditionalContributionsPeriod == 4) {
	  // Per quarter => factor = 91
          divideFactor = 91;
      }
      else if (aditionalContributionsPeriod == 5) {
	  // Per year => factor = 365
          divideFactor = 365;
      }
  } 
  else if (interestRatePeriod == 2) {
      // Additional contributions per month
      if (aditionalContributionsPeriod == 1) {
	  // Week
          divideFactor = 1 / 4;
      }
      else if (aditionalContributionsPeriod == 2) {
	  // Biweekly
          divideFactor = 1 / 2;
      }
      else if (aditionalContributionsPeriod == 3) {
	  // Monthly
          divideFactor = 1;
      }
      else if (aditionalContributionsPeriod == 4) {
	  // Per quarter
          divideFactor = 4;
      }
      else if (aditionalContributionsPeriod == 5) {
	  // Per year
          divideFactor = 12;
      }
  }   
  else if (interestRatePeriod == 3) {
      // Additional contributions per quarter
      if (aditionalContributionsPeriod == 1) {
	  // Week
          divideFactor = 1 / 13;
      }
      else if (aditionalContributionsPeriod == 2) {
	  // Biweekly
          divideFactor = 1 / 6.5;
      }
      else if (aditionalContributionsPeriod == 3) {
	  // Monthly
          divideFactor = 1 / 4;
      }
      else if (aditionalContributionsPeriod == 4) {
	  // Per quarter
          divideFactor = 1;
      }
      else if (aditionalContributionsPeriod == 5) {
	  // Per year
          divideFactor = 4;
      }
  }   
  else if (interestRatePeriod == 4) {
      // Additional contributions per year
      if (aditionalContributionsPeriod == 1) {
	  // Week
          divideFactor = 1 / 52;
      }
      else if (aditionalContributionsPeriod == 2) {
	  // Biweekly
          divideFactor = 1 / 26;
      }
      else if (aditionalContributionsPeriod == 3) {
	  // Monthly
          divideFactor = 1 / 12;
      }
      else if (aditionalContributionsPeriod == 4) {
	  // Per quarter 
          divideFactor = 1 / 4;
      }
      else if (aditionalContributionsPeriod == 5) {
	  // Per year
          divideFactor = 1;
      }
  }   
  return additionalContributions / divideFactor;
}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of mudbuggle
mudbuggle
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of selpmet
selpmet

ASKER

I don't understand the var multiplier - for instance 10 years would be 520 weeks and you're saying to subtract 1 from it?

Also, can you help me figure out the formula for calculating daily/monthly/quarterly/annually compound interest for weekly/daily/bi-weekly/monthly/annually made contributions? There has to be a financial math javascript library that already can do this like excel has.
the multiplier is for on a monthly basis it will calculate per month... as I wrote it it would work for 1 month. Turns out I misread what you were asking, that was my fault. I can come up with something it will take a little though.
This question has been classified as abandoned and is closed as part of the Cleanup Program. See the recommendation for more details.