The answer is yes, of course.
Over the course of 2020, the price of Tesla stock increased from $88 to $705 (~720%). This is despite revenue and earnings increasing only 39% and 73%, respectively. While the Tesla company is unquestionably impressive, these price gains seem excessive.
I’m going to make a bold and specific claim. On January 4th, 2021, when TSLA was selling for $730, it was fundamentally overvalued by 12.35x. In other words, Tesla’s closing price should have been about $59.
How can I claim this? I trained a machine learning model to predict stock prices.
Model basic anatomy
- Dataset: The latest balance sheet, income statement, and cash flow statement from each stock of the S&P 1500. The S&P 1500 is the combination of the S&P 500 (large-cap stocks), S&P 600 (mid-cap stocks), and S&P 400 (small-cap stocks). Because of missing data, I had to discard 93 stocks.
- Input variables (Xs): A total of 16 different financial figures for each company, pulled from the last quarterly filing (10Q). Think income, revenue, assets, dividends-paid, revenue-growth, etc.
- Output variable (Y): Market cap. This is the stock price multiplied by the number of shares outstanding. You can think of the market cap as the price to buy the entire company. Tesla’s market cap is currently about $700 billion.
In the sections below, I will detail what stock valuation is, how I designed my model, its weaknesses, and my results. To see just the data science, skip to the “ Model Design” section.
Perhaps the most well-known investment strategy is known as “value investing”. Most commonly associated with Benjamin Graham and Warren Buffet, value investing recommends buying undervalued stocks and holding them for long durations — usually years or decades. While value investing is conceptually simple, execution can be tricky.
One basic strategy is to look at valuation ratios. Some well-known ratios include the following:
The P/E ratio is a company’s market cap divided by its earnings. A good way to think of this ratio is how expensive a company is relative to its yearly profits. Since the 1920s, the P/E has been the most well-known and commonly used stock valuation metric. Tesla has a P/E of about 1400x which implies that it would take 1400 years of Tesla’s yearly profits to buy the company. For comparison, Apple’s P/E ratio is closer to 40 — slightly above the current market average.
The P/S ratio is a company’s market cap divided by its top-line sales. This ratio has become increasingly important in recent decades as more companies choose to forgo profits and instead reinvest their spare cash to grow faster. For example, consider that Amazon didn’t make a profit until 2017. Before that, AMZNs P/E was meaningless and it was more sensible to use P/S instead.
The P/B ratio is a company’s market cap divided by its “book” — which is its assets minus its liabilities (debt). Another way to think of “book” is how much you could get by closing down a company and selling everything. P/B is most useful in two categories: traditional companies with a lot of assets, and companies in financial trouble. For companies with a lot of assets, the P/B is a measure of how well they are making use of them. So a company that owns one factory but makes a lot of money from that factory would likely have a high valuation. At the other end, for companies in financial trouble, the P/B becomes a worst-case contingency measure. If the company must shut down, how do the stockholders fare after assets are sold and debt is settled?
The dividend yield is a little different than the other ratios above. It’s the total yearly dividends divided by the market cap — so the numerator and denominator are swapped. Before the 1920s, this was the primary stock valuation ratio. In that era, companies distributed most earnings back to the shareholders via dividends. Today, the biggest dividend payers tend to be old stable industries like utilities. These enduring, steady companies make regular profits but can’t easily reinvest them.
Using the valuation ratios above, we can get a sense of how overvalued Tesla is by comparing Tesla’s ratios to the market averages.
Leaving aside the possibility that Tesla is infinity-times overpriced, these figures suggest that TSLA costs between 11x and 37x what it is rationally worth. But which ratio is the appropriate one for understanding Tesla? The answer is none of the above. A fair valuation of Tesla is a factor of more than its earnings or sales or assets. At the very least, for a company like Tesla, we need to take its growth into account. More generally, any company’s underlying value is a factor of a thousand different things.
In the previous century, before computers, valuation ratios were the only reasonable way to do stock valuation. In that era, investors would look at several valuation ratios, decide whether a stock price felt “fair”, and trade accordingly.
With increasing computerization, many professionals now de-emphasize valuation ratios. Instead, they are deploying increasingly sophisticated multivariate models. Amateur investors, unfortunately, have not had the same opportunity. Most of the “odd-lotter” class, myself included, have had no choice but to use antiquated tools.
While it’s unlikely that amateur investors could ever catch up to the professionals, we can certainly get better. Hypothetically, most information that would impact underlying valuation exists in a company’s financial statements. The task then is to find a way to aggregate that information into a usable number. This is where machine learning comes in.
The financial statements of public US companies are available for free on the SEC website. Companies are required by law to disclose their finances in a quarterly form called the 10Q. In this document, you can find their balance sheet, income statement, and cash flow statement. While the SEC has mandated that this data must be available in computer-readable form, it is still quite burdensome to parse. As a result, several companies have stepped in to sell cleaned financial figures via API. I used EODHistoricalData.
For the market caps, I used the free (and deprecated) Yahoo finance API.
Estimating stock prices is a regression problem. We are taking a set of numbers and using that to estimate another number. In the regression algorithm class, there are a few options:
- Linear regression
- Polynomial regression
- Linear SVMs
- Decision trees
- Neural networks
Stock price estimation is a complex problem. As such, my initial tests with simple linear/polynomial regression didn’t go well. Linear SVMs were also unsuccessful. With decision trees (specifically XGBoost) and neural networks, I finally found some success. Overall, XGBoost performed somewhat better. With time, I think I could have designed a neural network with better performance than XGBoost. But, when taking into account how slow neural networks are to train, XGBoost was the obvious best choice.
In each SEC-filed 10Q, there are hundreds of figures that reveal a company’s financial health. Ideally, I would have preferred to use all of them as model inputs. However, I needed to limit the input count for two reasons:
- Lack of consistency: Apart from a handful of top-line items like revenue, earnings, and assets, companies are surprisingly different in what they choose to report and how they choose to calculate their figures.
- Overfitting: Overfitting is more likely when there is a limited dataset. My dataset only contained 1407 individual data points.
So given lots of financial figures and a small dataset, I needed to select a handful of “most important” figures as inputs. To do this, I started by training a model with as many figures as I could — in my case about 60. This initial model was deeply overfit — which was easy to detect. In its simplest definition, overfitting is when the test error is high relative to the training error.
To step down from 60 to 59 inputs, I utilized the “feature importance” metric of the XGBoost model. This provides a ranked list of features by importance. I removed the “least important” feature and retrained. I continued doing this until I minimized the test error at 16 inputs — listed below: