Merge pull request #103 from DidierRLopes/refactor-fa

Refactor FA folder
This commit is contained in:
Artem Veremey
2021-03-06 09:19:41 -08:00
committed by GitHub
7 changed files with 420 additions and 778 deletions

View File

@@ -4,10 +4,14 @@ from alpha_vantage.fundamentaldata import FundamentalData
import pandas as pd
from pandas.io.json import json_normalize
from gamestonk_terminal import config_terminal as cfg
from gamestonk_terminal.helper_funcs import check_positive, long_number_format
from gamestonk_terminal.dataframe_helpers import clean_df_index
from gamestonk_terminal.helper_funcs import (
check_positive,
long_number_format,
parse_known_args_and_warn,
)
# ---------------------------------------------------- OVERVIEW ----------------------------------------------------
def overview(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="overview",
@@ -17,23 +21,19 @@ def overview(l_args, s_ticker):
Address, Full time employees, Fiscal year end, Latest quarter, Market capitalization,
EBITDA, PE ratio, PEG ratio, Book value, Dividend per share, Dividend yield, EPS,
Revenue per share TTM, Profit margin, Operating margin TTM, Return on assets TTM,
Return on equity TTM, Revenue TTM, Gross profit TTM, Diluted EPS TTM, Quarterly earnings growth YOY,
Quarterly revenue growth YOY, Analyst target price, Trailing PE, Forward PE,
Price to sales ratio TTM, Price to book ratio, EV to revenue, EV to EBITDA, Beta, 52 week high,
52 week low, 50 day moving average, 200 day moving average, Shares outstanding, Shares float,
Shares short, Shares short prior month, Short ratio, Short percent outstanding, Short percent float,
Percent insiders, Percent institutions, Forward annual dividend rate, Forward annual dividend yield,
Payout ratio, Dividend date, Ex dividend date, Last split factor, and Last split date.
[Source: Alpha Vantage]
Return on equity TTM, Revenue TTM, Gross profit TTM, Diluted EPS TTM, Quarterly
earnings growth YOY, Quarterly revenue growth YOY, Analyst target price, Trailing PE,
Forward PE, Price to sales ratio TTM, Price to book ratio, EV to revenue, EV to EBITDA,
Beta, 52 week high, 52 week low, 50 day moving average, 200 day moving average, Shares
outstanding, Shares float, Shares short, Shares short prior month, Short ratio, Short
percent outstanding, Short percent float, Percent insiders, Percent institutions,
Forward annual dividend rate, Forward annual dividend yield, Payout ratio, Dividend
date, Ex dividend date, Last split factor, and Last split date. [Source: Alpha Vantage]
""",
)
try:
(_, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
return
parse_known_args_and_warn(parser, l_args)
# Request OVERVIEW data from Alpha Vantage API
s_req = f"https://www.alphavantage.co/query?function=OVERVIEW&symbol={s_ticker}&apikey={cfg.API_KEY_ALPHAVANTAGE}"
@@ -46,13 +46,7 @@ def overview(l_args, s_ticker):
# Keep json data sorting in dataframe
df_fa = df_fa[list(result.json().keys())].T
df_fa = df_fa.applymap(lambda x: long_number_format(x))
df_fa.index = [
"".join(
" " + char if char.isupper() else char.strip() for char in idx
).strip()
for idx in df_fa.index.tolist()
]
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
clean_df_index(df_fa)
df_fa = df_fa.rename(
index={
"E b i t d a": "EBITDA",
@@ -91,24 +85,20 @@ def overview(l_args, s_ticker):
return
# ------------------------------------------------------ KEY ------------------------------------------------------
def key(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="key",
description="""
Gives main key metrics about the company (it's a subset of the Overview data from Alpha Vantage API).
The following fields are expected: Market capitalization, EBITDA, EPS, PE ratio, PEG ratio, Price to book ratio,
Return on equity TTM, Payout ratio, Price to sales ratio TTM, Dividend yield, 50 day moving average, Analyst
target price, Beta [Source: Alpha Vantage API]
Gives main key metrics about the company (it's a subset of the Overview data from Alpha
Vantage API). The following fields are expected: Market capitalization, EBITDA, EPS, PE
ratio, PEG ratio, Price to book ratio, Return on equity TTM, Payout ratio, Price to
sales ratio TTM, Dividend yield, 50 day moving average, Analyst target price, Beta
[Source: Alpha Vantage API]
""",
)
try:
(_, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
return
parse_known_args_and_warn(parser, l_args)
# Request OVERVIEW data
s_req = f"https://www.alphavantage.co/query?function=OVERVIEW&symbol={s_ticker}&apikey={cfg.API_KEY_ALPHAVANTAGE}"
@@ -118,15 +108,8 @@ def key(l_args, s_ticker):
if result.status_code == 200:
df_fa = json_normalize(result.json())
df_fa = df_fa[list(result.json().keys())].T
df_fa = df_fa.applymap(lambda x: long_number_format(x))
df_fa.index = [
"".join(
" " + char if char.isupper() else char.strip() for char in idx
).strip()
for idx in df_fa.index.tolist()
]
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
clean_df_index(df_fa)
df_fa = df_fa.rename(
index={
"E b i t d a": "EBITDA",
@@ -165,19 +148,19 @@ def key(l_args, s_ticker):
return
# ---------------------------------------------------- INCOME_STATEMENT ----------------------------------------------------
def income_statement(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="incom",
description="""
Prints a complete income statement over time. This can be either quarterly or annually.
The following fields are expected: Accepted date, Cost and expenses, Cost of revenue, Depreciation
and amortization, Ebitda, Ebitdaratio, Eps, Epsdiluted, Filling date, Final link, General and
administrative expenses, Gross profit, Gross profit ratio, Income before tax, Income before tax ratio,
Income tax expense, Interest expense, Link, Net income, Net income ratio, Operating expenses,
Operating income, Operating income ratio, Other expenses, Period, Research and development expenses,
Revenue, Selling and marketing expenses, Total other income expenses net, Weighted average shs out,
Weighted average shs out dil [Source: Alpha Vantage]""",
The following fields are expected: Accepted date, Cost and expenses, Cost of revenue,
Depreciation and amortization, Ebitda, Ebitdaratio, Eps, Epsdiluted, Filling date,
Final link, General and administrative expenses, Gross profit, Gross profit ratio,
Income before tax, Income before tax ratio, Income tax expense, Interest expense, Link,
Net income, Net income ratio, Operating expenses, Operating income, Operating income
ratio, Other expenses, Period, Research and development expenses, Revenue, Selling and
marketing expenses, Total other income expenses net, Weighted average shs out, Weighted
average shs out dil [Source: Alpha Vantage]""",
)
parser.add_argument(
@@ -199,11 +182,7 @@ def income_statement(l_args, s_ticker):
)
try:
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
return
ns_parser = parse_known_args_and_warn(parser, l_args)
if ns_parser.n_num == 1:
pd.set_option("display.max_colwidth", -1)
@@ -218,24 +197,8 @@ def income_statement(l_args, s_ticker):
# pylint: disable=unbalanced-tuple-unpacking
df_fa, _ = fd.get_income_statement_annual(symbol=s_ticker)
# pylint: disable=no-member
df_fa = df_fa.set_index("fiscalDateEnding")
df_fa = df_fa.head(n=ns_parser.n_num).T
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num * ["None"])).dropna()
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num * ["0"])).dropna()
df_fa = df_fa.applymap(lambda x: long_number_format(x))
# begin problematic for pylint
df_fa.index = [
"".join(
" " + char if char.isupper() else char.strip() for char in idx
).strip()
for idx in df_fa.index.tolist()
]
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
df_fa.columns.name = "Fiscal Date Ending"
# end problematic for pylint
df_fa = clean_fundamentals_df(df_fa, num=ns_parser.n_num)
print(df_fa)
print("")
except Exception as e:
@@ -244,98 +207,23 @@ def income_statement(l_args, s_ticker):
return
# ---------------------------------------------------- BALANCE_SHEET ----------------------------------------------------
def balance_sheet(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="balance",
description="""
Prints a complete balance sheet statement over time. This can be either quarterly or annually.
The following fields are expected: Accepted date, Account payables, Accumulated other comprehensive
income loss, Cash and cash equivalents, Cash and short term investments, Common stock, Deferred revenue,
Deferred revenue non current, Deferred tax liabilities non current, Filling date, Final link, Goodwill,
Goodwill and intangible assets, Intangible assets, Inventory, Link, Long term debt, Long term investments,
Net debt, Net receivables, Other assets, Other current assets, Other current liabilities, Other liabilities,
Other non current assets, Other non current liabilities, Othertotal stockholders equity, Period, Property
plant equipment net, Retained earnings, Short term debt, Short term investments, Tax assets, Tax payables,
Total assets, Total current assets, Total current liabilities, Total debt, Total investments, Total
liabilities, Total liabilities and stockholders equity, Total non current assets, Total non current
liabilities, and Total stockholders equity. [Source: Alpha Vantage]
""",
)
parser.add_argument(
"-n",
"--num",
action="store",
dest="n_num",
type=check_positive,
default=1,
help="Number of latest years/quarters.",
)
parser.add_argument(
"-q",
"--quarter",
action="store_true",
default=False,
dest="b_quarter",
help="Quarter fundamental data flag.",
)
try:
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
return
if ns_parser.n_num == 1:
pd.set_option("display.max_colwidth", -1)
else:
pd.options.display.max_colwidth = 40
fd = FundamentalData(key=cfg.API_KEY_ALPHAVANTAGE, output_format="pandas")
if ns_parser.b_quarter:
df_fa, _ = fd.get_balance_sheet_quarterly(symbol=s_ticker)
else:
df_fa, _ = fd.get_balance_sheet_annual(symbol=s_ticker)
df_fa = df_fa.set_index("fiscalDateEnding")
df_fa = df_fa.head(n=ns_parser.n_num).T
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num * ["None"])).dropna()
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num * ["0"])).dropna()
df_fa = df_fa.applymap(lambda x: long_number_format(x))
df_fa.index = [
"".join(
" " + char if char.isupper() else char.strip() for char in idx
).strip()
for idx in df_fa.index.tolist()
]
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
df_fa.columns.name = "Fiscal Date Ending"
print(df_fa)
print("")
except Exception as e:
print(e)
print("")
return
# ---------------------------------------------------- CASH_FLOW ----------------------------------------------------
def cash_flow(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="cash",
description="""
Prints a complete cash flow statement over time. This can be either quarterly or annually. The following
fields are expected: Accepted date, Accounts payables, Accounts receivables, Acquisitions net, Capital
expenditure, Cash at beginning of period, Cash at end of period, Change in working capital, Common stock
issued, Common stock repurchased, Debt repayment, Deferred income tax, Depreciation and amortization,
Dividends paid, Effect of forex changes on cash, Filling date, Final link, Free cash flow, Inventory,
Investments in property plant and equipment, Link, Net cash provided by operating activities, Net cash
used for investing activities, Net cash used provided by financing activities, Net change in cash, Net income,
Operating cash flow, Other financing activities, Other investing activities, Other non cash items, Other working
capital, Period, Purchases of investments, Sales maturities of investments, Stock based compensation.
Prints a complete balance sheet statement over time. This can be either quarterly or
annually. The following fields are expected: Accepted date, Account payables,
Accumulated other comprehensive income loss, Cash and cash equivalents, Cash and short
term investments, Common stock, Deferred revenue, Deferred revenue non current,
Deferred tax liabilities non current, Filling date, Final link, Goodwill,
Goodwill and intangible assets, Intangible assets, Inventory, Link, Long term debt,
Long term investments, Net debt, Net receivables, Other assets, Other current assets,
Other current liabilities, Other liabilities, Other non current assets, Other non
current liabilities, Othertotal stockholders equity, Period, Property plant equipment
net, Retained earnings, Short term debt, Short term investments, Tax assets, Tax
payables, Total assets, Total current assets, Total current liabilities, Total debt,
Total investments, Total liabilities, Total liabilities and stockholders equity, Total
non current assets, Total non current liabilities, and Total stockholders equity.
[Source: Alpha Vantage]
""",
)
@@ -372,25 +260,77 @@ def cash_flow(l_args, s_ticker):
fd = FundamentalData(key=cfg.API_KEY_ALPHAVANTAGE, output_format="pandas")
if ns_parser.b_quarter:
df_fa, _ = fd.get_cash_flow_quarterly(symbol=s_ticker)
# pylint: disable=unbalanced-tuple-unpacking
df_fa, _ = fd.get_balance_sheet_quarterly(symbol=s_ticker)
else:
df_fa, _ = fd.get_cash_flow_annual(symbol=s_ticker)
# pylint: disable=unbalanced-tuple-unpacking
df_fa, _ = fd.get_balance_sheet_annual(symbol=s_ticker)
df_fa = df_fa.set_index("fiscalDateEnding")
df_fa = df_fa.head(n=ns_parser.n_num).T
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num * ["None"])).dropna()
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num * ["0"])).dropna()
df_fa = df_fa.applymap(lambda x: long_number_format(x))
df_fa.index = [
"".join(
" " + char if char.isupper() else char.strip() for char in idx
).strip()
for idx in df_fa.index.tolist()
]
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
df_fa.columns.name = "Fiscal Date Ending"
df_fa = clean_fundamentals_df(df_fa, num=ns_parser.n_num)
print(df_fa)
print("")
except Exception as e:
print(e)
print("")
return
def cash_flow(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="cash",
description="""
Prints a complete cash flow statement over time. This can be either quarterly or
annually. The following fields are expected: Accepted date, Accounts payables, Accounts
receivables, Acquisitions net, Capital expenditure, Cash at beginning of period, Cash
at end of period, Change in working capital, Common stock issued, Common stock
repurchased, Debt repayment, Deferred income tax, Depreciation and amortization,
Dividends paid, Effect of forex changes on cash, Filling date, Final link, Free cash
flow, Inventory, Investments in property plant and equipment, Link, Net cash provided
by operating activities, Net cash used for investing activities, Net cash used provided
by financing activities, Net change in cash, Net income, Operating cash flow, Other
financing activities, Other investing activities, Other non cash items, Other working
capital, Period, Purchases of investments, Sales maturities of investments, Stock based
compensation. [Source: Alpha Vantage]
""",
)
parser.add_argument(
"-n",
"--num",
action="store",
dest="n_num",
type=check_positive,
default=1,
help="Number of latest years/quarters.",
)
parser.add_argument(
"-q",
"--quarter",
action="store_true",
default=False,
dest="b_quarter",
help="Quarter fundamental data flag.",
)
try:
ns_parser = parse_known_args_and_warn(parser, l_args)
if ns_parser.n_num == 1:
pd.set_option("display.max_colwidth", -1)
else:
pd.options.display.max_colwidth = 40
fd = FundamentalData(key=cfg.API_KEY_ALPHAVANTAGE, output_format="pandas")
if ns_parser.b_quarter:
# pylint: disable=unbalanced-tuple-unpacking
df_fa, _ = fd.get_cash_flow_quarterly(symbol=s_ticker)
else:
# pylint: disable=unbalanced-tuple-unpacking
df_fa, _ = fd.get_cash_flow_annual(symbol=s_ticker)
df_fa = clean_fundamentals_df(df_fa, num=ns_parser.n_num)
print(df_fa)
print("")
except Exception as e:
@@ -399,13 +339,12 @@ def cash_flow(l_args, s_ticker):
return
# ---------------------------------------------------- EARNINGS ----------------------------------------------------
def earnings(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="earnings",
description="""
Print earnings dates and reported EPS of the company. The following fields are expected: Fiscal Date
Ending and Reported EPS. [Source: Alpha Vantage]
Print earnings dates and reported EPS of the company. The following fields are
expected: Fiscal Date Ending and Reported EPS. [Source: Alpha Vantage]
""",
)
@@ -428,11 +367,7 @@ def earnings(l_args, s_ticker):
)
try:
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
return
ns_parser = parse_known_args_and_warn(parser, l_args)
if ns_parser.n_num == 1:
pd.set_option("display.max_colwidth", -1)
@@ -488,3 +423,15 @@ def earnings(l_args, s_ticker):
print(e)
print("")
return
def clean_fundamentals_df(df_fa: pd.DataFrame, num: int) -> pd.DataFrame:
# pylint: disable=no-member
df_fa = df_fa.set_index("fiscalDateEnding")
df_fa = df_fa.head(n=num).T
df_fa = df_fa.mask(df_fa.astype(object).eq(num * ["None"])).dropna()
df_fa = df_fa.mask(df_fa.astype(object).eq(num * ["0"])).dropna()
df_fa = df_fa.applymap(lambda x: long_number_format(x))
clean_df_index(df_fa)
df_fa.columns.name = "Fiscal Date Ending"
return df_fa

View File

@@ -3,10 +3,9 @@ import requests
from bs4 import BeautifulSoup
import pandas as pd
from rapidfuzz import fuzz
from gamestonk_terminal.helper_funcs import get_user_agent
from gamestonk_terminal.helper_funcs import get_user_agent, parse_known_args_and_warn
# ---------------------------------------------------- MANAGEMENT ----------------------------------------------------
def management(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="mgmt",
@@ -17,11 +16,7 @@ def management(l_args, s_ticker):
)
try:
(_, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
return
parse_known_args_and_warn(parser, l_args)
url_market_business_insider = (
f"https://markets.businessinsider.com/stocks/{s_ticker.lower()}-stock"

View File

@@ -10,7 +10,6 @@ from gamestonk_terminal.fundamental_analysis import business_insider_api as bi_a
from gamestonk_terminal.fundamental_analysis import yahoo_finance_api as yf_api
# -----------------------------------------------------------------------------------------------------------------------
def print_fundamental_analysis(s_ticker, s_start, s_interval):
""" Print help """
@@ -65,9 +64,7 @@ def print_fundamental_analysis(s_ticker, s_start, s_interval):
return
# ---------------------------------------------------- INFO ----------------------------------------------------
# pylint: disable=unused-argument
def info(l_args, s_ticker):
def key_metrics_explained(l_args):
parser = argparse.ArgumentParser(
prog="info",
description="""
@@ -96,7 +93,6 @@ def info(l_args, s_ticker):
return
# ---------------------------------------------------- MENU ----------------------------------------------------
# pylint: disable=too-many-branches
def fa_menu(s_ticker, s_start, s_interval):
@@ -107,29 +103,29 @@ def fa_menu(s_ticker, s_start, s_interval):
choices=[
"help",
"q",
"quit", #
"screener", # Finviz
"mgmt", # Business Insider
"quit",
"screener",
"mgmt",
"info",
"shrs",
"sust",
"cal", # Yahoo Finance
"cal",
"income",
"assets",
"liabilities",
"operating",
"investing",
"financing", # MW
"financing",
"overview",
"key",
"incom",
"balance",
"cash",
"earnings", # AV
"earnings",
"profile",
"quote",
"enterprise",
"dcf", # FMP
"dcf",
"inc",
"bal",
"cashf",
@@ -137,7 +133,7 @@ def fa_menu(s_ticker, s_start, s_interval):
"ratios",
"growth",
],
) # FMP
)
print_fundamental_analysis(s_ticker, s_start, s_interval)
@@ -154,9 +150,6 @@ def fa_menu(s_ticker, s_start, s_interval):
print("The command selected doesn't exist\n")
continue
# if ns_known_args.cmd == 'info':
# info(l_args, s_ticker)
if ns_known_args.cmd == "help":
print_fundamental_analysis(s_ticker, s_start, s_interval)

View File

@@ -3,42 +3,36 @@ from datetime import datetime
import pandas as pd
import FundamentalAnalysis as fa # Financial Modeling Prep
from gamestonk_terminal import config_terminal as cfg
from gamestonk_terminal.helper_funcs import long_number_format, check_positive
from gamestonk_terminal.dataframe_helpers import clean_df_index
from gamestonk_terminal.helper_funcs import (
long_number_format,
check_positive,
parse_known_args_and_warn,
)
# ---------------------------------------------------- PROFILE ----------------------------------------------------
def profile(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="profile",
description="""
Prints information about, among other things, the industry, sector
exchange and company description. The following fields are expected: Address, Beta,
Ceo, Changes, Cik, City, Company name, Country, Currency, Cusip, Dcf, Dcf diff,
Default image, Description, Exchange, Exchange short name, Full time employees, Image,
Industry, Ipo date, Isin, Last div, Mkt cap, Phone, Price, Range, Sector, State, Symbol,
Vol avg, Website, Zip. [Source: Financial Modeling Prep]
Prints information about, among other things, the industry, sector exchange and company
description. The following fields are expected: Address, Beta, Ceo, Changes, Cik, City
Company name, Country, Currency, Cusip, Dcf, Dcf diff, Default image, Description,
Exchange, Exchange short name, Full time employees, Image, Industry, Ipo date, Isin,
Last div, Mkt cap, Phone, Price, Range, Sector, State, Symbol, Vol avg, Website, Zip.
[Source: Financial Modeling Prep]
""",
)
try:
(_, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
return
parse_known_args_and_warn(parser, l_args)
df_fa = fa.profile(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP)
df_fa.index = [
"".join(
" " + char if char.isupper() else char.strip() for char in idx
).strip()
for idx in df_fa.index.tolist()
]
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
clean_df_index(df_fa)
print(df_fa.drop(index=["Description", "Image"]).to_string(header=False))
print(f"\nImage: {df_fa.loc['Image'][0]}")
print(f"\nDescription: {df_fa.loc['Description'][0]}")
print("")
except Exception as e:
@@ -47,48 +41,40 @@ def profile(l_args, s_ticker):
return
# ---------------------------------------------------- QUOTE ----------------------------------------------------
def quote(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="quote",
description="""
Prints actual information about the company which is, among
other things, the day high, market cap, open and close price and price-to-equity
ratio. The following fields are expected: Avg volume, Change, Changes percentage,
Day high, Day low, Earnings announcement, Eps, Exchange, Market cap, Name, Open,
Pe, Previous close, Price, Price avg200, Price avg50, Shares outstanding, Symbol,
Timestamp, Volume, Year high, and Year low. [Source: Financial Modeling Prep]
Prints actual information about the company which is, among other things, the day high,
market cap, open and close price and price-to-equity ratio. The following fields are
expected: Avg volume, Change, Changes percentage, Day high, Day low, Earnings
announcement, Eps, Exchange, Market cap, Name, Open, Pe, Previous close, Price, Price
avg200, Price avg50, Shares outstanding, Symbol, Timestamp, Volume, Year high, and Year
low. [Source: Financial Modeling Prep]
""",
)
try:
(_, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
return
parse_known_args_and_warn(parser, l_args)
df_fa = fa.quote(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP)
df_fa.index = [
"".join(
" " + char if char.isupper() else char.strip() for char in idx
).strip()
for idx in df_fa.index.tolist()
]
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
clean_df_index(df_fa)
df_fa.loc["Market cap"][0] = long_number_format(df_fa.loc["Market cap"][0])
df_fa.loc["Shares outstanding"][0] = long_number_format(
df_fa.loc["Shares outstanding"][0]
)
df_fa.loc["Volume"][0] = long_number_format(df_fa.loc["Volume"][0])
earning_announcment = datetime.strptime(
df_fa.loc["Earnings announcement"][0][0:19], "%Y-%m-%dT%H:%M:%S"
)
df_fa.loc["Earnings announcement"][
0
] = f"{earning_announcment.date()} {earning_announcment.time()}"
# Check if there is a valid earnings announcement
if df_fa.loc["Earnings announcement"][0]:
earning_announcement = datetime.strptime(
df_fa.loc["Earnings announcement"][0][0:19], "%Y-%m-%dT%H:%M:%S"
)
df_fa.loc["Earnings announcement"][
0
] = f"{earning_announcement.date()} {earning_announcement.time()}"
print(df_fa.to_string(header=False))
print("")
except Exception as e:
@@ -97,7 +83,6 @@ def quote(l_args, s_ticker):
return
# ---------------------------------------------------- ENTERPRISE ----------------------------------------------------
def enterprise(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="enterprise",
@@ -128,11 +113,7 @@ def enterprise(l_args, s_ticker):
)
try:
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
return
ns_parser = parse_known_args_and_warn(parser, l_args)
if ns_parser.n_num == 1:
pd.set_option("display.max_colwidth", -1)
@@ -146,17 +127,9 @@ def enterprise(l_args, s_ticker):
else:
df_fa = fa.enterprise(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP)
df_fa = df_fa.iloc[:, 0 : ns_parser.n_num]
df_fa = df_fa.applymap(lambda x: long_number_format(x))
df_fa.index = [
"".join(
" " + char if char.isupper() else char.strip() for char in idx
).strip()
for idx in df_fa.index.tolist()
]
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
print(df_fa)
df_fa = clean_metrics_df(df_fa, num=ns_parser.n_num, mask=False)
print(df_fa)
print("")
except Exception as e:
@@ -165,14 +138,13 @@ def enterprise(l_args, s_ticker):
return
# ------------------------------------------ DISCOUNTED CASH FLOW ------------------------------------------------------
def discounted_cash_flow(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="dcf",
description="""
Prints the discounted cash flow of a company over time including
the DCF of today. The following fields are expected: DCF, Stock price, and Date.
[Source: Financial Modeling Prep]
Prints the discounted cash flow of a company over time including the DCF of today. The
following fields are expected: DCF, Stock price, and Date. [Source: Financial Modeling
Prep]
""",
)
parser.add_argument(
@@ -194,11 +166,7 @@ def discounted_cash_flow(l_args, s_ticker):
)
try:
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
return
ns_parser = parse_known_args_and_warn(parser, l_args)
if ns_parser.n_num == 1:
pd.set_option("display.max_colwidth", -1)
@@ -212,18 +180,9 @@ def discounted_cash_flow(l_args, s_ticker):
else:
df_fa = fa.discounted_cash_flow(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP)
df_fa = df_fa.iloc[:, 0 : ns_parser.n_num]
df_fa = df_fa.applymap(lambda x: long_number_format(x))
df_fa.index = [
"".join(
" " + char if char.isupper() else char.strip() for char in idx
).strip()
for idx in df_fa.index.tolist()
]
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
df_fa = df_fa.rename(index={"D c f": "DCF"})
print(df_fa)
df_fa = clean_metrics_df(df_fa, num=ns_parser.n_num, mask=False)
print(df_fa)
print("")
except Exception as e:
@@ -232,19 +191,19 @@ def discounted_cash_flow(l_args, s_ticker):
return
# ---------------------------------------------------- INCOME_STATEMENT ----------------------------------------------------
def income_statement(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="inc",
description="""
Prints a complete income statement over time. This can be either quarterly
or annually. The following fields are expected: Accepted date, Cost and expenses, Cost of
revenue, Depreciation and amortization, Ebitda, Ebitdaratio, Eps, Epsdiluted, Filling date,
Final link, General and administrative expenses, Gross profit, Gross profit ratio, Income
before tax, Income before tax ratio, Income tax expense, Interest expense, Link, Net income,
Net income ratio, Operating expenses, Operating income, Operating income ratio, Other expenses,
Period, Research and development expenses, Revenue, Selling and marketing expenses, Total other
income expenses net, Weighted average shs out, Weighted average shs out dil [Source: Financial Modeling Prep]
Prints a complete income statement over time. This can be either quarterly or annually.
The following fields are expected: Accepted date, Cost and expenses, Cost of
revenue, Depreciation and amortization, Ebitda, Ebitdaratio, Eps, Epsdiluted, Filling
date, Final link, General and administrative expenses, Gross profit, Gross profit
ratio, Income before tax, Income before tax ratio, Income tax expense, Interest
expense, Link, Net income, Net income ratio, Operating expenses, Operating income,
Operating income ratio, Other expenses, Period, Research and development expenses,
Revenue, Selling and marketing expenses, Total other income expenses net, Weighted
average shs out, Weighted average shs out dil [Source: Financial Modeling Prep]
""",
)
@@ -267,11 +226,7 @@ def income_statement(l_args, s_ticker):
)
try:
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
return
ns_parser = parse_known_args_and_warn(parser, l_args)
if ns_parser.n_num == 1:
pd.set_option("display.max_colwidth", -1)
@@ -285,18 +240,8 @@ def income_statement(l_args, s_ticker):
else:
df_fa = fa.income_statement(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP)
df_fa = df_fa.iloc[:, 0 : ns_parser.n_num]
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num * ["None"])).dropna()
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num * ["0"])).dropna()
df_fa = df_fa.applymap(lambda x: long_number_format(x))
df_fa.index = [
"".join(
" " + char if char.isupper() else char.strip() for char in idx
).strip()
for idx in df_fa.index.tolist()
]
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
df_fa.columns.name = "Fiscal Date Ending"
df_fa = clean_metrics_df(df_fa, num=ns_parser.n_num)
print(df_fa.drop(index=["Final link", "Link"]).to_string())
pd.set_option("display.max_colwidth", -1)
@@ -304,7 +249,6 @@ def income_statement(l_args, s_ticker):
print(df_fa.loc["Final link"].to_frame().to_string())
print("")
print(df_fa.loc["Link"].to_frame().to_string())
print("")
except Exception as e:
@@ -313,7 +257,6 @@ def income_statement(l_args, s_ticker):
return
# ---------------------------------------------------- BALANCE_SHEET ----------------------------------------------------
def balance_sheet(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="bal",
@@ -327,11 +270,11 @@ def balance_sheet(l_args, s_ticker):
Link, Long term debt, Long term investments, Net debt, Net receivables, Other assets,
Other current assets, Other current liabilities, Other liabilities, Other non current
assets, Other non current liabilities, Othertotal stockholders equity, Period, Property
plant equipment net, Retained earnings, Short term debt, Short term investments, Tax assets,
Tax payables, Total assets, Total current assets, Total current liabilities, Total debt,
Total investments, Total liabilities, Total liabilities and stockholders equity, Total
non current assets, Total non current liabilities, and Total stockholders equity.
[Source: Financial Modeling Prep]
plant equipment net, Retained earnings, Short term debt, Short term investments, Tax
assets, Tax payables, Total assets, Total current assets, Total current liabilities,
Total debt, Total investments, Total liabilities, Total liabilities and stockholders
equity, Total non current assets, Total non current liabilities, and Total stockholders
equity. [Source: Financial Modeling Prep]
""",
)
@@ -354,11 +297,7 @@ def balance_sheet(l_args, s_ticker):
)
try:
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
return
ns_parser = parse_known_args_and_warn(parser, l_args)
if ns_parser.n_num == 1:
pd.set_option("display.max_colwidth", -1)
@@ -374,18 +313,8 @@ def balance_sheet(l_args, s_ticker):
s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP
)
df_fa = df_fa.iloc[:, 0 : ns_parser.n_num]
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num * ["None"])).dropna()
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num * ["0"])).dropna()
df_fa = df_fa.applymap(lambda x: long_number_format(x))
df_fa.index = [
"".join(
" " + char if char.isupper() else char.strip() for char in idx
).strip()
for idx in df_fa.index.tolist()
]
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
df_fa.columns.name = "Fiscal Date Ending"
df_fa = clean_metrics_df(df_fa, num=ns_parser.n_num)
print(df_fa.drop(index=["Final link", "Link"]).to_string())
pd.set_option("display.max_colwidth", -1)
@@ -393,7 +322,6 @@ def balance_sheet(l_args, s_ticker):
print(df_fa.loc["Final link"].to_frame().to_string())
print("")
print(df_fa.loc["Link"].to_frame().to_string())
print("")
except Exception as e:
@@ -402,22 +330,22 @@ def balance_sheet(l_args, s_ticker):
return
# ---------------------------------------------------- CASH_FLOW ----------------------------------------------------
def cash_flow(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="cash",
description="""
Prints a complete cash flow statement over time. This can be either
quarterly or annually. The following fields are expected: Accepted date, Accounts payables,
Accounts receivables, Acquisitions net, Capital expenditure, Cash at beginning of period,
Cash at end of period, Change in working capital, Common stock issued, Common stock repurchased,
Debt repayment, Deferred income tax, Depreciation and amortization, Dividends paid,
Effect of forex changes on cash, Filling date, Final link, Free cash flow, Inventory,
Investments in property plant and equipment, Link, Net cash provided by operating activities,
Net cash used for investing activities, Net cash used provided by financing activities, Net
change in cash, Net income, Operating cash flow, Other financing activities, Other investing
activities, Other non cash items, Other working capital, Period, Purchases of investments,
Sales maturities of investments, Stock based compensation. [Source: Financial Modeling Prep]
quarterly or annually. The following fields are expected: Accepted date, Accounts
payables, Accounts receivables, Acquisitions net, Capital expenditure, Cash at
beginning of period, Cash at end of period, Change in working capital, Common stock
issued, Common stock repurchased, Debt repayment, Deferred income tax, Depreciation and
amortization, Dividends paid, Effect of forex changes on cash, Filling date, Final
link, Free cash flow, Inventory, Investments in property plant and equipment, Link, Net
cash provided by operating activities, Net cash used for investing activities, Net cash
used provided by financing activities, Net change in cash, Net income, Operating cash
flow, Other financing activities, Other investing activities, Other non cash items,
Other working capital, Period, Purchases of investments, Sales maturities of
investments, Stock based compensation. [Source: Financial Modeling Prep]
""",
)
@@ -440,11 +368,7 @@ def cash_flow(l_args, s_ticker):
)
try:
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
return
ns_parser = parse_known_args_and_warn(parser, l_args)
if ns_parser.n_num == 1:
pd.set_option("display.max_colwidth", -1)
@@ -458,18 +382,8 @@ def cash_flow(l_args, s_ticker):
else:
df_fa = fa.cash_flow_statement(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP)
df_fa = df_fa.iloc[:, 0 : ns_parser.n_num]
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num * ["None"])).dropna()
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num * ["0"])).dropna()
df_fa = df_fa.applymap(lambda x: long_number_format(x))
df_fa.index = [
"".join(
" " + char if char.isupper() else char.strip() for char in idx
).strip()
for idx in df_fa.index.tolist()
]
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
df_fa.columns.name = "Fiscal Date Ending"
df_fa = clean_metrics_df(df_fa, num=ns_parser.n_num)
print(df_fa.drop(index=["Final link", "Link"]).to_string())
pd.set_option("display.max_colwidth", -1)
@@ -477,7 +391,6 @@ def cash_flow(l_args, s_ticker):
print(df_fa.loc["Final link"].to_frame().to_string())
print("")
print(df_fa.loc["Link"].to_frame().to_string())
print("")
except Exception as e:
@@ -486,7 +399,6 @@ def cash_flow(l_args, s_ticker):
return
# ---------------------------------------------------- KEY_METRICS ----------------------------------------------------
def key_metrics(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="metrics",
@@ -496,17 +408,18 @@ def key_metrics(l_args, s_ticker):
Working Capital, Current Ratio and Debt to Assets. The following fields are expected:
Average inventory, Average payables, Average receivables, Book value per share, Capex
per share, Capex to depreciation, Capex to operating cash flow, Capex to revenue, Cash
per share, Current ratio, Days of inventory on hand, Days payables outstanding, Days sales
outstanding, Debt to assets, Debt to equity, Dividend yield, Earnings yield, Enterprise value,
Enterprise value over EBITDA, Ev to free cash flow, Ev to operating cash flow, Ev to sales,
Free cash flow per share, Free cash flow yield, Graham net net, Graham number, Income quality,
Intangibles to total assets, Interest debt per share, Inventory turnover, Market cap, Net
current asset value, Net debt to EBITDA, Net income per share, Operating cash flow per share,
Payables turnover, Payout ratio, Pb ratio, Pe ratio, Pfcf ratio, Pocfratio, Price to sales ratio,
Ptb ratio, Receivables turnover, Research and ddevelopement to revenue, Return on tangible assets,
Revenue per share, Roe, Roic, Sales general and administrative to revenue, Shareholders equity per
share, Stock based compensation to revenue, Tangible book value per share, and Working capital.
[Source: Financial Modeling Prep]
per share, Current ratio, Days of inventory on hand, Days payables outstanding, Days
sales outstanding, Debt to assets, Debt to equity, Dividend yield, Earnings yield,
Enterprise value, Enterprise value over EBITDA, Ev to free cash flow, Ev to operating
cash flow, Ev to sales, Free cash flow per share, Free cash flow yield, Graham net net,
Graham number, Income quality, Intangibles to total assets, Interest debt per share,
Inventory turnover, Market cap, Net current asset value, Net debt to EBITDA, Net income
per share, Operating cash flow per share, Payables turnover, Payout ratio, Pb ratio, Pe
ratio, Pfcf ratio, Pocfratio, Price to sales ratio, Ptb ratio, Receivables turnover,
Research and ddevelopement to revenue, Return on tangible assets, Revenue per share,
Roe, Roic, Sales general and administrative to revenue, Shareholders equity per
share, Stock based compensation to revenue, Tangible book value per share, and Working
capital. [Source: Financial Modeling Prep]
""",
)
@@ -529,11 +442,7 @@ def key_metrics(l_args, s_ticker):
)
try:
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
return
ns_parser = parse_known_args_and_warn(parser, l_args)
if ns_parser.n_num == 1:
pd.set_option("display.max_colwidth", -1)
@@ -547,24 +456,9 @@ def key_metrics(l_args, s_ticker):
else:
df_fa = fa.key_metrics(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP)
df_fa = df_fa.iloc[:, 0 : ns_parser.n_num]
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num * ["None"])).dropna()
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num * ["0"])).dropna()
df_fa = df_fa.applymap(lambda x: long_number_format(x))
df_fa.index = [
"".join(
" " + char if char.isupper() else char.strip() for char in idx
).strip()
for idx in df_fa.index.tolist()
]
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
df_fa.columns.name = "Fiscal Date Ending"
df_fa = df_fa.rename(
index={"Enterprise value over e b i t d a": "Enterprise value over EBITDA"}
)
df_fa = df_fa.rename(index={"Net debt to e b i t d a": "Net debt to EBITDA"})
print(df_fa)
df_fa = clean_metrics_df(df_fa, num=ns_parser.n_num)
print(df_fa)
print("")
except Exception as e:
@@ -573,28 +467,28 @@ def key_metrics(l_args, s_ticker):
return
# ---------------------------------------------------- FINANCIAL_RATIOS ----------------------------------------------------
def financial_ratios(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="ratios",
description="""
Prints in-depth ratios of a company over time. This can be either
quarterly or annually. This contains, among other things, Price-to-Book Ratio, Payout
Ratio and Operating Cycle. The following fields are expected: Asset turnover, Capital
expenditure coverage ratio, Cash conversion cycle, Cash flow coverage ratios, Cash flow
to debt ratio, Cash per share, Cash ratio, Company equity multiplier, Current ratio,
Days of inventory outstanding, Days of payables outstanding, Days of sales outstanding,
Debt equity ratio, Debt ratio, Dividend paid and capex coverage ratio, Dividend payout ratio,
Dividend yield, Ebit per revenue, Ebt per ebit, Effective tax rate, Enterprise value multiple,
Fixed asset turnover, Free cash flow operating cash flow ratio, Free cash flow per share, Gross
profit margin, Inventory turnover, Long term debt to capitalization, Net income per EBT, Net
profit margin, Operating cash flow per share, Operating cash flow sales ratio, Operating cycle,
Operating profit margin, Payables turnover, Payout ratio, Pretax profit margin, Price book value
ratio, Price cash flow ratio, Price earnings ratio, Price earnings to growth ratio, Price fair value,
Price sales ratio, Price to book ratio, Price to free cash flows ratio, Price to operating cash flows
ratio, Price to sales ratio, Quick ratio, Receivables turnover, Return on assets, Return on capital
employed, Return on equity, Short term coverage ratios, and Total debt to capitalization.
[Source: Financial Modeling Prep]
Prints in-depth ratios of a company over time. This can be either quarterly or
annually. This contains, among other things, Price-to-Book Ratio, Payout Ratio and
Operating Cycle. The following fields are expected: Asset turnover, Capital expenditure
coverage ratio, Cash conversion cycle, Cash flow coverage ratios, Cash flow to debt
ratio, Cash per share, Cash ratio, Company equity multiplier, Current ratio, Days of
inventory outstanding, Days of payables outstanding, Days of sales outstanding, Debt
equity ratio, Debt ratio, Dividend paid and capex coverage ratio, Dividend payout ratio,
Dividend yield, Ebit per revenue, Ebt per ebit, Effective tax rate, Enterprise value
multiple, Fixed asset turnover, Free cash flow operating cash flow ratio, Free cash
flow per share, Gross profit margin, Inventory turnover, Long term debt to
capitalization, Net income per EBT, Net profit margin, Operating cash flow per share,
Operating cash flow sales ratio, Operating cycle, Operating profit margin, Payables
turnover, Payout ratio, Pretax profit margin, Price book value ratio, Price cash flow
ratio, Price earnings ratio, Price earnings to growth ratio, Price fair value,
Price sales ratio, Price to book ratio, Price to free cash flows ratio, Price to
operating cash flows ratio, Price to sales ratio, Quick ratio, Receivables turnover,
Return on assets, Return on capital employed, Return on equity, Short term coverage
ratios, and Total debt to capitalization. [Source: Financial Modeling Prep]
""",
)
@@ -617,11 +511,7 @@ def financial_ratios(l_args, s_ticker):
)
try:
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
return
ns_parser = parse_known_args_and_warn(parser, l_args)
if ns_parser.n_num == 1:
pd.set_option("display.max_colwidth", -1)
@@ -635,21 +525,9 @@ def financial_ratios(l_args, s_ticker):
else:
df_fa = fa.financial_ratios(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP)
df_fa = df_fa.iloc[:, 0 : ns_parser.n_num]
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num * ["None"])).dropna()
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num * ["0"])).dropna()
df_fa = df_fa.applymap(lambda x: long_number_format(x))
df_fa.index = [
"".join(
" " + char if char.isupper() else char.strip() for char in idx
).strip()
for idx in df_fa.index.tolist()
]
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
df_fa.columns.name = "Fiscal Date Ending"
df_fa = df_fa.rename(index={"Net income per e b t": "Net income per EBT"})
print(df_fa)
df_fa = clean_metrics_df(df_fa, num=ns_parser.n_num)
print(df_fa)
print("")
except Exception as e:
@@ -658,25 +536,24 @@ def financial_ratios(l_args, s_ticker):
return
# ---------------------------------------------------- FINANCIAL_STATEMENT_GROWTH ----------------------------------------------------
def financial_statement_growth(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="growth",
description="""
Prints the growth of several financial statement items and ratios over time. This can be
either annually and quarterly. These are, among other things, Revenue Growth (3, 5 and 10 years),
inventory growth and operating cash flow growth (3, 5 and 10 years). The following fields
are expected: Asset growth, Book valueper share growth, Debt growth, Dividendsper share growth,
Ebitgrowth, Epsdiluted growth, Epsgrowth, Five y dividendper share growth per share, Five y net
income growth per share, Five y operating c f growth per share, Five y revenue growth per share,
Five y shareholders equity growth per share, Free cash flow growth, Gross profit growth, Inventory
growth, Net income growth, Operating cash flow growth, Operating income growth, Rdexpense growth,
Receivables growth, Revenue growth, Sgaexpenses growth, Ten y dividendper share growth per share,
Ten y net income growth per share, Ten y operating c f growth per share, Ten y revenue growth per
share, Ten y shareholders equity growth per share, Three y dividendper share growth per share,
Three y net income growth per share, Three y operating c f growth per share, Three y revenue growth
per share, Three y shareholders equity growth per share, Weighted average shares diluted growth,
and Weighted average shares growth [Source: Financial Modeling Prep]
description=""" Prints the growth of several financial statement items and ratios over
time. This can be either annually and quarterly. These are, among other things, Revenue
Growth (3, 5 and 10 years), inventory growth and operating cash flow growth (3, 5 and 10
years). The following fields are expected: Asset growth, Book valueper share growth, Debt
growth, Dividendsper share growth, Ebitgrowth, Epsdiluted growth, Epsgrowth, Five y
dividendper share growth per share, Five y net income growth per share, Five y operating c
f growth per share, Five y revenue growth per share, Five y shareholders equity growth per
share, Free cash flow growth, Gross profit growth, Inventory growth, Net income growth,
Operating cash flow growth, Operating income growth, Rdexpense growth, Receivables growth,
Revenue growth, Sgaexpenses growth, Ten y dividendper share growth per share, Ten y net
income growth per share, Ten y operating c f growth per share, Ten y revenue growth per
share, Ten y shareholders equity growth per share, Three y dividendper share growth per
share, Three y net income growth per share, Three y operating c f growth per share, Three y
revenue growth per share, Three y shareholders equity growth per share, Weighted average
shares diluted growth, and Weighted average shares growth [Source: Financial Modeling Prep]
""",
)
@@ -699,11 +576,7 @@ def financial_statement_growth(l_args, s_ticker):
)
try:
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
return
ns_parser = parse_known_args_and_warn(parser, l_args)
if ns_parser.n_num == 1:
pd.set_option("display.max_colwidth", -1)
@@ -719,23 +592,31 @@ def financial_statement_growth(l_args, s_ticker):
s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP
)
df_fa = df_fa.iloc[:, 0 : ns_parser.n_num]
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num * ["None"])).dropna()
df_fa = df_fa.mask(df_fa.astype(object).eq(ns_parser.n_num * ["0"])).dropna()
df_fa = df_fa.applymap(lambda x: long_number_format(x))
df_fa.index = [
"".join(
" " + char if char.isupper() else char.strip() for char in idx
).strip()
for idx in df_fa.index.tolist()
]
df_fa.index = [s_val.capitalize() for s_val in df_fa.index]
df_fa.columns.name = "Fiscal Date Ending"
print(df_fa)
df_fa = clean_metrics_df(df_fa, num=ns_parser.n_num)
print(df_fa)
print("")
except Exception as e:
print(e)
print("")
return
def clean_metrics_df(df_fa: pd.DataFrame, num: int, mask: bool = True) -> pd.DataFrame:
df_fa = df_fa.iloc[:, 0:num]
if mask:
df_fa = df_fa.mask(df_fa.astype(object).eq(num * ["None"])).dropna()
df_fa = df_fa.mask(df_fa.astype(object).eq(num * ["0"])).dropna()
df_fa = df_fa.applymap(lambda x: long_number_format(x))
clean_df_index(df_fa)
df_fa.columns.name = "Fiscal Date Ending"
df_fa = df_fa.rename(
index={
"Enterprise value over e b i t d a": "Enterprise value over EBITDA",
"Net debt to e b i t d a": "Net debt to EBITDA",
"D c f": "DCF",
"Net income per e b t": "Net income per EBT",
}
)
return df_fa

View File

@@ -1,9 +1,9 @@
import argparse
import finviz
import pandas as pd
from gamestonk_terminal.helper_funcs import parse_known_args_and_warn
# ---------------------------------------------------- SCREENER ----------------------------------------------------
def screener(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="screener",
@@ -23,11 +23,7 @@ def screener(l_args, s_ticker):
)
try:
(_, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
return
parse_known_args_and_warn(parser, l_args)
d_finviz_stock = finviz.get_stock(s_ticker)
df_fa = pd.DataFrame.from_dict(

View File

@@ -1,30 +1,33 @@
import argparse
import re
import requests
import pandas as pd
from bs4 import BeautifulSoup
from gamestonk_terminal.helper_funcs import get_user_agent
from gamestonk_terminal.helper_funcs import get_user_agent, parse_known_args_and_warn
# ---------------------------------------------------- INCOME ----------------------------------------------------
def income(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="income",
description="""
Prints either yearly or quarterly income statement the company.
The following fields are expected: Sales Growth, Cost of Goods Sold (COGS) incl. D&A,
COGS Growth, COGS excluding D&A, Depreciation & Amortization Expense, Depreciation,
Amortization of Intangibles, Gross Income, Gross Income Growth, Gross Profit Margin,
SG&A Expense, SGA Growth, Research & Development, Other SG&A, Other Operating Expense,
Unusual Expense, EBIT after Unusual Expense, Non Operating Income/Expense, Non-Operating
Interest Income, Equity in Affiliates (Pretax), Interest Expense, Interest Expense Growth,
Gross Interest Expense, Interest Capitalized, Pretax Income, Pretax Income Growth, Pretax Margin,
Income Tax, Income Tax - Current Domestic, Income Tax - Current Foreign, Income Tax - Deferred
Domestic, Income Tax - Deferred Foreign, Income Tax Credits, Equity in Affiliates, Other After
Tax Income (Expense), Consolidated Net Income, Minority Interest Expense, Net Income Growth,
Net Margin Growth, Extraordinaries & Discontinued Operations, Extra Items & Gain/Loss Sale Of Assets,
Cumulative Effect - Accounting Chg, Discontinued Operations, Net Income After Extraordinaries,
Prints either yearly or quarterly income statement the company. The following fields
are expected: Sales Growth, Cost of Goods Sold (COGS) incl. D&A, COGS Growth, COGS
excluding D&A, Depreciation & Amortization Expense, Depreciation, Amortization of
Intangibles, Gross Income, Gross Income Growth, Gross Profit Margin, SG&A Expense, SGA
Growth, Research & Development, Other SG&A, Other Operating Expense, Unusual Expense,
EBIT after Unusual Expense, Non Operating Income/Expense, Non-Operating Interest
Income, Equity in Affiliates (Pretax), Interest Expense, Interest Expense Growth,
Gross Interest Expense, Interest Capitalized, Pretax Income, Pretax Income Growth,
Pretax Margin, Income Tax, Income Tax - Current Domestic, Income Tax - Current Foreign,
Income Tax - Deferred Domestic, Income Tax - Deferred Foreign, Income Tax Credits,
Equity in Affiliates, Other After Tax Income (Expense), Consolidated Net Income,
Minority Interest Expense, Net Income Growth, Net Margin Growth, Extraordinaries &
Discontinued Operations, Extra Items & Gain/Loss Sale Of Assets, Cumulative Effect -
Accounting Chg, Discontinued Operations, Net Income After Extraordinaries,
Preferred Dividends, Net Income Available to Common, EPS (Basic), EPS (Basic) Growth,
Basic Shares Outstanding, EPS (Diluted), EPS (Diluted) Growth, Diluted Shares Outstanding, EBITDA,
EBITDA Growth, EBITDA Margin, Sales/Revenue, and Net Income. [Source: Market Watch]
Basic Shares Outstanding, EPS (Diluted), EPS (Diluted) Growth, Diluted Shares
Outstanding, EBITDA, EBITDA Growth, EBITDA Margin, Sales/Revenue, and Net Income.
[Source: Market Watch]
""",
)
@@ -38,43 +41,16 @@ def income(l_args, s_ticker):
)
try:
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
return
ns_parser = parse_known_args_and_warn(parser, l_args)
if ns_parser.b_quarter:
url_financials = f"https://www.marketwatch.com/investing/stock/{s_ticker}/financials/income/quarter"
else:
url_financials = f"https://www.marketwatch.com/investing/stock/{s_ticker}/financials/income"
text_soup_financials = BeautifulSoup(
requests.get(url_financials, headers={"User-Agent": get_user_agent()}).text,
"lxml",
)
df_financials = prepare_df_financials(url_financials, ns_parser.b_quarter)
# Define financials columns
a_financials_header = list()
for financials_header in text_soup_financials.findAll(
"th", {"class": "overflow__heading"}
):
a_financials_header.append(
financials_header.text.strip("\n").split("\n")[0]
)
df_financials = pd.DataFrame(columns=a_financials_header[0:-1])
# Add financials values
soup_financials = text_soup_financials.findAll("tr", {"class": "table__row "})
soup_financials += text_soup_financials.findAll(
"tr", {"class": "table__row is-highlighted"}
)
for financials_info in soup_financials:
a_financials_info = financials_info.text.split("\n")
l_financials = [a_financials_info[2]]
l_financials.extend(a_financials_info[5:-2])
# Append data values to financials
df_financials.loc[len(df_financials.index)] = l_financials
df_financials = df_financials.drop(index="Item")
print(df_financials.to_string(index=False))
print("")
@@ -85,22 +61,22 @@ def income(l_args, s_ticker):
return
# ---------------------------------------------------- ASSETS ----------------------------------------------------
def assets(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="assets",
description="""
Prints either yearly or quarterly assets from balance sheet of the company.
The following fields are expected: Cash & Short Term Investments, Cash & Short Term Investments
Growth, Cash Only, Short-Term Investments, Cash & ST Investments / Total Assets, Total Accounts
Receivable, Total Accounts Receivable Growth, Accounts Receivables, Net, Accounts Receivables,
Gross, Bad Debt/Doubtful Accounts, Other Receivable, Accounts Receivable Turnover, Inventories,
Finished Goods, Work in Progress, Raw Materials, Progress Payments & Other, Other Current Assets,
Miscellaneous Current Assets, Net Property, Plant & Equipment, Property, Plant & Equipment - Gross,
Buildings, Land & Improvements, Computer Software and Equipment, Other Property, Plant & Equipment,
Accumulated Depreciation, Total Investments and Advances, Other Long-Term Investments,
Long-Term Note Receivables, Intangible Assets, Net Goodwill, Net Other Intangibles, Other Assets
[Source: Market Watch]
The following fields are expected: Cash & Short Term Investments, Cash & Short Term
Investments Growth, Cash Only, Short-Term Investments, Cash & ST Investments / Total
Assets, Total Accounts Receivable, Total Accounts Receivable Growth, Accounts
Receivables, Net, Accounts Receivables, Gross, Bad Debt/Doubtful Accounts, Other
Receivable, Accounts Receivable Turnover, Inventories, Finished Goods, Work in
Progress, Raw Materials, Progress Payments & Other, Other Current Assets,
Miscellaneous Current Assets, Net Property, Plant & Equipment, Property, Plant &
Equipment - Gross, Buildings, Land & Improvements, Computer Software and Equipment,
Other Property, Plant & Equipment, Accumulated Depreciation, Total Investments and
Advances, Other Long-Term Investments, Long-Term Note Receivables, Intangible Assets,
Net Goodwill, Net Other Intangibles, Other Assets [Source: Market Watch]
""",
)
@@ -114,50 +90,16 @@ def assets(l_args, s_ticker):
)
try:
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}")
ns_parser = parse_known_args_and_warn(parser, l_args)
if ns_parser.b_quarter:
url_financials = f"https://www.marketwatch.com/investing/stock/{s_ticker}/financials/balance-sheet/quarter"
else:
url_financials = f"https://www.marketwatch.com/investing/stock/{s_ticker}/financials/balance-sheet"
text_soup_financials = BeautifulSoup(
requests.get(url_financials, headers={"User-Agent": get_user_agent()}).text,
"lxml",
)
df_financials = prepare_df_financials(url_financials, ns_parser.b_quarter)
# Define financials columns
a_financials_header = list()
for financials_header in text_soup_financials.findAll(
"th", {"class": "overflow__heading"}
):
a_financials_header.append(
financials_header.text.strip("\n").split("\n")[0]
)
s_header_end_trend = ("5-year trend", "5- qtr trend")[ns_parser.b_quarter]
df_financials = pd.DataFrame(
columns=a_financials_header[
0 : a_financials_header.index(s_header_end_trend)
]
)
# Add financials values
soup_financials = text_soup_financials.findAll("tr", {"class": "table__row "})
soup_financials += text_soup_financials.findAll(
"tr", {"class": "table__row is-highlighted"}
)
for financials_info in soup_financials:
a_financials_info = financials_info.text.split("\n")
l_financials = [a_financials_info[2]]
l_financials.extend(a_financials_info[5:-2])
# Append data values to financials
df_financials.loc[len(df_financials.index)] = l_financials
# Set item name as index
df_financials = df_financials.set_index("Item")
df_financials.drop(index="Item")
print(df_financials.iloc[:33].to_string())
print("")
@@ -168,25 +110,27 @@ def assets(l_args, s_ticker):
return
# ---------------------------------------------------- LIABILITIES ----------------------------------------------------
def liabilities(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="liabilities",
description="""
Prints either yearly or quarterly liablities and shareholders' equity from balance sheet of the company.
The following fields are expected: ST Debt & Current Portion LT Debt, Short Term Debt,
Current Portion of Long Term Debt, Accounts Payable, Accounts Payable Growth, Income Tax Payable,
Other Current Liabilities, Dividends Payable, Accrued Payroll, Miscellaneous Current Liabilities,
Long-Term Debt, Long-Term Debt excl. Capitalized Leases, Non-Convertible Debt, Convertible Debt,
Capitalized Lease Obligations, Provision for Risks & Charges, Deferred Taxes, Deferred Taxes - Credits,
Deferred Taxes - Debit, Other Liabilities, Other Liabilities (excl. Deferred Income), Deferred Income,
Non-Equity Reserves, Total Liabilities / Total Assets, Preferred Stock (Carrying Value),
Redeemable Preferred Stock, Non-Redeemable Preferred Stock, Common Equity (Total), Common Equity/Total Assets,
Common Stock Par/Carry Value, Retained Earnings, ESOP Debt Guarantee, Cumulative Translation
Adjustment/Unrealized For. Exch. Gain, Unrealized Gain/Loss Marketable Securities, Revaluation Reserves,
Treasury Stock, Total Shareholders' Equity, Total Shareholders' Equity / Total Assets,
Accumulated Minority Interest, Total Equity, Total Current Assets, Total Assets, Total Current Liabilities,
Total Liabilities, and Liabilities & Shareholders' Equity. [Source: Market Watch]
Prints either yearly or quarterly liablities and shareholders' equity from balance
sheet of the company. The following fields are expected: ST Debt & Current Portion LT
Debt, Short Term Debt, Current Portion of Long Term Debt, Accounts Payable, Accounts
Payable Growth, Income Tax Payable, Other Current Liabilities, Dividends Payable,
Accrued Payroll, Miscellaneous Current Liabilities, Long-Term Debt, Long-Term Debt
excl. Capitalized Leases, Non-Convertible Debt, Convertible Debt, Capitalized Lease
Obligations, Provision for Risks & Charges, Deferred Taxes, Deferred Taxes - Credits,
Deferred Taxes - Debit, Other Liabilities, Other Liabilities (excl. Deferred Income),
Deferred Income, Non-Equity Reserves, Total Liabilities / Total Assets, Preferred Stock
(Carrying Value), Redeemable Preferred Stock, Non-Redeemable Preferred Stock, Common
Equity (Total), Common Equity/Total Assets, Common Stock Par/Carry Value, Retained
Earnings, ESOP Debt Guarantee, Cumulative Translation Adjustment/Unrealized For. Exch.
Gain, Unrealized Gain/Loss Marketable Securities, Revaluation Reserves, Treasury Stock,
Total Shareholders' Equity, Total Shareholders' Equity / Total Assets, Accumulated
Minority Interest, Total Equity, Total Current Assets, Total Assets, Total Current
Liabilities, Total Liabilities, and Liabilities & Shareholders' Equity. [Source: Market
Watch]
""",
)
@@ -200,51 +144,14 @@ def liabilities(l_args, s_ticker):
)
try:
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
return
ns_parser = parse_known_args_and_warn(parser, l_args)
if ns_parser.b_quarter:
url_financials = f"https://www.marketwatch.com/investing/stock/{s_ticker}/financials/balance-sheet/quarter"
else:
url_financials = f"https://www.marketwatch.com/investing/stock/{s_ticker}/financials/balance-sheet"
text_soup_financials = BeautifulSoup(
requests.get(url_financials, headers={"User-Agent": get_user_agent()}).text,
"lxml",
)
# Define financials columns
a_financials_header = list()
for financials_header in text_soup_financials.findAll(
"th", {"class": "overflow__heading"}
):
a_financials_header.append(
financials_header.text.strip("\n").split("\n")[0]
)
s_header_end_trend = ("5-year trend", "5- qtr trend")[ns_parser.b_quarter]
df_financials = pd.DataFrame(
columns=a_financials_header[
0 : a_financials_header.index(s_header_end_trend)
]
)
# Add financials values
soup_financials = text_soup_financials.findAll("tr", {"class": "table__row "})
soup_financials += text_soup_financials.findAll(
"tr", {"class": "table__row is-highlighted"}
)
for financials_info in soup_financials:
a_financials_info = financials_info.text.split("\n")
l_financials = [a_financials_info[2]]
l_financials.extend(a_financials_info[5:-2])
# Append data values to financials
df_financials.loc[len(df_financials.index)] = l_financials
# Set item name as index
df_financials = df_financials.set_index("Item")
df_financials = prepare_df_financials(url_financials, ns_parser.b_quarter)
print(df_financials.iloc[34:].to_string())
print("")
@@ -255,17 +162,17 @@ def liabilities(l_args, s_ticker):
return
# ---------------------------------------------------- OPERATING ----------------------------------------------------
def operating(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="operating",
description="""
Prints either yearly or quarterly cash flow operating activities of the company.
The following fields are expected: Net Income before Extraordinaries, Net Income Growth, Depreciation,
Depletion & Amortization, Depreciation and Depletion, Amortization of Intangible Assets,
Deferred Taxes & Investment Tax Credit, Deferred Taxes, Investment Tax Credit, Other Funds,
Funds from Operations, Extraordinaries, Changes in Working Capital, Receivables, Accounts Payable,
Other Assets/Liabilities, and Net Operating Cash Flow Growth. [Source: Market Watch]
The following fields are expected: Net Income before Extraordinaries, Net Income
Growth, Depreciation, Depletion & Amortization, Depreciation and Depletion,
Amortization of Intangible Assets, Deferred Taxes & Investment Tax Credit, Deferred
Taxes, Investment Tax Credit, Other Funds, Funds from Operations, Extraordinaries,
Changes in Working Capital, Receivables, Accounts Payable, Other Assets/Liabilities,
and Net Operating Cash Flow Growth. [Source: Market Watch]
""",
)
@@ -279,55 +186,16 @@ def operating(l_args, s_ticker):
)
try:
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
return
ns_parser = parse_known_args_and_warn(parser, l_args)
if ns_parser.b_quarter:
url_financials = f"https://www.marketwatch.com/investing/stock/{s_ticker}/financials/cash-flow/quarter"
else:
url_financials = f"https://www.marketwatch.com/investing/stock/{s_ticker}/financials/cash-flow"
text_soup_financials = BeautifulSoup(
requests.get(url_financials, headers={"User-Agent": get_user_agent()}).text,
"lxml",
)
df_financials = prepare_df_financials(url_financials, ns_parser.b_quarter)
# Define financials columns
a_financials_header = list()
for financials_header in text_soup_financials.findAll(
"th", {"class": "overflow__heading"}
):
a_financials_header.append(
financials_header.text.strip("\n").split("\n")[0]
)
s_header_end_trend = ("5-year trend", "5- qtr trend")[ns_parser.b_quarter]
df_financials = pd.DataFrame(
columns=a_financials_header[
0 : a_financials_header.index(s_header_end_trend)
]
)
# Add financials values
soup_financials = text_soup_financials.findAll("tr", {"class": "table__row "})
soup_financials += text_soup_financials.findAll(
"tr", {"class": "table__row is-highlighted"}
)
for financials_info in soup_financials:
a_financials_info = financials_info.text.split("\n")
l_financials = [a_financials_info[2]]
l_financials.extend(a_financials_info[5:-2])
n_vals_to_add = len(df_financials.columns) - len(l_financials)
if n_vals_to_add > 0:
l_financials.append(n_vals_to_add * " ")
# Append data values to financials
df_financials.loc[len(df_financials.index)] = l_financials
# Set item name as index
df_financials = df_financials.set_index("Item")
df_financials.drop(index="Item")
print(df_financials.iloc[:16].to_string())
print("")
@@ -338,17 +206,16 @@ def operating(l_args, s_ticker):
return
# ---------------------------------------------------- INVESTING ----------------------------------------------------
def investing(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="investing",
description="""
Prints either yearly or quarterly cash flow investing activities of the company.
The following fields are expected: Capital Expenditures, Capital Expenditures Growth, Capital
Expenditures/Sales, Capital Expenditures (Fixed Assets), Capital Expenditures (Other Assets),
Net Assets from Acquisitions, Sale of Fixed Assets & Businesses, Purchase/Sale of Investments,
Purchase of Investments, Sale/Maturity of Investments, Other Uses, Other Sources, Net Investing
Cash Flow Growth. [Source: Market Watch]
The following fields are expected: Capital Expenditures, Capital Expenditures Growth,
Capital Expenditures/Sales, Capital Expenditures (Fixed Assets), Capital Expenditures
(Other Assets), Net Assets from Acquisitions, Sale of Fixed Assets & Businesses,
Purchase/Sale of Investments, Purchase of Investments, Sale/Maturity of Investments,
Other Uses, Other Sources, Net Investing Cash Flow Growth. [Source: Market Watch]
""",
)
@@ -362,55 +229,14 @@ def investing(l_args, s_ticker):
)
try:
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
return
ns_parser = parse_known_args_and_warn(parser, l_args)
if ns_parser.b_quarter:
url_financials = f"https://www.marketwatch.com/investing/stock/{s_ticker}/financials/cash-flow/quarter"
else:
url_financials = f"https://www.marketwatch.com/investing/stock/{s_ticker}/financials/cash-flow"
text_soup_financials = BeautifulSoup(
requests.get(url_financials, headers={"User-Agent": get_user_agent()}).text,
"lxml",
)
# Define financials columns
a_financials_header = list()
for financials_header in text_soup_financials.findAll(
"th", {"class": "overflow__heading"}
):
a_financials_header.append(
financials_header.text.strip("\n").split("\n")[0]
)
s_header_end_trend = ("5-year trend", "5- qtr trend")[ns_parser.b_quarter]
df_financials = pd.DataFrame(
columns=a_financials_header[
0 : a_financials_header.index(s_header_end_trend)
]
)
# Add financials values
soup_financials = text_soup_financials.findAll("tr", {"class": "table__row "})
soup_financials += text_soup_financials.findAll(
"tr", {"class": "table__row is-highlighted"}
)
for financials_info in soup_financials:
a_financials_info = financials_info.text.split("\n")
l_financials = [a_financials_info[2]]
l_financials.extend(a_financials_info[5:-2])
n_vals_to_add = len(df_financials.columns) - len(l_financials)
if n_vals_to_add > 0:
l_financials.append(n_vals_to_add * " ")
# Append data values to financials
df_financials.loc[len(df_financials.index)] = l_financials
# Set item name as index
df_financials = df_financials.set_index("Item")
df_financials = prepare_df_financials(url_financials, ns_parser.b_quarter)
print(df_financials.iloc[17:30].to_string())
print("")
@@ -421,20 +247,20 @@ def investing(l_args, s_ticker):
return
# ---------------------------------------------------- FINANCING ----------------------------------------------------
def financing(l_args, s_ticker):
parser = argparse.ArgumentParser(
prog="financing",
description="""
Prints either yearly or quarterly cash flow financing activities of the company.
The following fields are expected: Cash Dividends Paid - Total, Common Dividends, Preferred Dividends,
Change in Capital Stock, Repurchase of Common & Preferred Stk., Sale of Common & Preferred Stock,
Proceeds from Stock Options, Other Proceeds from Sale of Stock, Issuance/Reduction of Debt, Net,
Change in Current Debt, Change in Long-Term Debt, Issuance of Long-Term Debt, Reduction in Long-Term Debt,
Other Funds, Other Uses, Other Sources, Net Financing Cash Flow Growth, Net Financing Cash Flow/Sales,
Exchange Rate Effect, Miscellaneous Funds, Net Change in Cash, Free Cash Flow, Free Cash Flow Growth,
Free Cash Flow Yield, Net Operating Cash Flow, Net Investing Cash Flow, Net Financing Cash Flow
[Source: Market Watch]
The following fields are expected: Cash Dividends Paid - Total, Common Dividends,
Preferred Dividends, Change in Capital Stock, Repurchase of Common & Preferred Stk.,
Sale of Common & Preferred Stock, Proceeds from Stock Options, Other Proceeds from Sale
of Stock, Issuance/Reduction of Debt, Net, Change in Current Debt, Change in Long-Term
Debt, Issuance of Long-Term Debt, Reduction in Long-Term Debt, Other Funds, Other Uses,
Other Sources, Net Financing Cash Flow Growth, Net Financing Cash Flow/Sales, Exchange
Rate Effect, Miscellaneous Funds, Net Change in Cash, Free Cash Flow, Free Cash Flow
Growth, Free Cash Flow Yield, Net Operating Cash Flow, Net Investing Cash Flow, Net
Financing Cash Flow [Source: Market Watch]
""",
)
@@ -448,55 +274,14 @@ def financing(l_args, s_ticker):
)
try:
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}\n")
return
ns_parser = parse_known_args_and_warn(parser, l_args)
if ns_parser.b_quarter:
url_financials = f"https://www.marketwatch.com/investing/stock/{s_ticker}/financials/cash-flow/quarter"
else:
url_financials = f"https://www.marketwatch.com/investing/stock/{s_ticker}/financials/cash-flow"
text_soup_financials = BeautifulSoup(
requests.get(url_financials, headers={"User-Agent": get_user_agent()}).text,
"lxml",
)
# Define financials columns
a_financials_header = list()
for financials_header in text_soup_financials.findAll(
"th", {"class": "overflow__heading"}
):
a_financials_header.append(
financials_header.text.strip("\n").split("\n")[0]
)
s_header_end_trend = ("5-year trend", "5- qtr trend")[ns_parser.b_quarter]
df_financials = pd.DataFrame(
columns=a_financials_header[
0 : a_financials_header.index(s_header_end_trend)
]
)
# Add financials values
soup_financials = text_soup_financials.findAll("tr", {"class": "table__row "})
soup_financials += text_soup_financials.findAll(
"tr", {"class": "table__row is-highlighted"}
)
for financials_info in soup_financials:
a_financials_info = financials_info.text.split("\n")
l_financials = [a_financials_info[2]]
l_financials.extend(a_financials_info[5:-2])
n_vals_to_add = len(df_financials.columns) - len(l_financials)
if n_vals_to_add > 0:
l_financials.append(n_vals_to_add * " ")
# Append data values to financials
df_financials.loc[len(df_financials.index)] = l_financials
# Set item name as index
df_financials = df_financials.set_index("Item")
df_financials = prepare_df_financials(url_financials, ns_parser.b_quarter)
print(df_financials.iloc[31:].to_string())
print("")
@@ -505,3 +290,46 @@ def financing(l_args, s_ticker):
print(e)
print("")
return
def prepare_df_financials(url_financials: str, quarter: bool) -> pd.DataFrame:
text_soup_financials = BeautifulSoup(
requests.get(url_financials, headers={"User-Agent": get_user_agent()}).text,
"lxml",
)
# Define financials columns
a_financials_header = list()
for financials_header in text_soup_financials.findAll(
"th", {"class": "overflow__heading"}
):
a_financials_header.append(financials_header.text.strip("\n").split("\n")[0])
s_header_end_trend = ("5-year trend", "5- qtr trend")[quarter]
df_financials = pd.DataFrame(
columns=a_financials_header[0 : a_financials_header.index(s_header_end_trend)]
)
# Add financials values
soup_financials = text_soup_financials.findAll(
lambda tag: tag.name == "tr" and tag.get("class") == ["table__row"]
)
soup_financials += text_soup_financials.findAll(
"tr", {"class": "table__row is-highlighted"}
)
for financials_info in soup_financials:
financials_row = financials_info.text.split("\n")
if len(financials_row) > 5:
for item in financials_row:
if bool(re.search(r"\d", item)):
a_financials_info = financials_info.text.split("\n")
l_financials = [a_financials_info[2]]
l_financials.extend(a_financials_info[5:-2])
# Append data values to financials
df_financials.loc[len(df_financials.index)] = l_financials
break
# Set item name as index
df_financials = df_financials.set_index("Item")
return df_financials

View File

@@ -455,6 +455,7 @@ def main():
ts = TimeSeries(
key=cfg.API_KEY_ALPHAVANTAGE, output_format="pandas"
)
# pylint: disable=unbalanced-tuple-unpacking
df_stock_pred, _ = ts.get_daily_adjusted(
symbol=s_ticker, outputsize="full"
)
@@ -465,8 +466,9 @@ def main():
df_stock_pred, s_ticker, s_start, s_interval="1440min"
)
except Exception as e:
print("Either the ticker or the API_KEY are invalids. Try again!")
print(e)
print("Either the ticker or the API_KEY are invalids. Try again!")
b_quit = False
return