IsThisStockGood icon indicating copy to clipboard operation
IsThisStockGood copied to clipboard

Add 10Cap valuation

Open kocielnik opened this issue 1 year ago • 2 comments

Phil once mentioned ^1 he typically values each company using three methods: MOSP, Payback Time, and 10Cap.

If two methods roughly agree on a particular value, he uses it as his buy price.

Perhaps the 10Cap method would be useful for us here too, to compare against the other two.

If we decide to add it, that should not be excessively difficult.

The 10Cap formula is ^2:

Owners earnings = Net income + Non-cash charges - Maintenance capital expenditures (CapEx)

What we have, and what remains to be obtained:

  1. Net income: OK (we have net_income_history),
  2. Non-cash charges (how to fetch it?),
  3. CapEx (I see it under MSN Money -> Financials).

kocielnik avatar Sep 21 '24 12:09 kocielnik

Adding example valuations from Phil's Toolbox.

They illustrate that 10-Cap and PBT valuations are not exactly the same, even though both these methods base on a similar concept: current earnings accumulating over time, without assuming future growth.

Example valuation for Coterra (CTRA):

  • 10 CAP Price: 26.51
  • 10 CAP Sticker Price: 53.02
  • MOS Price: 46.27
  • MOS Sticker Price: 92.54
  • PBT Price: 21.93
  • PBT Sticker Price: 43.86
  • PBT at Current Price: 8.33 years

Example valuation for Nvidia (NVDA):

  • 10 CAP Price: 127.43
  • 10 CAP Sticker Price: 254.86
  • MOS Price: 141.24
  • MOS Sticker Price: 282.48
  • PBT Price: 186.48
  • PBT Sticker Price: 372.96
  • PBT at Current Price: 5.83 years

kocielnik avatar Sep 21 '24 19:09 kocielnik

Somehow related:

We already show quite a lot and it takes up most of the screen space. I want the end result to be glanceable and ideally fit within one monitor without scrolling (which we already don't exactly do. it's a bit long).

– https://github.com/mrhappyasthma/IsThisStockGood/issues/85#issuecomment-2293961113

I consider brevity an important aspect of IsThisStockGood.

I appreciate that IsThisStockGood shows only the key info, without clutter. I agree it should be that way.

If your experience, @mrhappyasthma, indicates this method is somehow redundant given PBT and MOSP are working fine, please let me know!

kocielnik avatar Sep 21 '24 20:09 kocielnik

I'm open to adding this. I'll review the code when I get some time. Sorry for the slow replies.

mrhappyasthma avatar Oct 28 '24 20:10 mrhappyasthma

Understood! Thanks! :)

kocielnik avatar Oct 28 '24 20:10 kocielnik

Early-draft PR: #90

kocielnik avatar Nov 05 '24 11:11 kocielnik

Additional findings:

Buy it at ten times Owner's Earnings

"10Cap" assumes it usually makes sense to buy a company for a price equal to 10 * owner_earnings^1.

At that price, we expect to get back about 10% of our initial investment, which makes it a "10Cap" investment.

Phil also mentioned scenarios, where he was to buy something at a "15Cap" price, meaning each year he would get back (in the form of owner earnings) around 15% of the price he paid.

Free Cash Flow = Owner's Earnings

Free cash flow, or owner earnings as Warren Buffet likes to call it, is a measure of the company’s ability to generate cash over a period of time.

-- Business Literacy Institute

For a better-known source to confirm the latter:

Owner earnings run rate is an extrapolated estimate of an owner's earnings (free cash flow) over a defined period of time — typically a year.

-- Investopedia

So Free Cash Flow turns out to be the same as Owner's Earnings!

Yahoo Finance has Free Cash Flow in: Financials -> Cash Flow -> (bottom of the table)

free-cash-flow

kocielnik avatar Nov 30 '24 20:11 kocielnik

When I tried to scrape the Yahoo site for that data, it also returned the error already known from #91.

Also tried yfinance, and that also doesn't seem to be able to get that value:

In [1]: import yfinance as yf                              
   ...:                    
   ...: comp = yf.Ticker("META")
   ...: fcf = comp.cashflow.loc['Free Cash Flow']
   ...: most_recent_fcf = fcf[0]
   ...: print("Most recent FCF:", most_recent_fcf)
(...)
KeyError: 'Free Cash Flow'
In [2]: import yfinance as yf
   ...: 
   ...: comp = yf.Ticker("META")
   ...: fcf = comp.cashflow

In [3]: fcf
Out[3]: 
Empty DataFrame
Columns: []
Index: []

I see the Internet Archive is able to save these pages, and parsing their copy was successful when I tried it with another value in mind (the growth rate).

It doesn't seem practical to fall back to the archived copy every time.

Given the Internet Archive is still able to save these pages, perhaps there is a way that could succeed for us too.

I only hope it's not as sophisticated as: Selenium + Web browser.

kocielnik avatar Nov 30 '24 20:11 kocielnik