Dom Vacchiano

Build a Stock Screener with Python (Part 1): Initial Stock Screener

Build a stock screener in python in 10 minutes If you are interested in investing and/or coding, this post will teach you how to create a basic stock screener in under 10 minutes using python.

The python script will pull tickers we put into a .txt file and fetch the market cap, EV, and cash. We will display this in a table format so we can quickly screen the metrics.

You can find the full code in the repo


The final output will look like this:

+---------+------------+----------+---------+---------+
| Tickers | Market Cap |    EV    |  Cash   | EV/Cash |
+---------+------------+----------+---------+---------+
|  PRAX   |  $950.8M   | $529.6M  | $328.0M |  1.61   |
|  ATXS   |  $349.9M   | $107.8M  | $295.1M |  0.37   |
|  ATAI   |  $583.4M   | $369.7M  | $98.2M  |  3.76   |
|  RCUS   |  $870.4M   | -$54.1M  | $997.0M |  -0.05  |
|  HRMY   |   $1.9B    |  $1.5B   | $507.0M |  2.93   |
|  AAPL   |  $3135.8B  | $3114.1B | $48.5B  |  64.21  |
|  TLSA   |  $178.8M   | $172.5M  |  $3.7M  |  46.32  |
|  NFLX   |  $548.8B   | $579.1B  |  $8.4B  |  69.18  |
|  GOOG   |  $2149.5B  | $2085.8B | $95.3B  |  21.88  |
+---------+------------+----------+---------+---------+


Let's get started!

  1. The first thing you want to do is confirm you have python installed on your machine or download and install it.

  2. Once downloaded, via your folder system or terminal, navigate to the location you want to build this project and create a new file: "script.py".


Before we start coding we need to create a virtual environment and install a few python packages. Virtual environments allow us to install python packages in a standalone 'environment' so we can use them for specific projects.

  1. In your terminal create and activate a virtual environment named 'env':
>>> python -m venv env
>>> .\env\Scripts\activate
>>> (env)

you should see (env) appear in your terminal after it's activated.

  1. In your terminal with the active environment, let's install two packages we need for this project, yfinance & tabulate:
>>> pip install yfinance tabulate


Now let's code 💻🖥️

  1. Our python script will consist of 3 functions:

    a. get_stock_data() - will accept a ticker and get the data from Yahoo Finance.

    b. format_number() - will handle formatting the number values to look better (e.g., $1M, $1B).

    c. main() - will read in the tickers we put into a .txt file and orchestrate the output.

  2. At the top of the script file, let's import the modules we installed.

import yfinance as yf
from tabulate import tabulate
  1. Now let's create the get_stock_data function that will fetch the stock data for a ticker we pass in from yahoo finance.
def get_stock_data(ticker):
    stock = yf.Ticker(ticker)
    
    try:
        info = stock.get_info()
        market_cap = info.get("marketCap", None)
        enterprise_value = info.get("enterpriseValue", None)
        total_cash = info.get("totalCash", None)


        ev_cash_ratio = (enterprise_value / total_cash) if enterprise_value and total_cash else None

    except Exception as e:
        print(f"Error fetching data for {ticker}: {e}")
        return None


    return {
        "Ticker": ticker,
        "Market Cap": market_cap,
        "EV": enterprise_value,
        "Cash": total_cash,
        "EV/Cash": ev_cash_ratio,
    }

This function accepts a ticker, and uses the yfinance package to fetch the data about that ticker from yahoo finance. We return a dictionary with the fetched data.

  1. Next let's build our format_num function that will format the data values we fetched above to look 'prettier'.
def format_number(num):
    if num is None:
        return "-"
    
    is_neg = num < 0
    num = abs(num)

    if num > 1e9:
        formatted = f"${num/1e9:.1f}B"
    elif num > 1e6:
        formatted = f"${num/1e6:.1f}M"
    else:
        formatted = f"${num:,.0f}"

    return f"-{formatted}" if is_neg else formatted

We accept a number to be passed in, check if it's a positive or neg number, and then format for million/billions and decimals. We return the formatted number checking if it's a positive/negative number.

  1. Let's create our main function that will call our helper functions above and display the final table.
def main():
    with open("tickers.txt") as f:
        tickers = [line.strip().upper() for line in f if line.strip()]

    results = []
    for ticker in tickers:
        data = get_stock_data(ticker)
        results.append([
            data["Ticker"],
            format_number(data["Market Cap"]),
            format_number(data["EV"]),
            format_number(data["Cash"]),
            f"{data['EV/Cash']:.2f}" if data["EV/Cash"] else "-",
        ])

    headers = ["Tickers", "Market Cap", "EV", "Cash", "EV/Cash"]
    print(tabulate(results, headers=headers, tablefmt="pretty"))

We start by reading in tickers from a file 'tickers.txt', calling our get_stock_data function for each ticker, and then displaying our results using the tabulate package.

  1. Before we run our script we need to create a 'tickers.txt' file and add 2 final lines of code to our 'script.py' file.

  2. In the same directory/folder as your 'scripts.py' file create another file 'tickers.txt' and add a ticker you want to screen to each line (and save the file).

PRAX
ATXS
ATAI
RCUS
  1. The last 2 lines of code our script needs is to call our main() function when we run our script. We can do that by checking if the name of the module is main() (which happens when we run our script directly).
if __name__ == "__main__":
    main()
  1. Now run the script!
>>> python script.py


You should see the table output with the information for the tickers you put in your .txt file 🎉 Next up is Part 2 where we pull in catalyst data...

+---------+------------+----------+---------+---------+
| Tickers | Market Cap |    EV    |  Cash   | EV/Cash |
+---------+------------+----------+---------+---------+
|  PRAX   |  $950.8M   | $529.6M  | $328.0M |  1.61   |
|  ATXS   |  $349.9M   | $107.8M  | $295.1M |  0.37   |
|  ATAI   |  $583.4M   | $369.7M  | $98.2M  |  3.76   |
|  RCUS   |  $870.4M   | -$54.1M  | $997.0M |  -0.05  |
|  HRMY   |   $1.9B    |  $1.5B   | $507.0M |  2.93   |
|  AAPL   |  $3135.8B  | $3114.1B | $48.5B  |  64.21  |
|  TLSA   |  $178.8M   | $172.5M  |  $3.7M  |  46.32  |
|  NFLX   |  $548.8B   | $579.1B  |  $8.4B  |  69.18  |
|  GOOG   |  $2149.5B  | $2085.8B | $95.3B  |  21.88  |
+---------+------------+----------+---------+---------+

#coding_tutorial #stock_screener_1 #tutorial