Files
OpenBB/gamestonk_terminal/fundamental_analysis/fa_controller.py

263 lines
8.0 KiB
Python

""" Fundamental Analysis Controller """
__docformat__ = "numpy"
import argparse
from typing import List
from prompt_toolkit.completion import NestedCompleter
from gamestonk_terminal.fundamental_analysis import alpha_vantage_controller as avc
from gamestonk_terminal.fundamental_analysis import business_insider_view as biw
from gamestonk_terminal.fundamental_analysis import (
financial_modeling_prep_controller as fmpc,
financial_modeling_prep_view as fmpv,
)
from gamestonk_terminal.fundamental_analysis import finviz_view
from gamestonk_terminal.fundamental_analysis import market_watch_view
from gamestonk_terminal.fundamental_analysis import yahoo_finance_view
from gamestonk_terminal import feature_flags as gtff
from gamestonk_terminal.helper_funcs import get_flair
from gamestonk_terminal.menu import session
class FundamentalAnalysisController:
"""Fundamental Analysis Controller"""
# Command choices
CHOICES = [
"help",
"q",
"quit",
"score",
"screener",
"income",
"balance",
"cash",
"mgmt",
"info",
"shrs",
"sust",
"cal",
"av",
"fmp",
]
def __init__(self, ticker: str, start: str, interval: str):
"""Constructor
Parameters
----------
ticker : str
Fundamental analysis ticker symbol
start : str
Stat date of the stock data
interval : str
Stock data interval
"""
self.ticker = ticker
self.start = start
self.interval = interval
self.fa_parser = argparse.ArgumentParser(add_help=False, prog="fa")
self.fa_parser.add_argument(
"cmd",
choices=self.CHOICES,
)
def print_help(self):
"""Print help"""
intraday = (f"Intraday {self.interval}", "Daily")[self.interval == "1440min"]
if self.start:
print(
f"\n{intraday} Stock: {self.ticker} (from {self.start.strftime('%Y-%m-%d')})"
)
else:
print(f"\n{intraday} Stock: {self.ticker}")
print(
"\nFundamental Analysis:"
) # https://github.com/JerBouma/FundamentalAnalysis
print(" help show this fundamental analysis menu again")
print(" q quit this menu, and shows back to main menu")
print(" quit quit to abandon program")
print("")
print(" screener screen info about the company [Finviz]")
print(" mgmt management team of the company [Business Insider]")
print(
" score investing score from Warren Buffett, Joseph Piotroski and Benjamin Graham [FMP]"
)
print("")
print("Market Watch API")
print(" income income statement of the company")
print(" balance balance sheet of the company")
print(" cash cash flow statement of the company")
print("")
print("Yahoo Finance API")
print(" info information scope of the company")
print(" shrs shareholders of the company")
print(" sust sustainability values of the company")
print(" cal calendar earnings and estimates of the company")
print("")
print("Other Sources:")
print("> av Alpha Vantage MENU")
print("> fmp Financial Modeling Prep MENU")
print("")
def switch(self, an_input: str):
"""Process and dispatch input
Returns
-------
True, False or None
False - quit the menu
True - quit the program
None - continue in the menu
"""
(known_args, other_args) = self.fa_parser.parse_known_args(an_input.split())
return getattr(
self, "call_" + known_args.cmd, lambda: "Command not recognized!"
)(other_args)
def call_help(self, _):
"""Process Help command"""
self.print_help()
def call_q(self, _):
"""Process Q command - quit the menu"""
return False
def call_quit(self, _):
"""Process Quit command - quit the program"""
return True
def call_mgmt(self, other_args: List[str]):
"""Process mgmt command"""
biw.management(other_args, self.ticker)
def call_screener(self, other_args: List[str]):
"""Process screener command"""
finviz_view.screener(other_args, self.ticker)
def call_score(self, other_args: List[str]):
"""Process score command"""
fmpv.valinvest_score(other_args, self.ticker)
def call_income(self, other_args: List[str]):
"""Process income command"""
market_watch_view.income(other_args, self.ticker)
def call_balance(self, other_args: List[str]):
"""Process balance command"""
market_watch_view.balance(other_args, self.ticker)
def call_cash(self, other_args: List[str]):
"""Process cash command"""
market_watch_view.cash(other_args, self.ticker)
def call_info(self, other_args: List[str]):
"""Process info command"""
yahoo_finance_view.info(other_args, self.ticker)
def call_shrs(self, other_args: List[str]):
"""Process shrs command"""
yahoo_finance_view.shareholders(other_args, self.ticker)
def call_sust(self, other_args: List[str]):
"""Process sust command"""
yahoo_finance_view.sustainability(other_args, self.ticker)
def call_cal(self, other_args: List[str]):
"""Process cal command"""
yahoo_finance_view.calendar_earnings(other_args, self.ticker)
# pylint: disable=unused-argument
def call_av(self, other_args: List[str]):
"""Process av command"""
ret = avc.menu(self.ticker, self.start, self.interval)
if ret is not True:
self.print_help()
# pylint: disable=unused-argument
def call_fmp(self, other_args: List[str]):
"""Process fmp command"""
ret = fmpc.menu(self.ticker, self.start, self.interval)
if ret is not True:
self.print_help()
def key_metrics_explained(other_args: List[str]):
parser = argparse.ArgumentParser(
add_help=False,
prog="info",
description="""
Provides information about main key metrics. Namely: EBITDA,
EPS, P/E, PEG, FCF, P/B, ROE, DPR, P/S, Dividend Yield Ratio, D/E, and Beta.
""",
)
try:
(_, l_unknown_args) = parser.parse_known_args(other_args)
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}")
filepath = "fundamental_analysis/key_metrics_explained.txt"
with open(filepath) as fp:
line = fp.readline()
while line:
print(f"{line.strip()}")
line = fp.readline()
print("")
except Exception as e:
print(e)
print("ERROR!\n")
return
def menu(ticker: str, start: str, interval: str):
"""Fundamental Analysis menu
Parameters
----------
ticker : str
Fundamental analysis ticker symbol
start : str
Start date of the stock data
interval : str
Stock data interval
"""
fa_controller = FundamentalAnalysisController(ticker, start, interval)
fa_controller.call_help(None)
while True:
# Get input command from user
if session and gtff.USE_PROMPT_TOOLKIT:
completer = NestedCompleter.from_nested_dict(
{c: None for c in fa_controller.CHOICES}
)
an_input = session.prompt(
f"{get_flair()} (fa)> ",
completer=completer,
)
else:
an_input = input(f"{get_flair()} (fa)> ")
try:
process_input = fa_controller.switch(an_input)
if process_input is not None:
return process_input
except SystemExit:
print("The command selected doesn't exist\n")
continue