Stock analysis takes a lot of time to filter and find the right one for a long-term investment. So I thought I could speed up the process by calculating a few basic values and write them all into one report file. Now I'd like to simplify everything as I'm sure there are a lot of redundant and repeating parts in it.
My code:
#!/usr/bin/python3
import locale
from time import strftime
print("-------------------------")
print(" Stock analysis ")
print("-------------------------")
# Declare base variables
locale.setlocale(locale.LC_ALL, '')
date = strftime("%Y-%m-%d")
time = strftime(" %H:%M:%S")
partners = "none"
trends = "none"
assets_increase = "y"
liabilities_increase = "n"
income_increase = "y"
age = "y"
forecast = "y"
commodity_reliance = "y"
# Start the dialogue
print("Let's start with some basic values...")
print("You can get the required information using Onvista or Yahoo Finance")
print("\n\nPlease note: This program uses the american number writing style. If you want to write decimal numbers, "
"please use a point instead of a comma to separate the digits (e.g. 1.1 instead of 1,1).\n\n")
name = input("Name of the company: ")
file = open("%s-report.txt" % name, "a")
wkn = input("WKN: ")
symbol = input("Symbol: ")
isin = input("ISIN: ")
sector = input("Sector: ")
# Check initial numbers
while True:
try:
current_price = float(input("Current price: "))
eps = float(input("EPS: "))
pe = float(input("PE: "))
market_cap = float(input("Market capitalization: "))
break
except ValueError:
print("please enter only numbers without comma and use . for decimals (e.g. 5.55 instead of 5,55")
continue
# Check next variables with failsafe so the program doesn't crash when the user enters wrong values
def check_partners_trends():
# Check Partners
global partners, trends
while True:
partner_check = input("Does it have big partners? (y/n): ")
if not partner_check.isalpha():
print("Please only enter y or n")
continue
if partner_check == "y":
partners = input("Who? ")
break
elif partner_check == "n":
partners = "none"
break
else:
print("Please only enter y or n")
continue
# Check Trend
while True:
trend_check = input("Is it participating in any current trends? (y/n): ")
if not trend_check.isalpha():
print("Please only enter y or n")
continue
if trend_check == "y":
trends = input("Which? ")
break
elif trend_check == "n":
trends = "none"
break
else:
print("Please only enter y or n")
continue
return partners, trends
check_partners_trends()
# Write to the report file
file.write("Report for company: " + name)
file.write("\nWKN: %s\tSymbol: %s\nISIN: %s\tSector: %s" % (wkn, symbol, isin, sector))
file.write("\n\nEvaluated: %s\nAt: %s\n\n\n" % (date, time)) # first \n for new line, second \n for one blank line
file.write(name + " is currently trading at: " + locale.currency(current_price, grouping=True))
file.write("\nEPS: %s\n\t--> The higher the better\nP/E: %s\nMarket capitalization: %s" % (eps, pe, locale.currency(market_cap, grouping=True)))
file.write("\n\nIt has the following partners: %s\nAnd is participating in the trend: %s" % (partners, trends))
print("\n__________")
print("Income Statement Analysis")
print("__________\n")
# Check income numbers
while True:
try:
total_revenue = float(input("Total Revenue: "))
gross_profit = float(input("Gross profit: "))
operating_expenses = float(input("Operating expenses: "))
cost_of_revenue = float(input("Cost of revenue: "))
net_income = float(input("Net income: "))
ebit = float(input("EBIT: "))
ebitda = float(input("EBITDA: "))
break
except ValueError:
print("please enter only numbers without comma and use . for decimals (e.g. 5.55 instead of 5,55")
continue
income_red_flags = 0
### Start writing to the report ###
file.write("\n\n\n_____________\n\nIncome Statement Analysis\n_____________\n")
file.write(
"\nTotal revenue: %s\nGross profit: %s\nOperating expenses: %s\nNet income: %s\nCost of revenue: %s\nEBIT: %s\n --> analyzes the performance of core operations\nEBITDA: %s\n --> earnings before interest, taxes, depreciation and amortization --> analyzes performance and projects earnings potential" % (
locale.currency(total_revenue, grouping=True), locale.currency(gross_profit, grouping=True),
locale.currency(operating_expenses, grouping=True), locale.currency(net_income, grouping=True),
locale.currency(cost_of_revenue, grouping=True), locale.currency(ebit, grouping=True),
locale.currency(ebitda, grouping=True)))
def analyze_income():
"""Analyze some of the given values and write them to the report"""
global income_red_flags, gross_profit, total_revenue, operating_expenses, cost_of_revenue
gross_margin = '{0:.2f}%'.format((gross_profit / total_revenue * 100))
# Return this value as percentage
operating_income = gross_profit - operating_expenses
file.write("\n\n\n[-->] Analyzing income...\n")
file.write(
"\nGross margin: {}\n --> Portion of each dollar of revenue that the company retains as profit (35% = 0,35 cent/dollar)\n".format(
gross_margin))
if operating_income < 0:
income_red_flags += 1
file.write(
"\n[!] Operating expenses are negative: %s\n --> Company is generating a loss." % locale.currency(
operating_income, grouping=True))
# company is generating loss
if operating_expenses > total_revenue:
income_red_flags += 1
file.write(
"\n[!] Operating expenses are higher than the revenue --> The company is spending more money than it is receiving.")
# company is spending more than it's receiving
if cost_of_revenue > gross_profit:
income_red_flags += 1
file.write("\n[!] Cost of revenue is higher than gross profits --> The product costs more than it pays.")
# the product costs more than it gives you
file.write("\n[!] Income red flags: %s" % income_red_flags)
return gross_margin, operating_income, income_red_flags
analyze_income()
print("\n__________")
print("Balance Sheet Analysis")
print("__________\n")
# Check Balance numbers
while True:
try:
# Can be liquidated within 1 year
total_assets = float(input("Total assets: "))
current_assets = float(input("Current Assets: "))
cash = float(input("Cash and cash equivalents: "))
inventory = float(input("Inventory: "))
# Total non-current assets -> can't be liquidated within 1 year
net_ppe = float(input("Net PPE: "))
# Check how that property is divided
depreciation = float(input("Depreciation: "))
intangible_assets = float(input("Intangible Assets: "))
# Liabilities
total_liabilities = float(input("Total Liabilities: "))
current_liabilities = float(input("Current Liabilities: "))
# total non current liabilities
long_term_debt = float(input("Long term debt: "))
stockholders_equity = float(input("Stockholders' Equity: "))
total_debt = float(input("Total Debt: "))
break
except ValueError:
print("please enter only numbers without comma and use . for decimals (e.g. 5.55 instead of 5,55")
continue
# Check asset increase
def check_assets_liabilities():
global assets_increase, liabilities_increase, receivable_increase
# Check assets
while True:
assets_increase_check = input("Have the total assets increased year over year? (y/n): ")
if not assets_increase_check.isalpha():
print("Please only enter y or n")
continue
if assets_increase_check == "y":
assets_increase = "y"
break
elif assets_increase_check == "n":
assets_increase = "n"
break
else:
print("Please only enter y or n")
continue
# Check liabilities
while True:
liabilities_increase_check = input("Have the total liabilities decreased year over year? (y/n): ")
if not liabilities_increase_check.isalpha():
print("Please only enter y or n")
continue
if liabilities_increase_check == "y":
liabilities_increase = "y"
break
elif liabilities_increase_check == "n":
liabilities_increase = "n"
break
else:
print("Please only enter y or n")
continue
return assets_increase, liabilities_increase
check_assets_liabilities()
balance_red_flags = 0
### Start writing to the report ###
file.write("\n\n\n_____________\n\nBalance Sheet Analysis\n_____________\n")
# Liquidatable assets
file.write("\n\n--- Assets that can be liquidated within 1 year ---\n")
file.write("\nTotal assets: %s\nCurrent assets: %s" % (
locale.currency(total_assets, grouping=True), locale.currency(current_assets, grouping=True)))
file.write("\nCash and cash equivalents: %s\nInventory value: %s" % (
locale.currency(cash, grouping=True), locale.currency(inventory, grouping=True)))
# Non-liquidatable assets
file.write("\n\n--- Non-current assets which can't be liquidated within 1 year ---\n")
file.write(
"\nNet PPE (property, plant and equipment): %s\n --> These are long term assets important for business operations.\nDepreciation: %s" % (
locale.currency(net_ppe, grouping=True), locale.currency(depreciation, grouping=True)))
file.write("\nIntangible Assets: %s --> Brand recognition, brand names, etc. How well the company is known." % locale.currency(intangible_assets, grouping=True))
# Liabilities
file.write("\n\n--- Liabilities ---\n")
file.write(
"\nTotal Liabilities: %s\nCurrent Liabilities: %s\nLong term debt: %s\n[!] Stockholders Equity: %s\nTotal debt: %s" % (
locale.currency(total_liabilities, grouping=True), locale.currency(current_liabilities, grouping=True),
locale.currency(long_term_debt, grouping=True), locale.currency(stockholders_equity, grouping=True),
locale.currency(total_debt, grouping=True)))
def analyze_balance():
"""Analyze the Balance sheet and write the results to the report"""
global balance_red_flags, assets_increase, liabilities_increase, stockholders_equity
file.write("\n\n\n[-->] Analyzing balance...\n")
if assets_increase == "n":
balance_red_flags += 1
file.write("\n[!] Assets are _not_ increasing.")
if liabilities_increase == "y":
balance_red_flags += 1
file.write("\n[!] Liabilities are increasing -> more debt is being accumulated.")
if stockholders_equity < 0:
balance_red_flags += 1
file.write("\n[!] Stockholders equity is negative. Liabilities are growing faster than assets.")
file.write("\n[!] Balance red flags: %s" % balance_red_flags)
return balance_red_flags
analyze_balance()
print("\n__________")
print("Cash Flow Analysis")
print("__________\n")
# Check balance numbers
while True:
try:
operating_cash_flow = float(input("Operating Cash Flow: "))
investing_cash_flow = float(input("Investing Cash Flow: "))
financing_cash_flow = float(input("Financing Cash Flow: "))
stock_compensation = float(input("Stock based compensation: "))
break
except ValueError:
print("please enter only numbers without comma and use . for decimals (e.g. 5.55 instead of 5,55")
continue
# Check income increase
def check_income():
global income_increase
while True:
income_increase_check = input("Is the company's net income increasing year over year? (y/n): ")
if not income_increase_check.isalpha():
print("Please only enter y or n")
continue
if income_increase_check == "y":
income_increase = "y"
break
elif income_increase_check == "n":
income_increase = "n"
break
else:
print("Please only enter y or n")
continue
return income_increase
check_income()
cash_red_flags = 0
### Start writing the report ###
file.write("\n\n\n_____________\n\nCash Flow Analysis\n_____________\n")
file.write(
"\nOperating cash flow: %s\nInvesting cash flow: %s\nFinancing cash flow: %s\nStock based compensation: %s" % (
locale.currency(operating_cash_flow, grouping=True), locale.currency(investing_cash_flow, grouping=True),
locale.currency(financing_cash_flow, grouping=True), locale.currency(stock_compensation, grouping=True)))
def analyze_cash():
global cash_red_flags, current_assets, current_liabilities, operating_cash_flow, investing_cash_flow, financing_cash_flow, income_increase, operating_cash_flow
file.write("\n\n\n[-->] Analyzing Cash-flow...\n")
working_capital = current_assets - current_liabilities
net_change_cash = operating_cash_flow - investing_cash_flow - financing_cash_flow
if income_increase == "n":
cash_red_flags += 1
file.write("\n[!] Income is not increasing each year -> take a look at the company's files to figure out why.")
if working_capital < 0:
cash_red_flags += 1
file.write(
"\n[!] Working capital negative: %s\n\t--> Company took on more debt or sold something to generate more money" % locale.currency(
working_capital, grouping=True))
if net_change_cash < 0:
cash_red_flags += 1
file.write(
"\n[!] Negative Net cash: %s\n\t--> Find out why and if it was warranted" % locale.currency(net_change_cash,
grouping=True))
if operating_cash_flow < 0:
cash_red_flags += 1
file.write(
"\nCash flow from financing activities is negative: %s\n\t--> Why? Where's the company's money coming from if they're not producing income?" % locale.currency(
operating_cash_flow, grouping=True))
return cash_red_flags, working_capital, net_change_cash
analyze_cash()
print("\n__________")
print("Intrinsic value analysis")
print("__________\n")
def check_age_forecast_commodity():
global age, forecast, commodity_reliance
# Check age
while True:
age_check = input("Is the company older than 10 years? (y/n): ")
if not age_check.isalpha():
print("Please only enter y or n")
continue
if age_check == "y":
age = "y"
break
elif age_check == "n":
age = "n"
break
else:
print("Please only enter y or n")
continue
# Check forecast
while True:
forecast_check = input("Do you still see it around in 10 years? (y/n): ")
if not forecast_check.isalpha():
print("Please only enter y or n")
continue
if forecast_check == "y":
forecast = "y"
break
elif forecast_check == "n":
forecast = "n"
break
else:
print("Please only enter y or n")
continue
# Check commodity reliance
while True:
commodity_check = input("Is the company distinguishable from others/ Does it have an economic moat? (y/n): ")
if not commodity_check.isalpha():
print("Please only enter y or n")
continue
if commodity_check == "y":
commodity_reliance = "y"
break
elif commodity_check == "n":
commodity_reliance = "n"
break
else:
print("Please only enter y or n")
continue
return age, forecast, commodity_reliance
check_age_forecast_commodity()
intrinsic_score = 0
def intrinsic_value():
global total_assets, total_liabilities, total_debt, current_price, net_income, stockholders_equity, income_red_flags, balance_red_flags, cash_red_flags, ebit, current_price, intrinsic_score
file.write(
"\n\n\n________________________________________\n\nIntrinsic value analysis\n\n________________________________________")
book_value = total_assets - total_liabilities
pbv = current_price / book_value
roe = '{0:.2f}%'.format((net_income / stockholders_equity * 100))
debt_to_equity_ratio = total_liabilities / stockholders_equity
rcoe = ebit / (total_assets - current_liabilities)
rcoe_to_price = rcoe * current_price
total_red_flags = income_red_flags + balance_red_flags + cash_red_flags
# Write to the report
file.write(
"\n\n\nBook value: %s --> Should be > 1. If the business went out of business now, how many times could it pay off all its debt.\nPrice to book value (P/BV): %s\n\t--> Should be > 1.5." % (locale.currency(book_value, grouping=True), pbv))
file.write(
"\nDebt to equity ratio: %s\n\t--> How much the company is financing its operations through debt." % debt_to_equity_ratio)
file.write(
"\nReturn on Equity (ROE): {}\n\t--> Should be > 10%. How effectively the management is using a company's assets to create profits.".format(
roe))
file.write(
"\nReturn on capital employed (RCOE): %s\n\ŧ--> Amount of profit a company is generating per 1$ employed -> good for peer comparison." % rcoe)
file.write(
"\nRCOE in comparison to price per share: %s\n\t--> Amount of money the company is generating per one share at the current price." % locale.currency(
rcoe_to_price, grouping=True))
# Calculate Score
if age == "y" or "Y": intrinsic_score += 1
if forecast == "y" or "Y": intrinsic_score += 1
if commodity_reliance == "y" or "Y": intrinsic_score += 1
if book_value > 0: intrinsic_score += 1
if pbv < 1.5: intrinsic_score += 1
if roe > 0.1: intrinsic_score += 1
if debt_to_equity_ratio < 1: intrinsic_score += 1
if total_red_flags < 1: intrinsic_score += 1
file.write(
"\n\n_________________________________\nFINAL INTRINSIC VALUE\n_________________________________\n\nIntrinsic value score: %s/8" % intrinsic_score)
if intrinsic_score <= 3:
file.write("\n\n[-->] Analysis: High risk!\n\t\t[>] Be careful investing into this companyand make sure to check the financial statements and company story again properly. Further research recommended!")
elif intrinsic_score == 4 or 5 or 6:
file.write("\n\n[-->] Analysis: Medium risk.\n\t\t[>] This company could be turning a profit but for safety reasons, please check the financial statements, red flags and other facts again, to be sure that nothing is inadvertently overlooked")
elif intrinsic_score == 7 or 8:
file.write("\n\n[-->] Analysis: Low risk.\n\t\t[>] It's unlikely that the company will go bankrupt in the foreseeable future.")
return book_value, pbv, roe, debt_to_equity_ratio, rcoe, total_red_flags, intrinsic_score
intrinsic_value()
print("\n\nDone.\n")
print("The intrinsic value score is: " + str(intrinsic_score) + "/8\n")
print(
"A report has been generated. Please check the same directory this program is located in\nThank you for using the Stock analysis tool.")
file.close()
Thank you for taking the time to read until here :)