zhaopinboai.com

How to Create a Custom Value Investing Stock Screener in Python

Written on

Chapter 1: Introduction to Building a Stock Screener

Many investors, including myself, often shy away from traditional stock screeners, as they don't always present the data in the way I prefer. My main interest lies in a concise table showing revenue, EBIT, equity, and debt over recent years. I find that preliminary assessments do not require a deep dive into assets or liabilities; rather, I focus on whether a company is successfully growing its earnings year after year and how that growth is financed—through debt or equity. The more thorough analysis can come later.

To address this need, I decided to create my own stock screener, and I’m excited to share the process with you. This project will be executed in a Jupyter Notebook. When I refer to a screener, I mean screening one company at a time rather than evaluating numerous stocks simultaneously.

Section 1.1: Setting Up the API

For this tutorial, we will utilize Yahoo Finance. Specifically, I recommend the YH Finance API from RapidAPI, which provides the financials endpoint we need for our project. After registering for a RapidAPI account and selecting the basic plan, ensure you use the get-financials endpoint.

Yahoo Finance API setup

The basic plan allows for 500 free requests monthly, which is more than sufficient for our requirements. Additionally, RapidAPI has a convenient feature where the code for calling the API is pre-written for you, located on the right side of the interface.

Section 1.2: Importing Necessary Libraries

To start, we need to import a few essential libraries in Python:

import pandas as pd

import numpy as np

import requests

Next, copy the code provided by RapidAPI into your IDE, but exclude the import for the ‘requests’ library since we’ve already done that. You can also skip the 'print(response.text)' line as it isn't necessary for our purposes.

querystring = {"symbol":"AAPL"}

headers = {

"X-RapidAPI-Key": "...",

"X-RapidAPI-Host": "yh-finance.p.rapidapi.com"

}

response = requests.request("GET", url, headers=headers, params=querystring)

Section 1.3: Loading Data into a DataFrame

The API returns data in JSON format, so we will load the response into a Pandas DataFrame using the following commands:

df = response.json()

df1 = pd.json_normalize(df)

Section 2: Preparing Financial Data

Now we will extract the financial statements we need. The Yahoo Finance API generates numerous column names, so filtering them to match our requirements is the best approach. If you wish to explore different columns, you can use a template function like df.loc[:, df.columns.str.contains('...')].

For our project, we’ll pull specific data:

balancesheet = df1.loc[:, df1.columns.str.contains('balanceSheetHistory.balanceSheetStatement')]

cashflow = df1.loc[:, df1.columns.str.contains('cashflowStatementHistoryQuarterly.cashflowStatements')]

incomestatement = df1.loc[:, df1.columns.str.contains('incomeStatementHistory.incomeStatementHistory')]

Section 2.1: Data Cleaning Function

We need to create a function to clean the nested JSON data we receive. This function will unwrap the data to extract the variables we want. Here’s how it works:

  • Select the first cell from our financial sheets.
  • Choose the desired column by its name.
  • Load the data from JSON into a Pandas DataFrame.
  • Rename the column to reflect the metric we want.

def clean(x, y):

df = pd.DataFrame(x.iloc[0, 0])

df = df.loc[:, df.columns.str.contains(y)]

df = pd.json_normalize(df[y])

df = pd.DataFrame(df.raw)

df.columns = [y]

return df

Section 2.2: Extracting Key Metrics

Here are examples of the financial metrics I focus on for stock screening:

revenue = clean(incomestatement, 'totalRevenue')

ebit = clean(incomestatement, 'ebit')

equity = clean(balancesheet, 'totalStockholderEquity')

debt = clean(balancesheet, 'longTermDebt')

If you're interested in other metrics, you can adjust the functions accordingly. Don’t forget to set the Pandas display options so your DataFrame isn’t truncated:

pd.set_option('display.max_columns', None)

pd.DataFrame(balancesheet.iloc[0, 0])

Section 2.3: Combining Metrics

To consolidate all metrics into one DataFrame, use the following command:

df = pd.concat([revenue, ebit, equity, debt], axis=1)

Section 2.4: Calculating Financial Ratios

While Yahoo Finance provides some financial ratios, we can calculate them directly using our raw numbers:

df['Operating Margin'] = df['ebit'] / df['totalRevenue']

df['DE'] = df['longTermDebt'] / df['totalStockholderEquity']

df['RoE'] = df['ebit'] / df['totalStockholderEquity']

df['RoIC'] = df['ebit'] / (df['totalStockholderEquity'] + df['longTermDebt'])

Chapter 3: Evaluating the Results

Here’s an example of the output for Apple. Note that Yahoo Finance provides only the last four years of financial data, with the latest annual report year being 2021.

Apple financial data from Yahoo Finance

From my own analysis of Apple's annual reports, the figures are in billions.

Apple annual reports financial data

While the numbers may not match exactly, they remain sufficiently consistent with the actual reports.

Section 3.1: Interpreting the Data

This process enables me to quickly screen companies. If a firm shows negative earnings consistently, I know to avoid it and focus on more promising opportunities.

For a more detailed interpretation, I look for:

  • Year-on-year EBIT growth with strong operating profit margins (e.g., >10%).
  • This growth should not come at the expense of increased equity or borrowing. I aim to ensure that the company is not merely 'buying' growth but is instead making its products increasingly desirable over time.

Section 3.2: Detecting Capital Raising

To determine if a company's growth stems from capital raising, utilize the following code. An increase in outstanding shares year over year indicates that the growth is likely due to capital raising. While management's stock options can dilute shares, a capital-raising strategy usually results in greater dilution.

df2 = pd.DataFrame(df1)

df3 = df2.loc[:, df1.columns.str.contains('timeSeries.annualDilutedAverageShares')]

df4 = clean(df3, 'reportedValue')

shares = df4[::-1].reset_index(drop=True)

shares.columns = ["Shares Outstanding"]

df = pd.concat([revenue, ebit, equity, debt, shares], axis=1)

Updated financial data with shares outstanding

Chapter 4: Additional Resources

If you found this guide helpful, consider joining Medium for more insightful articles from various writers. You can sign up using my link below, and I will receive a small commission.

This video titled "How To Build a Stock Screener | Python For Finance Episode 3" provides a great visual guide to creating stock screeners.

Check out "Python Programming Tutorial - How to Make a Stock Screener" for a step-by-step walkthrough on the same topic.

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

Break Free from the People-Pleasing Trap: Embrace Your Authenticity

Learn how to escape the cycle of people-pleasing and embrace your true self to enhance your personal and social life.

Exploring the Enigmatic World of Quantum Physics

Discover the fascinating and strange phenomena in quantum physics that challenge our understanding of reality.

Silicon Valley 2.0: The Rise of Utah's Tech Scene

Explore how Utah's tech landscape is emerging as a viable alternative to Silicon Valley.

Crafting an Effective Strategy for Substack Subscriber Growth

Discover how to create a powerful content strategy and delivery plan to enhance subscriber growth on Substack.

Mastering the Execution of Python Scripts from Any Directory on MacOS

Learn how to run Python scripts from any directory on your Mac with simple commands and aliases.

Innovative Facebook AR Glasses Reveal Dating Costs and More

Facebook's new AR glasses show the hidden costs of dating, offering insights into potential partners' backgrounds.

Navigating the Entrepreneurial Landscape: Insights from a Guide

A comprehensive review of a guide for aspiring entrepreneurs, offering valuable insights and practical steps for business success.

Navigating Future Business in China: Insights from American Leaders

Explore the evolving dynamics of American CEOs and government leaders in their pursuit of future business opportunities in China.