The rate calculated was 1.17%.
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
public class SolverExample {
static SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
public static void main(String[] args) {
try {
Double currentNetWorth = 3170.14;
Date currentDate = sdf.parse("05/30/2014");
Map<Double, Double> yearsToPaymentsMap = new LinkedHashMap<Double, Double>();
yearsToPaymentsMap.put(yearsBetween(sdf.parse("04/02/2013"), currentDate), 300.00);
yearsToPaymentsMap.put(yearsBetween(sdf.parse("05/03/2013"), currentDate), 300.00);
yearsToPaymentsMap.put(yearsBetween(sdf.parse("09/03/2013"), currentDate), 300.00);
yearsToPaymentsMap.put(yearsBetween(sdf.parse("10/01/2013"), currentDate), 300.00);
yearsToPaymentsMap.put(yearsBetween(sdf.parse("11/01/2013"), currentDate), 300.00);
yearsToPaymentsMap.put(yearsBetween(sdf.parse("12/01/2013"), currentDate), 300.00);
yearsToPaymentsMap.put(yearsBetween(sdf.parse("01/02/2014"), currentDate), 250.00);
yearsToPaymentsMap.put(yearsBetween(sdf.parse("02/04/2014"), currentDate), 250.00);
yearsToPaymentsMap.put(yearsBetween(sdf.parse("03/04/2014"), currentDate), 250.00);
yearsToPaymentsMap.put(yearsBetween(sdf.parse("04/02/2014"), currentDate), 300.00);
yearsToPaymentsMap.put(yearsBetween(sdf.parse("05/02/2014"), currentDate), 300.00);
Double rate = findRateOfReturn(-1.00, 1.00, yearsToPaymentsMap, currentDate, currentNetWorth);
System.out.println("Rate:"+rate);
} catch (ParseException e) {
e.printStackTrace();
}
}
/**
* Uses a binary search to converge on an interest rate between two guesses: lowRate and highRate
* @param lowRate
* @param highRate
* @param yearsToPaymentsMap
* @param currentDate
* @param currentNetWorth
* @return
*/
private static Double findRateOfReturn(double lowRate, double highRate, Map<Double, Double> yearsToPaymentsMap, Date currentDate, Double currentNetWorth) {
while(highRate-lowRate > .0001) {
double testRate = (lowRate + highRate)/2;
Double calculatedNetWorth = calculateNetWorth(testRate, yearsToPaymentsMap);
if(calculatedNetWorth < currentNetWorth) {
lowRate = testRate;
} else {
highRate = testRate;
}
}
return lowRate;
}
/**
* Returns P1(1+r)^Y1 + P2(1+r)^Y2 + ...
* @param interestRate - r
* @param yearsToPaymentsMap - give Y1->P1, Y2->P2, etc
* @return
*/
private static double calculateNetWorth(double interestRate, Map<Double, Double> yearsToPaymentsMap) {
double sum = 0.0;
for(double years: yearsToPaymentsMap.keySet()) {
double payment = yearsToPaymentsMap.get(years);
sum = sum + payment*Math.pow((1 + interestRate), years); // P(1+r)^y
}
return sum;
}
/**
* 1000 millisec/sec * 60 sec/min * 60 min/hr * 24 hr/day * 365 day/year = 31536000000 millisec/year
* @param d1
* @param d2
* @return
*/
public static double yearsBetween(Date d1, Date d2){
return (double) (d2.getTime() - d1.getTime()) / 31536000000.0;
}
}
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
public class SolverExample {
static SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
public static void main(String[] args) {
try {
Double currentNetWorth = 3170.14;
Date currentDate = sdf.parse("05/30/2014");
Map<Double, Double> yearsToPaymentsMap = new LinkedHashMap<Double, Double>();
yearsToPaymentsMap.put(yearsBetween(sdf.parse("04/02/2013"), currentDate), 300.00);
yearsToPaymentsMap.put(yearsBetween(sdf.parse("05/03/2013"), currentDate), 300.00);
yearsToPaymentsMap.put(yearsBetween(sdf.parse("09/03/2013"), currentDate), 300.00);
yearsToPaymentsMap.put(yearsBetween(sdf.parse("10/01/2013"), currentDate), 300.00);
yearsToPaymentsMap.put(yearsBetween(sdf.parse("11/01/2013"), currentDate), 300.00);
yearsToPaymentsMap.put(yearsBetween(sdf.parse("12/01/2013"), currentDate), 300.00);
yearsToPaymentsMap.put(yearsBetween(sdf.parse("01/02/2014"), currentDate), 250.00);
yearsToPaymentsMap.put(yearsBetween(sdf.parse("02/04/2014"), currentDate), 250.00);
yearsToPaymentsMap.put(yearsBetween(sdf.parse("03/04/2014"), currentDate), 250.00);
yearsToPaymentsMap.put(yearsBetween(sdf.parse("04/02/2014"), currentDate), 300.00);
yearsToPaymentsMap.put(yearsBetween(sdf.parse("05/02/2014"), currentDate), 300.00);
Double rate = findRateOfReturn(-1.00, 1.00, yearsToPaymentsMap, currentDate, currentNetWorth);
System.out.println("Rate:"+rate);
} catch (ParseException e) {
e.printStackTrace();
}
}
/**
* Uses a binary search to converge on an interest rate between two guesses: lowRate and highRate
* @param lowRate
* @param highRate
* @param yearsToPaymentsMap
* @param currentDate
* @param currentNetWorth
* @return
*/
private static Double findRateOfReturn(double lowRate, double highRate, Map<Double, Double> yearsToPaymentsMap, Date currentDate, Double currentNetWorth) {
while(highRate-lowRate > .0001) {
double testRate = (lowRate + highRate)/2;
Double calculatedNetWorth = calculateNetWorth(testRate, yearsToPaymentsMap);
if(calculatedNetWorth < currentNetWorth) {
lowRate = testRate;
} else {
highRate = testRate;
}
}
return lowRate;
}
/**
* Returns P1(1+r)^Y1 + P2(1+r)^Y2 + ...
* @param interestRate - r
* @param yearsToPaymentsMap - give Y1->P1, Y2->P2, etc
* @return
*/
private static double calculateNetWorth(double interestRate, Map<Double, Double> yearsToPaymentsMap) {
double sum = 0.0;
for(double years: yearsToPaymentsMap.keySet()) {
double payment = yearsToPaymentsMap.get(years);
sum = sum + payment*Math.pow((1 + interestRate), years); // P(1+r)^y
}
return sum;
}
/**
* 1000 millisec/sec * 60 sec/min * 60 min/hr * 24 hr/day * 365 day/year = 31536000000 millisec/year
* @param d1
* @param d2
* @return
*/
public static double yearsBetween(Date d1, Date d2){
return (double) (d2.getTime() - d1.getTime()) / 31536000000.0;
}
}
This post was reposted from http://scottizu.wordpress.com/2014/05/30/binary-search-algorithm-for-calculating-interest-rate/, originally written on May 30th, 2014.
dear sir,
ReplyDeleteI need calculation algorithm of interest rate having qarterly Payment frequency and monthly compounding
Monthly compounding means the interest is added to the account each month.
ReplyDeleteQuarterly payment frequency might mean the extra funds are not released until the end of the quarter.
Can you clarify?
Thank you for helping me.
DeleteActually i want to calculate Interest Rate on Loan where installment is Paid after every 3 Months with monthly compounding. I know loan amount, Loan Period in months and installment amount.
for ex:
Loan Amount : 100000
Period :36 months;
Quarterly Installment : 10500(in advance)
with help of above values i have to find Interest rate?
ans should be :17.7802
Please see this blog post. http://sizustech.blogspot.com/2015/11/calculating-loan-amortization-with.html
ReplyDeleteI used the loan amount, interest rate and monthly payments you supplied. After 36 months, you would still owe $7,329. Please post further questions there and I can help you further.