diff --git a/gamestonk_terminal/parent_classes.py b/gamestonk_terminal/parent_classes.py index 08af98bdec1..f934fa82b59 100644 --- a/gamestonk_terminal/parent_classes.py +++ b/gamestonk_terminal/parent_classes.py @@ -7,15 +7,24 @@ import re import os import difflib from typing import Union, List, Dict, Any +from datetime import datetime, timedelta from prompt_toolkit.completion import NestedCompleter from rich.markdown import Markdown +import pandas as pd +import numpy as np from gamestonk_terminal.menu import session from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.decorators import try_except -from gamestonk_terminal.helper_funcs import system_clear, get_flair +from gamestonk_terminal.helper_funcs import ( + system_clear, + get_flair, + valid_date, + parse_known_args_and_warn, +) from gamestonk_terminal.rich_config import console +from gamestonk_terminal.stocks import stocks_helper controllers: Dict[str, Any] = {} @@ -285,3 +294,129 @@ class BaseController(metaclass=ABCMeta): self.queue.insert(0, an_input) else: console.print("\n") + + +class StockController(BaseController, metaclass=ABCMeta): + def __init__(self, queue): + """ + This is a base class for Stock Controllers that use a load function. + """ + super().__init__(queue) + self.stock = pd.DataFrame() + self.interval = "1440min" + self.ticker = "" + self.start = "" + self.suffix = "" # To hold suffix for Yahoo Finance + self.add_info = stocks_helper.additional_info_about_ticker("") + + def call_load(self, other_args: List[str]): + """Process load command""" + parser = argparse.ArgumentParser( + 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.", + ) + parser.add_argument( + "-t", + "--ticker", + action="store", + dest="ticker", + required="-h" not in other_args, + help="Stock ticker", + ) + parser.add_argument( + "-s", + "--start", + type=valid_date, + default=(datetime.now() - timedelta(days=1100)).strftime("%Y-%m-%d"), + dest="start", + help="The starting date (format YYYY-MM-DD) of the stock", + ) + parser.add_argument( + "-e", + "--end", + type=valid_date, + default=datetime.now().strftime("%Y-%m-%d"), + dest="end", + help="The ending date (format YYYY-MM-DD) of the stock", + ) + parser.add_argument( + "-i", + "--interval", + action="store", + dest="interval", + type=int, + default=1440, + choices=[1, 5, 15, 30, 60], + help="Intraday stock minutes", + ) + parser.add_argument( + "--source", + action="store", + dest="source", + choices=["yf", "av", "iex"] if "-i" not in other_args else ["yf"], + default="yf", + help="Source of historical data.", + ) + parser.add_argument( + "-p", + "--prepost", + action="store_true", + default=False, + dest="prepost", + help="Pre/After market hours. Only works for 'yf' source, and intraday data", + ) + parser.add_argument( + "-r", + "--iexrange", + dest="iexrange", + help="Range for using the iexcloud api. Note that longer range requires more tokens in account", + choices=["ytd", "1y", "2y", "5y", "6m"], + type=str, + default="ytd", + ) + if other_args and "-" not in other_args[0][0]: + other_args.insert(0, "-t") + + ns_parser = parse_known_args_and_warn(parser, other_args) + if ns_parser: + df_stock_candidate = stocks_helper.load( + ns_parser.ticker, + ns_parser.start, + ns_parser.interval, + ns_parser.end, + ns_parser.prepost, + ns_parser.source, + ) + if not df_stock_candidate.empty: + self.stock = df_stock_candidate + self.add_info = stocks_helper.additional_info_about_ticker( + ns_parser.ticker + ) + console.print(self.add_info) + if "." in ns_parser.ticker: + self.ticker, self.suffix = ns_parser.ticker.upper().split(".") + else: + self.ticker = ns_parser.ticker.upper() + self.suffix = "" + + if ns_parser.source == "iex": + self.start = self.stock.index[0].strftime("%Y-%m-%d") + else: + self.start = ns_parser.start + self.interval = f"{ns_parser.interval}min" + + if self.PATH in ["/stocks/qa/", "/stocks/pred/"]: + self.stock["Returns"] = self.stock["Adj Close"].pct_change() + self.stock["LogRet"] = np.log(self.stock["Adj Close"]) - np.log( + self.stock["Adj Close"].shift(1) + ) + self.stock["LogPrice"] = np.log(self.stock["Adj Close"]) + self.stock = self.stock.rename(columns={"Adj Close": "AdjClose"}) + self.stock = self.stock.dropna() + self.stock.columns = [x.lower() for x in self.stock.columns] + console.print("") diff --git a/gamestonk_terminal/stocks/behavioural_analysis/ba_controller.py b/gamestonk_terminal/stocks/behavioural_analysis/ba_controller.py index 28bebc2a80d..cdf9eb2077a 100644 --- a/gamestonk_terminal/stocks/behavioural_analysis/ba_controller.py +++ b/gamestonk_terminal/stocks/behavioural_analysis/ba_controller.py @@ -7,8 +7,7 @@ from datetime import datetime, timedelta from prompt_toolkit.completion import NestedCompleter from gamestonk_terminal.rich_config import console -from gamestonk_terminal.parent_classes import BaseController -from gamestonk_terminal.decorators import try_except +from gamestonk_terminal.parent_classes import StockController from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.helper_funcs import ( EXPORT_BOTH_RAW_DATA_AND_FIGURES, @@ -28,12 +27,11 @@ from gamestonk_terminal.common.behavioural_analysis import ( twitter_view, sentimentinvestor_view, ) -from gamestonk_terminal.stocks import stocks_helper # pylint:disable=R0904,C0302 -class BehaviouralAnalysisController(BaseController): +class BehaviouralAnalysisController(StockController): """Behavioural Analysis Controller class""" CHOICES_COMMANDS = [ @@ -114,51 +112,6 @@ class BehaviouralAnalysisController(BaseController): """ console.print(text=help_text, menu="Stocks - Behavioural Analysis") - @try_except - def call_load(self, other_args: List[str]): - """Process load command""" - parser = argparse.ArgumentParser( - 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.", - ) - parser.add_argument( - "-t", - "--ticker", - action="store", - dest="ticker", - required="-h" not in other_args, - help="Stock ticker", - ) - parser.add_argument( - "-s", - "--start", - type=valid_date, - default=(datetime.now() - timedelta(days=366)).strftime("%Y-%m-%d"), - dest="start", - help="The starting date (format YYYY-MM-DD) of the stock", - ) - if other_args and "-" not in other_args[0][0]: - other_args.insert(0, "-t") - ns_parser = parse_known_args_and_warn(parser, other_args) - if ns_parser: - df_stock_candidate = stocks_helper.load( - ns_parser.ticker, - ns_parser.start, - ) - if not df_stock_candidate.empty: - self.start = ns_parser.start - if "." in ns_parser.ticker: - self.ticker = ns_parser.ticker.upper().split(".")[0] - else: - self.ticker = ns_parser.ticker.upper() - else: - console.print("Provide a valid ticker") - def call_watchlist(self, other_args: List[str]): """Process watchlist command""" parser = argparse.ArgumentParser( diff --git a/gamestonk_terminal/stocks/dark_pool_shorts/dps_controller.py b/gamestonk_terminal/stocks/dark_pool_shorts/dps_controller.py index 36dedc240ae..e08e350328a 100644 --- a/gamestonk_terminal/stocks/dark_pool_shorts/dps_controller.py +++ b/gamestonk_terminal/stocks/dark_pool_shorts/dps_controller.py @@ -7,7 +7,7 @@ from datetime import datetime, timedelta import pandas as pd from prompt_toolkit.completion import NestedCompleter from gamestonk_terminal.rich_config import console -from gamestonk_terminal.parent_classes import BaseController +from gamestonk_terminal.parent_classes import StockController from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.menu import session from gamestonk_terminal.helper_funcs import ( @@ -18,7 +18,6 @@ from gamestonk_terminal.helper_funcs import ( EXPORT_BOTH_RAW_DATA_AND_FIGURES, EXPORT_ONLY_RAW_DATA_ALLOWED, ) -from gamestonk_terminal.stocks import stocks_helper from gamestonk_terminal.stocks.dark_pool_shorts import ( yahoofinance_view, stockgrid_view, @@ -30,7 +29,7 @@ from gamestonk_terminal.stocks.dark_pool_shorts import ( ) -class DarkPoolShortsController(BaseController): +class DarkPoolShortsController(StockController): """Dark Pool Shorts Controller class""" CHOICES_COMMANDS = [ @@ -100,49 +99,6 @@ class DarkPoolShortsController(BaseController): {has_ticker_end}""" console.print(text=help_text, menu="Stocks - Dark Pool and Short data") - def call_load(self, other_args: List[str]): - """Process load command""" - parser = argparse.ArgumentParser( - 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.", - ) - parser.add_argument( - "-t", - "--ticker", - action="store", - dest="ticker", - required="-h" not in other_args, - help="Stock ticker", - ) - parser.add_argument( - "-s", - "--start", - type=valid_date, - default=(datetime.now() - timedelta(days=366)).strftime("%Y-%m-%d"), - dest="start", - help="The starting date (format YYYY-MM-DD) of the stock", - ) - if other_args and "-" not in other_args[0][0]: - other_args.insert(0, "-t") - ns_parser = parse_known_args_and_warn(parser, other_args) - if ns_parser: - df_stock_candidate = stocks_helper.load( - ns_parser.ticker, - ns_parser.start, - ) - - if not df_stock_candidate.empty: - self.stock = df_stock_candidate - self.start = ns_parser.start - if "." in ns_parser.ticker: - self.ticker = ns_parser.ticker.upper().split(".")[0] - else: - self.ticker = ns_parser.ticker.upper() - def call_shorted(self, other_args: List[str]): """Process shorted command""" parser = argparse.ArgumentParser( diff --git a/gamestonk_terminal/stocks/due_diligence/dd_controller.py b/gamestonk_terminal/stocks/due_diligence/dd_controller.py index 2c2ad0ee582..d3f48c58459 100644 --- a/gamestonk_terminal/stocks/due_diligence/dd_controller.py +++ b/gamestonk_terminal/stocks/due_diligence/dd_controller.py @@ -3,12 +3,11 @@ __docformat__ = "numpy" import argparse from typing import List -from datetime import datetime, timedelta from pandas.core.frame import DataFrame from prompt_toolkit.completion import NestedCompleter from gamestonk_terminal.rich_config import console -from gamestonk_terminal.parent_classes import BaseController +from gamestonk_terminal.parent_classes import StockController from gamestonk_terminal.stocks.due_diligence import ( fmp_view, business_insider_view, @@ -23,13 +22,12 @@ from gamestonk_terminal.helper_funcs import ( parse_known_args_and_warn, check_positive, EXPORT_ONLY_RAW_DATA_ALLOWED, - valid_date, ) from gamestonk_terminal.menu import session from gamestonk_terminal.stocks import stocks_helper -class DueDiligenceController(BaseController): +class DueDiligenceController(StockController): """Due Diligence Controller class""" CHOICES_COMMANDS = [ @@ -98,74 +96,6 @@ class DueDiligenceController(BaseController): return ["stocks", f"load {self.ticker}", "dd"] return [] - def call_load(self, other_args: List[str]): - """Process load command""" - parser = argparse.ArgumentParser( - 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.", - ) - parser.add_argument( - "-t", - "--ticker", - action="store", - dest="ticker", - required="-h" not in other_args, - help="Stock ticker", - ) - parser.add_argument( - "-s", - "--start", - type=valid_date, - default=(datetime.now() - timedelta(days=366)).strftime("%Y-%m-%d"), - dest="start", - help="The starting date (format YYYY-MM-DD) of the stock", - ) - parser.add_argument( - "-i", - "--interval", - action="store", - dest="interval", - type=int, - default=1440, - choices=stocks_helper.INTERVALS, - help="Intraday stock minutes", - ) - parser.add_argument( - "--source", - action="store", - dest="source", - choices=stocks_helper.SOURCES, - default="yf", - help="Source of historical data.", - ) - # For the case where a user uses: 'load BB' - if other_args and "-t" not in other_args and "-h" not in other_args: - other_args.insert(0, "-t") - - ns_parser = parse_known_args_and_warn( - parser, other_args, EXPORT_ONLY_RAW_DATA_ALLOWED - ) - if ns_parser: - df_stock_candidate = stocks_helper.load( - ticker=ns_parser.ticker, - start=ns_parser.start, - interval=ns_parser.interval, - source=ns_parser.source, - ) - - if not df_stock_candidate.empty: - self.stock = df_stock_candidate - self.start = ns_parser.start - if "." in ns_parser.ticker: - self.ticker = ns_parser.ticker.upper().split(".")[0] - else: - self.ticker = ns_parser.ticker.upper() - def call_analyst(self, other_args: List[str]): """Process analyst command""" parser = argparse.ArgumentParser( diff --git a/gamestonk_terminal/stocks/fundamental_analysis/fa_controller.py b/gamestonk_terminal/stocks/fundamental_analysis/fa_controller.py index 72a26e367a6..786fd28e051 100644 --- a/gamestonk_terminal/stocks/fundamental_analysis/fa_controller.py +++ b/gamestonk_terminal/stocks/fundamental_analysis/fa_controller.py @@ -2,12 +2,11 @@ __docformat__ = "numpy" import argparse -from datetime import datetime, timedelta from typing import List from prompt_toolkit.completion import NestedCompleter from gamestonk_terminal.rich_config import console -from gamestonk_terminal.parent_classes import BaseController +from gamestonk_terminal.parent_classes import StockController from gamestonk_terminal.stocks.fundamental_analysis.financial_modeling_prep import ( fmp_controller, fmp_view, @@ -26,7 +25,6 @@ from gamestonk_terminal.helper_funcs import ( EXPORT_ONLY_RAW_DATA_ALLOWED, parse_known_args_and_warn, check_positive, - valid_date, ) from gamestonk_terminal.stocks import stocks_helper from gamestonk_terminal.menu import session @@ -34,7 +32,7 @@ from gamestonk_terminal.menu import session # pylint: disable=inconsistent-return-statements -class FundamentalAnalysisController(BaseController): +class FundamentalAnalysisController(StockController): """Fundamental Analysis Controller class""" CHOICES_COMMANDS = [ @@ -131,74 +129,6 @@ Ticker: [/param] {self.ticker} [cmds] return ["stocks", f"load {self.ticker}", "fa"] return [] - def call_load(self, other_args: List[str]): - """Process load command.""" - parser = argparse.ArgumentParser( - 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.", - ) - parser.add_argument( - "-t", - "--ticker", - action="store", - dest="ticker", - required="-h" not in other_args, - help="Stock ticker", - ) - parser.add_argument( - "-s", - "--start", - type=valid_date, - default=(datetime.now() - timedelta(days=366)).strftime("%Y-%m-%d"), - dest="start", - help="The starting date (format YYYY-MM-DD) of the stock", - ) - parser.add_argument( - "-i", - "--interval", - action="store", - dest="interval", - type=int, - default=1440, - choices=stocks_helper.INTERVALS, - help="Intraday stock minutes", - ) - parser.add_argument( - "--source", - action="store", - dest="source", - choices=stocks_helper.SOURCES, - default="yf", - help="Source of historical data.", - ) - # For the case where a user uses: 'load BB' - if other_args and "-t" not in other_args and "-h" not in other_args: - other_args.insert(0, "-t") - - ns_parser = parse_known_args_and_warn( - parser, other_args, EXPORT_ONLY_RAW_DATA_ALLOWED - ) - if ns_parser: - df_stock_candidate = stocks_helper.load( - ticker=ns_parser.ticker, - start=ns_parser.start, - interval=ns_parser.interval, - source=ns_parser.source, - ) - - if not df_stock_candidate.empty: - self.start = ns_parser.start - self.interval = str(ns_parser.interval) + "min" - if "." in ns_parser.ticker: - self.ticker = ns_parser.ticker.upper().split(".")[0] - else: - self.ticker = ns_parser.ticker.upper() - def call_analysis(self, other_args: List[str]): """Process analysis command.""" parser = argparse.ArgumentParser( diff --git a/gamestonk_terminal/stocks/government/gov_controller.py b/gamestonk_terminal/stocks/government/gov_controller.py index a5f39be6a42..3966c841133 100644 --- a/gamestonk_terminal/stocks/government/gov_controller.py +++ b/gamestonk_terminal/stocks/government/gov_controller.py @@ -2,28 +2,25 @@ __docformat__ = "numpy" import argparse -from datetime import datetime, timedelta from typing import List from prompt_toolkit.completion import NestedCompleter from gamestonk_terminal.rich_config import console -from gamestonk_terminal.parent_classes import BaseController +from gamestonk_terminal.parent_classes import StockController from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.menu import session from gamestonk_terminal.stocks.government import quiverquant_view from gamestonk_terminal.helper_funcs import ( parse_known_args_and_warn, check_positive, - valid_date, ) -from gamestonk_terminal.stocks import stocks_helper from gamestonk_terminal.helper_funcs import ( EXPORT_ONLY_RAW_DATA_ALLOWED, EXPORT_BOTH_RAW_DATA_AND_FIGURES, ) -class GovController(BaseController): +class GovController(StockController): """Gov Controller class""" CHOICES_COMMANDS = [ @@ -97,46 +94,6 @@ class GovController(BaseController): return ["stocks", f"load {self.ticker}", "gov"] return [] - def call_load(self, other_args: List[str]): - """Process load command""" - parser = argparse.ArgumentParser( - 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.", - ) - parser.add_argument( - "-t", - "--ticker", - action="store", - dest="ticker", - required="-h" not in other_args, - help="Stock ticker", - ) - parser.add_argument( - "-s", - "--start", - type=valid_date, - default=(datetime.now() - timedelta(days=366)).strftime("%Y-%m-%d"), - dest="start", - help="The starting date (format YYYY-MM-DD) of the stock", - ) - if other_args and "-" not in other_args[0][0]: - other_args.insert(0, "-t") - ns_parser = parse_known_args_and_warn(parser, other_args) - if ns_parser: - df_stock_candidate = stocks_helper.load( - ns_parser.ticker, - ns_parser.start, - ) - if not df_stock_candidate.empty: - self.ticker = ns_parser.ticker.upper() - else: - console.print("Ticker selected does not exist!", "\n") - def call_lasttrades(self, other_args: List[str]): """Process lasttrades command""" parser = argparse.ArgumentParser( diff --git a/gamestonk_terminal/stocks/insider/insider_controller.py b/gamestonk_terminal/stocks/insider/insider_controller.py index cfb32e105fe..74de189ca21 100644 --- a/gamestonk_terminal/stocks/insider/insider_controller.py +++ b/gamestonk_terminal/stocks/insider/insider_controller.py @@ -9,7 +9,7 @@ import pandas as pd from prompt_toolkit.completion import NestedCompleter from gamestonk_terminal.rich_config import console -from gamestonk_terminal.parent_classes import BaseController +from gamestonk_terminal.parent_classes import StockController from gamestonk_terminal.helper_funcs import ( EXPORT_ONLY_RAW_DATA_ALLOWED, parse_known_args_and_warn, @@ -17,7 +17,6 @@ from gamestonk_terminal.helper_funcs import ( ) from gamestonk_terminal.menu import session from gamestonk_terminal import feature_flags as gtff -from gamestonk_terminal.stocks import stocks_helper from gamestonk_terminal.stocks.insider import ( openinsider_view, businessinsider_view, @@ -33,7 +32,7 @@ presets_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), "presets # - unification of model return types (now some return dataframes other records list) -class InsiderController(BaseController): +class InsiderController(StockController): """Screener Controller class""" CHOICES_COMMANDS = [ @@ -150,42 +149,6 @@ class InsiderController(BaseController): return ["stocks", f"load {self.ticker}", "ins"] return [] - def call_load(self, other_args: List[str]): - """Process load command""" - parser = argparse.ArgumentParser( - 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.", - ) - parser.add_argument( - "-t", - "--ticker", - action="store", - dest="ticker", - required="-h" not in other_args, - help="Stock ticker", - ) - if other_args and "-" not in other_args[0][0]: - other_args.insert(0, "-t") - ns_parser = parse_known_args_and_warn(parser, other_args) - if ns_parser: - df_stock_candidate = stocks_helper.load( - ns_parser.ticker, - ) - if not df_stock_candidate.empty: - if "." in ns_parser.ticker: - self.ticker = ns_parser.ticker.upper().split(".")[0] - else: - self.ticker = ns_parser.ticker.upper() - - self.stock = df_stock_candidate - self.start = self.stock.index[0].strftime("%Y-%m-%d") - self.interval = "1440min" - def call_view(self, other_args: List[str]): """Process view command""" parser = argparse.ArgumentParser( diff --git a/gamestonk_terminal/stocks/prediction_techniques/pred_controller.py b/gamestonk_terminal/stocks/prediction_techniques/pred_controller.py index 91374daf0f5..2b0c3367c5a 100644 --- a/gamestonk_terminal/stocks/prediction_techniques/pred_controller.py +++ b/gamestonk_terminal/stocks/prediction_techniques/pred_controller.py @@ -3,7 +3,7 @@ __docformat__ = "numpy" import argparse from typing import List -from datetime import datetime, timedelta +from datetime import datetime import pandas as pd import numpy as np from prompt_toolkit.completion import NestedCompleter @@ -122,102 +122,6 @@ class PredictionTechniquesController(BaseController): return ["stocks", f"load {self.ticker}", "pred"] return [] - def call_load(self, other_args: List[str]): - """Process load command""" - parser = argparse.ArgumentParser( - 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.", - ) - parser.add_argument( - "-t", - "--ticker", - action="store", - dest="ticker", - required="-h" not in other_args, - help="Stock ticker", - ) - parser.add_argument( - "-s", - "--start", - type=valid_date, - default=(datetime.now() - timedelta(days=366)).strftime("%Y-%m-%d"), - dest="start", - help="The starting date (format YYYY-MM-DD) of the stock", - ) - parser.add_argument( - "-e", - "--end", - type=valid_date, - default=datetime.now().strftime("%Y-%m-%d"), - dest="end", - help="The ending date (format YYYY-MM-DD) of the stock", - ) - parser.add_argument( - "-i", - "--interval", - action="store", - dest="interval", - type=int, - default=1440, - choices=stocks_helper.INTERVALS, - help="Intraday stock minutes", - ) - parser.add_argument( - "--source", - action="store", - dest="source", - choices=stocks_helper.SOURCES, - default="yf", - help="Source of historical data.", - ) - parser.add_argument( - "-p", - "--prepost", - action="store_true", - default=False, - dest="prepost", - help="Pre/After market hours. Only works for 'yf' source, and intraday data", - ) - - # For the case where a user uses: 'load BB' - if other_args and "-t" not in other_args and "-h" not in other_args: - other_args.insert(0, "-t") - - ns_parser = parse_known_args_and_warn( - parser, other_args, EXPORT_ONLY_FIGURES_ALLOWED - ) - if ns_parser: - df_stock_candidate = stocks_helper.load( - ns_parser.ticker, - ns_parser.start, - ns_parser.interval, - ns_parser.end, - ns_parser.prepost, - ns_parser.source, - ) - - if not df_stock_candidate.empty: - self.stock = df_stock_candidate - if "." in ns_parser.ticker: - self.ticker = ns_parser.ticker.upper().split(".")[0] - else: - self.ticker = ns_parser.ticker.upper() - - self.start = ns_parser.start - self.interval = str(ns_parser.interval) + "min" - - self.stock["Returns"] = self.stock["Adj Close"].pct_change() - self.stock["LogRet"] = np.log(self.stock["Adj Close"]) - np.log( - self.stock["Adj Close"].shift(1) - ) - self.stock = self.stock.rename(columns={"Adj Close": "AdjClose"}) - self.stock = self.stock.dropna() - def call_pick(self, other_args: List[str]): """Process pick command""" parser = argparse.ArgumentParser( diff --git a/gamestonk_terminal/stocks/quantitative_analysis/qa_controller.py b/gamestonk_terminal/stocks/quantitative_analysis/qa_controller.py index 9210330ea9c..9d32c048d37 100644 --- a/gamestonk_terminal/stocks/quantitative_analysis/qa_controller.py +++ b/gamestonk_terminal/stocks/quantitative_analysis/qa_controller.py @@ -3,32 +3,30 @@ __docformat__ = "numpy" import argparse from typing import List -from datetime import datetime, timedelta +from datetime import datetime import numpy as np import pandas as pd from prompt_toolkit.completion import NestedCompleter from gamestonk_terminal.rich_config import console -from gamestonk_terminal.parent_classes import BaseController +from gamestonk_terminal.parent_classes import StockController from gamestonk_terminal.common.quantitative_analysis import ( qa_view, rolling_view, ) from gamestonk_terminal import feature_flags as gtff -from gamestonk_terminal.stocks import stocks_helper from gamestonk_terminal.helper_funcs import ( EXPORT_ONLY_RAW_DATA_ALLOWED, EXPORT_ONLY_FIGURES_ALLOWED, check_positive, check_proportion_range, parse_known_args_and_warn, - valid_date, ) from gamestonk_terminal.menu import session from gamestonk_terminal.stocks.quantitative_analysis.factors_view import capm_view -class QaController(BaseController): +class QaController(StockController): """Quantitative Analysis Controller class""" CHOICES_COMMANDS = [ @@ -143,104 +141,6 @@ class QaController(BaseController): return ["stocks", f"load {self.ticker}", "qa"] return [] - def call_load(self, other_args: List[str]): - """Process load command""" - parser = argparse.ArgumentParser( - 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.", - ) - parser.add_argument( - "-t", - "--ticker", - action="store", - dest="ticker", - required="-h" not in other_args, - help="Stock ticker", - ) - parser.add_argument( - "-s", - "--start", - type=valid_date, - default=(datetime.now() - timedelta(days=1100)).strftime("%Y-%m-%d"), - dest="start", - help="The starting date (format YYYY-MM-DD) of the stock", - ) - parser.add_argument( - "-e", - "--end", - type=valid_date, - default=datetime.now().strftime("%Y-%m-%d"), - dest="end", - help="The ending date (format YYYY-MM-DD) of the stock", - ) - parser.add_argument( - "-i", - "--interval", - action="store", - dest="interval", - type=int, - default=1440, - choices=self.stock_interval, - help="Intraday stock minutes", - ) - parser.add_argument( - "--source", - action="store", - dest="source", - choices=self.stock_sources, - default="yf", - help="Source of historical data.", - ) - parser.add_argument( - "-p", - "--prepost", - action="store_true", - default=False, - dest="prepost", - help="Pre/After market hours. Only works for 'yf' source, and intraday data", - ) - - # For the case where a user uses: 'load BB' - if other_args and "-t" not in other_args and "-h" not in other_args: - other_args.insert(0, "-t") - - ns_parser = parse_known_args_and_warn(parser, other_args) - if ns_parser: - - df_stock_candidate = stocks_helper.load( - ns_parser.ticker, - ns_parser.start, - ns_parser.interval, - ns_parser.end, - ns_parser.prepost, - ns_parser.source, - ) - - if not df_stock_candidate.empty: - self.stock = df_stock_candidate - if "." in ns_parser.ticker: - self.ticker = ns_parser.ticker.upper().split(".")[0] - else: - self.ticker = ns_parser.ticker.upper() - - self.start = ns_parser.start - self.interval = str(ns_parser.interval) + "min" - - self.stock["Returns"] = self.stock["Adj Close"].pct_change() - self.stock["LogRet"] = np.log(self.stock["Adj Close"]) - np.log( - self.stock["Adj Close"].shift(1) - ) - self.stock["LogPrice"] = np.log(self.stock["Adj Close"]) - self.stock = self.stock.rename(columns={"Adj Close": "AdjClose"}) - self.stock = self.stock.dropna() - self.stock.columns = [x.lower() for x in self.stock.columns] - console.print("") - def call_pick(self, other_args: List[str]): """Process pick command""" parser = argparse.ArgumentParser( diff --git a/gamestonk_terminal/stocks/stocks_controller.py b/gamestonk_terminal/stocks/stocks_controller.py index 5637d24cd3e..bd2ea544123 100644 --- a/gamestonk_terminal/stocks/stocks_controller.py +++ b/gamestonk_terminal/stocks/stocks_controller.py @@ -8,11 +8,10 @@ from typing import List from datetime import datetime, timedelta import yfinance as yf -import pandas as pd from prompt_toolkit.completion import NestedCompleter from gamestonk_terminal.rich_config import console -from gamestonk_terminal.parent_classes import BaseController +from gamestonk_terminal.parent_classes import StockController from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.common import newsapi_view from gamestonk_terminal.helper_funcs import ( @@ -32,7 +31,7 @@ from gamestonk_terminal.common.quantitative_analysis import qa_view logger = logging.getLogger(__name__) -class StocksController(BaseController): +class StocksController(StockController): """Stocks Controller class""" CHOICES_COMMANDS = [ @@ -69,13 +68,6 @@ class StocksController(BaseController): """Constructor""" super().__init__(queue) - self.stock = pd.DataFrame() - self.ticker = "" - self.suffix = "" # To hold suffix for Yahoo Finance - self.start = "" - self.interval = "1440min" - self.add_info = stocks_helper.additional_info_about_ticker("") - if session and gtff.USE_PROMPT_TOOLKIT: choices: dict = {c: {} for c in self.controller_choices} self.completer = NestedCompleter.from_nested_dict(choices) @@ -163,108 +155,6 @@ Stock: [/param]{stock_text} if ns_parser: stocks_helper.search(query=ns_parser.query, amount=ns_parser.amount) - def call_load(self, other_args: List[str]): - """Process load command""" - parser = argparse.ArgumentParser( - 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.", - ) - parser.add_argument( - "-t", - "--ticker", - action="store", - dest="ticker", - required="-h" not in other_args, - help="Stock ticker", - ) - parser.add_argument( - "-s", - "--start", - type=valid_date, - default=(datetime.now() - timedelta(days=1100)).strftime("%Y-%m-%d"), - dest="start", - help="The starting date (format YYYY-MM-DD) of the stock", - ) - parser.add_argument( - "-e", - "--end", - type=valid_date, - default=datetime.now().strftime("%Y-%m-%d"), - dest="end", - help="The ending date (format YYYY-MM-DD) of the stock", - ) - parser.add_argument( - "-i", - "--interval", - action="store", - dest="interval", - type=int, - default=1440, - choices=[1, 5, 15, 30, 60], - help="Intraday stock minutes", - ) - parser.add_argument( - "--source", - action="store", - dest="source", - choices=["yf", "av", "iex"] if "-i" not in other_args else ["yf"], - default="yf", - help="Source of historical data.", - ) - parser.add_argument( - "-p", - "--prepost", - action="store_true", - default=False, - dest="prepost", - help="Pre/After market hours. Only works for 'yf' source, and intraday data", - ) - parser.add_argument( - "-r", - "--iexrange", - dest="iexrange", - help="Range for using the iexcloud api. Note that longer range requires more tokens in account", - choices=["ytd", "1y", "2y", "5y", "6m"], - type=str, - default="ytd", - ) - if other_args and "-" not in other_args[0][0]: - other_args.insert(0, "-t") - - ns_parser = parse_known_args_and_warn(parser, other_args) - if ns_parser: - df_stock_candidate = stocks_helper.load( - ns_parser.ticker, - ns_parser.start, - ns_parser.interval, - ns_parser.end, - ns_parser.prepost, - ns_parser.source, - ) - if not df_stock_candidate.empty: - self.stock = df_stock_candidate - self.add_info = stocks_helper.additional_info_about_ticker( - ns_parser.ticker - ) - console.print(self.add_info) - if "." in ns_parser.ticker: - self.ticker, self.suffix = ns_parser.ticker.upper().split(".") - else: - self.ticker = ns_parser.ticker.upper() - self.suffix = "" - - if ns_parser.source == "iex": - self.start = self.stock.index[0].strftime("%Y-%m-%d") - else: - self.start = ns_parser.start - self.interval = f"{ns_parser.interval}min" - console.print("") - def call_quote(self, other_args: List[str]): """Process quote command""" stocks_helper.quote( diff --git a/gamestonk_terminal/stocks/technical_analysis/ta_controller.py b/gamestonk_terminal/stocks/technical_analysis/ta_controller.py index 94e195cd3b5..b38607fcfcc 100644 --- a/gamestonk_terminal/stocks/technical_analysis/ta_controller.py +++ b/gamestonk_terminal/stocks/technical_analysis/ta_controller.py @@ -4,12 +4,12 @@ __docformat__ = "numpy" import argparse from typing import List -from datetime import datetime, timedelta +from datetime import datetime import pandas as pd from prompt_toolkit.completion import NestedCompleter from gamestonk_terminal.rich_config import console -from gamestonk_terminal.parent_classes import BaseController +from gamestonk_terminal.parent_classes import StockController from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.helper_funcs import ( EXPORT_BOTH_RAW_DATA_AND_FIGURES, @@ -41,7 +41,7 @@ from gamestonk_terminal.common.technical_analysis import ( from gamestonk_terminal.stocks import stocks_helper -class TechnicalAnalysisController(BaseController): +class TechnicalAnalysisController(StockController): """Technical Analysis Controller class""" CHOICES_COMMANDS = [ @@ -151,95 +151,6 @@ class TechnicalAnalysisController(BaseController): return ["stocks", f"load {self.ticker}", "ta"] return [] - def call_load(self, other_args: List[str]): - """Process load command""" - parser = argparse.ArgumentParser( - 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.", - ) - parser.add_argument( - "-t", - "--ticker", - action="store", - dest="ticker", - required="-h" not in other_args, - help="Stock ticker", - ) - parser.add_argument( - "-s", - "--start", - type=valid_date, - default=(datetime.now() - timedelta(days=366)).strftime("%Y-%m-%d"), - dest="start", - help="The starting date (format YYYY-MM-DD) of the stock", - ) - parser.add_argument( - "-e", - "--end", - type=valid_date, - default=datetime.now().strftime("%Y-%m-%d"), - dest="end", - help="The ending date (format YYYY-MM-DD) of the stock", - ) - parser.add_argument( - "-i", - "--interval", - action="store", - dest="interval", - type=int, - default=1440, - choices=stocks_helper.INTERVALS, - help="Intraday stock minutes", - ) - parser.add_argument( - "--source", - action="store", - dest="source", - choices=stocks_helper.SOURCES, - default="yf", - help="Source of historical data.", - ) - parser.add_argument( - "-p", - "--prepost", - action="store_true", - default=False, - dest="prepost", - help="Pre/After market hours. Only works for 'yf' source, and intraday data", - ) - - # For the case where a user uses: 'load BB' - if other_args and "-t" not in other_args and "-h" not in other_args: - other_args.insert(0, "-t") - - ns_parser = parse_known_args_and_warn( - parser, other_args, EXPORT_BOTH_RAW_DATA_AND_FIGURES - ) - if ns_parser: - df_stock_candidate = stocks_helper.load( - ns_parser.ticker, - ns_parser.start, - ns_parser.interval, - ns_parser.end, - ns_parser.prepost, - ns_parser.source, - ) - - if not df_stock_candidate.empty: - self.stock = df_stock_candidate - if "." in ns_parser.ticker: - self.ticker = ns_parser.ticker.upper().split(".")[0] - else: - self.ticker = ns_parser.ticker.upper() - - self.start = ns_parser.start - self.interval = f"{ns_parser.interval}min" - # SPECIFIC def call_view(self, other_args: List[str]): diff --git a/tests/gamestonk_terminal/stocks/behavioural_analysis/test_ba_controller.py b/tests/gamestonk_terminal/stocks/behavioural_analysis/test_ba_controller.py index 6a63b3b6a38..ccc3b37e82b 100644 --- a/tests/gamestonk_terminal/stocks/behavioural_analysis/test_ba_controller.py +++ b/tests/gamestonk_terminal/stocks/behavioural_analysis/test_ba_controller.py @@ -8,6 +8,7 @@ import pytest # IMPORTATION INTERNAL from gamestonk_terminal.stocks.behavioural_analysis import ba_controller +from gamestonk_terminal import parent_classes # pylint: disable=E1101 # pylint: disable=W0603 @@ -481,7 +482,6 @@ def test_call_func( @pytest.mark.parametrize( "func", [ - "call_load", "call_watchlist", "call_spac", "call_spac_c", @@ -556,7 +556,7 @@ def test_call_func_no_ticker(func, mocker): @pytest.mark.vcr def test_call_load(mocker): - yf_download = ba_controller.stocks_helper.yf.download + yf_download = parent_classes.stocks_helper.yf.download def mock_yf_download(*args, **kwargs): kwargs["threads"] = False diff --git a/tests/gamestonk_terminal/stocks/dark_pool_shorts/test_dps_controller.py b/tests/gamestonk_terminal/stocks/dark_pool_shorts/test_dps_controller.py index c0c58076992..b119b16e3e2 100644 --- a/tests/gamestonk_terminal/stocks/dark_pool_shorts/test_dps_controller.py +++ b/tests/gamestonk_terminal/stocks/dark_pool_shorts/test_dps_controller.py @@ -436,7 +436,6 @@ def test_call_func(tested_func, mocked_func, other_args, called_with, mocker): @pytest.mark.parametrize( "func", [ - "call_load", "call_shorted", "call_hsi", "call_prom", diff --git a/tests/gamestonk_terminal/stocks/government/test_gov_controller.py b/tests/gamestonk_terminal/stocks/government/test_gov_controller.py index 4a8f400378b..ca9504ec590 100644 --- a/tests/gamestonk_terminal/stocks/government/test_gov_controller.py +++ b/tests/gamestonk_terminal/stocks/government/test_gov_controller.py @@ -6,6 +6,7 @@ import pytest # IMPORTATION INTERNAL from gamestonk_terminal.stocks.government import gov_controller +from gamestonk_terminal import parent_classes # pylint: disable=E1101 # pylint: disable=W0603 @@ -374,7 +375,6 @@ def test_call_func(tested_func, mocked_func, other_args, called_with, mocker): @pytest.mark.parametrize( "func", [ - "call_load", "call_contracts", "call_gtrades", "call_histcont", @@ -425,7 +425,7 @@ def test_call_func_no_ticker(func, mocker): @pytest.mark.vcr def test_call_load(mocker): - yf_download = gov_controller.stocks_helper.yf.download + yf_download = parent_classes.stocks_helper.yf.download def mock_yf_download(*args, **kwargs): kwargs["threads"] = False diff --git a/tests/gamestonk_terminal/stocks/insider/test_insider_controller.py b/tests/gamestonk_terminal/stocks/insider/test_insider_controller.py index 83a38549efd..ed49250c90a 100644 --- a/tests/gamestonk_terminal/stocks/insider/test_insider_controller.py +++ b/tests/gamestonk_terminal/stocks/insider/test_insider_controller.py @@ -522,7 +522,6 @@ def test_call_func( @pytest.mark.parametrize( "func", [ - "call_load", "call_act", "call_lins", ], @@ -601,10 +600,9 @@ def test_call_func_no_stock(func): @pytest.mark.vcr(record_mode="none") def test_call_load(mocker): - path_controller = "gamestonk_terminal.stocks.insider.insider_controller" # MOCK LOAD - target = f"{path_controller}.stocks_helper.load" + target = "gamestonk_terminal.parent_classes.stocks_helper.load" mocker.patch(target=target, return_value=DF_STOCK) controller = insider_controller.InsiderController( diff --git a/tests/gamestonk_terminal/stocks/quantitative_analysis/test_qa_controller.py b/tests/gamestonk_terminal/stocks/quantitative_analysis/test_qa_controller.py index f6b8bb9b101..5514c62884d 100644 --- a/tests/gamestonk_terminal/stocks/quantitative_analysis/test_qa_controller.py +++ b/tests/gamestonk_terminal/stocks/quantitative_analysis/test_qa_controller.py @@ -8,6 +8,7 @@ import pytest # IMPORTATION INTERNAL from gamestonk_terminal.stocks.quantitative_analysis import qa_controller +from gamestonk_terminal import parent_classes # pylint: disable=E1101 # pylint: disable=W0603 @@ -531,7 +532,7 @@ def test_call_func( @pytest.mark.vcr def test_call_load(mocker): - yf_download = qa_controller.stocks_helper.yf.download + yf_download = parent_classes.stocks_helper.yf.download def mock_yf_download(*args, **kwargs): kwargs["threads"] = False diff --git a/tests/gamestonk_terminal/stocks/test_stocks_controller.py b/tests/gamestonk_terminal/stocks/test_stocks_controller.py index 10e0252d166..d72b19f2f17 100644 --- a/tests/gamestonk_terminal/stocks/test_stocks_controller.py +++ b/tests/gamestonk_terminal/stocks/test_stocks_controller.py @@ -485,7 +485,6 @@ def test_call_func( "func", [ "call_search", - "call_load", "call_candle", ], )