diff --git a/gamestonk_terminal/comparison_analysis/ca_controller.py b/gamestonk_terminal/comparison_analysis/ca_controller.py index 499b6c9cd39..3772807b71a 100644 --- a/gamestonk_terminal/comparison_analysis/ca_controller.py +++ b/gamestonk_terminal/comparison_analysis/ca_controller.py @@ -2,23 +2,24 @@ __docformat__ = "numpy" import argparse -import requests import random from typing import List from datetime import datetime +import requests import pandas as pd from matplotlib import pyplot as plt +from finvizfinance.screener.overview import Overview +from prompt_toolkit.completion import NestedCompleter + from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal import config_terminal as cfg -from finvizfinance.screener.overview import Overview from gamestonk_terminal.helper_funcs import get_flair, parse_known_args_and_warn -from gamestonk_terminal.comparison_analysis import yahoo_finance_api as yf_api -from gamestonk_terminal.comparison_analysis import market_watch_api as mw_api -from gamestonk_terminal.comparison_analysis import finbrain_api as f_api +from gamestonk_terminal.comparison_analysis import yahoo_finance_view +from gamestonk_terminal.comparison_analysis import market_watch_view +from gamestonk_terminal.comparison_analysis import finbrain_view from gamestonk_terminal.comparison_analysis import finviz_compare_view from gamestonk_terminal.portfolio_optimization import po_controller from gamestonk_terminal.menu import session -from prompt_toolkit.completion import NestedCompleter class ComparisonAnalysisController: @@ -54,9 +55,23 @@ class ComparisonAnalysisController: start: datetime, interval: str, similar: List[str], - user: bool, ): - """Constructor""" + """Constructor + + Parameters + ---------- + stock : pd.DataFrame + Stock data + ticker : str + Stock ticker + start : datetime + Start time + interval : str + Time interval + similar : List[str] + List of similar tickers + """ + self.similar = similar self.user = "" self.stock = stock @@ -69,7 +84,6 @@ class ComparisonAnalysisController: choices=self.CHOICES, ) - @staticmethod def print_help(self): """Print help""" @@ -108,14 +122,21 @@ class ComparisonAnalysisController: print(" performance brief performance comparison") print(" technical brief technical comparison") print("") + if self.similar: print(" > po portfolio optimization for selected tickers") print("") return - @staticmethod def get_similar_companies(self, other_args: List[str]): - """ Get similar companies. [Source: Polygon API] """ + """Get similar companies. [Source: Polygon API] + + Parameters + ---------- + other_args : List[str] + argparse other args + """ + parser = argparse.ArgumentParser( add_help=False, prog="get", @@ -189,9 +210,15 @@ class ComparisonAnalysisController: print("") return - @staticmethod def select_similar_companies(self, other_args: List[str]): - """ Select similar companies, e.g. NIO,XPEV,LI""" + """Select similar companies, e.g. NIO,XPEV,LI + + Parameters + ---------- + other_args : List[str] + argparse other args + """ + parser = argparse.ArgumentParser( add_help=False, prog="select", @@ -242,7 +269,7 @@ class ComparisonAnalysisController: def call_help(self, _): """Process Help command""" - self.print_help(self) + self.print_help() def call_q(self, _): """Process Q command - quit the menu""" @@ -254,43 +281,43 @@ class ComparisonAnalysisController: def call_get(self, other_args: List[str]): """Process get command""" - self.get_similar_companies(self, other_args) + self.get_similar_companies(other_args) def call_select(self, other_args: List[str]): """Process select command""" - self.select_similar_companies(self, other_args) + self.select_similar_companies(other_args) def call_historical(self, other_args: List[str]): """Process historical command""" - yf_api.historical( + yahoo_finance_view.historical( other_args, self.stock, self.ticker, self.start, self.interval, self.similar ) def call_hcorr(self, other_args: List[str]): """Process historical correlation command""" - yf_api.correlation( + yahoo_finance_view.correlation( other_args, self.stock, self.ticker, self.start, self.interval, self.similar ) def call_income(self, other_args: List[str]): """Process income command""" - mw_api.compare_income(other_args, self.ticker, self.similar) + market_watch_view.compare_income(other_args, self.ticker, self.similar) def call_balance(self, other_args: List[str]): """Process balance command""" - mw_api.compare_balance(other_args, self.ticker, self.similar) + market_watch_view.compare_balance(other_args, self.ticker, self.similar) def call_cashflow(self, other_args: List[str]): """Process cashflow command""" - mw_api.compare_cashflow(other_args, self.ticker, self.similar) + market_watch_view.compare_cashflow(other_args, self.ticker, self.similar) def call_sentiment(self, other_args: List[str]): """Process sentiment command""" - f_api.sentiment_compare(other_args, self.ticker, self.similar) + finbrain_view.sentiment_compare(other_args, self.ticker, self.similar) def call_scorr(self, other_args: List[str]): """Process sentiment correlation command""" - f_api.sentiment_correlation(other_args, self.ticker, self.similar) + finbrain_view.sentiment_correlation(other_args, self.ticker, self.similar) def call_overview(self, other_args: List[str]): """Process overview command""" @@ -324,11 +351,21 @@ class ComparisonAnalysisController: def menu(stock: pd.DataFrame, ticker: str, start: datetime, interval: str): - """Comparison Analysis Menu""" + """Comparison Analysis Menu - ca_controller = ComparisonAnalysisController( - stock, ticker, start, interval, [], False - ) + Parameters + ---------- + stock : pd.DataFrame + Stock data + ticker : str + Stock ticker + start : datetime + Time start + interval : str + Time interval + """ + + ca_controller = ComparisonAnalysisController(stock, ticker, start, interval, []) ca_controller.call_help(None) while True: diff --git a/gamestonk_terminal/comparison_analysis/finbrain_api.py b/gamestonk_terminal/comparison_analysis/finbrain_view.py similarity index 99% rename from gamestonk_terminal/comparison_analysis/finbrain_api.py rename to gamestonk_terminal/comparison_analysis/finbrain_view.py index c1cb629d893..cc0ee139d64 100644 --- a/gamestonk_terminal/comparison_analysis/finbrain_api.py +++ b/gamestonk_terminal/comparison_analysis/finbrain_view.py @@ -10,6 +10,7 @@ import pandas as pd from pandas.plotting import register_matplotlib_converters import numpy as np import seaborn as sns + from gamestonk_terminal.helper_funcs import ( parse_known_args_and_warn, plot_autoscale, @@ -33,6 +34,7 @@ def sentiment_compare(other_args: List[str], ticker: str, similar: List[str]): similar : List[str] Similar companies to compare income with """ + parser = argparse.ArgumentParser( add_help=False, prog="sentiment_compare", @@ -98,6 +100,7 @@ def sentiment_correlation(other_args: List[str], ticker: str, similar: List[str] similar : List[str] Similar companies to compare income with """ + parser = argparse.ArgumentParser( add_help=False, prog="sentiment_compare", @@ -164,6 +167,7 @@ def get_sentiments(similar: List[str]) -> pd.DataFrame: DataFrame() Contains sentiment analysis from several tickers """ + df_sentiment = pd.DataFrame() for ticker in similar: result = requests.get(f"https://api.finbrain.tech/v0/sentiments/{ticker}") @@ -196,6 +200,7 @@ def plot_sentiments(df_sentiment: pd.DataFrame, similar: List[str]): similar : List[str] List of similar companies """ + plt.figure(figsize=plot_autoscale(), dpi=PLOT_DPI) for idx, ticker in enumerate(similar): @@ -251,6 +256,7 @@ def plot_correlation(df_sentiment: pd.DataFrame, similar: List[str]): similar : List[str] List of similar companies """ + plt.figure(figsize=plot_autoscale(), dpi=PLOT_DPI) mask = np.zeros((len(similar), len(similar)), dtype=bool) diff --git a/gamestonk_terminal/comparison_analysis/market_watch_api.py b/gamestonk_terminal/comparison_analysis/market_watch_view.py similarity index 99% rename from gamestonk_terminal/comparison_analysis/market_watch_api.py rename to gamestonk_terminal/comparison_analysis/market_watch_view.py index 5067cdeae38..4cef54e2b79 100644 --- a/gamestonk_terminal/comparison_analysis/market_watch_api.py +++ b/gamestonk_terminal/comparison_analysis/market_watch_view.py @@ -27,6 +27,7 @@ def compare_income(other_args: List[str], ticker: str, similar: List[str]): similar : List[str] Similar companies to compare income with """ + parser = argparse.ArgumentParser( add_help=False, prog="income", @@ -132,6 +133,7 @@ def compare_balance(other_args: List[str], ticker: str, similar: List[str]): similar : List[str] Similar companies to compare income with """ + parser = argparse.ArgumentParser( add_help=False, prog="compare_balance", @@ -237,6 +239,7 @@ def compare_cashflow(other_args: List[str], ticker: str, similar: List[str]): similar : List[str] Similar companies to compare income with """ + parser = argparse.ArgumentParser( add_help=False, prog="compare_cashflow", diff --git a/gamestonk_terminal/comparison_analysis/yahoo_finance_api.py b/gamestonk_terminal/comparison_analysis/yahoo_finance_view.py similarity index 77% rename from gamestonk_terminal/comparison_analysis/yahoo_finance_api.py rename to gamestonk_terminal/comparison_analysis/yahoo_finance_view.py index 72df9f825ad..095a506b4f6 100644 --- a/gamestonk_terminal/comparison_analysis/yahoo_finance_api.py +++ b/gamestonk_terminal/comparison_analysis/yahoo_finance_view.py @@ -1,4 +1,9 @@ +""" Comparison Analysis Yahoo Finance View """ +__docformat__ = "numpy" + import argparse +from typing import List +from datetime import datetime import numpy as np import pandas as pd from pandas.plotting import register_matplotlib_converters @@ -21,6 +26,24 @@ d_candle_types = { def check_one_of_ohlca(type_candles: str) -> str: + """Convert a candle type + + Parameters + ---------- + type_candles : str + OHLCA candle type + + Returns + ------- + str + Converted candle type + + Raises + ------ + argparse.ArgumentTypeError + Unknown candle type + """ + if ( type_candles == "o" or type_candles == "h" @@ -32,7 +55,32 @@ def check_one_of_ohlca(type_candles: str) -> str: raise argparse.ArgumentTypeError("The type of candles specified is not recognized") -def historical(l_args, df_stock, s_ticker, s_start, s_interval, similar): +def historical( + other_args: List[str], + df_stock: pd.DataFrame, + ticker: str, + start: datetime, + interval: str, + similar: List[str], +): + """Display historical data from Yahoo Finance + + Parameters + ---------- + other_args : List[str] + Command line arguments to be processed with argparse + df_stock : pd.DataFrame + Stock data + ticker : str + Ticker symbol + start : datetime + Time start + interval : str + Time interval + similar : List[str] + List of similar tickers + """ + parser = argparse.ArgumentParser( add_help=False, prog="historical", @@ -66,11 +114,11 @@ def historical(l_args, df_stock, s_ticker, s_start, s_interval, similar): ) try: - if s_interval != "1440min": + if interval != "1440min": print("Intraday historical data analysis comparison is not yet available.") # Alpha Vantage only supports 5 calls per minute, we need another API to get intraday data else: - ns_parser = parse_known_args_and_warn(parser, l_args) + ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: return @@ -80,16 +128,14 @@ def historical(l_args, df_stock, s_ticker, s_start, s_interval, similar): similar += ns_parser.l_also plt.figure(figsize=plot_autoscale(), dpi=PLOT_DPI) - plt.title(f"Similar companies to {s_ticker}") - df_stock = yf.download( - s_ticker, start=s_start, progress=False, threads=False - ) + plt.title(f"Similar companies to {ticker}") + df_stock = yf.download(ticker, start=start, progress=False, threads=False) plt.plot( df_stock.index, df_stock[d_candle_types[ns_parser.type_candle]].values ) # plt.plot(df_stock.index, df_stock["5. adjusted close"].values, lw=2) l_min = [df_stock.index[0]] - l_leg = [s_ticker] + l_leg = [ticker] l_stocks = similar[:] @@ -98,7 +144,7 @@ def historical(l_args, df_stock, s_ticker, s_start, s_interval, similar): for symbol in l_stocks: try: df_similar_stock = yf.download( - symbol, start=s_start, progress=False, threads=False + symbol, start=start, progress=False, threads=False ) if not df_similar_stock.empty: plt.plot( @@ -141,7 +187,25 @@ def historical(l_args, df_stock, s_ticker, s_start, s_interval, similar): print(e, "\n") -def correlation(l_args, df_stock, s_ticker, s_start, s_interval, similar): +def correlation(other_args, df_stock, ticker, start, interval, similar): + """[summary] + + Parameters + ---------- + other_args : [type] + Command line arguments to be processed with argparse + df_stock : pd.DataFrame + Stock data + ticker : str + Ticker symbol + start : datetime + Time start + interval : str + Time interval + similar : [type] + List of similar tickers + """ + parser = argparse.ArgumentParser( add_help=False, prog="corr", @@ -176,11 +240,11 @@ def correlation(l_args, df_stock, s_ticker, s_start, s_interval, similar): ) try: - if s_interval != "1440min": + if interval != "1440min": print("Intraday historical data analysis comparison is not yet available.") # Alpha Vantage only supports 5 calls per minute, we need another API to get intraday data else: - ns_parser = parse_known_args_and_warn(parser, l_args) + ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: return @@ -193,21 +257,21 @@ def correlation(l_args, df_stock, s_ticker, s_start, s_interval, similar): print("Provide at least a similar company for correlation") else: d_stock = {} - d_stock[s_ticker] = yf.download(s_ticker, start=s_start, progress=False) - l_min = [d_stock[s_ticker].index[0]] + d_stock[ticker] = yf.download(ticker, start=start, progress=False) + l_min = [d_stock[ticker].index[0]] for symbol in similar: - d_stock[symbol] = yf.download(symbol, start=s_start, progress=False) + d_stock[symbol] = yf.download(symbol, start=start, progress=False) if not d_stock[symbol].empty: l_min.append(d_stock[symbol].index[0]) min_start_date = max(l_min) - df_stock = d_stock[s_ticker][ + df_stock = d_stock[ticker][ d_candle_types[ns_parser.type_candle] - ].rename(s_ticker) + ].rename(ticker) for symbol in d_stock: - if symbol != s_ticker: + if symbol != ticker: if not d_stock[symbol].empty: df_stock = pd.concat( [