Creating a Stock Analytics Algorithm in Python Part 1

Before we begin, I’d like to talk about our affiliate NordVPN, which use the link provided can get you access to special discounts that you can’t find elsewhere!

While I have always been interested in creating a program to automate stock trading for me, I had never really ben able to find the time to actually do it. I’ve seen banks and brokerage firm suggest their own algo trading algorithms, but I wanted to create a script by myself so I could learn the intricate details on how to do it. The final script can be found at this github repo.

To start off this project, I had to choose what API I would use to get the latest info and statistics of any given stock at any given time. To do this, I actually used two different APIs, the Yahoo Finance API and the Financial Modeling Prep API. I used the Yahoo Finance API to get the basic info of a stock at any given time, and because its free, the amount of requests I send isn’t an issue. However, for which I’ll go into more detail later, I use the Financial Modeling Prep to get info from a companies quarterly and annually financial statements, info which isn’t available with the Yahoo finance API. For the Financial Modeling Prep, or FMP API, depending on what you want from it, you might have to pay a subscription amount per month, like in my case for getting info from a quarterly report, which was about $20 a month. If needed, there is a free version available, its just dependent on what kind of information your trying to get from the FMP API.

For the first part of the script, I just define basic parameters, the API key for FMP, what exchanges I would be scanning, the period of where the financial statements would be coming from, and some misc. settings that I use to sort through found companies that I’ll go deeper into later on.

# The Financial Modeling Prep API Key
API_KEY = "YOUR_KEY_HERE"

# If I want to run NCAVPS calculations
DO_NCAVPS = True

# What exchange to use
EXCHANGE = ["NYSE", "NASDAQ"]

# What period do you want to view the balance sheets from (quarterly or annually)
PERIOD = "quarter"

# The minimum price you want to pay attention to
MIN_PRICE = 6.00

# The minimum amount of volume a stock should trade
MIN_VOLUME = 50000

stocks = []

The next couple function are used to get info from a specific ticker, along with price history. When I query the tickers, I send a request to the FMP API using the link below.

def get_tickers():
    for market in EXCHANGE:

        # Get the list of tickers
        querytickers = requests.get(f'https://financialmodelingprep.com/api/v3/search?query=&limit=10000000&exchange=' + market + '&apikey=' + API_KEY)
        querytickers = querytickers.json()

        print("Market: " + market + ", Number of Listings: " + str(len(querytickers)))

        # At the selected number of tickers to the list
        list_500 = querytickers
        for item in list_500:
            stocks.append(item['symbol'])
    
    return stocks

def get_yfinance_ticker(company):
    return yf.Ticker(company)

def get_past_30_day_price(company):
    ticker = get_yfinance_ticker(company)
    past_30_days = ticker.history(period="1mo")
    return past_30_days

The next section of the code is where I do the main analyzing of the stocks statistics using a factor called NCAVPS. Net Current Asset Value Per Share, or NCAVPS, is a measurement developed by legendary value investor Benjamin Graham, who also was a mentor to Warren Buffett, which takes into account a companies current assets vs its liabilities. The formula for it can be found below.

NCAVPS = Current Assets – (Total Liabilities + Preferred Stock) / Shares Outstanding

The key of this measurement is that its used to determine what a stock should be worth as a price per share. In theory, if the price per share was less than the NCAVPS, than the stock would be considered undervalued. As a key factor, Graham also mentions that as a good rule of thumb, only invest in companies where the stock price was no more than 67% of their NCAVPS. Graham also mentions that its ideal to diversify using this strategy, with 30 stocks being his recommended holdings.

def calculate_NCAVPS(company):
    # Get the balance sheet of the company
    Balance_Sheet = requests.get(f'https://financialmodelingprep.com/api/v3/financials/balance-sheet-statement/{company}?period=' + PERIOD + '&apikey=' + API_KEY)
    Balance_Sheet = Balance_Sheet.json()

    # Get the total current assets
    total_current_assets = float(Balance_Sheet['financials'][0]['Total current assets'])

    # Get the total liabilities
    total_liabilities = float(Balance_Sheet['financials'][0]['Total liabilities'])

    # Get the Yahoo Finance info on the curreny company
    ticker = get_yfinance_ticker(company)

    # Get the number of shares outstanding
    shares_outstanding = ticker.info["sharesOutstanding"]

    # Here we are calculating the Net Current Asset Value per Share (NCAVPS)
    # If a stock is trading below the NCAVPS then its a good buy
    # Aim for the stock price to be 66% less than its NCAVPS
    NCAVPS = (total_current_assets - total_liabilities) / shares_outstanding

    return NCAVPS

After I defined the method for calculating NCAVPS, I then just run over all of the stocks that exist on my desired exchanges, and make sure they meet certain criteria like a minimum amount of volume and a price over a certain value.

stocks = get_tickers()
    
print("Total Stocks To Evaluate: " + str(len(stocks)))

company_counter = 0

# Get the following info from each company within the stocks list
for company in stocks:

    if DO_NCAVPS:
        # Incrament the company counter by one
        company_counter = company_counter + 1

        try:
            NCAVPS = calculate_NCAVPS(company)

            ticker = get_yfinance_ticker(company)

            # Get volume of the company
            volume = ticker.info["volume"]

            # Get the P/E ratio
            TRAILING_PE_RATIO = ticker.info["trailingPE"]
            FORWARD_PE_RATIO = ticker.info["forwardPE"]

            # Get the current price of the company
            price = ticker.info['currentPrice']

            # Only companies where NCAVPS is below the stock price
            if price < 0.67 * NCAVPS and volume > MIN_VOLUME:
                print("Company " + str(company_counter) + ": " + company + ", Current Price: " + str(price) + ", NCAVPS: " + str(NCAVPS) + ", Trailing P/E Ratio: " 
                + str(TRAILING_PE_RATIO) + ", Forward P/E Ratio: " + str(FORWARD_PE_RATIO) + ", Volume: " + str(volume))

                if price > MIN_PRICE:
                    print("Company " + str(company_counter) + ": " + company + ", Current Price: " + str(price) + ", NCAVPS: " + str(NCAVPS) + ", Trailing P/E Ratio: " 
                    + str(TRAILING_PE_RATIO) + ", Forward P/E Ratio: " + str(FORWARD_PE_RATIO) + ", Volume: " + str(volume) + "\n" + "https://finance.yahoo.com/quote/" + company + "/\n")
        
        except:
            pass
    else:
        print("here")

While this is a pretty simple example of an algo trading script, I plan to expand on it in the weeks to come, and I’ll post more updates on it as well.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: