Skip to content

This project provides a comprehensive and reliable method to calculate the intrinsic value of a stock based on fundamental analysis. The intrinsic value is an essential concept for investors to determine whether a stock is overvalued or undervalued.

Notifications You must be signed in to change notification settings

devjoemar/intrinsic-value

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

3 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿ“ˆ Intrinsic Value Calculation Service

Welcome to the Intrinsic Value Calculation Service project! This project provides a comprehensive and reliable method to calculate the intrinsic value of a stock based on fundamental analysis. The intrinsic value is an essential concept for investors to determine whether a stock is overvalued or undervalued.

๐Ÿš€ Introduction

Investing in stocks requires a thorough understanding of a company's financial health and future growth prospects. One way to evaluate a stock's worth is through intrinsic value calculation, which estimates the inherent worth of a stock based on its expected future cash flows.

The intrinsic value calculation helps investors make informed decisions about buying or selling a stock by comparing the intrinsic value with the current market price. If the intrinsic value is higher than the current market price, the stock is considered undervalued and may be a good investment opportunity. Conversely, if the intrinsic value is lower than the current market price, the stock is considered overvalued.

๐Ÿ› ๏ธ Project Overview

This project provides a Spring Boot microservice that calculates the intrinsic value of a stock using the following parameters:

  • Free Cash Flow for the last year (fcfLastYear)
  • Expected growth rate for the next 10 years (growthRate)
  • Discount rate (discountRate)
  • Terminal growth rate (terminalGrowthRate)
  • Total number of outstanding shares (sharesOutstanding)
  • Net debt (netDebt)
  • Current market price of the stock (currentMarketPrice)

The service exposes a REST API to receive these inputs and returns the intrinsic value per share along with a remark indicating if the stock is undervalued or overvalued.

๐Ÿ“š Key Concepts and Formulas

๐Ÿ’ต Free Cash Flow (FCF)

Free Cash Flow represents the cash generated by the company that is available for distribution to its securities holders. It is a key indicator of a company's financial health. The intrinsic value calculation starts with the FCF of the last year.

๐Ÿ“ˆ Growth Rate

The growth rate is the expected rate at which the company's FCF will grow over the next 10 years. A higher growth rate indicates expectations of higher future cash flows.

๐Ÿ“‰ Discount Rate

The discount rate is used to discount future cash flows to their present value. It reflects the time value of money and the risk associated with the investment. A higher discount rate indicates higher perceived risk.

๐ŸŒฑ Terminal Growth Rate

The terminal growth rate is used to estimate the value of the company's cash flows beyond the forecast period. It reflects long-term growth expectations.

๐Ÿ“ Shares Outstanding

Shares outstanding refer to the total number of shares issued by the company that are held by investors, including restricted shares owned by the company's officers and insiders.

๐Ÿ’ณ Net Debt

Net debt is the company's total debt minus its cash and cash equivalents. It is used to adjust the enterprise value to account for the company's financial obligations.

๐Ÿ’ฒ Current Market Price

The current market price is the price at which the stock is currently trading in the market. It is used to compare against the intrinsic value to determine if the stock is undervalued or overvalued.

๐Ÿงฎ Formulas and Reasoning

๐Ÿ”ฎ Future Cash Flows

Future cash flows are projected by growing the last year's FCF (fcfLastYear) by the growth rate (growthRate) each year for the next 10 years.

FCF_year = FCF_last_year * (1 + growthRate)

BigDecimal[] forecastedFcfs = new BigDecimal[forecastPeriodYears];
forecastedFcfs[0] = dto.getFcfLastYear().multiply(BigDecimal.ONE.add(dto.getGrowthRate()));
for (int year = 1; year < forecastPeriodYears; year++) {
    forecastedFcfs[year] = forecastedFcfs[year - 1].multiply(BigDecimal.ONE.add(dto.getGrowthRate()));
}

๐Ÿ“… Terminal Value

The terminal value is estimated using the terminal growth rate (terminalGrowthRate) and discount rate (discountRate). If the discount rate is zero, the terminal value is calculated differently to avoid division by zero.

Terminal Value = FCF_year10 * (1 + terminalGrowthRate) / (discountRate - terminalGrowthRate)

BigDecimal terminalValue;
if (dto.getDiscountRate().compareTo(BigDecimal.ZERO) > 0) {
    terminalValue = forecastedFcfs[forecastPeriodYears - 1].multiply(BigDecimal.ONE.add(dto.getTerminalGrowthRate()))
            .divide(dto.getDiscountRate().subtract(dto.getTerminalGrowthRate()), RoundingMode.HALF_UP);
} else {
    terminalValue = forecastedFcfs[forecastPeriodYears - 1].multiply(BigDecimal.ONE.add(dto.getTerminalGrowthRate()));
}

๐Ÿ’ฐ Present Value

Future cash flows and terminal value are discounted back to their present value using the discount rate (discountRate).

Present Value of FCFs = Sum(FCF_t / (1 + discountRate)^t) for t = 1 to 10

BigDecimal totalPresentValueOfFcfs = BigDecimal.ZERO;
for (int year = 0; year < forecastPeriodYears; year++) {
    totalPresentValueOfFcfs = totalPresentValueOfFcfs.add(forecastedFcfs[year].divide(BigDecimal.ONE.add(dto.getDiscountRate()).pow(year + 1), RoundingMode.HALF_UP));
}
BigDecimal presentValueOfTerminalValue = terminalValue.divide(BigDecimal.ONE.add(dto.getDiscountRate()).pow(forecastPeriodYears), RoundingMode.HALF_UP);

๐Ÿ“Š Total Enterprise Value

The total enterprise value is the sum of the present values of all future cash flows and the terminal value.

Total Enterprise Value = Present Value of FCFs + Present Value of Terminal Value

BigDecimal totalEnterpriseValue = totalPresentValueOfFcfs.add(presentValueOfTerminalValue);

โš–๏ธ Adjusted Enterprise Value

The adjusted enterprise value is the total enterprise value adjusted for net debt (netDebt) to account for the company's financial obligations.

Adjusted Enterprise Value = Total Enterprise Value - netDebt

BigDecimal adjustedTotalEnterpriseValue = totalEnterpriseValue.subtract(dto.getNetDebt());

๐Ÿงฎ Intrinsic Value per Share

The intrinsic value per share is the adjusted enterprise value divided by the number of outstanding shares (sharesOutstanding).

Intrinsic Value per Share = Adjusted Enterprise Value / sharesOutstanding

BigDecimal intrinsicValuePerShare = adjustedTotalEnterpriseValue.multiply(new BigDecimal(1000)).divide(dto.getSharesOutstanding(), RoundingMode.HALF_UP);

๐Ÿ“‰ Undervalued or Overvalued

The intrinsic value per share is compared with the current market price (currentMarketPrice) to determine if the stock is undervalued or overvalued.

  • If Intrinsic Value per Share > Current Market Price, the stock is Undervalued.
  • If Intrinsic Value per Share < Current Market Price, the stock is Overvalued.

๐Ÿ“‹ API Usage

๐Ÿ“ฅ Request

To calculate the intrinsic value of a stock, send a POST request to /api/v1/intrinsic-value/calculate with the following JSON payload:

{
  "fcfLastYear": 1.1,
  "growthRate": 0.15,
  "discountRate": 0.10,
  "terminalGrowthRate": 0.03,
  "sharesOutstanding": 122,
  "netDebt": 0.5,
  "currentMarketPrice": 291.06
}

๐Ÿ“ค Response

The response will contain the intrinsic value per share and a remark indicating if the stock is undervalued or overvalued:

{
  "intrinsicValue": 318.91,
  "currency": "USD",
  "remarks": "Undervalued"
}

๐Ÿงช Unit Tests

The project includes comprehensive unit tests to validate the intrinsic value calculation for various scenarios. Each test case is designed to verify a specific aspect of the calculation to ensure robustness and accuracy.

๐Ÿ“ Reasoning Behind Each Test Case

  • calculateIntrinsicValue_shouldReturnCorrectIntrinsicValueAndRemark_whenInputIsValid: Verifies that the intrinsic value calculation returns the correct value and remark for valid input data. This test ensures that the calculation logic is correct under normal circumstances.

  • calculateIntrinsicValue_shouldReturnBelowZeroIntrinsicValue_whenFCFIsZero: Checks if the intrinsic value calculation returns a value below zero when the Free Cash Flow (FCF) is zero. This test ensures that the logic correctly handles cases where the company generates no free cash flow.

  • calculateIntrinsicValue_shouldReturnHigherIntrinsicValue_whenNetDebtIsNegative: Ensures that the intrinsic value calculation returns a higher value when the net debt is negative. Negative net debt indicates that the company has more cash than debt, increasing its intrinsic value.

  • calculateIntrinsicValue_shouldReturnLowerIntrinsicValue_whenGrowthRateIsZero: Verifies that the intrinsic value calculation returns a lower value when the growth rate is zero. This test ensures that the calculation correctly reflects the lack of growth in future cash flows.

  • calculateIntrinsicValue_shouldReturnLowerIntrinsicValue_whenTerminalGrowthRateIsZero: Checks if the intrinsic value calculation returns a lower value when the terminal growth rate is zero. This test ensures that the logic correctly handles cases where there is no growth expected beyond the forecast period.

  • calculateIntrinsicValue_shouldHandleLowGrowthRateAndHighDiscountRate: Ensures that the intrinsic value calculation handles scenarios with low growth rate and high discount rate correctly. This test verifies that the calculation reflects higher perceived risk and lower growth expectations.

  • calculateIntrinsicValue_shouldHandleHighGrowthRateAndLowDiscountRate: Verifies that the intrinsic value calculation handles scenarios with high growth rate and low discount rate correctly. This test ensures that the calculation reflects lower perceived risk and higher growth expectations.


About

This project provides a comprehensive and reliable method to calculate the intrinsic value of a stock based on fundamental analysis. The intrinsic value is an essential concept for investors to determine whether a stock is overvalued or undervalued.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages