Last active
July 14, 2024 11:21
-
-
Save haran090/dd0434bc505b96b5cdc0096b467bcc44 to your computer and use it in GitHub Desktop.
Internal Rate of Return Method (IRR)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import java.math.BigDecimal; | |
| public class IRR { | |
| //Approximate number of days between 2 successive cash flows. Eg. For monthly cash flows interval will be 30 | |
| private static final int INTERVAL = 30; | |
| public static BigDecimal getAnnualIrr(double[] cash_flows) { | |
| return calculateIrrRecursively(BigDecimal.valueOf(1.0), BigDecimal.valueOf(100.0), BigDecimal.valueOf(1.0), cash_flows); | |
| } | |
| public static BigDecimal calculateIrrRecursively(BigDecimal start, BigDecimal end, BigDecimal precision, double[] cash_flows) { | |
| BigDecimal test_rate = start; | |
| BigDecimal sum; | |
| Double previous_diff = null; | |
| double final_cash_flow = cash_flows[cash_flows.length - 1]; | |
| while (test_rate.compareTo(end) != 1) { | |
| sum = new BigDecimal(0); | |
| for (int i = 0; i < cash_flows.length - 1; i++) { | |
| double current_cash_flow = cash_flows[i]; | |
| int days_in_between = getDaysInbetween(i, cash_flows.length); | |
| BigDecimal calc_value = (BigDecimal.valueOf(1).add(test_rate.divide(BigDecimal.valueOf(100)))); | |
| sum = sum.add(BigDecimal.valueOf(current_cash_flow * Math.pow(calc_value.doubleValue(), (days_in_between / 365.0)))); | |
| } | |
| double difference = (Math.abs(final_cash_flow) - Math.abs(sum.doubleValue())); | |
| if (previous_diff == null) { | |
| previous_diff = difference; | |
| } | |
| if (difference < 1 && difference > -1) { | |
| return returnCorrectTestRate(precision, test_rate, previous_diff, difference); | |
| } else if ((previous_diff < 0 && difference > 0) || (previous_diff > 0 && difference < 0)) { | |
| if ((precision.divide(BigDecimal.valueOf(10))).compareTo(BigDecimal.valueOf(0.001)) == -1) {// precision/10 < 0.001 | |
| return returnCorrectTestRate(precision, test_rate, previous_diff, difference); | |
| } else { | |
| return calculateIrrRecursively(test_rate.subtract(precision), test_rate, precision.divide(BigDecimal.valueOf(10)), cash_flows); | |
| } | |
| } else { | |
| previous_diff = difference; | |
| test_rate = test_rate.add(precision); | |
| } | |
| } | |
| return end.subtract(precision); | |
| } | |
| private static BigDecimal returnCorrectTestRate(BigDecimal precision, BigDecimal test_rate, double previous_diff, double difference) { | |
| if (Math.abs(difference) < Math.abs(previous_diff)) { | |
| return test_rate; | |
| } else { | |
| return test_rate.subtract(precision); | |
| } | |
| } | |
| private static int getDaysInbetween(int current_iteration, int total_cash_flows) { | |
| return (total_cash_flows - current_iteration) * INTERVAL; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment