diff --git a/gamestonk_terminal/fundamental_analysis/business_insider_api.py b/gamestonk_terminal/fundamental_analysis/business_insider_api.py index 69d0d11e27b..bc65b08367f 100644 --- a/gamestonk_terminal/fundamental_analysis/business_insider_api.py +++ b/gamestonk_terminal/fundamental_analysis/business_insider_api.py @@ -86,7 +86,9 @@ def management(l_args, s_ticker): for ind in df_management.index: s_name = f"{ind}{(max([len(x) for x in df_management.index])-len(ind))*' '}" - s_title = f"{df_management['Title'][ind]}{(max([len(x) for x in df_management['Title']])-len(df_management['Title'][ind]))*' '}" + df_mgmt_title = df_management["Title"] + spaces = max([len(x) for x in df_mgmt_title]) - len(df_mgmt_title[ind]) + s_title = f"{df_mgmt_title[ind]}{spaces * ' '}" s_management = f"""{s_name} {s_title} {df_management['Info'][ind]}""" print(s_management) if df_management["Insider Activity"][ind] not in "-": diff --git a/gamestonk_terminal/helper_funcs.py b/gamestonk_terminal/helper_funcs.py index 0c25390f896..250989fad1b 100644 --- a/gamestonk_terminal/helper_funcs.py +++ b/gamestonk_terminal/helper_funcs.py @@ -6,9 +6,14 @@ import sys from pytz import timezone import iso8601 import matplotlib.pyplot as plt +from holidays import US as holidaysUS +from colorama import Fore, Style +import pandas as pd import pandas.io.formats.format from pandas._config.config import get_option -from holidays import US as holidaysUS +from pandas.plotting import register_matplotlib_converters + +register_matplotlib_converters() def check_non_negative(value) -> int: @@ -51,69 +56,6 @@ def plot_view_stock(df, symbol): print("") -def plot_stock_ta(df_stock, s_ticker, df_ta, s_ta): - plt.plot(df_stock.index, df_stock.values, color="k") - plt.plot(df_ta.index, df_ta.values) - plt.title(f"{s_ta} on {s_ticker}") - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.xlabel("Time") - plt.ylabel("Share Price ($)") - # Pandas series - if len(df_ta.shape) == 1: - l_legend = [s_ticker, s_ta] - # Pandas dataframe - else: - l_legend = df_ta.columns.tolist() - l_legend.insert(0, s_ticker) - plt.legend(l_legend) - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.show() - print("") - - -def plot_stock_and_ta(df_stock, s_ticker, df_ta, s_ta): - _, axPrice = plt.subplots() - plt.title(f"{s_ta} on {s_ticker}") - plt.plot(df_stock.index, df_stock.values, "k", lw=3) - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.xlabel("Time") - plt.ylabel(f"Share Price of {s_ticker} ($)") - axTa = axPrice.twinx() - plt.plot(df_ta.index, df_ta.values) - # Pandas series - if len(df_ta.shape) == 1: - l_legend = [s_ta] - # Pandas dataframe - else: - l_legend = df_ta.columns.tolist() - plt.legend(l_legend) - axTa.set_ylabel(s_ta, color="tab:blue") - axTa.spines["right"].set_color("tab:blue") - axTa.tick_params(axis="y", colors="tab:blue") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.show() - print("") - - -def plot_ta(s_ticker, df_ta, s_ta): - plt.plot(df_ta.index, df_ta.values) - plt.title(f"{s_ta} on {s_ticker}") - plt.xlim(df_ta.index[0], df_ta.index[-1]) - plt.xlabel("Time") - # plt.ylabel('Share Price ($)') - # if isinstance(df_ta, pd.DataFrame): - # plt.legend(df_ta.columns) - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.show() - print("") - - def b_is_stock_market_open() -> bool: """ checks if the stock market is open """ # Get current US time @@ -335,3 +277,18 @@ def parse_known_args_and_warn(parser, l_args): if l_unknown_args: print(f"The following args couldn't be interpreted: {l_unknown_args}") return ns_parser + + +def price_prediction_color(val: int, last_val: int) -> str: + if float(val) > last_val: + color = Fore.GREEN + else: + color = Fore.RED + return f"{color}{val:.2f} ${Style.RESET_ALL}" + + +def print_pretty_prediction(df_pred: pd.DataFrame, last_price: float): + print(f"Actual price: {Fore.YELLOW}{last_price:.2f} ${Style.RESET_ALL}\n") + + print("Prediction:") + print(df_pred.apply(price_prediction_color, last_val=last_price).to_string()) diff --git a/gamestonk_terminal/prediction_techniques/arima.py b/gamestonk_terminal/prediction_techniques/arima.py index 77109e2d22b..cd4900234f2 100644 --- a/gamestonk_terminal/prediction_techniques/arima.py +++ b/gamestonk_terminal/prediction_techniques/arima.py @@ -4,25 +4,27 @@ import pandas as pd from pandas.plotting import register_matplotlib_converters import pmdarima from statsmodels.tsa.arima.model import ARIMA -from gamestonk_terminal.helper_funcs import check_positive, get_next_stock_market_days +from gamestonk_terminal.helper_funcs import ( + check_positive, + get_next_stock_market_days, + parse_known_args_and_warn, + print_pretty_prediction, +) register_matplotlib_converters() -# -------------------------------------------------- ARIMA -------------------------------------------------- -# pylint: disable=unused-argument -def arima(l_args, s_ticker, s_interval, df_stock): +def arima(l_args, s_ticker, df_stock): parser = argparse.ArgumentParser( prog="arima", description=""" - In statistics and econometrics, and in particular in time - series analysis, an autoregressive integrated moving average (ARIMA) model - is a generalization of an autoregressive moving average (ARMA) model. Both - of these models are fitted to time series data either to better understand - the data or to predict future points in the series (forecasting). - ARIMA(p,d,q) where parameters p, d, and q are non-negative integers, p is - the order (number of time lags) of the autoregressive model, d is the degree - of differencing (the number of times the data have had past values subtracted), + In statistics and econometrics, and in particular in time series analysis, an + autoregressive integrated moving average (ARIMA) model is a generalization of an + autoregressive moving average (ARMA) model. Both of these models are fitted to time + series data either to better understand the data or to predict future points in the + series (forecasting). ARIMA(p,d,q) where parameters p, d, and q are non-negative + integers, p is the order (number of time lags) of the autoregressive model, d is the + degree of differencing (the number of times the data have had past values subtracted), and q is the order of the moving-average model. """, ) @@ -72,11 +74,7 @@ def arima(l_args, s_ticker, s_interval, df_stock): ) try: - (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) - - if l_unknown_args: - print(f"The following args couldn't be interpreted: {l_unknown_args}\n") - return + ns_parser = parse_known_args_and_warn(parser, l_args) # Machine Learning model if ns_parser.s_order: @@ -116,6 +114,7 @@ def arima(l_args, s_ticker, s_interval, df_stock): print("") # Plotting + plt.figure() plt.plot(df_stock.index, df_stock["5. adjusted close"], lw=2) if ns_parser.s_order: plt.title( @@ -148,12 +147,11 @@ def arima(l_args, s_ticker, s_interval, df_stock): plt.vlines( df_stock.index[-1], ymin, ymax, linewidth=1, linestyle="--", color="k" ) + plt.ion() plt.show() # Print prediction data - print("Predicted share price:") - df_pred = df_pred.apply(lambda x: f"{x:.2f} $") - print(df_pred.to_string()) + print_pretty_prediction(df_pred, df_stock["5. adjusted close"].values[-1]) print("") except Exception as e: diff --git a/gamestonk_terminal/prediction_techniques/fbprophet.py b/gamestonk_terminal/prediction_techniques/fbprophet.py index b11e1f8429e..3f894feb7c9 100644 --- a/gamestonk_terminal/prediction_techniques/fbprophet.py +++ b/gamestonk_terminal/prediction_techniques/fbprophet.py @@ -4,22 +4,25 @@ import matplotlib.pyplot as plt import pandas as pd from pandas.plotting import register_matplotlib_converters from fbprophet import Prophet -from gamestonk_terminal.helper_funcs import check_positive, get_next_stock_market_days +from gamestonk_terminal.helper_funcs import ( + check_positive, + get_next_stock_market_days, + parse_known_args_and_warn, +) register_matplotlib_converters() warnings.simplefilter("ignore") -# ----------------------------------------------------- FBPROPHET ----------------------------------------------------- -# pylint: disable=unused-argument -def fbprophet(l_args, s_ticker, s_interval, df_stock): +def fbprophet(l_args, s_ticker, df_stock): parser = argparse.ArgumentParser( prog="fbprophet", description=""" Facebook Prophet is a forecasting procedure that is fast and provides - completely automated forecasts that can be tuned by hand by data scientists and analysts. - It was developed by Facebook's data science team and is open source. + completely automated forecasts that can be tuned by hand by data scientists + and analysts. It was developed by Facebook's data science team and is open + source. """, ) @@ -34,11 +37,7 @@ def fbprophet(l_args, s_ticker, s_interval, df_stock): ) try: - (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) - - if l_unknown_args: - print(f"The following args couldn't be interpreted: {l_unknown_args}\n") - return + ns_parser = parse_known_args_and_warn(parser, l_args) df_stock = df_stock.sort_index(ascending=True) df_stock.reset_index(level=0, inplace=True) @@ -78,6 +77,7 @@ def fbprophet(l_args, s_ticker, s_interval, df_stock): df_stock["ds"].values[0], get_next_stock_market_days(l_pred_days[-1], 1)[-1] ) plt.title(f"Fb Prophet on {s_ticker} - {ns_parser.n_days} days prediction") + plt.ion() plt.show() print("") diff --git a/gamestonk_terminal/prediction_techniques/knn.py b/gamestonk_terminal/prediction_techniques/knn.py index ba08de31066..1fc1cfa0417 100644 --- a/gamestonk_terminal/prediction_techniques/knn.py +++ b/gamestonk_terminal/prediction_techniques/knn.py @@ -4,14 +4,17 @@ import pandas as pd from pandas.plotting import register_matplotlib_converters from sklearn import neighbors from TimeSeriesCrossValidation import splitTrain -from gamestonk_terminal.helper_funcs import check_positive, get_next_stock_market_days +from gamestonk_terminal.helper_funcs import ( + check_positive, + get_next_stock_market_days, + parse_known_args_and_warn, + print_pretty_prediction, +) register_matplotlib_converters() -# ----------------------------------------------------- kNN ----------------------------------------------------- -# pylint: disable=unused-argument -def k_nearest_neighbors(l_args, s_ticker, s_interval, df_stock): +def k_nearest_neighbors(l_args, s_ticker, df_stock): parser = argparse.ArgumentParser( prog="knn", description=""" @@ -59,11 +62,7 @@ def k_nearest_neighbors(l_args, s_ticker, s_interval, df_stock): ) try: - (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) - - if l_unknown_args: - print(f"The following args couldn't be interpreted: {l_unknown_args}\n") - return + ns_parser = parse_known_args_and_warn(parser, l_args) # Split training data stock_x, stock_y = splitTrain.split_train( @@ -88,6 +87,7 @@ def k_nearest_neighbors(l_args, s_ticker, s_interval, df_stock): df_pred = pd.Series(l_predictions, index=l_pred_days, name="Price") # Plotting + plt.figure() plt.plot(df_stock.index, df_stock["5. adjusted close"], lw=2) plt.title( f"{ns_parser.n_neighbors}-Nearest Neighbors on {s_ticker} - {ns_parser.n_days} days prediction" @@ -115,12 +115,11 @@ def k_nearest_neighbors(l_args, s_ticker, s_interval, df_stock): plt.vlines( df_stock.index[-1], ymin, ymax, linewidth=1, linestyle="--", color="k" ) + plt.ion() plt.show() # Print prediction data - print("Predicted share price:") - df_pred = df_pred.apply(lambda x: f"{x:.2f} $") - print(df_pred.to_string()) + print_pretty_prediction(df_pred, df_stock["5. adjusted close"].values[-1]) print("") except Exception as e: diff --git a/gamestonk_terminal/prediction_techniques/neural_networks.py b/gamestonk_terminal/prediction_techniques/neural_networks.py index 49b79bbb668..4fab5020788 100644 --- a/gamestonk_terminal/prediction_techniques/neural_networks.py +++ b/gamestonk_terminal/prediction_techniques/neural_networks.py @@ -8,17 +8,15 @@ from pandas.plotting import register_matplotlib_converters from TimeSeriesCrossValidation import splitTrain from sklearn.preprocessing import MinMaxScaler, StandardScaler from tensorflow.keras.models import Sequential -from tensorflow.keras.layers import ( - LSTM, - SimpleRNN, - Dense, - Dropout, - # Activation, - # RepeatVector, - # TimeDistributed, +from tensorflow.keras.layers import LSTM, SimpleRNN, Dense, Dropout + +from gamestonk_terminal.helper_funcs import ( + check_positive, + get_next_stock_market_days, + parse_known_args_and_warn, + print_pretty_prediction, ) -from gamestonk_terminal.helper_funcs import check_positive, get_next_stock_market_days from gamestonk_terminal import config_neural_network_models as cfg_nn_models @@ -77,9 +75,7 @@ def build_neural_network_model(Recurrent_Neural_Network, n_inputs, n_days): return model -# -------------------------------------------------- MLP -------------------------------------------------- -# pylint: disable=unused-argument -def mlp(l_args, s_ticker, s_interval, df_stock): +def mlp(l_args, s_ticker, df_stock): parser = argparse.ArgumentParser( prog="mlp", description="""Multilayer Perceptron. """ ) @@ -159,11 +155,7 @@ def mlp(l_args, s_ticker, s_interval, df_stock): ) try: - (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) - - if l_unknown_args: - print(f"The following args couldn't be interpreted: {l_unknown_args}\n") - return + ns_parser = parse_known_args_and_warn(parser, l_args) # Pre-process data if ns_parser.s_preprocessing == "standardization": @@ -227,6 +219,7 @@ def mlp(l_args, s_ticker, s_interval, df_stock): df_pred = pd.Series(y_pred_test_t[0].tolist(), index=l_pred_days, name="Price") # Plotting + plt.figure() plt.plot(df_stock.index, df_stock["5. adjusted close"], lw=3) plt.title(f"MLP on {s_ticker} - {ns_parser.n_days} days prediction") plt.xlim( @@ -258,12 +251,11 @@ def mlp(l_args, s_ticker, s_interval, df_stock): linestyle="--", color="k", ) + plt.ion() plt.show() # Print prediction data - print("Predicted share price:") - df_pred = df_pred.apply(lambda x: f"{x:.2f} $") - print(df_pred.to_string()) + print_pretty_prediction(df_pred, df_stock["5. adjusted close"].values[-1]) print("") except Exception as e: @@ -271,9 +263,7 @@ def mlp(l_args, s_ticker, s_interval, df_stock): print("") -# -------------------------------------------------- RNN -------------------------------------------------- -# pylint: disable=unused-argument -def rnn(l_args, s_ticker, s_interval, df_stock): +def rnn(l_args, s_ticker, df_stock): parser = argparse.ArgumentParser( prog="rnn", description="""Recurrent Neural Network. """ ) @@ -353,11 +343,7 @@ def rnn(l_args, s_ticker, s_interval, df_stock): ) try: - (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) - - if l_unknown_args: - print(f"The following args couldn't be interpreted: {l_unknown_args}\n") - return + ns_parser = parse_known_args_and_warn(parser, l_args) # Pre-process data if ns_parser.s_preprocessing == "standardization": @@ -421,6 +407,7 @@ def rnn(l_args, s_ticker, s_interval, df_stock): df_pred = pd.Series(y_pred_test_t[0].tolist(), index=l_pred_days, name="Price") # Plotting + plt.figure() plt.plot(df_stock.index, df_stock["5. adjusted close"], lw=3) plt.title(f"RNN on {s_ticker} - {ns_parser.n_days} days prediction") plt.xlim( @@ -452,12 +439,11 @@ def rnn(l_args, s_ticker, s_interval, df_stock): linestyle="--", color="k", ) + plt.ion() plt.show() # Print prediction data - print("Predicted share price:") - df_pred = df_pred.apply(lambda x: f"{x:.2f} $") - print(df_pred.to_string()) + print_pretty_prediction(df_pred, df_stock["5. adjusted close"].values[-1]) print("") except Exception as e: @@ -465,9 +451,7 @@ def rnn(l_args, s_ticker, s_interval, df_stock): print("") -# -------------------------------------------------- LSTM -------------------------------------------------- -# pylint: disable=unused-argument -def lstm(l_args, s_ticker, s_interval, df_stock): +def lstm(l_args, s_ticker, df_stock): parser = argparse.ArgumentParser( prog="lstm", description="""Long-Short Term Memory. """ ) @@ -547,11 +531,7 @@ def lstm(l_args, s_ticker, s_interval, df_stock): ) try: - (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) - - if l_unknown_args: - print(f"The following args couldn't be interpreted: {l_unknown_args}\n") - return + ns_parser = parse_known_args_and_warn(parser, l_args) # Pre-process data if ns_parser.s_preprocessing == "standardization": @@ -615,6 +595,7 @@ def lstm(l_args, s_ticker, s_interval, df_stock): df_pred = pd.Series(y_pred_test_t[0].tolist(), index=l_pred_days, name="Price") # Plotting + plt.figure() plt.plot(df_stock.index, df_stock["5. adjusted close"], lw=3) plt.title(f"LSTM on {s_ticker} - {ns_parser.n_days} days prediction") plt.xlim( @@ -646,12 +627,11 @@ def lstm(l_args, s_ticker, s_interval, df_stock): linestyle="--", color="k", ) + plt.ion() plt.show() # Print prediction data - print("Predicted share price:") - df_pred = df_pred.apply(lambda x: f"{x:.2f} $") - print(df_pred.to_string()) + print_pretty_prediction(df_pred, df_stock["5. adjusted close"].values[-1]) print("") except Exception as e: diff --git a/gamestonk_terminal/prediction_techniques/pred_menu.py b/gamestonk_terminal/prediction_techniques/pred_menu.py index 1c66988ec44..940fdd1e8db 100644 --- a/gamestonk_terminal/prediction_techniques/pred_menu.py +++ b/gamestonk_terminal/prediction_techniques/pred_menu.py @@ -6,9 +6,9 @@ from gamestonk_terminal.prediction_techniques import regression from gamestonk_terminal.prediction_techniques import arima from gamestonk_terminal.prediction_techniques import fbprophet from gamestonk_terminal.prediction_techniques import neural_networks +import matplotlib.pyplot as plt -# ----------------------------------------------------------------------------------------------------------------------- def print_prediction(s_ticker, s_start, s_interval): """ Print help """ @@ -38,7 +38,6 @@ def print_prediction(s_ticker, s_start, s_interval): print("") -# ---------------------------------------------------- MENU ---------------------------------------------------- def pred_menu(df_stock, s_ticker, s_start, s_interval): # Add list of arguments that the prediction techniques parser accepts @@ -70,6 +69,9 @@ def pred_menu(df_stock, s_ticker, s_start, s_interval): # Get input command from user as_input = input("> ") + # Images are non blocking - allows to close them if we type other command + plt.close() + # Parse prediction techniques command of the list of possible commands try: (ns_known_args, l_args) = pred_parser.parse_known_args(as_input.split()) @@ -89,53 +91,38 @@ def pred_menu(df_stock, s_ticker, s_start, s_interval): # Abandon the program return True - # ------------------------------------------ SIMPLE MOVING AVERAGE ------------------------------------------ elif ns_known_args.cmd == "sma": - sma.simple_moving_average(l_args, s_ticker, s_interval, df_stock) + sma.simple_moving_average(l_args, s_ticker, df_stock) - # ------------------------------------------- k NEAREST NEIGHBORS ------------------------------------------ elif ns_known_args.cmd == "knn": - knn.k_nearest_neighbors(l_args, s_ticker, s_interval, df_stock) + knn.k_nearest_neighbors(l_args, s_ticker, df_stock) - # ----------------------------------------------- REGRESSION ------------------------------------------------- elif ns_known_args.cmd == "linear": - regression.regression( - l_args, s_ticker, s_interval, df_stock, regression.LINEAR - ) + regression.regression(l_args, s_ticker, df_stock, regression.LINEAR) elif ns_known_args.cmd == "quadratic": - regression.regression( - l_args, s_ticker, s_interval, df_stock, regression.QUADRATIC - ) + regression.regression(l_args, s_ticker, df_stock, regression.QUADRATIC) elif ns_known_args.cmd == "cubic": - regression.regression( - l_args, s_ticker, s_interval, df_stock, regression.CUBIC - ) + regression.regression(l_args, s_ticker, df_stock, regression.CUBIC) elif ns_known_args.cmd == "regression": - regression.regression( - l_args, s_ticker, s_interval, df_stock, regression.USER_INPUT - ) + regression.regression(l_args, s_ticker, df_stock, regression.USER_INPUT) - # ------------------------------------------------- ARIMA ------------------------------------------------- elif ns_known_args.cmd == "arima": - arima.arima(l_args, s_ticker, s_interval, df_stock) + arima.arima(l_args, s_ticker, df_stock) - # ------------------------------------------------ FBPROPHET ------------------------------------------------ elif ns_known_args.cmd == "prophet": - fbprophet.fbprophet(l_args, s_ticker, s_interval, df_stock) + fbprophet.fbprophet(l_args, s_ticker, df_stock) - # ---------------------------------------------- NEURAL NETWORK ---------------------------------------------- elif ns_known_args.cmd == "mlp": - neural_networks.mlp(l_args, s_ticker, s_interval, df_stock) + neural_networks.mlp(l_args, s_ticker, df_stock) elif ns_known_args.cmd == "rnn": - neural_networks.rnn(l_args, s_ticker, s_interval, df_stock) + neural_networks.rnn(l_args, s_ticker, df_stock) elif ns_known_args.cmd == "lstm": - neural_networks.lstm(l_args, s_ticker, s_interval, df_stock) + neural_networks.lstm(l_args, s_ticker, df_stock) - # ------------------------------------------------------------------------------------------------------------ else: print("Command not recognized!") diff --git a/gamestonk_terminal/prediction_techniques/regression.py b/gamestonk_terminal/prediction_techniques/regression.py index 0a82a0a0c21..841ff00371f 100644 --- a/gamestonk_terminal/prediction_techniques/regression.py +++ b/gamestonk_terminal/prediction_techniques/regression.py @@ -7,7 +7,12 @@ from sklearn import linear_model from sklearn import pipeline from sklearn import preprocessing -from gamestonk_terminal.helper_funcs import check_positive, get_next_stock_market_days +from gamestonk_terminal.helper_funcs import ( + check_positive, + get_next_stock_market_days, + parse_known_args_and_warn, + print_pretty_prediction, +) register_matplotlib_converters() @@ -17,9 +22,7 @@ QUADRATIC = 2 CUBIC = 3 -# -------------------------------------------------- REGRESSION -------------------------------------------------- -# pylint: disable=unused-argument -def regression(l_args, s_ticker, s_interval, df_stock, polynomial): +def regression(l_args, s_ticker, df_stock, polynomial): parser = argparse.ArgumentParser( prog="regression", description=""" @@ -70,11 +73,7 @@ def regression(l_args, s_ticker, s_interval, df_stock, polynomial): ) try: - (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) - - if l_unknown_args: - print(f"The following args couldn't be interpreted: {l_unknown_args}\n") - return + ns_parser = parse_known_args_and_warn(parser, l_args) # Split training data stock_x, stock_y = splitTrain.split_train( @@ -107,6 +106,7 @@ def regression(l_args, s_ticker, s_interval, df_stock, polynomial): df_pred = pd.Series(l_predictions, index=l_pred_days, name="Price") # Plotting + plt.figure() plt.plot(df_stock.index, df_stock["5. adjusted close"], lw=2) plt.title( f"Regression (polynomial {polynomial}) on {s_ticker} - {ns_parser.n_days} days prediction" @@ -134,12 +134,11 @@ def regression(l_args, s_ticker, s_interval, df_stock, polynomial): plt.vlines( df_stock.index[-1], ymin, ymax, linewidth=1, linestyle="--", color="k" ) + plt.ion() plt.show() # Print prediction data - print("Predicted share price:") - df_pred = df_pred.apply(lambda x: f"{x:.2f} $") - print(df_pred.to_string()) + print_pretty_prediction(df_pred, df_stock["5. adjusted close"].values[-1]) print("") except Exception as e: diff --git a/gamestonk_terminal/prediction_techniques/sma.py b/gamestonk_terminal/prediction_techniques/sma.py index 4bc368e4925..5755212614b 100644 --- a/gamestonk_terminal/prediction_techniques/sma.py +++ b/gamestonk_terminal/prediction_techniques/sma.py @@ -4,14 +4,18 @@ import matplotlib.pyplot as plt import pandas as pd from pandas.plotting import register_matplotlib_converters -from gamestonk_terminal.helper_funcs import check_positive, get_next_stock_market_days +from gamestonk_terminal.helper_funcs import ( + check_positive, + get_next_stock_market_days, + parse_known_args_and_warn, + print_pretty_prediction, +) register_matplotlib_converters() -# ----------------------------------------------------- SMA ----------------------------------------------------- # pylint: disable=unused-argument -def simple_moving_average(l_args, s_ticker, s_interval, df_stock): +def simple_moving_average(l_args, s_ticker, df_stock): parser = argparse.ArgumentParser( prog="sma", description=""" @@ -45,11 +49,7 @@ def simple_moving_average(l_args, s_ticker, s_interval, df_stock): ) try: - (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) - - if l_unknown_args: - print(f"The following args couldn't be interpreted: {l_unknown_args}\n") - return + ns_parser = parse_known_args_and_warn(parser, l_args) # Prediction data l_predictions = list() @@ -98,12 +98,11 @@ def simple_moving_average(l_args, s_ticker, s_interval, df_stock): plt.vlines( df_stock.index[-1], ymin, ymax, linewidth=1, linestyle="--", color="k" ) + plt.ion() plt.show() # Print prediction data - print("Predicted share price:") - df_pred = df_pred.apply(lambda x: f"{x:.2f} $") - print(df_pred.to_string()) + print_pretty_prediction(df_pred, df_stock["5. adjusted close"].values[-1]) print("") except Exception as e: diff --git a/gamestonk_terminal/technical_analysis/momentum.py b/gamestonk_terminal/technical_analysis/momentum.py index 9b4f1deee41..f24df060607 100644 --- a/gamestonk_terminal/technical_analysis/momentum.py +++ b/gamestonk_terminal/technical_analysis/momentum.py @@ -2,12 +2,11 @@ import argparse import matplotlib.pyplot as plt import pandas_ta as ta from pandas.plotting import register_matplotlib_converters -from gamestonk_terminal.helper_funcs import check_positive +from gamestonk_terminal.helper_funcs import check_positive, parse_known_args_and_warn register_matplotlib_converters() -# ----------------------------------------------------- CCI ----------------------------------------------------- def cci(l_args, s_ticker, s_interval, df_stock): parser = argparse.ArgumentParser( prog="cci", @@ -49,11 +48,7 @@ def cci(l_args, s_ticker, s_interval, df_stock): ) try: - (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) - - if l_unknown_args: - print(f"The following args couldn't be interpreted: {l_unknown_args}\n") - return + ns_parser = parse_known_args_and_warn(parser, l_args) # Daily if s_interval == "1440min": @@ -66,30 +61,6 @@ def cci(l_args, s_ticker, s_interval, df_stock): offset=ns_parser.n_offset, ).dropna() - plt.subplot(211) - plt.title(f"Commodity Channel Index (CCI) on {s_ticker}") - plt.plot(df_stock.index, df_stock["5. adjusted close"].values, "k", lw=2) - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.ylabel("Share Price ($)") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.subplot(212) - plt.plot(df_ta.index, df_ta.values, "b", lw=2) - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.axhspan(100, plt.gca().get_ylim()[1], facecolor="r", alpha=0.2) - plt.axhspan(plt.gca().get_ylim()[0], -100, facecolor="g", alpha=0.2) - plt.axhline(100, linewidth=3, color="r", ls="--") - plt.axhline(-100, linewidth=3, color="g", ls="--") - plt.xlabel("Time") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.gca().twinx() - plt.ylim(plt.gca().get_ylim()) - plt.yticks([0.2, 0.8], ("OVERSOLD", "OVERBOUGHT")) - plt.show() - # Intraday else: df_ta = ta.cci( @@ -101,29 +72,35 @@ def cci(l_args, s_ticker, s_interval, df_stock): offset=ns_parser.n_offset, ).dropna() - plt.subplot(211) - plt.title(f"Commodity Channel Index (CCI) on {s_ticker}") + plt.figure() + plt.subplot(211) + plt.title(f"Commodity Channel Index (CCI) on {s_ticker}") + if s_interval == "1440min": + plt.plot(df_stock.index, df_stock["5. adjusted close"].values, "k", lw=2) + else: plt.plot(df_stock.index, df_stock["4. close"].values, "k", lw=2) - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.ylabel("Share Price ($)") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.subplot(212) - plt.plot(df_ta.index, df_ta.values, "b", lw=2) - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.axhspan(100, plt.gca().get_ylim()[1], facecolor="r", alpha=0.2) - plt.axhspan(plt.gca().get_ylim()[0], -100, facecolor="g", alpha=0.2) - plt.axhline(100, linewidth=3, color="r", ls="--") - plt.axhline(-100, linewidth=3, color="g", ls="--") - plt.xlabel("Time") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.gca().twinx() - plt.ylim(plt.gca().get_ylim()) - plt.yticks([0.2, 0.8], ("OVERSOLD", "OVERBOUGHT")) - plt.show() + plt.xlim(df_stock.index[0], df_stock.index[-1]) + plt.ylabel("Share Price ($)") + plt.grid(b=True, which="major", color="#666666", linestyle="-") + plt.minorticks_on() + plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) + plt.subplot(212) + plt.plot(df_ta.index, df_ta.values, "b", lw=2) + plt.xlim(df_stock.index[0], df_stock.index[-1]) + plt.axhspan(100, plt.gca().get_ylim()[1], facecolor="r", alpha=0.2) + plt.axhspan(plt.gca().get_ylim()[0], -100, facecolor="g", alpha=0.2) + plt.axhline(100, linewidth=3, color="r", ls="--") + plt.axhline(-100, linewidth=3, color="g", ls="--") + plt.xlabel("Time") + plt.grid(b=True, which="major", color="#666666", linestyle="-") + plt.minorticks_on() + plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) + plt.gca().twinx() + plt.ylim(plt.gca().get_ylim()) + plt.yticks([0.2, 0.8], ("OVERSOLD", "OVERBOUGHT")) + plt.ion() + plt.show() + print("") except Exception as e: @@ -131,7 +108,6 @@ def cci(l_args, s_ticker, s_interval, df_stock): print("") -# ----------------------------------------------------- MACD ----------------------------------------------------- def macd(l_args, s_ticker, s_interval, df_stock): parser = argparse.ArgumentParser( prog="macd", @@ -185,11 +161,7 @@ def macd(l_args, s_ticker, s_interval, df_stock): ) try: - (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) - - if l_unknown_args: - print(f"The following args couldn't be interpreted: {l_unknown_args}\n") - return + ns_parser = parse_known_args_and_warn(parser, l_args) # Daily if s_interval == "1440min": @@ -201,32 +173,6 @@ def macd(l_args, s_ticker, s_interval, df_stock): offset=ns_parser.n_offset, ).dropna() - plt.subplot(211) - plt.title(f"Moving Average Convergence Divergence (MACD) on {s_ticker}") - plt.plot(df_stock.index, df_stock["4. close"].values, "k", lw=2) - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.ylabel("Share Price ($)") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.subplot(212) - plt.plot(df_ta.index, df_ta.iloc[:, 0].values, "b", lw=2) - plt.plot(df_ta.index, df_ta.iloc[:, 2].values, "r", lw=2) - plt.bar(df_ta.index, df_ta.iloc[:, 1].values, color="g") - plt.legend( - [ - f"MACD Line {df_ta.columns[0]}", - f"Signal Line {df_ta.columns[2]}", - f"Histogram {df_ta.columns[1]}", - ] - ) - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.xlabel("Time") - plt.show() - # Intraday else: df_ta = ta.macd( @@ -237,31 +183,36 @@ def macd(l_args, s_ticker, s_interval, df_stock): offset=ns_parser.n_offset, ).dropna() - plt.subplot(211) - plt.title(f"Moving Average Convergence Divergence (MACD) on {s_ticker}") + plt.figure() + plt.subplot(211) + plt.title(f"Moving Average Convergence Divergence (MACD) on {s_ticker}") + if s_interval == "1440min": + plt.plot(df_stock.index, df_stock["5. adjusted close"].values, "k", lw=2) + else: plt.plot(df_stock.index, df_stock["4. close"].values, "k", lw=2) - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.ylabel("Share Price ($)") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.subplot(212) - plt.plot(df_ta.index, df_ta.iloc[:, 0].values, "b", lw=2) - plt.plot(df_ta.index, df_ta.iloc[:, 2].values, "r", lw=2) - plt.bar(df_ta.index, df_ta.iloc[:, 1].values, color="g") - plt.legend( - [ - f"MACD Line {df_ta.columns[0]}", - f"Signal Line {df_ta.columns[2]}", - f"Histogram {df_ta.columns[1]}", - ] - ) - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.xlabel("Time") - plt.show() + plt.xlim(df_stock.index[0], df_stock.index[-1]) + plt.ylabel("Share Price ($)") + plt.grid(b=True, which="major", color="#666666", linestyle="-") + plt.minorticks_on() + plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) + plt.subplot(212) + plt.plot(df_ta.index, df_ta.iloc[:, 0].values, "b", lw=2) + plt.plot(df_ta.index, df_ta.iloc[:, 2].values, "r", lw=2) + plt.bar(df_ta.index, df_ta.iloc[:, 1].values, color="g") + plt.legend( + [ + f"MACD Line {df_ta.columns[0]}", + f"Signal Line {df_ta.columns[2]}", + f"Histogram {df_ta.columns[1]}", + ] + ) + plt.xlim(df_stock.index[0], df_stock.index[-1]) + plt.grid(b=True, which="major", color="#666666", linestyle="-") + plt.minorticks_on() + plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) + plt.xlabel("Time") + plt.ion() + plt.show() print("") except Exception as e: @@ -269,7 +220,6 @@ def macd(l_args, s_ticker, s_interval, df_stock): print("") -# ----------------------------------------------------- RSI ----------------------------------------------------- def rsi(l_args, s_ticker, s_interval, df_stock): parser = argparse.ArgumentParser( prog="rsi", @@ -320,11 +270,7 @@ def rsi(l_args, s_ticker, s_interval, df_stock): ) try: - (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) - - if l_unknown_args: - print(f"The following args couldn't be interpreted: {l_unknown_args}\n") - return + ns_parser = parse_known_args_and_warn(parser, l_args) # Daily if s_interval == "1440min": @@ -336,31 +282,6 @@ def rsi(l_args, s_ticker, s_interval, df_stock): offset=ns_parser.n_offset, ).dropna() - plt.subplot(211) - plt.plot(df_stock.index, df_stock["5. adjusted close"].values, "k", lw=2) - plt.title(f"Relative Strength Index (RSI) on {s_ticker}") - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.ylabel("Share Price ($)") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.subplot(212) - plt.plot(df_ta.index, df_ta.values, "b", lw=2) - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.axhspan(70, 100, facecolor="r", alpha=0.2) - plt.axhspan(0, 30, facecolor="g", alpha=0.2) - plt.axhline(70, linewidth=3, color="r", ls="--") - plt.axhline(30, linewidth=3, color="g", ls="--") - plt.xlabel("Time") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.ylim([0, 100]) - plt.gca().twinx() - plt.ylim(plt.gca().get_ylim()) - plt.yticks([0.15, 0.85], ("OVERSOLD", "OVERBOUGHT")) - plt.show() - # Intraday else: df_ta = ta.rsi( @@ -371,30 +292,36 @@ def rsi(l_args, s_ticker, s_interval, df_stock): offset=ns_parser.n_offset, ).dropna() - plt.subplot(211) + plt.figure() + plt.subplot(211) + if s_interval == "1440min": + plt.plot(df_stock.index, df_stock["5. adjusted close"].values, "k", lw=2) + else: plt.plot(df_stock.index, df_stock["4. close"].values, "k", lw=2) - plt.title(f"Relative Strength Index (RSI) on {s_ticker}") - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.ylabel("Share Price ($)") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.subplot(212) - plt.plot(df_ta.index, df_ta.values, "b", lw=2) - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.axhspan(70, 100, facecolor="r", alpha=0.2) - plt.axhspan(0, 30, facecolor="g", alpha=0.2) - plt.axhline(70, linewidth=3, color="r", ls="--") - plt.axhline(30, linewidth=3, color="g", ls="--") - plt.xlabel("Time") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.ylim([0, 100]) - plt.gca().twinx() - plt.ylim(plt.gca().get_ylim()) - plt.yticks([0.15, 0.85], ("OVERSOLD", "OVERBOUGHT")) - plt.show() + plt.title(f"Relative Strength Index (RSI) on {s_ticker}") + plt.xlim(df_stock.index[0], df_stock.index[-1]) + plt.ylabel("Share Price ($)") + plt.grid(b=True, which="major", color="#666666", linestyle="-") + plt.minorticks_on() + plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) + plt.subplot(212) + plt.plot(df_ta.index, df_ta.values, "b", lw=2) + plt.xlim(df_stock.index[0], df_stock.index[-1]) + plt.axhspan(70, 100, facecolor="r", alpha=0.2) + plt.axhspan(0, 30, facecolor="g", alpha=0.2) + plt.axhline(70, linewidth=3, color="r", ls="--") + plt.axhline(30, linewidth=3, color="g", ls="--") + plt.xlabel("Time") + plt.grid(b=True, which="major", color="#666666", linestyle="-") + plt.minorticks_on() + plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) + plt.ylim([0, 100]) + plt.gca().twinx() + plt.ylim(plt.gca().get_ylim()) + plt.yticks([0.15, 0.85], ("OVERSOLD", "OVERBOUGHT")) + plt.ion() + plt.show() + print("") except Exception as e: @@ -402,7 +329,6 @@ def rsi(l_args, s_ticker, s_interval, df_stock): print("") -# ----------------------------------------------------- STOCH ----------------------------------------------------- def stoch(l_args, s_ticker, s_interval, df_stock): parser = argparse.ArgumentParser( prog="stoch", @@ -453,11 +379,7 @@ def stoch(l_args, s_ticker, s_interval, df_stock): ) try: - (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) - - if l_unknown_args: - print(f"The following args couldn't be interpreted: {l_unknown_args}\n") - return + ns_parser = parse_known_args_and_warn(parser, l_args) # Daily if s_interval == "1440min": @@ -471,33 +393,6 @@ def stoch(l_args, s_ticker, s_interval, df_stock): offset=ns_parser.n_offset, ).dropna() - plt.subplot(211) - plt.plot(df_stock.index, df_stock["5. adjusted close"].values, "k", lw=2) - plt.title(f"Stochastic Relative Strength Index (STOCH RSI) on {s_ticker}") - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.ylabel("Share Price ($)") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.subplot(212) - plt.plot(df_ta.index, df_ta.iloc[:, 0].values, "k", lw=2) - plt.plot(df_ta.index, df_ta.iloc[:, 1].values, "b", lw=2, ls="--") - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.axhspan(80, 100, facecolor="r", alpha=0.2) - plt.axhspan(0, 20, facecolor="g", alpha=0.2) - plt.axhline(80, linewidth=3, color="r", ls="--") - plt.axhline(20, linewidth=3, color="g", ls="--") - plt.legend([f"%K {df_ta.columns[0]}", f"%D {df_ta.columns[1]}"]) - plt.xlabel("Time") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.ylim([0, 100]) - plt.gca().twinx() - plt.ylim(plt.gca().get_ylim()) - plt.yticks([0.1, 0.9], ("OVERSOLD", "OVERBOUGHT")) - plt.show() - # Intraday else: df_ta = ta.stoch( @@ -510,32 +405,38 @@ def stoch(l_args, s_ticker, s_interval, df_stock): offset=ns_parser.n_offset, ).dropna() - plt.subplot(211) + plt.figure() + plt.subplot(211) + if s_interval == "1440min": + plt.plot(df_stock.index, df_stock["5. adjusted close"].values, "k", lw=2) + else: plt.plot(df_stock.index, df_stock["4. close"].values, "k", lw=2) - plt.title(f"Stochastic Relative Strength Index (STOCH RSI) on {s_ticker}") - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.ylabel("Share Price ($)") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.subplot(212) - plt.plot(df_ta.index, df_ta.iloc[:, 0].values, "k", lw=2) - plt.plot(df_ta.index, df_ta.iloc[:, 1].values, "b", lw=2, ls="--") - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.axhspan(80, 100, facecolor="r", alpha=0.2) - plt.axhspan(0, 20, facecolor="g", alpha=0.2) - plt.axhline(80, linewidth=3, color="r", ls="--") - plt.axhline(20, linewidth=3, color="g", ls="--") - plt.legend([f"%K {df_ta.columns[0]}", f"%D {df_ta.columns[1]}"]) - plt.xlabel("Time") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.ylim([0, 100]) - plt.gca().twinx() - plt.ylim(plt.gca().get_ylim()) - plt.yticks([0.1, 0.9], ("OVERSOLD", "OVERBOUGHT")) - plt.show() + plt.title(f"Stochastic Relative Strength Index (STOCH RSI) on {s_ticker}") + plt.xlim(df_stock.index[0], df_stock.index[-1]) + plt.ylabel("Share Price ($)") + plt.grid(b=True, which="major", color="#666666", linestyle="-") + plt.minorticks_on() + plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) + plt.subplot(212) + plt.plot(df_ta.index, df_ta.iloc[:, 0].values, "k", lw=2) + plt.plot(df_ta.index, df_ta.iloc[:, 1].values, "b", lw=2, ls="--") + plt.xlim(df_stock.index[0], df_stock.index[-1]) + plt.axhspan(80, 100, facecolor="r", alpha=0.2) + plt.axhspan(0, 20, facecolor="g", alpha=0.2) + plt.axhline(80, linewidth=3, color="r", ls="--") + plt.axhline(20, linewidth=3, color="g", ls="--") + plt.legend([f"%K {df_ta.columns[0]}", f"%D {df_ta.columns[1]}"]) + plt.xlabel("Time") + plt.grid(b=True, which="major", color="#666666", linestyle="-") + plt.minorticks_on() + plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) + plt.ylim([0, 100]) + plt.gca().twinx() + plt.ylim(plt.gca().get_ylim()) + plt.yticks([0.1, 0.9], ("OVERSOLD", "OVERBOUGHT")) + plt.ion() + plt.show() + print("") except Exception as e: diff --git a/gamestonk_terminal/technical_analysis/overlap.py b/gamestonk_terminal/technical_analysis/overlap.py index 0794e93ba09..8e6ba2db373 100644 --- a/gamestonk_terminal/technical_analysis/overlap.py +++ b/gamestonk_terminal/technical_analysis/overlap.py @@ -2,12 +2,11 @@ import argparse import matplotlib.pyplot as plt import pandas_ta as ta from pandas.plotting import register_matplotlib_converters -from gamestonk_terminal.helper_funcs import check_positive, plot_stock_ta +from gamestonk_terminal.helper_funcs import check_positive, parse_known_args_and_warn register_matplotlib_converters() -# ----------------------------------------------------- EMA ----------------------------------------------------- def ema(l_args, s_ticker, s_interval, df_stock): parser = argparse.ArgumentParser( prog="ema", @@ -43,11 +42,7 @@ def ema(l_args, s_ticker, s_interval, df_stock): ) try: - (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) - - if l_unknown_args: - print(f"The following args couldn't be interpreted: {l_unknown_args}\n") - return + ns_parser = parse_known_args_and_warn(parser, l_args) # Daily if s_interval == "1440min": @@ -56,12 +51,6 @@ def ema(l_args, s_ticker, s_interval, df_stock): length=ns_parser.n_length, offset=ns_parser.n_offset, ).dropna() - plot_stock_ta( - df_stock["5. adjusted close"], - s_ticker, - df_ta, - f"{ns_parser.n_length} EMA", - ) # Intraday else: @@ -70,16 +59,49 @@ def ema(l_args, s_ticker, s_interval, df_stock): length=ns_parser.n_length, offset=ns_parser.n_offset, ).dropna() - plot_stock_ta( - df_stock["4. close"], s_ticker, df_ta, f"{ns_parser.n_length} EMA" + + _, axPrice = plt.subplots() + plt.title(f"{ns_parser.n_length} EMA on {s_ticker}") + if s_interval == "1440min": + plt.plot( + df_stock["5. adjusted close"].index, + df_stock["5. adjusted close"].values, + "k", + lw=3, ) + plt.xlim( + df_stock["5. adjusted close"].index[0], + df_stock["5. adjusted close"].index[-1], + ) + else: + plt.plot(df_stock["4. close"].index, df_stock["4. close"].values, "k", lw=3) + plt.xlim(df_stock["4. close"].index[0], df_stock["4. close"].index[-1]) + plt.xlabel("Time") + plt.ylabel(f"Share Price of {s_ticker} ($)") + axTa = axPrice.twinx() + plt.plot(df_ta.index, df_ta.values) + # Pandas series + if len(df_ta.shape) == 1: + l_legend = ["{ns_parser.n_length} EMA"] + # Pandas dataframe + else: + l_legend = df_ta.columns.tolist() + plt.legend(l_legend) + axTa.set_ylabel("{ns_parser.n_length} EMA", color="tab:blue") + axTa.spines["right"].set_color("tab:blue") + axTa.tick_params(axis="y", colors="tab:blue") + plt.grid(b=True, which="major", color="#666666", linestyle="-") + plt.minorticks_on() + plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) + plt.ion() + plt.show() + print("") except Exception as e: print(e) print("") -# ----------------------------------------------------- SMA ----------------------------------------------------- def sma(l_args, s_ticker, s_interval, df_stock): parser = argparse.ArgumentParser( prog="sma", @@ -113,55 +135,38 @@ def sma(l_args, s_ticker, s_interval, df_stock): ) try: - (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) + ns_parser = parse_known_args_and_warn(parser, l_args) - if l_unknown_args: - print(f"The following args couldn't be interpreted: {l_unknown_args}\n") - return - - # Daily + plt.figure() if s_interval == "1440min": plt.plot(df_stock.index, df_stock["5. adjusted close"].values, color="k") - l_legend = list() - l_legend.append(s_ticker) - for length in ns_parser.l_length: + else: + plt.plot(df_stock.index, df_stock["4. close"].values, color="k") + l_legend = list() + l_legend.append(s_ticker) + for length in ns_parser.l_length: + if s_interval == "1440min": df_ta = ta.sma( df_stock["5. adjusted close"], length=length, offset=ns_parser.n_offset, ).dropna() - plt.plot(df_ta.index, df_ta.values) - l_legend.append(f"{length} SMA") - plt.title(f"SMA on {s_ticker}") - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.xlabel("Time") - plt.ylabel("Share Price ($)") - plt.legend(l_legend) - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.show() - - # Intraday - else: - plt.plot(df_stock.index, df_stock["4. close"].values, color="k") - l_legend = list() - l_legend.append(s_ticker) - for length in ns_parser.n_length: + else: df_ta = ta.sma( df_stock["4. close"], length=length, offset=ns_parser.n_offset ).dropna() - plt.plot(df_ta.index, df_ta.values) - l_legend.append(f"{length} SMA") - plt.title(f"SMA on {s_ticker}") - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.xlabel("Time") - plt.ylabel("Share Price ($)") - plt.legend(l_legend) - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.show() + plt.plot(df_ta.index, df_ta.values) + l_legend.append(f"{length} SMA") + plt.title(f"SMA on {s_ticker}") + plt.xlim(df_stock.index[0], df_stock.index[-1]) + plt.xlabel("Time") + plt.ylabel("Share Price ($)") + plt.legend(l_legend) + plt.grid(b=True, which="major", color="#666666", linestyle="-") + plt.minorticks_on() + plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) + plt.ion() + plt.show() print("") except Exception as e: @@ -169,7 +174,6 @@ def sma(l_args, s_ticker, s_interval, df_stock): print("") -# ----------------------------------------------------- VWAP ----------------------------------------------------- def vwap(l_args, s_ticker, s_interval, df_stock): parser = argparse.ArgumentParser( prog="vwap", @@ -190,11 +194,7 @@ def vwap(l_args, s_ticker, s_interval, df_stock): ) try: - (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) - - if l_unknown_args: - print(f"The following args couldn't be interpreted: {l_unknown_args}\n") - return + ns_parser = parse_known_args_and_warn(parser, l_args) # Daily if s_interval == "1440min": @@ -206,29 +206,6 @@ def vwap(l_args, s_ticker, s_interval, df_stock): offset=ns_parser.n_offset, ) - _, axPrice = plt.subplots() - plt.plot(df_stock.index, df_stock["5. adjusted close"].values, color="k") - plt.plot(df_ta.index, df_ta.values) - plt.title(f"VWAP on {s_ticker}") - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.xlabel("Time") - plt.ylabel("Share Price ($)") - plt.legend([s_ticker, "VWAP"]) - _ = axPrice.twinx() - plt.bar( - df_stock.index, - df_stock["6. volume"].values, - color="k", - alpha=0.8, - width=0.3, - ) - plt.ylabel("Volume") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.show() - print("") - # Intraday else: df_ta = ta.vwap( @@ -239,15 +216,27 @@ def vwap(l_args, s_ticker, s_interval, df_stock): offset=ns_parser.n_offset, ) - _, axPrice = plt.subplots() + _, axPrice = plt.subplots() + if s_interval == "1440min": + plt.plot(df_stock.index, df_stock["5. adjusted close"].values, color="k") + else: plt.plot(df_stock.index, df_stock["4. close"].values, color="k") - plt.plot(df_ta.index, df_ta.values) - plt.title(f"VWAP on {s_ticker}") - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.xlabel("Time") - plt.ylabel("Share Price ($)") - plt.legend([s_ticker, "VWAP"]) - _ = axPrice.twinx() + plt.plot(df_ta.index, df_ta.values) + plt.title(f"VWAP on {s_ticker}") + plt.xlim(df_stock.index[0], df_stock.index[-1]) + plt.xlabel("Time") + plt.ylabel("Share Price ($)") + plt.legend([s_ticker, "VWAP"]) + _ = axPrice.twinx() + if s_interval == "1440min": + plt.bar( + df_stock.index, + df_stock["6. volume"].values, + color="k", + alpha=0.8, + width=0.3, + ) + else: plt.bar( df_stock.index, df_stock["5. volume"].values, @@ -255,12 +244,13 @@ def vwap(l_args, s_ticker, s_interval, df_stock): alpha=0.8, width=0.3, ) - plt.ylabel("Volume") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.show() - print("") + plt.ylabel("Volume") + plt.grid(b=True, which="major", color="#666666", linestyle="-") + plt.minorticks_on() + plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) + plt.ion() + plt.show() + print("") except Exception as e: print(e) diff --git a/gamestonk_terminal/technical_analysis/ta_menu.py b/gamestonk_terminal/technical_analysis/ta_menu.py index 288a4500a57..a78cc074793 100644 --- a/gamestonk_terminal/technical_analysis/ta_menu.py +++ b/gamestonk_terminal/technical_analysis/ta_menu.py @@ -5,9 +5,9 @@ from gamestonk_terminal.technical_analysis import momentum as ta_momentum from gamestonk_terminal.technical_analysis import trend as ta_trend from gamestonk_terminal.technical_analysis import volatility as ta_volatility from gamestonk_terminal.technical_analysis import volume as ta_volume +import matplotlib.pyplot as plt -# ----------------------------------------------------------------------------------------------------------------------- def print_technical_analysis(s_ticker, s_start, s_interval): """ Print help """ @@ -42,7 +42,6 @@ def print_technical_analysis(s_ticker, s_start, s_interval): print("") -# ---------------------------------------------------- MENU ---------------------------------------------------- def ta_menu(df_stock, s_ticker, s_start, s_interval): # Add list of arguments that the technical analysis parser accepts @@ -55,18 +54,18 @@ def ta_menu(df_stock, s_ticker, s_start, s_interval): "quit", "ema", "sma", - "vwap", # overlap + "vwap", "cci", "macd", "rsi", - "stoch", # momentum + "stoch", "adx", - "aroon", # trend - "bbands", # volatility + "aroon", + "bbands", "ad", "obv", ], - ) # volume + ) print_technical_analysis(s_ticker, s_start, s_interval) @@ -75,6 +74,9 @@ def ta_menu(df_stock, s_ticker, s_start, s_interval): # Get input command from user as_input = input("> ") + # Images are non blocking - allows to close them if we type other command + plt.close() + # Parse fundamental analysis command of the list of possible commands try: (ns_known_args, l_args) = ta_parser.parse_known_args(as_input.split()) @@ -94,7 +96,7 @@ def ta_menu(df_stock, s_ticker, s_start, s_interval): # Abandon the program return True - # -------------------------------------------------- OVERLAP -------------------------------------------------- + # OVERLAP elif ns_known_args.cmd == "ema": ta_overlap.ema(l_args, s_ticker, s_interval, df_stock) @@ -104,7 +106,7 @@ def ta_menu(df_stock, s_ticker, s_start, s_interval): elif ns_known_args.cmd == "vwap": ta_overlap.vwap(l_args, s_ticker, s_interval, df_stock) - # --------------------------------------------------- MOMENTUM --------------------------------------------------- + # MOMENTUM elif ns_known_args.cmd == "cci": ta_momentum.cci(l_args, s_ticker, s_interval, df_stock) @@ -117,24 +119,23 @@ def ta_menu(df_stock, s_ticker, s_start, s_interval): elif ns_known_args.cmd == "stoch": ta_momentum.stoch(l_args, s_ticker, s_interval, df_stock) - # ---------------------------------------------------- TREND ---------------------------------------------------- + # TREND elif ns_known_args.cmd == "adx": ta_trend.adx(l_args, s_ticker, s_interval, df_stock) elif ns_known_args.cmd == "aroon": ta_trend.aroon(l_args, s_ticker, s_interval, df_stock) - # -------------------------------------------------- VOLATILITY -------------------------------------------------- + # VOLATILITY elif ns_known_args.cmd == "bbands": ta_volatility.bbands(l_args, s_ticker, s_interval, df_stock) - # ---------------------------------------------------- VOLUME ---------------------------------------------------- + # VOLUME elif ns_known_args.cmd == "ad": ta_volume.ad(l_args, s_ticker, s_interval, df_stock) elif ns_known_args.cmd == "obv": ta_volume.obv(l_args, s_ticker, s_interval, df_stock) - # ------------------------------------------------------------------------------------------------------------ else: print("Command not recognized!") diff --git a/gamestonk_terminal/technical_analysis/trend.py b/gamestonk_terminal/technical_analysis/trend.py index 0ae45b8315c..654e28e1d4a 100644 --- a/gamestonk_terminal/technical_analysis/trend.py +++ b/gamestonk_terminal/technical_analysis/trend.py @@ -2,12 +2,11 @@ import argparse import matplotlib.pyplot as plt import pandas_ta as ta from pandas.plotting import register_matplotlib_converters -from gamestonk_terminal.helper_funcs import check_positive +from gamestonk_terminal.helper_funcs import check_positive, parse_known_args_and_warn register_matplotlib_converters() -# ----------------------------------------------------- ADX ----------------------------------------------------- def adx(l_args, s_ticker, s_interval, df_stock): parser = argparse.ArgumentParser( prog="adx", @@ -56,11 +55,7 @@ def adx(l_args, s_ticker, s_interval, df_stock): ) try: - (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) - - if l_unknown_args: - print(f"The following args couldn't be interpreted: {l_unknown_args}\n") - return + ns_parser = parse_known_args_and_warn(parser, l_args) # Daily if s_interval == "1440min": @@ -74,34 +69,6 @@ def adx(l_args, s_ticker, s_interval, df_stock): offset=ns_parser.n_offset, ).dropna() - plt.subplot(211) - plt.plot(df_stock.index, df_stock["5. adjusted close"].values, "k", lw=2) - plt.title(f"Average Directional Movement Index (ADX) on {s_ticker}") - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.ylabel("Share Price ($)") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.subplot(212) - plt.plot(df_ta.index, df_ta.iloc[:, 0].values, "b", lw=2) - plt.plot(df_ta.index, df_ta.iloc[:, 1].values, "g", lw=1) - plt.plot(df_ta.index, df_ta.iloc[:, 2].values, "r", lw=1) - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.axhline(25, linewidth=3, color="k", ls="--") - plt.legend( - [ - f"ADX ({df_ta.columns[0]})", - f"+DI ({df_ta.columns[1]})", - f"- DI ({df_ta.columns[2]})", - ] - ) - plt.xlabel("Time") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.ylim([0, 100]) - plt.show() - # Intraday else: df_ta = ta.adx( @@ -114,33 +81,8 @@ def adx(l_args, s_ticker, s_interval, df_stock): offset=ns_parser.n_offset, ).dropna() - plt.subplot(211) - plt.plot(df_stock.index, df_stock["4. close"].values, "k", lw=2) - plt.title(f"Average Directional Movement Index (ADX) on {s_ticker}") - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.ylabel("Share Price ($)") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.subplot(212) - plt.plot(df_ta.index, df_ta.iloc[:, 0].values, "b", lw=2) - plt.plot(df_ta.index, df_ta.iloc[:, 1].values, "g", lw=1) - plt.plot(df_ta.index, df_ta.iloc[:, 2].values, "r", lw=1) - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.axhline(25, linewidth=3, color="k", ls="--") - plt.legend( - [ - f"ADX ({df_ta.columns[0]})", - f"+DI ({df_ta.columns[1]})", - f"- DI ({df_ta.columns[2]})", - ] - ) - plt.xlabel("Time") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.ylim([0, 100]) - plt.show() + plot_adx(df_stock, s_ticker, df_ta) + print("") except Exception as e: @@ -148,7 +90,38 @@ def adx(l_args, s_ticker, s_interval, df_stock): print("") -# ----------------------------------------------------- AROON ----------------------------------------------------- +def plot_adx(df_stock, s_ticker, df_ta): + plt.figure() + plt.subplot(211) + plt.plot(df_stock.index, df_stock["4. close"].values, "k", lw=2) + plt.title(f"Average Directional Movement Index (ADX) on {s_ticker}") + plt.xlim(df_stock.index[0], df_stock.index[-1]) + plt.ylabel("Share Price ($)") + plt.grid(b=True, which="major", color="#666666", linestyle="-") + plt.minorticks_on() + plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) + plt.subplot(212) + plt.plot(df_ta.index, df_ta.iloc[:, 0].values, "b", lw=2) + plt.plot(df_ta.index, df_ta.iloc[:, 1].values, "g", lw=1) + plt.plot(df_ta.index, df_ta.iloc[:, 2].values, "r", lw=1) + plt.xlim(df_stock.index[0], df_stock.index[-1]) + plt.axhline(25, linewidth=3, color="k", ls="--") + plt.legend( + [ + f"ADX ({df_ta.columns[0]})", + f"+DI ({df_ta.columns[1]})", + f"- DI ({df_ta.columns[2]})", + ] + ) + plt.xlabel("Time") + plt.grid(b=True, which="major", color="#666666", linestyle="-") + plt.minorticks_on() + plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) + plt.ylim([0, 100]) + plt.ion() + plt.show() + + def aroon(l_args, s_ticker, s_interval, df_stock): parser = argparse.ArgumentParser( prog="aroon", @@ -195,11 +168,7 @@ def aroon(l_args, s_ticker, s_interval, df_stock): ) try: - (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) - - if l_unknown_args: - print(f"The following args couldn't be interpreted: {l_unknown_args}\n") - return + ns_parser = parse_known_args_and_warn(parser, l_args) df_ta = ta.aroon( high=df_stock["2. high"], @@ -209,21 +178,22 @@ def aroon(l_args, s_ticker, s_interval, df_stock): offset=ns_parser.n_offset, ).dropna() + plt.figure() plt.subplot(311) # Daily if s_interval == "1440min": - # plot_stock_and_ta(df_stock['5. adjusted close'], s_ticker, df_ta.iloc[:,-1], "AROON") plt.plot(df_stock.index, df_stock["5. adjusted close"].values, "k", lw=2) # Intraday else: - # plot_stock_and_ta(df_stock['4. close'], s_ticker, df_ta.iloc[:,-1], "AROON") plt.plot(df_stock.index, df_stock["4. close"].values, "k", lw=2) + plt.title(f"Aroon on {s_ticker}") plt.xlim(df_stock.index[0], df_stock.index[-1]) plt.ylabel("Share Price ($)") plt.grid(b=True, which="major", color="#666666", linestyle="-") plt.minorticks_on() plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) + plt.subplot(312) plt.plot(df_ta.index, df_ta.iloc[:, 0].values, "r", lw=2) plt.plot(df_ta.index, df_ta.iloc[:, 1].values, "g", lw=2) @@ -236,6 +206,7 @@ def aroon(l_args, s_ticker, s_interval, df_stock): plt.minorticks_on() plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) plt.ylim([0, 100]) + plt.subplot(313) plt.plot(df_ta.index, df_ta.iloc[:, 2].values, "b", lw=2) plt.xlabel("Time") @@ -244,6 +215,7 @@ def aroon(l_args, s_ticker, s_interval, df_stock): plt.minorticks_on() plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) plt.ylim([-100, 100]) + plt.ion() plt.show() print("") diff --git a/gamestonk_terminal/technical_analysis/volatility.py b/gamestonk_terminal/technical_analysis/volatility.py index 1fc3b344ead..c6ef28a0176 100644 --- a/gamestonk_terminal/technical_analysis/volatility.py +++ b/gamestonk_terminal/technical_analysis/volatility.py @@ -2,12 +2,11 @@ import argparse import matplotlib.pyplot as plt import pandas_ta as ta from pandas.plotting import register_matplotlib_converters -from gamestonk_terminal.helper_funcs import check_positive +from gamestonk_terminal.helper_funcs import check_positive, parse_known_args_and_warn register_matplotlib_converters() -# ----------------------------------------------------- BBANDS ----------------------------------------------------- def bbands(l_args, s_ticker, s_interval, df_stock): parser = argparse.ArgumentParser( prog="bbands", @@ -15,13 +14,13 @@ def bbands(l_args, s_ticker, s_interval, df_stock): Bollinger Bands consist of three lines. The middle band is a simple moving average (generally 20 periods) of the typical price (TP). The upper and lower bands are F standard deviations (generally 2) above and below the middle band. - The bands widen and narrow when the volatility of the price is higher or lower, respectively. - \n \nBollinger Bands do not, in themselves, generate buy or sell signals; they are an - indicator of overbought or oversold conditions. When the price is near the upper or lower - band it indicates that a reversal may be imminent. The middle band becomes a support or - resistance level. The upper and lower bands can also be interpreted as price targets. - When the price bounces off of the lower band and crosses the middle band, then the - upper band becomes the price target. + The bands widen and narrow when the volatility of the price is higher or lower, + respectively. \n \nBollinger Bands do not, in themselves, generate buy or sell signals; + they are an indicator of overbought or oversold conditions. When the price is near the + upper or lower band it indicates that a reversal may be imminent. The middle band + becomes a support or resistance level. The upper and lower bands can also be + interpreted as price targets. When the price bounces off of the lower band and crosses + the middle band, then the upper band becomes the price target. """, ) @@ -57,11 +56,7 @@ def bbands(l_args, s_ticker, s_interval, df_stock): ) try: - (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) - - if l_unknown_args: - print(f"The following args couldn't be interpreted: {l_unknown_args}\n") - return + ns_parser = parse_known_args_and_warn(parser, l_args) # Daily if s_interval == "1440min": @@ -72,30 +67,6 @@ def bbands(l_args, s_ticker, s_interval, df_stock): mamode=ns_parser.s_mamode, offset=ns_parser.n_offset, ).dropna() - # plot_stock_ta(df_stock['5. adjusted close'], s_ticker, df_ta, "BBANDS") - - plt.plot( - df_stock.index, df_stock["5. adjusted close"].values, color="k", lw=3 - ) - plt.plot(df_ta.index, df_ta.iloc[:, 0].values, "r", lw=2) - plt.plot(df_ta.index, df_ta.iloc[:, 1].values, "b", lw=1.5, ls="--") - plt.plot(df_ta.index, df_ta.iloc[:, 2].values, "g", lw=2) - plt.title(f"Bollinger Band (BBands) on {s_ticker}") - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.xlabel("Time") - plt.ylabel("Share Price ($)") - plt.legend([s_ticker, df_ta.columns[0], df_ta.columns[1], df_ta.columns[2]]) - plt.gca().fill_between( - df_ta.index, - df_ta.iloc[:, 0].values, - df_ta.iloc[:, 2].values, - alpha=0.1, - color="b", - ) - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.show() # Intraday else: @@ -106,28 +77,34 @@ def bbands(l_args, s_ticker, s_interval, df_stock): mamode=ns_parser.s_mamode, offset=ns_parser.n_offset, ).dropna() - # plot_stock_ta(df_stock['4. close'], s_ticker, df_ta, "BBANDS") - plt.plot(df_stock.index, df_stock["4. close"].values, color="k", lw=3) - plt.plot(df_ta.index, df_ta.iloc[:, 0].values, "r", lw=2) - plt.plot(df_ta.index, df_ta.iloc[:, 1].values, "b", lw=1.5, ls="--") - plt.plot(df_ta.index, df_ta.iloc[:, 2].values, "g", lw=2) - plt.title(f"Bollinger Band (BBands) on {s_ticker}") - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.xlabel("Time") - plt.ylabel("Share Price ($)") - plt.legend([s_ticker, df_ta.columns[0], df_ta.columns[1], df_ta.columns[2]]) - plt.gca().fill_between( - df_ta.index, - df_ta.iloc[:, 0].values, - df_ta.iloc[:, 2].values, - alpha=0.1, - color="b", + plt.figure() + if s_ticker == "1440min": + plt.plot( + df_stock.index, df_stock["5. adjusted close"].values, color="k", lw=3 ) - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.show() + else: + plt.plot(df_stock.index, df_stock["4. close"].values, color="k", lw=3) + plt.plot(df_ta.index, df_ta.iloc[:, 0].values, "r", lw=2) + plt.plot(df_ta.index, df_ta.iloc[:, 1].values, "b", lw=1.5, ls="--") + plt.plot(df_ta.index, df_ta.iloc[:, 2].values, "g", lw=2) + plt.title(f"Bollinger Band (BBands) on {s_ticker}") + plt.xlim(df_stock.index[0], df_stock.index[-1]) + plt.xlabel("Time") + plt.ylabel("Share Price ($)") + plt.legend([s_ticker, df_ta.columns[0], df_ta.columns[1], df_ta.columns[2]]) + plt.gca().fill_between( + df_ta.index, + df_ta.iloc[:, 0].values, + df_ta.iloc[:, 2].values, + alpha=0.1, + color="b", + ) + plt.grid(b=True, which="major", color="#666666", linestyle="-") + plt.minorticks_on() + plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) + plt.ion() + plt.show() print("") except Exception as e: diff --git a/gamestonk_terminal/technical_analysis/volume.py b/gamestonk_terminal/technical_analysis/volume.py index 0c4c01f8197..7d0168fe50f 100644 --- a/gamestonk_terminal/technical_analysis/volume.py +++ b/gamestonk_terminal/technical_analysis/volume.py @@ -2,12 +2,11 @@ import argparse import matplotlib.pyplot as plt import pandas_ta as ta from pandas.plotting import register_matplotlib_converters -from gamestonk_terminal.helper_funcs import check_positive +from gamestonk_terminal.helper_funcs import check_positive, parse_known_args_and_warn register_matplotlib_converters() -# ------------------------------------------------------- AD ------------------------------------------------------- def ad(l_args, s_ticker, s_interval, df_stock): parser = argparse.ArgumentParser( prog="ad", @@ -43,11 +42,7 @@ def ad(l_args, s_ticker, s_interval, df_stock): ) try: - (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) - - if l_unknown_args: - print(f"The following args couldn't be interpreted: {l_unknown_args}\n") - return + ns_parser = parse_known_args_and_warn(parser, l_args) # Daily if s_interval == "1440min": @@ -71,33 +66,6 @@ def ad(l_args, s_ticker, s_interval, df_stock): offset=ns_parser.n_offset, ).dropna() - axPrice = plt.subplot(211) - plt.plot(df_stock.index, df_stock["5. adjusted close"].values, "k", lw=2) - plt.title(f"Accumulation/Distribution Line (AD) on {s_ticker}") - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.ylabel("Share Price ($)") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - _ = axPrice.twinx() - plt.bar( - df_stock.index, - df_stock["6. volume"].values, - color="k", - alpha=0.8, - width=0.3, - ) - plt.subplot(212) - plt.plot(df_ta.index, df_ta.values, "b", lw=1) - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.axhline(0, linewidth=2, color="k", ls="--") - plt.legend(["Chaikin Oscillator"]) - plt.xlabel("Time") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.show() - # Intraday else: # Use open stock values @@ -120,15 +88,28 @@ def ad(l_args, s_ticker, s_interval, df_stock): offset=ns_parser.n_offset, ).dropna() - axPrice = plt.subplot(211) + plt.figure() + axPrice = plt.subplot(211) + if s_interval == "1440min": + plt.plot(df_stock.index, df_stock["5. adjusted close"].values, "k", lw=2) + else: plt.plot(df_stock.index, df_stock["4. close"].values, "k", lw=2) - plt.title(f"Accumulation/Distribution Line (AD) on {s_ticker}") - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.ylabel("Share Price ($)") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - _ = axPrice.twinx() + plt.title(f"Accumulation/Distribution Line (AD) on {s_ticker}") + plt.xlim(df_stock.index[0], df_stock.index[-1]) + plt.ylabel("Share Price ($)") + plt.grid(b=True, which="major", color="#666666", linestyle="-") + plt.minorticks_on() + plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) + _ = axPrice.twinx() + if s_interval == "1440min": + plt.bar( + df_stock.index, + df_stock["6. volume"].values, + color="k", + alpha=0.8, + width=0.3, + ) + else: plt.bar( df_stock.index, df_stock["5. volume"].values, @@ -136,16 +117,17 @@ def ad(l_args, s_ticker, s_interval, df_stock): alpha=0.8, width=0.3, ) - plt.subplot(212) - plt.plot(df_ta.index, df_ta.values, "b", lw=1) - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.axhline(0, linewidth=2, color="k", ls="--") - plt.legend(["Chaikin Oscillator"]) - plt.xlabel("Time") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.show() + plt.subplot(212) + plt.plot(df_ta.index, df_ta.values, "b", lw=1) + plt.xlim(df_stock.index[0], df_stock.index[-1]) + plt.axhline(0, linewidth=2, color="k", ls="--") + plt.legend(["Chaikin Oscillator"]) + plt.xlabel("Time") + plt.grid(b=True, which="major", color="#666666", linestyle="-") + plt.minorticks_on() + plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) + plt.ion() + plt.show() print("") except Exception as e: @@ -154,7 +136,6 @@ def ad(l_args, s_ticker, s_interval, df_stock): return -# ------------------------------------------------------- OBV ------------------------------------------------------- def obv(l_args, s_ticker, s_interval, df_stock): parser = argparse.ArgumentParser( prog="obv", @@ -180,11 +161,7 @@ def obv(l_args, s_ticker, s_interval, df_stock): ) try: - (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) - - if l_unknown_args: - print(f"The following args couldn't be interpreted: {l_unknown_args}\n") - return + ns_parser = parse_known_args_and_warn(parser, l_args) # Daily if s_interval == "1440min": @@ -194,32 +171,6 @@ def obv(l_args, s_ticker, s_interval, df_stock): offset=ns_parser.n_offset, ).dropna() - axPrice = plt.subplot(211) - plt.plot(df_stock.index, df_stock["5. adjusted close"].values, "k", lw=2) - plt.title(f"On-Balance Volume (OBV) on {s_ticker}") - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.ylabel("Share Price ($)") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - _ = axPrice.twinx() - plt.bar( - df_stock.index, - df_stock["6. volume"].values, - color="k", - alpha=0.8, - width=0.3, - ) - plt.subplot(212) - plt.plot(df_ta.index, df_ta.values, "b", lw=1) - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.legend(["OBV"]) - plt.xlabel("Time") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.show() - # Intraday else: df_ta = ta.obv( @@ -228,15 +179,28 @@ def obv(l_args, s_ticker, s_interval, df_stock): offset=ns_parser.n_offset, ).dropna() - axPrice = plt.subplot(211) + plt.figure() + axPrice = plt.subplot(211) + if s_interval == "1440min": plt.plot(df_stock.index, df_stock["5. adjusted close"].values, "k", lw=2) - plt.title(f"On-Balance Volume (OBV) on {s_ticker}") - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.ylabel("Share Price ($)") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - _ = axPrice.twinx() + else: + plt.plot(df_stock.index, df_stock["4. close"].values, "k", lw=2) + plt.title(f"On-Balance Volume (OBV) on {s_ticker}") + plt.xlim(df_stock.index[0], df_stock.index[-1]) + plt.ylabel("Share Price ($)") + plt.grid(b=True, which="major", color="#666666", linestyle="-") + plt.minorticks_on() + plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) + _ = axPrice.twinx() + if s_interval == "1440min": + plt.bar( + df_stock.index, + df_stock["6. volume"].values, + color="k", + alpha=0.8, + width=0.3, + ) + else: plt.bar( df_stock.index, df_stock["5. volume"].values, @@ -244,15 +208,16 @@ def obv(l_args, s_ticker, s_interval, df_stock): alpha=0.8, width=0.3, ) - plt.subplot(212) - plt.plot(df_ta.index, df_ta.values, "b", lw=1) - plt.xlim(df_stock.index[0], df_stock.index[-1]) - plt.legend(["OBV"]) - plt.xlabel("Time") - plt.grid(b=True, which="major", color="#666666", linestyle="-") - plt.minorticks_on() - plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) - plt.show() + plt.subplot(212) + plt.plot(df_ta.index, df_ta.values, "b", lw=1) + plt.xlim(df_stock.index[0], df_stock.index[-1]) + plt.legend(["OBV"]) + plt.xlabel("Time") + plt.grid(b=True, which="major", color="#666666", linestyle="-") + plt.minorticks_on() + plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2) + plt.ion() + plt.show() print("")