FMP
Sep 11, 2023 5:37 PM - Rajnish Katharotiya
Image credit: Victor
During this post we are going to perform an industry analysis with Python. We will build, analyse and compare all stocks operating within an industry. To do so, we will pick an industry and get all important financial metrics for companies operating in that industry. Then, we will use a couple of filters to identify the most attractive stocks operating in that sector. As a heads-up, you can see an extract of the expected result in below screenshot. We will end up having more than 19 financial metrics for each of the companies!
Photo by Pixabay on Pexels
An industry analysis is a very effective way to put into perspective and compare different stocks operating within an industry. This is particularly useful to compare company performance. Given that companies operating in the same industry share certain similarities, it can be a good starting point to benchmark different companies together.
In addition to comparing companies, performing an industry analysis will help us understand opportunities and threads that are characteristics of that industry. For example, we could apply the 5 forces of Porte to get to know the strengths and weaknesses of an industry. If an industry is very competitive and with low barriers of entry, it may be difficult for a company to thrive.
In this post, we will focus more on comparing companies with each other by building a screener for a selected industry.
To perform the industry analysis, we will perform below steps:
Create an industry Python screener to retrieve all tickers from companies operating in the selected industry.
Calculate all relevant financial ratios.
Add all companies into a Pandas DataFrame. This will easily allow us to compare company financials within the industry.
Create filters to find attractive stocks within the selected industries. E.g. keep only companies with Price to Earnings ratio below 10 and revenue growth of at least 10% in the last 4 quarters.
Plot the selected stocks for easy visualisation
First of all, lets start by getting tickers for all stocks within the Technology sector.
To begin, you need to define our screener criteria. Technology stocks trading in NASDAQ and with a market capitalization higher than $100,000,000. In the example the limit of the number of companies is 100. Feel free to increase or remove the limit to include more companies in the analysis.
import requests
import numpy as np
import pandas as pd
demo = 'your api key'
sector = 'Technology'
exchange = 'NASDAQ'
marketcapmorethan = '1000000000'
number_of_companies = 100
symbols = []
screener = requests.get(f'https://financialmodelingprep.com/api/v3/stock-screener?{marketcapmorethan}=1000000000&volumeMoreThan=10000§or={sector}&exchange={exchange}&limit={number_of_companies}&apikey={demo}').json()
for item in screener:
symbols.append(item['symbol'])
symbols
Now that we have all Technology related tickers in a Python list, we can start retrieving company financials from the API. This is very similar to what we have been doing in previous posts.
What the code below is doing is looping through each of the companies obtained in the section before. Then, it retrieves the company Income Statement, Balance Sheet and Cash Flow financial statements. Next, we calculate each of the financial metrics such as ROE, revenue growth, dividend yield, etc.
Finally, we add all metrics into a Python Dictionary.
FinMetrics = {}
for company in symbols:
try:
companydata = requests.get(f'https://financialmodelingprep.com/api/v3/profile/{company}?apikey={demo}').json()
IS = requests.get(f'https://financialmodelingprep.com/api/v3/income-statement/{company}?period=quarter&apikey={demo}').json()
BS = requests.get(f'https://financialmodelingprep.com/api/v3/balance-sheet-statement/{company}?period=quarter&apikey={demo}').json()
CF = requests.get(f'https://financialmodelingprep.com/api/v3/cash-flow-statement/{company}?period=quarter&apikey={demo}').json()
#revenue last 4 years
revenue = [IS[0]['revenue'],IS[1]['revenue'],IS[2]['revenue'],IS[3]['revenue']]
revenue = np.array(revenue).sum()
net_income = [IS[0]['netIncome'],IS[1]['netIncome'],IS[2]['netIncome'],IS[3]['netIncome']]
net_income = np.array(net_income).sum()
FCF = CF[0]['freeCashFlow'] + CF[1]['freeCashFlow'] + CF[2]['freeCashFlow'] + CF[3]['freeCashFlow']
OperatingCF = CF[0]['operatingCashFlow'] + CF[1]['operatingCashFlow'] + CF[2]['operatingCashFlow'] + CF[3]['operatingCashFlow']
total_debt = BS[0]['totalDebt']
eps_diluted = [IS[0]['epsdiluted'],IS[1]['epsdiluted'],IS[2]['epsdiluted'],IS[3]['epsdiluted']]
eps_diluted = np.array(eps_diluted).sum()
total_shareholders_equity = BS[0]['totalStockholdersEquity']
shareholders_equity_2_quarters_Average = (BS[0]['totalStockholdersEquity'] + BS[1]['totalStockholdersEquity']) / 2
total_assets_2qts = (BS[0]['totalAssets'] + BS[1]['totalAssets']) / 2
latest_Annual_Dividend = companydata[0]['lastDiv']
price = companydata[0]['price']
market_Capitalization = companydata[0]['mktCap']
name = companydata[0]['companyName']
exchange = companydata[0]['exchange']
EBITDATTM = IS[0]['ebitda'] + IS[1]['ebitda'] + IS[2]['ebitda'] + IS[3]['ebitda']
EBITDA5YTTM = IS[20]['ebitda'] + IS[21]['ebitda'] + IS[22]['ebitda'] + IS[23]['ebitda']
EBITDA5YGrowht = (( EBITDATTM - EBITDA5YTTM) / EBITDA5YTTM)*100
grossprofitma12TTMgrowht = ((IS[0]['grossProfitRatio'] - IS[3]['grossProfitRatio']) / IS[3]['grossProfitRatio']) *100
dividend_Yield= latest_Annual_Dividend/price
FinMetrics[company] = {}
FinMetrics[company]['Dividend_Yield'] = dividend_Yield * 100
FinMetrics[company]['latest_Price'] = price
FinMetrics[company]['latest_Dividend'] = latest_Annual_Dividend
FinMetrics[company]['market_Capit_in_M'] = market_Capitalization/1000000
FinMetrics[company]['pe'] = price / eps_diluted
FinMetrics[company]['ps'] = market_Capitalization / revenue
FinMetrics[company]['pb'] = market_Capitalization / total_shareholders_equity
FinMetrics[company]['PEG'] = FinMetrics[company]['pe'] / EBITDA5YGrowht
FinMetrics[company]['GPM'] = IS[0]['grossProfitRatio']
FinMetrics[company]['latest_Financials'] = IS[0]['date']
FinMetrics[company]['GPM12TTMGrowth'] = grossprofitma12TTMgrowht
FinMetrics[company]['Revenue_last6qts_inM'] = [IS[0]['revenue'],IS[1]['revenue'],IS[2]['revenue'],IS[3]['revenue'],IS[4]['revenue'],IS[5]['revenue']]
FinMetrics[company]['Revenue_last6qts_inM'] = np.array(FinMetrics[company]['Revenue_last6qts_inM']) / 1000000
FinMetrics[company]['ptoOperatingCF'] = market_Capitalization / OperatingCF
FinMetrics[company]['ptoFCF'] = market_Capitalization / FCF
FinMetrics[company]['Debt_to_Equity'] = total_debt / total_shareholders_equity
FinMetrics[company]['ROE'] = net_income / shareholders_equity_2_quarters_Average
FinMetrics[company]['ROA'] = net_income / total_assets_2qts
FinMetrics[company]['revenue_growht_4qrts'] = ((IS[0]['revenue'] - IS[3]['revenue'])/ IS[3]['revenue']) *100
FinMetrics[company]['earnings_growht_4qrts'] = ((IS[0]['netIncome'] - IS[3]['netIncome'])/ IS[3]['netIncome']) *100
except:
pass
Note that we include a try and except as part of the code so that in case some of the API calls return an error, our code keeps working.
You can see that we have calculated more than 18 financial metrics for our industry analysis with Python.
Finally, we convert our FinMetrics dictionary into a Pandas DataFrame:
all_measures= pd.DataFrame.from_dict(FinMetrics,orient='index')
print(all_measures.head(5))
Let's make the tool better by having some filters and plotting capabilities.
Right now, we have a huge number of rows in our industry stock DataFrame. This may not be the best option in order to identify attractive stocks since it is difficult to look at more than 70 rows simultaneously. Our eyes are not built for that.
Therefore, we are going to create some custom filters. In this example, lets find stocks with low price to xxx ratios. Stocks having a low price to earnings/sales ratio are considered to be value stocks. They may be seen as a bargain (of course further research is required before putting our money into them):
First, we keep only companies with a price to earnings ratio higher than 0. This way, we get ride of companies having a negative profit.
Then, I have only activated filter number 1 in below code. Which will filter stocks with a PE ratio lower than 30, PS ratio lower than 20, PB ratio lower than 20 and price to FCF lower than 20.
Next, we sort by companies with the lowest Price to Earnings ratio. The idea is to keep only 8 companies.
Finally, lets also compute and add as a new row the median of the industry for each of the financial ratios.
#keep only companies with a PE higher than 10
price_earnings = all_measures[all_measures['pe'] > 0]
#filter option 1
price_earnings = price_earnings[(price_earnings['pe'] < 30) & (price_earnings['ps'] < 20) & (price_earnings['pb'] < 20) & (price_earnings['ptoFCF'] < 20)]
#filter option 2
#price_earnings = price_earnings[(price_earnings['pe'] < 20) & (price_earnings['revenue_growht_4qrts'] > 10)]
#Sort entities to show companies with lower PE ratio first
price_earnings = price_earnings.sort_values('pe')
#keep only 8 companies:
price_earnings = price_earnings[0:8]
#calculate industry median for each of the ratios:
price_earnings.loc[-1] = all_measures.median()
#rename the column
price_earnings.rename(index={-1: "median_industry"},inplace=True)
print(price_earnings)
The last step of our industry analyser tool is to plot the results. That way, we can easily visualise and compare between the stocks within the selected industry or sector:
price_earnings[['pe','ps','pb','PEG','ptoFCF']].plot()
price_earnings[['Dividend_Yield','revenue_growht_4qrts']].plot(kind='bar')
We have built an amazing tool to perform an industry analysis with Python. Some websites are charging a crazy amount of money for a similar service. Here, we have built it ourselves and we can customise it to our needs!
My advise is to use the tool as a screener to find interesting stocks in an industry. However, do not invest in any stock by simply applying this analysis. You must perform some additional research on the selected company.
Also, read the latest company financial report to see how the company sees its future outlook. Google also the company to find out if it is facing some legal challenges or any other negative surprises.
In addition, I also advise to do some due diligence on the company managers. Finally, consider how the current economy cycle is affecting the selected company.
The last piece of advise is to have a look at the company insider trading transactions of the company. If insiders are buying stocks may be a good sign.
May 14, 2024 11:41 AM - Sanzhi Kobzhan
A stock's target price, also known as its fair value, is an indication of what a share can cost based on the company’s forecasted financial statements. It is important to know a stock's fair value to find undervalued stocks with great growth potential. Let's consider how investment analysts calculat...
May 16, 2024 8:06 PM - Gordon Thompson
On Thursday, May 16, 2024, Deutsche Bank upgraded its rating on NASDAQ:ASTS to Buy, maintaining a hold position. At the time of the announcement, ASTS was trading at $4.03. This decision was accompanied by an increase in the price target for AST SpaceMobile, raised to $22 from $19, as detailed in a ...
May 24, 2024 9:30 AM - Rajnish Katharotiya
Earnings call transcripts are invaluable resources for investors, analysts, and financial enthusiasts. They provide insights into a company's performance, strategy, and future outlook, making them essential for making informed investment decisions. With Financial Modeling Prep, Earnings Call Transcr...