Files
OpenBB/openbb_terminal/stocks/fundamental_analysis/fmp_view.py
montezdesousa 02901f1473 Trim command output spaces (#3424)
* first round of removing spaces

* remove more print statemnts

* remove more spaces

* bullbear color

* spacc color

* improve stalker readability

* delete more spaces

* reddit colors

* rever hood

* flake8

* forgot this one

* fix econometrics tests

* fix econometrics tests

* fix more tests

Co-authored-by: James Maslek <jmaslek11@gmail.com>
2022-11-16 11:47:24 +00:00

529 lines
16 KiB
Python

""" Financial Modeling Prep View """
__docformat__ = "numpy"
import logging
import os
import matplotlib.pyplot as plt
import pandas as pd
from openbb_terminal.config_terminal import theme
from openbb_terminal.config_plot import PLOT_DPI
from openbb_terminal.decorators import check_api_key
from openbb_terminal.decorators import log_start_end
from openbb_terminal.helper_funcs import export_data, print_rich_table, plot_autoscale
from openbb_terminal.rich_config import console
from openbb_terminal.stocks.fundamental_analysis import fmp_model
from openbb_terminal.helpers_denomination import (
transform as transform_by_denomination,
)
logger = logging.getLogger(__name__)
@log_start_end(log=logger)
@check_api_key(["API_KEY_FINANCIALMODELINGPREP"])
def valinvest_score(symbol: str):
"""Value investing tool based on Warren Buffett, Joseph Piotroski and Benjamin Graham thoughts [Source: FMP]
Parameters
----------
symbol : str
Fundamental analysis ticker symbol
"""
score = fmp_model.get_score(symbol)
if score:
console.print(f"Score: {score:.2f}".rstrip("0").rstrip(".") + " %")
@log_start_end(log=logger)
@check_api_key(["API_KEY_FINANCIALMODELINGPREP"])
def display_profile(symbol: str):
"""Financial Modeling Prep ticker profile
Parameters
----------
symbol : str
Fundamental analysis ticker symbol
"""
profile = fmp_model.get_profile(symbol)
if not profile.empty:
print_rich_table(
profile.drop(index=["description", "image"]),
headers=[""],
title=f"{symbol.upper()} Profile",
show_index=True,
)
console.print(f"\nImage: {profile.loc['image'][0]}")
console.print(f"\nDescription: {profile.loc['description'][0]}")
else:
logger.error("Could not get data")
console.print("[red]Unable to get data[/red]\n")
console.print()
@log_start_end(log=logger)
@check_api_key(["API_KEY_FINANCIALMODELINGPREP"])
def display_quote(symbol: str):
"""Financial Modeling Prep ticker quote
Parameters
----------
symbol : str
Fundamental analysis ticker symbol
"""
quote = fmp_model.get_quote(symbol)
if quote.empty:
console.print("[red]Data not found[/red]\n")
else:
print_rich_table(quote, headers=[""], title=f"{symbol} Quote", show_index=True)
@log_start_end(log=logger)
@check_api_key(["API_KEY_FINANCIALMODELINGPREP"])
def display_enterprise(
symbol: str, limit: int = 5, quarterly: bool = False, export: str = ""
):
"""Financial Modeling Prep ticker enterprise
Parameters
----------
symbol : str
Fundamental analysis ticker symbol
limit: int
Number to get
quarterly: bool
Flag to get quarterly data
export: str
Format to export data
"""
df_fa = fmp_model.get_enterprise(symbol, limit, quarterly)
df_fa = df_fa[df_fa.columns[::-1]]
# Re-order the returned columns so they are in a more logical ordering
df_fa = df_fa.reindex(
[
"Symbol",
"Stock price",
"Number of shares",
"Market capitalization",
"Add total debt",
"Minus cash and cash equivalents",
"Enterprise value",
]
)
if df_fa.empty:
console.print("[red]No data available[/red]\n")
else:
print_rich_table(
df_fa,
headers=list(df_fa.columns),
title=f"{symbol} Enterprise",
show_index=True,
)
export_data(
export, os.path.dirname(os.path.abspath(__file__)), "enterprise", df_fa
)
@log_start_end(log=logger)
@check_api_key(["API_KEY_FINANCIALMODELINGPREP"])
def display_discounted_cash_flow(
symbol: str, limit: int = 5, quarterly: bool = False, export: str = ""
):
"""Financial Modeling Prep ticker discounted cash flow
Parameters
----------
symbol : str
Fundamental analysis ticker symbol
limit: int
Number to get
quarterly: bool
Flag to get quarterly data
export: str
Format to export data
"""
dcf = fmp_model.get_dcf(symbol, limit, quarterly)
dcf = dcf[dcf.columns[::-1]]
dcf.columns = dcf.iloc[0].values
dcf = dcf.drop("Date")
if dcf.empty:
console.print("[red]No data available[/red]\n")
else:
print_rich_table(dcf, title="Discounted Cash Flow", show_index=True)
export_data(export, os.path.dirname(os.path.abspath(__file__)), "dcf", dcf)
@log_start_end(log=logger)
@check_api_key(["API_KEY_FINANCIALMODELINGPREP"])
def display_income_statement(
symbol: str,
limit: int = 5,
quarterly: bool = False,
ratios: bool = False,
plot: list = None,
export: str = "",
):
"""Financial Modeling Prep ticker income statement
Parameters
----------
symbol : str
Fundamental analysis ticker symbol
limit: int
Number to get
quarterly: bool
Flag to get quarterly data
ratios: bool
Shows percentage change, by default False
plot: list
List of row labels to plot
export: str
Format to export data
"""
income = fmp_model.get_income(symbol, limit, quarterly, ratios, bool(plot))
if not income.empty:
if plot:
income_plot_data = income[income.columns[::-1]]
rows_plot = len(plot)
income_plot_data = income_plot_data.transpose()
income_plot_data.columns = income_plot_data.columns.str.lower()
if not ratios:
(df_rounded, denomination) = transform_by_denomination(income_plot_data)
if denomination == "Units":
denomination = ""
else:
df_rounded = income_plot_data
denomination = ""
if rows_plot == 1:
fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
df_rounded[plot[0].replace("_", "")].plot()
title = (
f"{plot[0].replace('_', ' ').lower()} {'QoQ' if quarterly else 'YoY'} Growth of {symbol.upper()}"
if ratios
else f"{plot[0].replace('_', ' ')} of {symbol.upper()} {denomination}"
)
plt.title(title)
theme.style_primary_axis(ax)
theme.visualize_output()
else:
fig, axes = plt.subplots(rows_plot)
for i in range(rows_plot):
axes[i].plot(df_rounded[plot[i].replace("_", "")])
axes[i].set_title(f"{plot[i].replace('_', ' ')} {denomination}")
theme.style_primary_axis(axes[0])
fig.autofmt_xdate()
else:
income = income[income.columns[::-1]]
print_rich_table(
income.drop(index=["Final link", "Link"]),
headers=list(income.columns),
title=f"{symbol.upper()} Income Statement"
if not ratios
else f"{'QoQ' if quarterly else 'YoY'} Change of {symbol.upper()} Income Statement",
show_index=True,
)
pd.set_option("display.max_colwidth", None)
console.print(income.loc["Final link"].to_frame().to_string())
console.print()
console.print(income.loc["Link"].to_frame().to_string())
console.print()
export_data(
export, os.path.dirname(os.path.abspath(__file__)), "income", income
)
else:
logger.error("Could not get data")
console.print("[red]Could not get data[/red]\n")
@log_start_end(log=logger)
@check_api_key(["API_KEY_FINANCIALMODELINGPREP"])
def display_balance_sheet(
symbol: str,
limit: int = 5,
quarterly: bool = False,
ratios: bool = False,
plot: list = None,
export: str = "",
):
"""Financial Modeling Prep ticker balance sheet
Parameters
----------
symbol : str
Fundamental analysis ticker symbol
limit: int
Number to get
quarterly: bool
Flag to get quarterly data
ratios: bool
Shows percentage change, by default False
plot: list
List of row labels to plot
export: str
Format to export data
"""
balance = fmp_model.get_balance(symbol, limit, quarterly, ratios, bool(plot))
if not balance.empty:
if plot:
balance_plot_data = balance[balance.columns[::-1]]
rows_plot = len(plot)
balance_plot_data = balance_plot_data.transpose()
balance_plot_data.columns = balance_plot_data.columns.str.lower()
if not ratios:
(df_rounded, denomination) = transform_by_denomination(
balance_plot_data
)
if denomination == "Units":
denomination = ""
else:
df_rounded = balance_plot_data
denomination = ""
if rows_plot == 1:
fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
df_rounded[plot[0].replace("_", "")].plot()
title = (
f"{plot[0].replace('_', ' ').lower()} {'QoQ' if quarterly else 'YoY'} Growth of {symbol.upper()}"
if ratios
else f"{plot[0].replace('_', ' ')} of {symbol.upper()} {denomination}"
)
plt.title(title)
theme.style_primary_axis(ax)
theme.visualize_output()
else:
fig, axes = plt.subplots(rows_plot)
for i in range(rows_plot):
axes[i].plot(df_rounded[plot[i].replace("_", "")])
axes[i].set_title(f"{plot[i].replace('_', ' ')} {denomination}")
theme.style_primary_axis(axes[0])
fig.autofmt_xdate()
else:
balance = balance[balance.columns[::-1]]
print_rich_table(
balance.drop(index=["Final link", "Link"]),
headers=list(balance.columns),
title=f"{symbol.upper()} Balance Sheet",
show_index=True,
)
pd.set_option("display.max_colwidth", None)
console.print(balance.loc["Final link"].to_frame().to_string())
console.print()
console.print(balance.loc["Link"].to_frame().to_string())
console.print()
export_data(
export, os.path.dirname(os.path.abspath(__file__)), "balance", balance
)
else:
logger.error("Could not get data")
console.print("[red]Could not get data[/red]\n")
@log_start_end(log=logger)
@check_api_key(["API_KEY_FINANCIALMODELINGPREP"])
def display_cash_flow(
symbol: str,
limit: int = 5,
quarterly: bool = False,
ratios: bool = False,
plot: list = None,
export: str = "",
):
"""Financial Modeling Prep ticker cash flow
Parameters
----------
symbol : str
Fundamental analysis ticker symbol
limit: int
Number to get
quarterly: bool
Flag to get quarterly data
ratios: bool
Shows percentage change, by default False
plot: list
List of row labels to plot
export: str
Format to export data
"""
cash = fmp_model.get_cash(symbol, limit, quarterly, ratios, bool(plot))
if not cash.empty:
if plot:
cash_plot_data = cash[cash.columns[::-1]]
rows_plot = len(plot)
cash_plot_data = cash_plot_data.transpose()
cash_plot_data.columns = cash_plot_data.columns.str.lower()
if not ratios:
(df_rounded, denomination) = transform_by_denomination(cash_plot_data)
if denomination == "Units":
denomination = ""
else:
df_rounded = cash_plot_data
denomination = ""
if rows_plot == 1:
fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
df_rounded[plot[0].replace("_", "")].plot()
title = (
f"{plot[0].replace('_', ' ').lower()} {'QoQ' if quarterly else 'YoY'} Growth of {symbol.upper()}"
if ratios
else f"{plot[0].replace('_', ' ')} of {symbol.upper()} {denomination}"
)
plt.title(title)
theme.style_primary_axis(ax)
theme.visualize_output()
else:
fig, axes = plt.subplots(rows_plot)
for i in range(rows_plot):
axes[i].plot(df_rounded[plot[i].replace("_", "")])
axes[i].set_title(f"{plot[i].replace('_', ' ')} {denomination}")
theme.style_primary_axis(axes[0])
fig.autofmt_xdate()
else:
cash = cash[cash.columns[::-1]]
print_rich_table(
cash.drop(index=["Final link", "Link"]),
headers=list(cash.columns),
title=f"{symbol.upper()} Cash Flow",
show_index=True,
)
pd.set_option("display.max_colwidth", None)
console.print(cash.loc["Final link"].to_frame().to_string())
console.print()
console.print(cash.loc["Link"].to_frame().to_string())
console.print()
export_data(export, os.path.dirname(os.path.abspath(__file__)), "cash", cash)
else:
logger.error("Could not get data")
console.print("[red]Could not get data[/red]\n")
@log_start_end(log=logger)
@check_api_key(["API_KEY_FINANCIALMODELINGPREP"])
def display_key_metrics(
symbol: str, limit: int = 5, quarterly: bool = False, export: str = ""
):
"""Financial Modeling Prep ticker key metrics
Parameters
----------
symbol : str
Fundamental analysis ticker symbol
limit: int
Number to get
quarterly: bool
Flag to get quarterly data
export: str
Format to export data
"""
key_metrics = fmp_model.get_key_metrics(symbol, limit, quarterly)
if not key_metrics.empty:
key_metrics = key_metrics[key_metrics.columns[::-1]]
print_rich_table(
key_metrics,
headers=list(key_metrics.columns),
title=f"{symbol.upper()} Key Metrics",
show_index=True,
)
export_data(
export, os.path.dirname(os.path.abspath(__file__)), "metrics", key_metrics
)
else:
logger.error("Could not get data")
console.print("[red]Could not get data[/red]\n")
@log_start_end(log=logger)
@check_api_key(["API_KEY_FINANCIALMODELINGPREP"])
def display_financial_ratios(
symbol: str, limit: int = 5, quarterly: bool = False, export: str = ""
):
"""Financial Modeling Prep ticker ratios
Parameters
----------
symbol : str
Fundamental analysis ticker symbol
limit: int
Number to get
quarterly: bool
Flag to get quarterly data
export: str
Format to export data
"""
ratios = fmp_model.get_key_ratios(symbol, limit, quarterly)
if not ratios.empty:
ratios = ratios[ratios.columns[::-1]]
print_rich_table(
ratios,
headers=list(ratios.columns),
title=f"{symbol.upper()} Ratios",
show_index=True,
)
export_data(
export, os.path.dirname(os.path.abspath(__file__)), "grratiosowth", ratios
)
else:
logger.error("Could not get data")
console.print("[red]Could not get data[/red]\n")
@log_start_end(log=logger)
@check_api_key(["API_KEY_FINANCIALMODELINGPREP"])
def display_financial_statement_growth(
symbol: str, limit: int = 5, quarterly: bool = False, export: str = ""
):
"""Financial Modeling Prep ticker growth
Parameters
----------
symbol : str
Fundamental analysis ticker symbol
limit: int
Number to get
quarterly: bool
Flag to get quarterly data
export: str
Format to export data
"""
growth = fmp_model.get_financial_growth(symbol, limit, quarterly)
if not growth.empty:
growth = growth[growth.columns[::-1]]
print_rich_table(
growth,
headers=list(growth.columns),
title=f"{symbol.upper()} Growth",
show_index=True,
)
export_data(
export, os.path.dirname(os.path.abspath(__file__)), "growth", growth
)
else:
logger.error("Could not get data")
console.print("[red]Could not get data[/red]\n")