By Ishan Shah
Value investment traces its origin back to Security Analysis and The Intelligent Investor books by Benjamin Graham in which he advocated detailed analysis of fundamental metrics to buy the stocks which are trading at a discount to their intrinsic value. Warren Buffet, one of the most famous students of Benjamin Graham, showed all of us the power of value investing to generate higher returns.

Investing In Value Stocks vs. Growth Stocks
According to a study by Brandes, value investing has substantially outperformed the market and growth stocks over long periods of time.

They have used a simple valuation metric such as P/E, P/B, and P/CF to identify value and growth stocks. [1]
One approach used was to sort all the stocks by P/B and then classify top 10% as the growth stocks and bottom 10% as the value stocks. They observed in the rolling 5-year periods that value stocks did much better than growth stocks.

Value outperformed Growth (Glamour) in more periods and longer stretches [2]
However, I believe much of the analysis conducted by value investors—reading financial statements and assessing relative valuations—can be done faster, more effectively, and across a wider group of securities through an automated process. Quantitative value investment strategy is an effort to identify the most robust long-term focused value stocks.
Approach
Quantitative value investment strategy approach can be defined in the following manner:
- Identify the full set of stocks
- Screen for value and quality
- Invest with conviction
A full list of stocks is defined from small cap to large cap and stocks with low liquidity and trading restrictions are excluded. Then filter based on various quantitative fundamental parameters to form a portfolio of cheapest and high-quality stocks. Let’s see how this can be done in Python.
Note: For the purpose of demonstration of this exercise, I have defined a small list of potential stocks. You can use the entire S&P 500 list as well.
Import The Libraries
The first step is to import the necessary libraries namely pandas, yahoo_fin.
Define The Method To Extract Fundamental Data
We will create two dataframes, 'ratio_valuation_function' and 'ratio_stat', which will be used to retreive the following financial information:
- Price/Book (mrq)
- Trailing P/E
- Forward P/E
- PEG Ratio (5 yr expected)
- Price/Sales (ttm)
- Total Debt/Equity (mrq)
- Diluted EPS (ttm)
- Trailing Annual Dividend Yield
- Forward Annual Dividend Yield 4
- % Held by Insiders 1
- Held by Institutions 1
- Return on Equity (ttm)
- Return on Assets (ttm)
- Quarterly Earnings Growth (yoy)
- Beta (5Y Monthly)
You can retrieve a lot more information but for the sake of simplicity, I will be limiting myself to these ratios and terms.
Now, I will create a simple list containing tickers of a few companies
I will then create a table to store all this information in one place.
The whole list can be seen by using the code, "final"
Price/Book (mrq) | Trailing P/E | Forward P/E 1 | PEG Ratio (5 yr expected) 1 | Price/Sales (ttm) | Total Debt/Equity (mrq) | Diluted EPS (ttm) | Trailing Annual Dividend Yield 3 | Forward Annual Dividend Yield 4 | % Held by Insiders 1 | % Held by Institutions 1 | Return on Equity (ttm) | Return on Assets (ttm) | Quarterly Earnings Growth (yoy) | Beta (5Y Monthly) | |
AMZN | 16.16 | 71.73 | 45.37 | 1.71 | 3.91 | 108.38 | 41.83 | NaN | NaN | 14.56% | 58.66% | 27.44% | 5.24% | 121.00% | 1.13 |
GOOG | 6.4 | 35.97 | 25.94 | 1.59 | 7.77 | 12.52 | 58.61 | NaN | NaN | 5.86% | 68.10% | 19.00% | 8.65% | 42.70% | 1 |
PG | 6.56 | 23.81 | 20.86 | 2.54 | 4.19 | 64.07 | 5.29 | 2.55% | 2.51% | 0.11% | 66.11% | 29.51% | 9.62% | 3.70% | 0.41 |
KO | 11.32 | 28.36 | 21.88 | 4.34 | 6.63 | 208.7 | 1.79 | 3.28% | 3.31% | 0.70% | 68.20% | 36.66% | 7.18% | -28.70% | 0.62 |
IBM | 5.32 | 19.7 | 10.17 | 1.92 | 1.49 | 320.7 | 6.23 | 5.42% | 5.31% | 0.13% | 58.58% | 26.38% | 3.94% | -63.10% | 1.25 |
MSFT | 13.42 | 34.53 | 28.63 | 1.82 | 11.4 | 63.56 | 6.71 | 0.94% | 0.97% | 0.06% | 71.84% | 42.70% | 12.81% | 32.70% | 0.81 |
TSLA | 25.83 | 934.3 | 108.72 | 6.45 | 18.2 | 56.32 | 0.64 | NaN | NaN | 19.99% | 42.53% | 5.42% | 2.82% | 157.10% | 2.06 |
WMT | 4.49 | 27.2 | 22.01 | 4.28 | 0.65 | 72.25 | 4.75 | 1.69% | 1.70% | 51.07% | 30.35% | 16.21% | 5.86% | NaN | 0.47 |
AMD | 16.29 | 38.04 | 31.04 | 1.73 | 9.74 | 9.8 | 2.06 | NaN | NaN | 0.62% | 73.87% | 57.48% | 11.42% | 947.60% | 2.18 |
ADBE | 15.92 | 40.7 | 33.25 | 2.43 | 16.4 | 35.49 | 10.83 | NaN | NaN | 0.31% | 86.10% | 44.21% | 11.76% | 164.40% | 0.96 |
ZM | 25.14 | 149.97 | 82.5 | 6.06 | 37.15 | 2.34 | 2.25 | NaN | NaN | 1.03% | 57.14% | 28.64% | 12.52% | 1599.00% | NaN |
QCOM | 19.97 | 22.18 | 16.04 | 0.92 | 5.52 | 213.16 | 5.85 | 2.01% | 2.00% | 0.14% | 77.64% | 113.14% | 13.68% | 165.40% | 1.34 |
CSCO | 4.99 | 19.35 | 13.6 | 2.13 | 4.07 | 39.93 | 2.39 | 3.23% | 3.20% | 0.06% | 74.11% | 27.14% | 9.12% | -11.60% | 0.91 |
NFLX | 20.67 | 84.93 | 39.84 | 1.33 | 9.15 | 167.29 | 6.08 | NaN | NaN | 1.55% | 81.92% | 29.62% | 7.82% | -7.60% | 0.83 |
PYPL | 14 | 67.53 | 41.72 | 2.41 | 13.05 | 48.47 | 3.54 | NaN | NaN | 0.10% | 85.54% | 22.72% | 3.52% | 209.10% | 1.15 |
MU | 2.49 | 33.55 | 10.23 | 0.7 | 4.51 | 18.08 | 2.65 | NaN | NaN | 0.19% | 84.31% | 7.86% | 4.12% | 63.50% | 1.26 |
INTU | 11.81 | 58.33 | 39.08 | 3.57 | 13.56 | 31.81 | 6.55 | 0.60% | 0.62% | 2.93% | 88.31% | 27.74% | 12.39% | -91.70% | 1.02 |
GILD | 4.45 | 659.39 | 9.52 | 3.39 | 3.29 | 176.26 | 0.1 | 4.30% | 4.39% | 0.11% | 80.07% | 0.44% | 10.78% | -42.50% | 0.42 |
AVGO | 7.64 | 52.06 | 16.01 | 2.03 | 7.44 | 174.72 | 8.65 | 3.09% | 3.20% | 2.49% | 83.17% | 16.36% | 4.14% | 257.90% | 1.04 |
FB | 5.87 | 26.19 | 19.55 | 1.1 | 8.75 | 8.71 | 10.09 | NaN | NaN | 0.63% | 79.77% | 25.42% | 13.95% | 52.70% | 1.25 |
AAPL | 30.85 | 32.93 | 25.94 | 2.02 | 6.93 | 169.19 | 3.69 | 0.67% | 0.68% | 0.07% | 59.66% | 82.09% | 13.36% | 29.30% | 1.25 |
AMAT | 9.07 | 27.13 | 17.7 | 0.91 | 5.72 | 49.66 | 4.18 | 0.81% | 0.78% | 0.41% | 83.07% | 38.31% | 14.14% | 26.70% | 1.49 |
With this list, you can play around and create various filters according to your choice. Based on these fundamental data, I have defined a Buffet-inspired stock screening model to identify stocks that will be part of my long portfolio. The criteria are:
1. Businesses which are quoted at low valuations
Let's find the companies which have their Trailing Price to earnings ratio less than 30 and Price to book value at less than 15
Thus, the condition is P/E < 30 P/B < 15
However, these ratios would differ from sector to sector, but for simplicity I’m using this numbers.
2. Businesses which have demonstrated earning power
I have kept the condition that the earnings per share is more than 4
3. Businesses earning good returns on equity while employing little or no debt
I am keeping the Debt to Equity ratio at 75 and Return on equity at more than 20%.
Note that Yahoo finance reports Debt to equity ratio in percentage. Thus, the figure 75 means it is 75% or o.75.
4. Management having substantial ownership in the business
Initially, you would like to keep the condition of selecting companies where the insiders own more than 30%. But since the list of potential stocks do not satisfy this criteria, I have kept it at 0.07%.
The companies which satisfy all the above criteria are shown below.
Price/Book (mrq) | Trailing P/E | Forward P/E 1 | PEG Ratio (5 yr expected) 1 | Price/Sales (ttm) | Total Debt/Equity (mrq) | Diluted EPS (ttm) | Trailing Annual Dividend Yield 3 | Forward Annual Dividend Yield 4 | % Held by Insiders 1 | % Held by Institutions 1 | Return on Equity (ttm) | Return on Assets (ttm) | Quarterly Earnings Growth (yoy) | Beta (5Y Monthly) | |
PG | 6.56 | 23.81 | 20.86 | 2.54 | 4.19 | 64.07 | 5.29 | 2.55% | 2.51% | 0.11% | 66.11% | 29.51% | 9.62% | 3.70% | 0.41 |
FB | 5.87 | 26.19 | 19.55 | 1.1 | 8.75 | 8.71 | 10.09 | NaN | NaN | 0.63% | 79.77% | 25.42% | 13.95% | 52.70% | 1.25 |
AMAT | 9.07 | 27.13 | 17.7 | 0.91 | 5.72 | 49.66 | 4.18 | 0.81% | 0.78% | 0.41% | 83.07% | 38.31% | 14.14% | 26.70% | 1.49 |
These are only some of the criteria. You may add more criteria to select stocks for your portfolios. Using Python, I was easily able to get data, create filters and identify the value stocks. However, this would have been very cumbersome to do in Excel.
You should be able to improve upon the edge that value investors can get through the addition of this simplistic quantitative value investment strategy.
Next Step
Learn the importance of understanding ‘beta’ in the stock market and how we can use beta effectively to hedge against market risk. Read our post on 'Asset Beta & Market Beta In Python' to know more.
Disclaimer: All investments and trading in the stock market involve risk. Any decisions to place trades in the financial markets, including trading in stock or options or other financial instruments is a personal decision that should only be made after thorough research, including a personal risk and financial assessment and the engagement of professional assistance to the extent you believe necessary. The trading strategies or related information mentioned in this article is for informational purposes only.
Download Data File
- Value investing strategy in python