From 42b1acf5c3d2f9e9922ac8c4e956fffc08a5d7ae Mon Sep 17 00:00:00 2001 From: Theodore Aptekarev Date: Thu, 13 Jan 2022 15:50:28 +0300 Subject: [PATCH] Add an API wrapper for terminal functions to be used in python (#1170) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Initial implementation of the API wrapper for stocks/disc * Create a file for helper classes * Move models namespace class where it belongs... TO THE HELPER_CLASSES🚀 * Add backtesting api wrapper * Add ba api wrapper * Add dps api wrapper * Fix flake8 warnings in command help strings * Add comparison analysis models * Add dd api wrapper * Add fa api wrapper * Add gov api wrapper * Add ins api wrapper *note the note * Add options api wrapper *note the note * Add prediction api wrapper * Add api support for importing models from both local and common contexts * Add qa api wrapper * Add screener api wrapper *note the note * Fix typos in sia controller * Add sia api wrapper * Add ta api wrapper * Disable linting for specific lines that fail in CI * Remove deprecated parameter * Add exception handling when prediction packages are not installed --- gamestonk_terminal/api.py | 3 + .../common/quantitative_analysis/qa_view.py | 4 +- .../cryptocurrency/pycoingecko_helpers.py | 4 +- gamestonk_terminal/helper_classes.py | 78 +++++++++++++++++++ gamestonk_terminal/helper_funcs.py | 30 ------- gamestonk_terminal/stocks/__init__.py | 18 ----- .../stocks/backtesting/bt_api.py | 15 ++++ .../stocks/behavioural_analysis/ba_api.py | 74 ++++++++++++++++++ .../behavioural_analysis/ba_controller.py | 9 ++- .../stocks/comparison_analysis/ca_api.py | 16 ++++ .../comparison_analysis/ca_controller.py | 7 +- .../stocks/dark_pool_shorts/dps_api.py | 21 +++++ .../stocks/discovery/__init__.py | 1 - .../stocks/discovery/disc_api.py | 29 +++++++ .../stocks/discovery/disc_controller.py | 5 +- .../stocks/due_diligence/dd_api.py | 20 +++++ .../stocks/due_diligence/dd_controller.py | 9 ++- .../stocks/fundamental_analysis/fa_api.py | 34 ++++++++ .../financial_modeling_prep/fmp_api.py | 22 ++++++ .../financial_modeling_prep/fmp_controller.py | 10 +-- .../stocks/government/gov_api.py | 22 ++++++ .../stocks/government/gov_controller.py | 9 ++- .../stocks/government/quiverquant_model.py | 13 ++-- .../stocks/insider/insider_api.py | 14 ++++ .../stocks/insider/insider_controller.py | 11 ++- .../stocks/options/options_api.py | 29 +++++++ .../stocks/options/options_controller.py | 30 +++++-- .../stocks/prediction_techniques/pred_api.py | 40 ++++++++++ .../prediction_techniques/pred_controller.py | 7 +- .../quantitative_analysis/factors_view.py | 10 ++- .../stocks/quantitative_analysis/qa_api.py | 58 ++++++++++++++ .../quantitative_analysis/qa_controller.py | 7 +- .../stocks/screener/screener_api.py | 13 ++++ .../stocks/screener/screener_controller.py | 4 + .../sector_industry_analysis/sia_api.py | 20 +++++ .../sia_controller.py | 33 ++++---- gamestonk_terminal/stocks/stocks_api.py | 28 +++++++ .../stocks/stocks_controller.py | 7 +- .../stocks/technical_analysis/ta_api.py | 60 ++++++++++++++ .../technical_analysis/ta_controller.py | 7 +- 40 files changed, 710 insertions(+), 121 deletions(-) create mode 100644 gamestonk_terminal/api.py create mode 100644 gamestonk_terminal/helper_classes.py create mode 100644 gamestonk_terminal/stocks/backtesting/bt_api.py create mode 100644 gamestonk_terminal/stocks/behavioural_analysis/ba_api.py create mode 100644 gamestonk_terminal/stocks/comparison_analysis/ca_api.py create mode 100644 gamestonk_terminal/stocks/dark_pool_shorts/dps_api.py create mode 100644 gamestonk_terminal/stocks/discovery/disc_api.py create mode 100644 gamestonk_terminal/stocks/due_diligence/dd_api.py create mode 100644 gamestonk_terminal/stocks/fundamental_analysis/fa_api.py create mode 100644 gamestonk_terminal/stocks/fundamental_analysis/financial_modeling_prep/fmp_api.py create mode 100644 gamestonk_terminal/stocks/government/gov_api.py create mode 100644 gamestonk_terminal/stocks/insider/insider_api.py create mode 100644 gamestonk_terminal/stocks/options/options_api.py create mode 100644 gamestonk_terminal/stocks/prediction_techniques/pred_api.py create mode 100644 gamestonk_terminal/stocks/quantitative_analysis/qa_api.py create mode 100644 gamestonk_terminal/stocks/screener/screener_api.py create mode 100644 gamestonk_terminal/stocks/sector_industry_analysis/sia_api.py create mode 100644 gamestonk_terminal/stocks/stocks_api.py create mode 100644 gamestonk_terminal/stocks/technical_analysis/ta_api.py diff --git a/gamestonk_terminal/api.py b/gamestonk_terminal/api.py new file mode 100644 index 00000000000..4bfaf59610f --- /dev/null +++ b/gamestonk_terminal/api.py @@ -0,0 +1,3 @@ +# flake8: noqa +# pylint: disable=unused-import +from .stocks import stocks_api as stocks diff --git a/gamestonk_terminal/common/quantitative_analysis/qa_view.py b/gamestonk_terminal/common/quantitative_analysis/qa_view.py index b73cafc5d06..2001ad35403 100644 --- a/gamestonk_terminal/common/quantitative_analysis/qa_view.py +++ b/gamestonk_terminal/common/quantitative_analysis/qa_view.py @@ -27,8 +27,8 @@ from gamestonk_terminal.helper_funcs import ( export_data, plot_autoscale, rich_table_from_df, - LineAnnotateDrawer, ) +from gamestonk_terminal.helper_classes import LineAnnotateDrawer register_matplotlib_converters() t_console = Console() @@ -457,7 +457,7 @@ def display_qqplot(name: str, df: pd.DataFrame, target: str): target : str Column in data to look at """ - # Statsmodels has a UserWarning for marker kwarg-- which we dont use + # Statsmodels has a UserWarning for marker kwarg-- which we don't use warnings.filterwarnings(category=UserWarning, action="ignore") data = df[target] fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI) diff --git a/gamestonk_terminal/cryptocurrency/pycoingecko_helpers.py b/gamestonk_terminal/cryptocurrency/pycoingecko_helpers.py index ce720344bae..0112319947b 100644 --- a/gamestonk_terminal/cryptocurrency/pycoingecko_helpers.py +++ b/gamestonk_terminal/cryptocurrency/pycoingecko_helpers.py @@ -229,8 +229,8 @@ def collateral_auditors_parse( auditors = [] else: n_elem = int(args[0]) - auditors = args[1 : n_elem + 1] - collateral = args[n_elem + 1 :] + auditors = args[1 : n_elem + 1] # noqa: E203 + collateral = args[n_elem + 1 :] # noqa: E203 return auditors, collateral except ValueError: diff --git a/gamestonk_terminal/helper_classes.py b/gamestonk_terminal/helper_classes.py new file mode 100644 index 00000000000..c1cb77c26ed --- /dev/null +++ b/gamestonk_terminal/helper_classes.py @@ -0,0 +1,78 @@ +"""Helper classes.""" +__docformat__ = "numpy" +import os +from importlib import machinery, util +from typing import Union, List +import matplotlib +import matplotlib.pyplot as plt + + +class LineAnnotateDrawer: + """Line drawing class.""" + + def __init__(self, ax: matplotlib.axes = None): + self.ax = ax + + def draw_lines_and_annotate(self): + """Draw lines.""" + print("Click twice for annotation.\nClose window to keep using terminal.\n") + + while True: + xy = plt.ginput(2) + # Check whether the user has closed the window or not + if not plt.get_fignums(): + print("") + return + + if len(xy) == 2: + x = [p[0] for p in xy] + y = [p[1] for p in xy] + + if (x[0] == x[1]) and (y[0] == y[1]): + txt = input("Annotation: ") + self.ax.annotate(txt, (x[0], y[1]), ha="center", va="center") + else: + self.ax.plot(x, y) + + self.ax.figure.canvas.draw() + + +# pylint: disable=too-few-public-methods +class ModelsNamespace: + """A namespace placeholder for the menu models. + + This class is used in all api wrappers to create a `models` namespace and import + all the model functions. + """ + + def __init__(self, folders: Union[str, List[str]]) -> None: + """Import all menu models into the models namespace. + + Instantiation of the namespace requires either a path to the folder that + contains model files or a list of such folders. + + Parameters + ---------- + folders : Union[str, List[str]] + a folder or a list of folders to import models from + """ + if isinstance(folders, str): + folders = [folders] + for folder in folders: + menu_models = [ + ( + f.replace("_model.py", ""), + os.path.abspath(os.path.join(folder, f)), + ) + for f in os.listdir(folder) + if f.endswith("_model.py") + ] + + for model_name, model_file in menu_models: + loader = machinery.SourceFileLoader(model_name, model_file) + spec = util.spec_from_loader(model_name, loader) + if spec is not None: + setattr(self, model_name, util.module_from_spec(spec)) + loader.exec_module(getattr(self, model_name)) + else: + pass diff --git a/gamestonk_terminal/helper_funcs.py b/gamestonk_terminal/helper_funcs.py index b5cfdb59046..50d81b125f5 100644 --- a/gamestonk_terminal/helper_funcs.py +++ b/gamestonk_terminal/helper_funcs.py @@ -930,36 +930,6 @@ def get_rf() -> float: return 0.02 -class LineAnnotateDrawer: - """Line drawing class.""" - - def __init__(self, ax: matplotlib.axes = None): - self.ax = ax - - def draw_lines_and_annotate(self): - """Draw lines.""" - print("Click twice for annotation.\nClose window to keep using terminal.\n") - - while True: - xy = plt.ginput(2) - # Check whether the user has closed the window or not - if not plt.get_fignums(): - print("") - return - - if len(xy) == 2: - x = [p[0] for p in xy] - y = [p[1] for p in xy] - - if (x[0] == x[1]) and (y[0] == y[1]): - txt = input("Annotation: ") - self.ax.annotate(txt, (x[0], y[1]), ha="center", va="center") - else: - self.ax.plot(x, y) - - self.ax.figure.canvas.draw() - - def system_clear(): """Clear screen""" os.system("cls||clear") # nosec diff --git a/gamestonk_terminal/stocks/__init__.py b/gamestonk_terminal/stocks/__init__.py index 9d834c96fa7..e69de29bb2d 100644 --- a/gamestonk_terminal/stocks/__init__.py +++ b/gamestonk_terminal/stocks/__init__.py @@ -1,18 +0,0 @@ -# flake8: noqa -from . import ( - backtesting, - behavioural_analysis, - comparison_analysis, - dark_pool_shorts, - discovery, - due_diligence, - fundamental_analysis, - government, - insider, - options, - prediction_techniques, - quantitative_analysis, - research, - screener, - technical_analysis, -) diff --git a/gamestonk_terminal/stocks/backtesting/bt_api.py b/gamestonk_terminal/stocks/backtesting/bt_api.py new file mode 100644 index 00000000000..d14d0ea62f0 --- /dev/null +++ b/gamestonk_terminal/stocks/backtesting/bt_api.py @@ -0,0 +1,15 @@ +"""Backtesting API.""" +import os +from gamestonk_terminal.helper_classes import ModelsNamespace as _models + +# flake8: noqa +# pylint: disable=unused-import + +# Menu commands +from .bt_view import display_whatif_scenario as whatif +from .bt_view import display_simple_ema as ema +from .bt_view import display_ema_cross as ema_cross +from .bt_view import display_rsi_strategy as rsi + +# Models +models = _models(os.path.abspath(os.path.dirname(__file__))) diff --git a/gamestonk_terminal/stocks/behavioural_analysis/ba_api.py b/gamestonk_terminal/stocks/behavioural_analysis/ba_api.py new file mode 100644 index 00000000000..b79ee969e21 --- /dev/null +++ b/gamestonk_terminal/stocks/behavioural_analysis/ba_api.py @@ -0,0 +1,74 @@ +"""Behavioural Analysis API.""" + +# flake8: noqa +# pylint: disable=unused-import + +# Menu commands +from gamestonk_terminal.common.behavioural_analysis.reddit_view import ( + display_watchlist as watchlist, +) +from gamestonk_terminal.common.behavioural_analysis.reddit_view import ( + display_spac as spac, +) +from gamestonk_terminal.common.behavioural_analysis.reddit_view import ( + display_spac_community as spac_c, +) +from gamestonk_terminal.common.behavioural_analysis.reddit_view import ( + display_wsb_community as wsb, +) +from gamestonk_terminal.common.behavioural_analysis.reddit_view import ( + display_popular_tickers as popular, +) +from gamestonk_terminal.common.behavioural_analysis.reddit_view import ( + display_due_diligence as getdd, +) +from gamestonk_terminal.common.behavioural_analysis.stocktwits_view import ( + display_bullbear as bullbear, +) +from gamestonk_terminal.common.behavioural_analysis.stocktwits_view import ( + display_messages as messages, +) +from gamestonk_terminal.common.behavioural_analysis.stocktwits_view import ( + display_trending as trending, +) +from gamestonk_terminal.common.behavioural_analysis.stocktwits_view import ( + display_stalker as stalker, +) +from gamestonk_terminal.common.behavioural_analysis.google_view import ( + display_mentions as mentions, +) +from gamestonk_terminal.common.behavioural_analysis.google_view import ( + display_regions as regions, +) +from gamestonk_terminal.common.behavioural_analysis.google_view import ( + display_queries as queries, +) +from gamestonk_terminal.common.behavioural_analysis.google_view import ( + display_rise as rise, +) +from gamestonk_terminal.common.behavioural_analysis.twitter_view import ( + display_inference as infer, +) +from gamestonk_terminal.common.behavioural_analysis.twitter_view import ( + display_sentiment as sentiment, +) +from gamestonk_terminal.common.behavioural_analysis.finbrain_view import ( + display_sentiment_analysis as headlines, +) +from gamestonk_terminal.common.behavioural_analysis.finnhub_view import ( + display_sentiment_stats as stats, +) +from gamestonk_terminal.common.behavioural_analysis.sentimentinvestor_view import ( + display_metrics as metrics, +) +from gamestonk_terminal.common.behavioural_analysis.sentimentinvestor_view import ( + display_social as social, +) +from gamestonk_terminal.common.behavioural_analysis.sentimentinvestor_view import ( + display_historical as historical, +) +from gamestonk_terminal.common.behavioural_analysis.sentimentinvestor_view import ( + display_top as popularsi, +) + +emerging = popularsi diff --git a/gamestonk_terminal/stocks/behavioural_analysis/ba_controller.py b/gamestonk_terminal/stocks/behavioural_analysis/ba_controller.py index d6ba0955242..9c529237e70 100644 --- a/gamestonk_terminal/stocks/behavioural_analysis/ba_controller.py +++ b/gamestonk_terminal/stocks/behavioural_analysis/ba_controller.py @@ -136,9 +136,10 @@ SentimentInvestor: add_help=False, formatter_class=argparse.ArgumentDefaultsHelpFormatter, prog="load", - description="Load stock ticker to perform analysis on. When the data source is 'yf', an Indian ticker can be" - " loaded by using '.NS' at the end, e.g. 'SBIN.NS'. See available market in" - " https://help.yahoo.com/kb/exchanges-data-providers-yahoo-finance-sln2310.html.", + description="Load stock ticker to perform analysis on. When the data " + + "source is 'yf', an Indian ticker can be loaded by using '.NS' at the end," + + " e.g. 'SBIN.NS'. See available market in" + + " https://help.yahoo.com/kb/exchanges-data-providers-yahoo-finance-sln2310.html.", ) parser.add_argument( "-t", @@ -931,7 +932,7 @@ SentimentInvestor: def call_emerging(self, other_args: List[str]): """Process emerging command""" command_description = f""" - The {Style.BRIGHT}emerging{Style.RESET_ALL} command prints the stocks with highest Relative Hype Index right now. + The {Style.BRIGHT}emerging{Style.RESET_ALL} command prints the stocks with highest Index right now. {Style.BRIGHT}RHI (Relative Hype Index){Style.RESET_ALL} --- diff --git a/gamestonk_terminal/stocks/comparison_analysis/ca_api.py b/gamestonk_terminal/stocks/comparison_analysis/ca_api.py new file mode 100644 index 00000000000..99d537ed197 --- /dev/null +++ b/gamestonk_terminal/stocks/comparison_analysis/ca_api.py @@ -0,0 +1,16 @@ +"""Comparison Analysis API.""" +import os +from gamestonk_terminal.helper_classes import ModelsNamespace as _models + +# flake8: noqa +# pylint: disable=unused-import + +# Menu commands +print("Comparison Analysis Warning.") +print( + "Menu commands API implementation is awaiting for comparison_analysis module refactoring." +) +print("Only data models can be used at this moment.") + +# Models +models = _models(os.path.abspath(os.path.dirname(__file__))) diff --git a/gamestonk_terminal/stocks/comparison_analysis/ca_controller.py b/gamestonk_terminal/stocks/comparison_analysis/ca_controller.py index 881832da21f..20048c659cb 100644 --- a/gamestonk_terminal/stocks/comparison_analysis/ca_controller.py +++ b/gamestonk_terminal/stocks/comparison_analysis/ca_controller.py @@ -34,6 +34,10 @@ from gamestonk_terminal.stocks.comparison_analysis import ( # pylint: disable=E1121,C0302,R0904 +# TODO: HELP WANTED! This controller still has some view functionality that should be +# refactored in order to implement an API wrapper. Use the discovery controller +# as an example. + class ComparisonAnalysisController(BaseController): """Comparison Analysis Controller class""" @@ -131,13 +135,14 @@ Finviz: return ["stocks", "ca", f"set {','.join(self.similar)}"] return [] + # TODO: Figure out if this function is actually needed here def call_ticker(self, other_args: List[str]): """Process ticker command""" parser = argparse.ArgumentParser( add_help=False, formatter_class=argparse.ArgumentDefaultsHelpFormatter, prog="ticker", - description="""Set ticker to extract similars from""", + description="""Set ticker to extract similar from""", ) parser.add_argument( "-t", diff --git a/gamestonk_terminal/stocks/dark_pool_shorts/dps_api.py b/gamestonk_terminal/stocks/dark_pool_shorts/dps_api.py new file mode 100644 index 00000000000..0de381ebf96 --- /dev/null +++ b/gamestonk_terminal/stocks/dark_pool_shorts/dps_api.py @@ -0,0 +1,21 @@ +"""Dark Pool Shorts API.""" +import os +from gamestonk_terminal.helper_classes import ModelsNamespace as _models + +# flake8: noqa +# pylint: disable=unused-import + +# Menu commands +from .yahoofinance_view import display_most_shorted as call_shorted +from .shortinterest_view import high_short_interest as call_hsi +from .finra_view import darkpool_otc as call_prom +from .stockgrid_view import dark_pool_short_positions as call_pos +from .stockgrid_view import short_interest_days_to_cover as call_sidtc +from .finra_view import darkpool_ats_otc as dpotc +from .sec_view import fails_to_deliver as ftd +from .stockgrid_view import net_short_position as spos +from .quandl_view import short_interest as psi +from .nyse_view import display_short_by_exchange as volexch + +# Models +models = _models(os.path.abspath(os.path.dirname(__file__))) diff --git a/gamestonk_terminal/stocks/discovery/__init__.py b/gamestonk_terminal/stocks/discovery/__init__.py index 0c8c0d157a7..e69de29bb2d 100644 --- a/gamestonk_terminal/stocks/discovery/__init__.py +++ b/gamestonk_terminal/stocks/discovery/__init__.py @@ -1 +0,0 @@ -from . import disc_controller # noqa: F401 diff --git a/gamestonk_terminal/stocks/discovery/disc_api.py b/gamestonk_terminal/stocks/discovery/disc_api.py new file mode 100644 index 00000000000..c97b6ec81f2 --- /dev/null +++ b/gamestonk_terminal/stocks/discovery/disc_api.py @@ -0,0 +1,29 @@ +"""Discovery API.""" +import os +from gamestonk_terminal.helper_classes import ModelsNamespace as _models + +# flake8: noqa +# pylint: disable=unused-import + +# Menu commands +from .geekofwallstreet_view import display_realtime_earnings as rtearn +from .finnhub_view import past_ipo as pipo +from .finnhub_view import future_ipo as fipo +from .yahoofinance_view import display_gainers as gainers +from .yahoofinance_view import display_losers as losers +from .yahoofinance_view import display_ugs as ugs +from .yahoofinance_view import display_gtech as gtech +from .yahoofinance_view import display_active as active +from .yahoofinance_view import display_ulc as ulc +from .yahoofinance_view import display_asc as asc +from .fidelity_view import orders_view as ford +from .ark_view import ark_orders_view as arkord +from .seeking_alpha_view import upcoming_earning_release_dates as upcoming +from .seeking_alpha_view import news as trending +from .shortinterest_view import low_float as lowfloat +from .seeking_alpha_view import display_news as cnews +from .shortinterest_view import hot_penny_stocks as hotpenny +from .nasdaq_view import display_top_retail as rtat + +# Models +models = _models(os.path.abspath(os.path.dirname(__file__))) diff --git a/gamestonk_terminal/stocks/discovery/disc_controller.py b/gamestonk_terminal/stocks/discovery/disc_controller.py index 63e13b67078..b2e4503b4db 100644 --- a/gamestonk_terminal/stocks/discovery/disc_controller.py +++ b/gamestonk_terminal/stocks/discovery/disc_controller.py @@ -314,9 +314,8 @@ NASDAQ Data Link (Formerly Quandl): add_help=False, formatter_class=argparse.ArgumentDefaultsHelpFormatter, prog="gtech", - description=""" - Print up to 25 top tech stocks with revenue and earnings growth in excess of 25%. [Source: Yahoo Finance] - """, + description="Print up to 25 top tech stocks with revenue and earnings" + + " growth in excess of 25%. [Source: Yahoo Finance]", ) parser.add_argument( "-l", diff --git a/gamestonk_terminal/stocks/due_diligence/dd_api.py b/gamestonk_terminal/stocks/due_diligence/dd_api.py new file mode 100644 index 00000000000..a8535130238 --- /dev/null +++ b/gamestonk_terminal/stocks/due_diligence/dd_api.py @@ -0,0 +1,20 @@ +"""Due Diligence API.""" +import os +from gamestonk_terminal.helper_classes import ModelsNamespace as _models + +# flake8: noqa +# pylint: disable=unused-import + +# Menu commands +from .finviz_view import analyst +from .business_insider_view import price_target_from_analysts as pt +from .business_insider_view import estimates as est +from .finnhub_view import rating_over_time as rot +from .fmp_view import rating +from .marketwatch_view import sec_filings as sec +from .csimarket_view import suppliers as supplier +from .csimarket_view import customers as customer +from .ark_view import display_ark_trades as arktrades + +# Models +models = _models(os.path.abspath(os.path.dirname(__file__))) diff --git a/gamestonk_terminal/stocks/due_diligence/dd_controller.py b/gamestonk_terminal/stocks/due_diligence/dd_controller.py index b2fd5a20e8a..9f299c565a9 100644 --- a/gamestonk_terminal/stocks/due_diligence/dd_controller.py +++ b/gamestonk_terminal/stocks/due_diligence/dd_controller.py @@ -102,9 +102,10 @@ cathiesark.com add_help=False, formatter_class=argparse.ArgumentDefaultsHelpFormatter, prog="load", - description="Load stock ticker to perform analysis on. When the data source is 'yf', an Indian ticker can be" - " loaded by using '.NS' at the end, e.g. 'SBIN.NS'. See available market in" - " https://help.yahoo.com/kb/exchanges-data-providers-yahoo-finance-sln2310.html.", + description="Load stock ticker to perform analysis on. When the data" + + " source is 'yf', an Indian ticker can be loaded by using '.NS' at the" + + " end, e.g. 'SBIN.NS'. See available market in" + + " https://help.yahoo.com/kb/exchanges-data-providers-yahoo-finance-sln2310.html.", ) parser.add_argument( "-t", @@ -387,7 +388,7 @@ cathiesark.com ) parser.add_argument( "-l", - "--limi", + "--limit", help="Limit of rows to show", dest="limit", default=10, diff --git a/gamestonk_terminal/stocks/fundamental_analysis/fa_api.py b/gamestonk_terminal/stocks/fundamental_analysis/fa_api.py new file mode 100644 index 00000000000..84fc3475666 --- /dev/null +++ b/gamestonk_terminal/stocks/fundamental_analysis/fa_api.py @@ -0,0 +1,34 @@ +"""Fundamental Analysis API.""" +import os +from gamestonk_terminal.helper_classes import ModelsNamespace as _models + +# flake8: noqa +# pylint: disable=unused-import + +# Menu commands +from .eclect_us_view import display_analysis as analysis +from .business_insider_view import display_management as mgmt +from .finviz_view import display_screen_data as data +from .financial_modeling_prep.fmp_view import valinvest_score as score +from .yahoo_finance_view import display_info as info +from .yahoo_finance_view import display_shareholders as shrs +from .yahoo_finance_view import display_sustainability as sust +from .yahoo_finance_view import display_calendar_earnings as cal +from .yahoo_finance_view import open_web as web +from .yahoo_finance_view import open_headquarters_map as hq +from .yahoo_finance_view import display_dividends as divs +from .av_view import display_overview as overview +from .av_view import display_key as key +from .av_view import display_income_statement as income +from .av_view import display_balance_sheet as balance +from .av_view import display_cash_flow as cash +from .av_view import display_earnings as earnings +from .av_view import display_fraud as fraud +from .dcf_view import CreateExcelFA as dcf +from .market_watch_view import display_sean_seah_warnings as warnings + +# Submenus +from .financial_modeling_prep import fmp_api as fmp + +# Models +models = _models(os.path.abspath(os.path.dirname(__file__))) diff --git a/gamestonk_terminal/stocks/fundamental_analysis/financial_modeling_prep/fmp_api.py b/gamestonk_terminal/stocks/fundamental_analysis/financial_modeling_prep/fmp_api.py new file mode 100644 index 00000000000..49a8ece021d --- /dev/null +++ b/gamestonk_terminal/stocks/fundamental_analysis/financial_modeling_prep/fmp_api.py @@ -0,0 +1,22 @@ +"""Financial Modeling Prep API.""" +import os +from gamestonk_terminal.helper_classes import ModelsNamespace as _models + +# flake8: noqa +# pylint: disable=unused-import + +# Menu commands +from .fmp_view import display_profile as profile +from .fmp_view import display_quote as quote +from .fmp_view import display_enterprise as enterprise +from .fmp_view import display_discounted_cash_flow as dcf +from .fmp_view import display_income_statement as income +from .fmp_view import display_balance_sheet as balance +from .fmp_view import display_cash_flow as cash +from .fmp_view import display_key_metrics as metrics +from .fmp_view import display_financial_ratios as ratios +from .fmp_view import display_financial_statement_growth as growth + + +# Models +models = _models(os.path.abspath(os.path.dirname(__file__))) diff --git a/gamestonk_terminal/stocks/fundamental_analysis/financial_modeling_prep/fmp_controller.py b/gamestonk_terminal/stocks/fundamental_analysis/financial_modeling_prep/fmp_controller.py index 606ef2556ec..1f959396dcc 100644 --- a/gamestonk_terminal/stocks/fundamental_analysis/financial_modeling_prep/fmp_controller.py +++ b/gamestonk_terminal/stocks/fundamental_analysis/financial_modeling_prep/fmp_controller.py @@ -206,7 +206,7 @@ Ticker: {self.ticker} 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 + revenue, Depreciation and amortization, EBITDA, EBITDA Ratio, Eps, Eps Diluted, 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, @@ -362,7 +362,7 @@ Ticker: {self.ticker} 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, + ratio, Pfcf ratio, Pocf ratio, Price to sales ratio, Ptb ratio, Receivables turnover, Research and development 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 @@ -462,12 +462,12 @@ Ticker: {self.ticker} 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 + growth, Dividendsper share growth, Ebit growth, Eps diluted growth, Eps growth, 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 + Operating cash flow growth, Operating income growth, Rd expense growth, Receivables growth, + Revenue growth, Sga expenses 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 diff --git a/gamestonk_terminal/stocks/government/gov_api.py b/gamestonk_terminal/stocks/government/gov_api.py new file mode 100644 index 00000000000..f9f697e1e16 --- /dev/null +++ b/gamestonk_terminal/stocks/government/gov_api.py @@ -0,0 +1,22 @@ +"""Due Diligence API.""" +import os +from gamestonk_terminal.helper_classes import ModelsNamespace as _models + +# flake8: noqa +# pylint: disable=unused-import + +# Menu commands +from .quiverquant_view import display_last_government as lasttrades +from .quiverquant_view import display_government_buys as topbuys +from .quiverquant_view import display_government_sells as topsells +from .quiverquant_view import display_last_contracts as lastcontracts +from .quiverquant_view import display_qtr_contracts as qtrcontracts +from .quiverquant_view import display_top_lobbying as toplobbying +from .quiverquant_view import display_government_trading as gtrades +from .quiverquant_view import display_contracts as contracts +from .quiverquant_view import display_hist_contracts as histcont +from .quiverquant_view import display_lobbying as lobbying + + +# Models +models = _models(os.path.abspath(os.path.dirname(__file__))) diff --git a/gamestonk_terminal/stocks/government/gov_controller.py b/gamestonk_terminal/stocks/government/gov_controller.py index 90c18e4ba41..7610576a176 100644 --- a/gamestonk_terminal/stocks/government/gov_controller.py +++ b/gamestonk_terminal/stocks/government/gov_controller.py @@ -31,10 +31,10 @@ class GovController(BaseController): "lasttrades", "topbuys", "topsells", + "lastcontracts", "qtrcontracts", "toplobbying", "gtrades", - "lastcontracts", "contracts", "histcont", "lobbying", @@ -100,9 +100,10 @@ Ticker: {self.ticker or None}{dim_no_ticker} add_help=False, formatter_class=argparse.ArgumentDefaultsHelpFormatter, prog="load", - description="Load stock ticker to perform analysis on. When the data source is 'yf', an Indian ticker can be" - " loaded by using '.NS' at the end, e.g. 'SBIN.NS'. See available market in" - " https://help.yahoo.com/kb/exchanges-data-providers-yahoo-finance-sln2310.html.", + description="Load stock ticker to perform analysis on. When the data source" + + " is 'yf', an Indian ticker can be loaded by using '.NS' at the end," + + " e.g. 'SBIN.NS'. See available market in" + + " https://help.yahoo.com/kb/exchanges-data-providers-yahoo-finance-sln2310.html.", ) parser.add_argument( "-t", diff --git a/gamestonk_terminal/stocks/government/quiverquant_model.py b/gamestonk_terminal/stocks/government/quiverquant_model.py index b58443e2aed..8e1ce64f4ef 100644 --- a/gamestonk_terminal/stocks/government/quiverquant_model.py +++ b/gamestonk_terminal/stocks/government/quiverquant_model.py @@ -18,7 +18,8 @@ def get_government_trading(gov_type: str, ticker: str = "") -> pd.DataFrame: Parameters ---------- gov_type: str - Type of government data between: Congress, Senate, House, Contracts, Quarter-Contracts and Corporate-Lobbying + Type of government data between: + 'congress', 'senate', 'house', 'contracts', 'quarter-contracts' and 'corporate-lobbying' ticker : str Ticker to get congress trading data from @@ -35,19 +36,19 @@ def get_government_trading(gov_type: str, ticker: str = "") -> pd.DataFrame: else: url = "https://api.quiverquant.com/beta/live/congresstrading" - elif gov_type == "senate": + elif gov_type.lower() == "senate": if ticker: url = f"https://api.quiverquant.com/beta/historical/senatetrading/{ticker}" else: url = "https://api.quiverquant.com/beta/live/senatetrading" - elif gov_type == "house": + elif gov_type.lower() == "house": if ticker: url = f"https://api.quiverquant.com/beta/historical/housetrading/{ticker}" else: url = "https://api.quiverquant.com/beta/live/housetrading" - elif gov_type == "contracts": + elif gov_type.lower() == "contracts": if ticker: url = ( f"https://api.quiverquant.com/beta/historical/govcontractsall/{ticker}" @@ -55,13 +56,13 @@ def get_government_trading(gov_type: str, ticker: str = "") -> pd.DataFrame: else: url = "https://api.quiverquant.com/beta/live/govcontractsall" - elif gov_type == "quarter-contracts": + elif gov_type.lower() == "quarter-contracts": if ticker: url = f"https://api.quiverquant.com/beta/historical/govcontracts/{ticker}" else: url = "https://api.quiverquant.com/beta/live/govcontracts" - elif gov_type == "corporate-lobbying": + elif gov_type.lower() == "corporate-lobbying": if ticker: url = f"https://api.quiverquant.com/beta/historical/lobbying/{ticker}" else: diff --git a/gamestonk_terminal/stocks/insider/insider_api.py b/gamestonk_terminal/stocks/insider/insider_api.py new file mode 100644 index 00000000000..a01539dadeb --- /dev/null +++ b/gamestonk_terminal/stocks/insider/insider_api.py @@ -0,0 +1,14 @@ +"""Insider Trading API.""" +import os +from gamestonk_terminal.helper_classes import ModelsNamespace as _models + +# flake8: noqa +# pylint: disable=unused-import + +# Menu commands +from .openinsider_view import print_insider_data +from .businessinsider_view import insider_activity as act +from .finviz_view import last_insider_activity as lins + +# Models +models = _models(os.path.abspath(os.path.dirname(__file__))) diff --git a/gamestonk_terminal/stocks/insider/insider_controller.py b/gamestonk_terminal/stocks/insider/insider_controller.py index ce9738e84df..7d1add49d01 100644 --- a/gamestonk_terminal/stocks/insider/insider_controller.py +++ b/gamestonk_terminal/stocks/insider/insider_controller.py @@ -27,6 +27,10 @@ presets_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), "presets # pylint: disable=,inconsistent-return-statements +# TODO: HELP WANTED! This menu required some refactoring. Things that can be addressed: +# - better preset management (MVC style) +# - unification of model return types (now some return dataframes other records list) + class InsiderController(BaseController): """Screener Controller class""" @@ -145,9 +149,10 @@ Top Insiders: add_help=False, formatter_class=argparse.ArgumentDefaultsHelpFormatter, prog="load", - description="Load stock ticker to perform analysis on. When the data source is 'yf', an Indian ticker can be" - " loaded by using '.NS' at the end, e.g. 'SBIN.NS'. See available market in" - " https://help.yahoo.com/kb/exchanges-data-providers-yahoo-finance-sln2310.html.", + description="Load stock ticker to perform analysis on. When the data source" + + " is 'yf', an Indian ticker can be loaded by using '.NS' at the end," + + " e.g. 'SBIN.NS'. See available market in" + + " https://help.yahoo.com/kb/exchanges-data-providers-yahoo-finance-sln2310.html.", ) parser.add_argument( "-t", diff --git a/gamestonk_terminal/stocks/options/options_api.py b/gamestonk_terminal/stocks/options/options_api.py new file mode 100644 index 00000000000..4bb2d017e81 --- /dev/null +++ b/gamestonk_terminal/stocks/options/options_api.py @@ -0,0 +1,29 @@ +"""Options API.""" +import os +from gamestonk_terminal.helper_classes import ModelsNamespace as _models + +# flake8: noqa +# pylint: disable=unused-import + +# Menu commands +from .calculator_view import view_calculator as calc +from .fdscanner_view import display_options as unu +from .alphaquery_view import display_put_call_ratio as pcr +from .barchart_view import print_options_data as info +from .syncretism_view import view_historical_greeks as grhist +from .chartexchange_view import display_raw as hist_ce +from .tradier_view import display_historical as hist_tr +from .tradier_view import display_chains as chains +from .tradier_view import plot_vol as vol_tr +from .yfinance_view import plot_vol as vol_yf +from .tradier_view import plot_volume_open_interest as voi_tr +from .yfinance_view import plot_volume_open_interest as voi_yf +from .tradier_view import plot_oi as oi_tr +from .yfinance_view import plot_oi as oi_yf +from .yfinance_view import plot_plot as plot +from .yfinance_view import show_parity as parity +from .yfinance_view import show_binom as binom + + +# Models +models = _models(os.path.abspath(os.path.dirname(__file__))) diff --git a/gamestonk_terminal/stocks/options/options_controller.py b/gamestonk_terminal/stocks/options/options_controller.py index e39fd5ea362..7ab1caa37d0 100644 --- a/gamestonk_terminal/stocks/options/options_controller.py +++ b/gamestonk_terminal/stocks/options/options_controller.py @@ -38,6 +38,11 @@ from gamestonk_terminal.stocks.options import ( # pylint: disable=R1710,C0302,R0916 +# TODO: HELP WANTED! This controller requires some MVC style refactoring +# - At the moment there's too much logic in the controller to implement an +# API wrapper. Please refactor functions like 'call_exp' +# - The separate controllers and related models/views should be moved to subfolders + class OptionsController(BaseController): """Options Controller class""" @@ -111,7 +116,7 @@ class OptionsController(BaseController): self.chain = None if ticker: - if TRADIER_TOKEN == "REPLACE_ME": + if TRADIER_TOKEN == "REPLACE_ME": # nosec print("Loaded expiry dates from Yahoo Finance") self.expiry_dates = yfinance_model.option_expirations(self.ticker) else: @@ -275,7 +280,7 @@ Expiry: {self.selected_date or None} ) def call_unu(self, other_args: List[str]): - """Process act command""" + """Process unu command""" parser = argparse.ArgumentParser( prog="unu", add_help=False, @@ -526,7 +531,7 @@ Expiry: {self.selected_date or None} self.ticker = ns_parser.ticker.upper() self.update_runtime_choices() - if TRADIER_TOKEN == "REPLACE_ME" or ns_parser.source == "yf": + if TRADIER_TOKEN == "REPLACE_ME" or ns_parser.source == "yf": # nosec self.expiry_dates = yfinance_model.option_expirations(self.ticker) else: self.expiry_dates = tradier_model.option_expirations(self.ticker) @@ -678,7 +683,7 @@ Expiry: {self.selected_date or None} ) else: - if TRADIER_TOKEN != "REPLACE_ME": + if TRADIER_TOKEN != "REPLACE_ME": # nosec tradier_view.display_historical( ticker=self.ticker, expiry=self.selected_date, @@ -752,7 +757,7 @@ Expiry: {self.selected_date or None} if ns_parser: if self.ticker: if self.selected_date: - if TRADIER_TOKEN != "REPLACE_ME": + if TRADIER_TOKEN != "REPLACE_ME": # nosec tradier_view.display_chains( ticker=self.ticker, expiry=self.selected_date, @@ -825,7 +830,10 @@ Expiry: {self.selected_date or None} if ns_parser: if self.ticker: if self.selected_date: - if ns_parser.source == "tr" and TRADIER_TOKEN != "REPLACE_ME": + if ( + ns_parser.source == "tr" + and TRADIER_TOKEN != "REPLACE_ME" # nosec + ): tradier_view.plot_vol( ticker=self.ticker, expiry=self.selected_date, @@ -897,7 +905,10 @@ Expiry: {self.selected_date or None} if ns_parser: if self.ticker: if self.selected_date: - if ns_parser.source == "tr" and TRADIER_TOKEN != "REPLACE_ME": + if ( + ns_parser.source == "tr" + and TRADIER_TOKEN != "REPLACE_ME" # nosec + ): tradier_view.plot_volume_open_interest( ticker=self.ticker, expiry=self.selected_date, @@ -975,7 +986,10 @@ Expiry: {self.selected_date or None} if ns_parser: if self.ticker: if self.selected_date: - if ns_parser.source == "tr" and TRADIER_TOKEN != "REPLACE_ME": + if ( + ns_parser.source == "tr" + and TRADIER_TOKEN != "REPLACE_ME" # nosec + ): tradier_view.plot_oi( ticker=self.ticker, expiry=self.selected_date, diff --git a/gamestonk_terminal/stocks/prediction_techniques/pred_api.py b/gamestonk_terminal/stocks/prediction_techniques/pred_api.py new file mode 100644 index 00000000000..47957f2ada1 --- /dev/null +++ b/gamestonk_terminal/stocks/prediction_techniques/pred_api.py @@ -0,0 +1,40 @@ +"""Inference API.""" +import os +from gamestonk_terminal.helper_classes import ModelsNamespace as _models + +# flake8: noqa +# pylint: disable=unused-import + +# Menu commands +from gamestonk_terminal.common.prediction_techniques.ets_view import ( + display_exponential_smoothing as ets, +) +from gamestonk_terminal.common.prediction_techniques.knn_view import ( + display_k_nearest_neighbors as knn, +) +from gamestonk_terminal.common.prediction_techniques.regression_view import ( + display_regression as regression, +) +from gamestonk_terminal.common.prediction_techniques.arima_view import ( + display_arima as arima, +) +from gamestonk_terminal.common.prediction_techniques.neural_networks_view import ( + display_mlp as mlp, +) +from gamestonk_terminal.common.prediction_techniques.neural_networks_view import ( + display_rnn as rnn, +) +from gamestonk_terminal.common.prediction_techniques.neural_networks_view import ( + display_lstm as lstm, +) +from gamestonk_terminal.common.prediction_techniques.neural_networks_view import ( + display_conv1d as conv1d, +) +from gamestonk_terminal.common.prediction_techniques.mc_view import ( + display_mc_forecast as mc, +) + +# Models +# NOTE: The ets function is used here to point to the commons path where all the +# inference models are expected to live +models = _models(os.path.abspath(os.path.dirname(ets.__code__.co_filename))) diff --git a/gamestonk_terminal/stocks/prediction_techniques/pred_controller.py b/gamestonk_terminal/stocks/prediction_techniques/pred_controller.py index 499d0b12504..b6416293999 100644 --- a/gamestonk_terminal/stocks/prediction_techniques/pred_controller.py +++ b/gamestonk_terminal/stocks/prediction_techniques/pred_controller.py @@ -126,9 +126,10 @@ Models: add_help=False, formatter_class=argparse.ArgumentDefaultsHelpFormatter, prog="load", - description="Load stock ticker to perform analysis on. When the data source is 'yf', an Indian ticker can be" - " loaded by using '.NS' at the end, e.g. 'SBIN.NS'. See available market in" - " https://help.yahoo.com/kb/exchanges-data-providers-yahoo-finance-sln2310.html.", + description="Load stock ticker to perform analysis on. When the data source" + + " is 'yf', an Indian ticker can be loaded by using '.NS' at the end," + + " e.g. 'SBIN.NS'. See available market in" + + " https://help.yahoo.com/kb/exchanges-data-providers-yahoo-finance-sln2310.html.", ) parser.add_argument( "-t", diff --git a/gamestonk_terminal/stocks/quantitative_analysis/factors_view.py b/gamestonk_terminal/stocks/quantitative_analysis/factors_view.py index 5730f255559..879eb5e7f2d 100644 --- a/gamestonk_terminal/stocks/quantitative_analysis/factors_view.py +++ b/gamestonk_terminal/stocks/quantitative_analysis/factors_view.py @@ -6,8 +6,14 @@ from gamestonk_terminal.stocks.quantitative_analysis.factors_model import ( ) -def capm_view(ticker): - """A view that displays information for the CAPM model.""" +def capm_view(ticker: str) -> None: + """Displays information for the CAPM model. + + Parameters + ---------- + ticker : str + Selected ticker + """ beta, sy = capm_information(ticker) print(f"Beta:\t\t\t{beta:.2f}") print(f"Systematic Risk:\t{sy*100:.2f}%") diff --git a/gamestonk_terminal/stocks/quantitative_analysis/qa_api.py b/gamestonk_terminal/stocks/quantitative_analysis/qa_api.py new file mode 100644 index 00000000000..d9b99b85546 --- /dev/null +++ b/gamestonk_terminal/stocks/quantitative_analysis/qa_api.py @@ -0,0 +1,58 @@ +"""Quantitative Analysis API.""" +import os +from gamestonk_terminal.helper_classes import ModelsNamespace as _models + +# flake8: noqa +# pylint: disable=unused-import + +# Menu commands +from gamestonk_terminal.common.quantitative_analysis.qa_view import display_raw as raw +from gamestonk_terminal.common.quantitative_analysis.qa_view import ( + display_summary as summary, +) +from gamestonk_terminal.common.quantitative_analysis.qa_view import display_line as line +from gamestonk_terminal.common.quantitative_analysis.qa_view import display_hist as hist +from gamestonk_terminal.common.quantitative_analysis.qa_view import display_cdf as cdf +from gamestonk_terminal.common.quantitative_analysis.qa_view import display_bw as bw +from gamestonk_terminal.common.quantitative_analysis.qa_view import ( + display_seasonal as decompose, +) +from gamestonk_terminal.common.quantitative_analysis.qa_view import ( + display_cusum as cusum, +) +from gamestonk_terminal.common.quantitative_analysis.qa_view import display_acf as acf +from gamestonk_terminal.common.quantitative_analysis.rolling_view import ( + display_mean_std as rolling, +) +from gamestonk_terminal.common.quantitative_analysis.rolling_view import ( + display_spread as spread, +) +from gamestonk_terminal.common.quantitative_analysis.rolling_view import ( + display_quantile as quantile, +) +from gamestonk_terminal.common.quantitative_analysis.rolling_view import ( + display_skew as skew, +) +from gamestonk_terminal.common.quantitative_analysis.rolling_view import ( + display_kurtosis as kurtosis, +) +from gamestonk_terminal.common.quantitative_analysis.qa_view import ( + display_normality as normality, +) +from gamestonk_terminal.common.quantitative_analysis.qa_view import ( + display_qqplot as qqplot, +) +from gamestonk_terminal.common.quantitative_analysis.qa_view import ( + display_unitroot as unitroot, +) +from .factors_view import capm_view as capm + +# Models +# NOTE: The raw function is used here to point to the commons path where all the +# qa models are expected to live +models = _models( + [ + os.path.abspath(os.path.dirname(raw.__code__.co_filename)), + os.path.abspath(os.path.dirname(__file__)), + ] +) diff --git a/gamestonk_terminal/stocks/quantitative_analysis/qa_controller.py b/gamestonk_terminal/stocks/quantitative_analysis/qa_controller.py index f4c39d72b6e..ececf9ec751 100644 --- a/gamestonk_terminal/stocks/quantitative_analysis/qa_controller.py +++ b/gamestonk_terminal/stocks/quantitative_analysis/qa_controller.py @@ -148,9 +148,10 @@ Other: add_help=False, formatter_class=argparse.ArgumentDefaultsHelpFormatter, prog="load", - description="Load stock ticker to perform analysis on. When the data source is 'yf', an Indian ticker can be" - " loaded by using '.NS' at the end, e.g. 'SBIN.NS'. See available market in" - " https://help.yahoo.com/kb/exchanges-data-providers-yahoo-finance-sln2310.html.", + description="Load stock ticker to perform analysis on. When the data source" + + " is 'yf', an Indian ticker can be loaded by using '.NS' at the end," + + " e.g. 'SBIN.NS'. See available market in" + + " https://help.yahoo.com/kb/exchanges-data-providers-yahoo-finance-sln2310.html.", ) parser.add_argument( "-t", diff --git a/gamestonk_terminal/stocks/screener/screener_api.py b/gamestonk_terminal/stocks/screener/screener_api.py new file mode 100644 index 00000000000..4bc415de97b --- /dev/null +++ b/gamestonk_terminal/stocks/screener/screener_api.py @@ -0,0 +1,13 @@ +"""Screener API.""" +import os +from gamestonk_terminal.helper_classes import ModelsNamespace as _models + +# flake8: noqa +# pylint: disable=unused-import + +# Menu commands +from .yahoofinance_view import historical +from .finviz_view import screener as finviz_screener + +# Models +models = _models(os.path.abspath(os.path.dirname(__file__))) diff --git a/gamestonk_terminal/stocks/screener/screener_controller.py b/gamestonk_terminal/stocks/screener/screener_controller.py index 176d95cae72..f80a970c7da 100644 --- a/gamestonk_terminal/stocks/screener/screener_controller.py +++ b/gamestonk_terminal/stocks/screener/screener_controller.py @@ -31,6 +31,10 @@ presets_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), "presets # pylint: disable=E1121 +# TODO: HELP WANTED! This menu required some refactoring. Things that can be addressed: +# - better preset management (MVC style). +# - decoupling view and model in the yfinance_view + class ScreenerController(BaseController): """Screener Controller class""" diff --git a/gamestonk_terminal/stocks/sector_industry_analysis/sia_api.py b/gamestonk_terminal/stocks/sector_industry_analysis/sia_api.py new file mode 100644 index 00000000000..356bf4da579 --- /dev/null +++ b/gamestonk_terminal/stocks/sector_industry_analysis/sia_api.py @@ -0,0 +1,20 @@ +"""Screener API.""" +import os +from gamestonk_terminal.helper_classes import ModelsNamespace as _models + +# flake8: noqa +# pylint: disable=unused-import + +# Menu commands +from .financedatabase_model import get_industries as industry +from .financedatabase_model import get_sectors as sector +from .financedatabase_model import get_countries as country +from .financedatabase_view import display_bars_financials as metric +from .financedatabase_view import display_companies_per_sector_in_country as cps +from .financedatabase_view import display_companies_per_industry_in_country as cpic +from .financedatabase_view import display_companies_per_industry_in_sector as cpis +from .financedatabase_view import display_companies_per_country_in_sector as cpcs +from .financedatabase_view import display_companies_per_country_in_industry as cpci + +# Models +models = _models(os.path.abspath(os.path.dirname(__file__))) diff --git a/gamestonk_terminal/stocks/sector_industry_analysis/sia_controller.py b/gamestonk_terminal/stocks/sector_industry_analysis/sia_controller.py index d43d2450473..8e2b90ac00b 100644 --- a/gamestonk_terminal/stocks/sector_industry_analysis/sia_controller.py +++ b/gamestonk_terminal/stocks/sector_industry_analysis/sia_controller.py @@ -134,7 +134,7 @@ class SectorIndustryAnalysisController(BaseController): self.sector = "Financial Services" self.industry = "Financial Data & Stock Exchanges" self.mktcap = "Large" - self.exclude_exhanges = True + self.exclude_exchanges = True self.ticker = ticker @@ -238,7 +238,7 @@ Industry : {self.industry} Sector : {self.sector} Country : {self.country} Market Cap : {self.mktcap} -Exclude Exchanges : {self.exclude_exhanges} +Exclude Exchanges : {self.exclude_exchanges} Statistics{c} cps companies per Sector based on Country{m} and Market Cap{r}{c} @@ -249,7 +249,7 @@ Statistics{c} {r}{Style.DIM if params else ''} Financials {'- loaded data (fast mode) 'if self.stocks_data else ''} sama see all metrics available - metric visualise financial metric across filters selected + metric visualize financial metric across filters selected {r if params else ''}{Style.DIM if len(self.tickers) == 0 else ''} Returned tickers: {', '.join(self.tickers)} > ca take these to comparison analysis menu @@ -268,9 +268,10 @@ Returned tickers: {', '.join(self.tickers)} add_help=False, formatter_class=argparse.ArgumentDefaultsHelpFormatter, prog="load", - description="Load stock ticker to perform analysis on. When the data source is 'yf', an Indian ticker can be" - " loaded by using '.NS' at the end, e.g. 'SBIN.NS'. See available market in" - " https://help.yahoo.com/kb/exchanges-data-providers-yahoo-finance-sln2310.html.", + description="Load stock ticker to perform analysis on. When the data source" + + " is 'yf', an Indian ticker can be loaded by using '.NS' at the end," + + " e.g. 'SBIN.NS'. See available market in" + + " https://help.yahoo.com/kb/exchanges-data-providers-yahoo-finance-sln2310.html.", ) parser.add_argument( "-t", @@ -559,9 +560,9 @@ Returned tickers: {', '.join(self.tickers)} ) ns_parser = parse_known_args_and_warn(parser, other_args) if ns_parser: - self.exclude_exhanges = not self.exclude_exhanges + self.exclude_exchanges = not self.exclude_exchanges print( - f"Internationa exchanges {'excluded' if self.exclude_exhanges else 'included'}", + f"Internationa exchanges {'excluded' if self.exclude_exchanges else 'included'}", "\n", ) @@ -602,7 +603,7 @@ Returned tickers: {', '.join(self.tickers)} self.country = "" self.mktcap = "" - self.exclude_exhanges = True + self.exclude_exchanges = True self.ticker = "" self.update_runtime_choices() self.stocks_data = {} @@ -661,7 +662,7 @@ Returned tickers: {', '.join(self.tickers)} add_help=False, formatter_class=argparse.ArgumentDefaultsHelpFormatter, prog="metric", - description="Visualise a particular metric with the filters selected", + description="Visualize a particular metric with the filters selected", ) parser.add_argument( "-m", @@ -704,7 +705,7 @@ Returned tickers: {', '.join(self.tickers)} self.sector, self.industry, self.mktcap, - self.exclude_exhanges, + self.exclude_exchanges, ns_parser.limit, ns_parser.export, ns_parser.raw, @@ -754,7 +755,7 @@ Returned tickers: {', '.join(self.tickers)} financedatabase_view.display_companies_per_sector_in_country( self.country, self.mktcap, - self.exclude_exhanges, + self.exclude_exchanges, ns_parser.export, ns_parser.raw, ns_parser.max_sectors_to_display, @@ -804,7 +805,7 @@ Returned tickers: {', '.join(self.tickers)} financedatabase_view.display_companies_per_industry_in_country( self.country, self.mktcap, - self.exclude_exhanges, + self.exclude_exchanges, ns_parser.export, ns_parser.raw, ns_parser.max_industries_to_display, @@ -854,7 +855,7 @@ Returned tickers: {', '.join(self.tickers)} financedatabase_view.display_companies_per_industry_in_sector( self.sector, self.mktcap, - self.exclude_exhanges, + self.exclude_exchanges, ns_parser.export, ns_parser.raw, ns_parser.max_industries_to_display, @@ -904,7 +905,7 @@ Returned tickers: {', '.join(self.tickers)} financedatabase_view.display_companies_per_country_in_sector( self.sector, self.mktcap, - self.exclude_exhanges, + self.exclude_exchanges, ns_parser.export, ns_parser.raw, ns_parser.max_countries_to_display, @@ -954,7 +955,7 @@ Returned tickers: {', '.join(self.tickers)} financedatabase_view.display_companies_per_country_in_industry( self.industry, self.mktcap, - self.exclude_exhanges, + self.exclude_exchanges, ns_parser.export, ns_parser.raw, ns_parser.max_countries_to_display, diff --git a/gamestonk_terminal/stocks/stocks_api.py b/gamestonk_terminal/stocks/stocks_api.py new file mode 100644 index 00000000000..5012c014d4b --- /dev/null +++ b/gamestonk_terminal/stocks/stocks_api.py @@ -0,0 +1,28 @@ +"""Stocks context API.""" +# flake8: noqa +# pylint: disable=unused-import + +# Context root level functions +from gamestonk_terminal.common.newsapi_view import news +from .stocks_helper import load, process_candle, search, quote +from .stocks_helper import display_candle as candle + +# Context menus +from .backtesting import bt_api as bt +from .behavioural_analysis import ba_api as ba +from .comparison_analysis import ca_api as ca +from .discovery import disc_api as disc +from .due_diligence import dd_api as dd +from .fundamental_analysis import fa_api as fa +from .government import gov_api as gov +from .insider import insider_api as ins +from .options import options_api as options +from .quantitative_analysis import qa_api as qa +from .screener import screener_api as screener +from .sector_industry_analysis import sia_api as sia +from .technical_analysis import ta_api as ta + +try: + from .prediction_techniques import pred_api as pred +except Exception: + print("Prediction API is not available.") diff --git a/gamestonk_terminal/stocks/stocks_controller.py b/gamestonk_terminal/stocks/stocks_controller.py index 41bc11e6451..f7ebb025c63 100644 --- a/gamestonk_terminal/stocks/stocks_controller.py +++ b/gamestonk_terminal/stocks/stocks_controller.py @@ -164,9 +164,10 @@ Stocks Menus: add_help=False, formatter_class=argparse.ArgumentDefaultsHelpFormatter, prog="load", - description="Load stock ticker to perform analysis on. When the data source is syf', an Indian ticker can be" - " loaded by using '.NS' at the end, e.g. 'SBIN.NS'. See available market in" - " https://help.yahoo.com/kb/exchanges-data-providers-yahoo-finance-sln2310.html.", + description="Load stock ticker to perform analysis on. When the data source" + + " is syf', an Indian ticker can be" + + " loaded by using '.NS' at the end, e.g. 'SBIN.NS'. See available market in" + + " https://help.yahoo.com/kb/exchanges-data-providers-yahoo-finance-sln2310.html.", ) parser.add_argument( "-t", diff --git a/gamestonk_terminal/stocks/technical_analysis/ta_api.py b/gamestonk_terminal/stocks/technical_analysis/ta_api.py new file mode 100644 index 00000000000..db2104ea85f --- /dev/null +++ b/gamestonk_terminal/stocks/technical_analysis/ta_api.py @@ -0,0 +1,60 @@ +"""Screener API.""" +import os +from gamestonk_terminal.helper_classes import ModelsNamespace as _models + +# flake8: noqa +# pylint: disable=unused-import + +# Menu commands +from gamestonk_terminal.common.technical_analysis.overlap_view import view_ma as ma +from gamestonk_terminal.common.technical_analysis.momentum_view import ( + display_cci as cci, +) +from gamestonk_terminal.common.technical_analysis.momentum_view import ( + display_macd as macd, +) +from gamestonk_terminal.common.technical_analysis.momentum_view import ( + display_rsi as rsi, +) +from gamestonk_terminal.common.technical_analysis.momentum_view import ( + display_stoch as stoch, +) +from gamestonk_terminal.common.technical_analysis.momentum_view import ( + display_fisher as fisher, +) +from gamestonk_terminal.common.technical_analysis.momentum_view import display_cg as cg +from gamestonk_terminal.common.technical_analysis.trend_indicators_view import ( + display_adx as adx, +) +from gamestonk_terminal.common.technical_analysis.trend_indicators_view import ( + display_aroon as aroon, +) +from gamestonk_terminal.common.technical_analysis.volatility_view import ( + display_bbands as bbands, +) +from gamestonk_terminal.common.technical_analysis.volatility_view import ( + display_donchian as donchian, +) +from gamestonk_terminal.common.technical_analysis.volatility_view import view_kc as kc +from gamestonk_terminal.common.technical_analysis.volume_view import display_ad as ad +from gamestonk_terminal.common.technical_analysis.volume_view import ( + display_adosc as adosc, +) +from gamestonk_terminal.common.technical_analysis.volume_view import display_obv as obv +from gamestonk_terminal.common.technical_analysis.custom_indicators_view import ( + fibonacci_retracement as fib, +) +from .finviz_view import view +from .finbrain_view import technical_summary_report as summary +from .tradingview_view import print_recommendation as recom + + +# Models +# NOTE: The ma function is used here to point to the commons path where all the +# ta models are expected to live +models = _models( + [ + os.path.abspath(os.path.dirname(ma.__code__.co_filename)), + os.path.abspath(os.path.dirname(__file__)), + ] +) diff --git a/gamestonk_terminal/stocks/technical_analysis/ta_controller.py b/gamestonk_terminal/stocks/technical_analysis/ta_controller.py index f3778e5838d..975962df7d5 100644 --- a/gamestonk_terminal/stocks/technical_analysis/ta_controller.py +++ b/gamestonk_terminal/stocks/technical_analysis/ta_controller.py @@ -156,9 +156,10 @@ Custom: add_help=False, formatter_class=argparse.ArgumentDefaultsHelpFormatter, prog="load", - description="Load stock ticker to perform analysis on. When the data source is 'yf', an Indian ticker can be" - " loaded by using '.NS' at the end, e.g. 'SBIN.NS'. See available market in" - " https://help.yahoo.com/kb/exchanges-data-providers-yahoo-finance-sln2310.html.", + description="Load stock ticker to perform analysis on. When the data source" + + " is 'yf', an Indian ticker can be loaded by using '.NS' at the end," + + " e.g. 'SBIN.NS'. See available market in" + + " https://help.yahoo.com/kb/exchanges-data-providers-yahoo-finance-sln2310.html.", ) parser.add_argument( "-t",