diff --git a/gamestonk_terminal/__init__.py b/gamestonk_terminal/__init__.py index bc157798fe5..e69de29bb2d 100644 --- a/gamestonk_terminal/__init__.py +++ b/gamestonk_terminal/__init__.py @@ -1,8 +0,0 @@ -# flake8: noqa -from . import discovery -from . import due_diligence -from . import fundamental_analysis -from . import papermill -from . import prediction_techniques -from . import behavioural_analysis -from . import technical_analysis diff --git a/gamestonk_terminal/behavioural_analysis/README.md b/gamestonk_terminal/common/behavioural_analysis/README.md similarity index 100% rename from gamestonk_terminal/behavioural_analysis/README.md rename to gamestonk_terminal/common/behavioural_analysis/README.md diff --git a/gamestonk_terminal/behavioural_analysis/finbrain_view.py b/gamestonk_terminal/common/behavioural_analysis/finbrain_view.py similarity index 100% rename from gamestonk_terminal/behavioural_analysis/finbrain_view.py rename to gamestonk_terminal/common/behavioural_analysis/finbrain_view.py diff --git a/gamestonk_terminal/behavioural_analysis/finnhub_view.py b/gamestonk_terminal/common/behavioural_analysis/finnhub_view.py similarity index 100% rename from gamestonk_terminal/behavioural_analysis/finnhub_view.py rename to gamestonk_terminal/common/behavioural_analysis/finnhub_view.py diff --git a/gamestonk_terminal/behavioural_analysis/google_view.py b/gamestonk_terminal/common/behavioural_analysis/google_view.py similarity index 100% rename from gamestonk_terminal/behavioural_analysis/google_view.py rename to gamestonk_terminal/common/behavioural_analysis/google_view.py diff --git a/gamestonk_terminal/behavioural_analysis/reddit_view.py b/gamestonk_terminal/common/behavioural_analysis/reddit_view.py similarity index 100% rename from gamestonk_terminal/behavioural_analysis/reddit_view.py rename to gamestonk_terminal/common/behavioural_analysis/reddit_view.py diff --git a/gamestonk_terminal/behavioural_analysis/sentimentinvestor_view.py b/gamestonk_terminal/common/behavioural_analysis/sentimentinvestor_view.py similarity index 100% rename from gamestonk_terminal/behavioural_analysis/sentimentinvestor_view.py rename to gamestonk_terminal/common/behavioural_analysis/sentimentinvestor_view.py diff --git a/gamestonk_terminal/behavioural_analysis/stocktwits_view.py b/gamestonk_terminal/common/behavioural_analysis/stocktwits_view.py similarity index 100% rename from gamestonk_terminal/behavioural_analysis/stocktwits_view.py rename to gamestonk_terminal/common/behavioural_analysis/stocktwits_view.py diff --git a/gamestonk_terminal/behavioural_analysis/twitter_view.py b/gamestonk_terminal/common/behavioural_analysis/twitter_view.py similarity index 100% rename from gamestonk_terminal/behavioural_analysis/twitter_view.py rename to gamestonk_terminal/common/behavioural_analysis/twitter_view.py diff --git a/gamestonk_terminal/exploratory_data_analysis/eda_api.py b/gamestonk_terminal/common/exploratory_data_analysis/eda_api.py similarity index 100% rename from gamestonk_terminal/exploratory_data_analysis/eda_api.py rename to gamestonk_terminal/common/exploratory_data_analysis/eda_api.py diff --git a/gamestonk_terminal/prediction_techniques/FUNE-TUNING-NN-models.md b/gamestonk_terminal/common/prediction_techniques/FUNE-TUNING-NN-models.md similarity index 98% rename from gamestonk_terminal/prediction_techniques/FUNE-TUNING-NN-models.md rename to gamestonk_terminal/common/prediction_techniques/FUNE-TUNING-NN-models.md index 2468e6f8c43..f5d7c9048c6 100644 --- a/gamestonk_terminal/prediction_techniques/FUNE-TUNING-NN-models.md +++ b/gamestonk_terminal/common/prediction_techniques/FUNE-TUNING-NN-models.md @@ -19,7 +19,7 @@ load MSFT -s 2014-01-01 Anyone reading this, note this is quite a discussion between the devs. Since this is a time series, there is an inherent ordering of the data. However, since returns are random, it is hard to predict, and ordering data may not have any meaning. -To this end, we allow users to specify how much validation data to use and if it should be shuffled. By default, we will split +To this end, we allow users to specify how much validation data to use and if it should be shuffled. By default, we will split into 10% validation data with a random shuffle. This will allow the user to see how the model performs at various times in your sequence. ``` @@ -108,7 +108,7 @@ This tells your model how "fast" to train by adjusting the factor that gets mult Select the number of epochs to train your model. The bigger number of epochs, the longer the training will take, and also increase chances of overfitting. -An early stopping has been implemented that will (if desired) stop training once the validation loss has plateaued. the patience (number of +An early stopping has been implemented that will (if desired) stop training once the validation loss has plateaued. the patience (number of epochs with no improvement) can be found in the config file. ``` --epochs : number of training epochs. Default 200. diff --git a/gamestonk_terminal/prediction_techniques/README-gpu-accel.md b/gamestonk_terminal/common/prediction_techniques/README-gpu-accel.md similarity index 100% rename from gamestonk_terminal/prediction_techniques/README-gpu-accel.md rename to gamestonk_terminal/common/prediction_techniques/README-gpu-accel.md diff --git a/gamestonk_terminal/prediction_techniques/README.md b/gamestonk_terminal/common/prediction_techniques/README.md similarity index 99% rename from gamestonk_terminal/prediction_techniques/README.md rename to gamestonk_terminal/common/prediction_techniques/README.md index 8fc2ef3347a..ff7369ac9dd 100644 --- a/gamestonk_terminal/prediction_techniques/README.md +++ b/gamestonk_terminal/common/prediction_techniques/README.md @@ -244,7 +244,7 @@ Long_Short_Term_Memory \ ## conv1d ``` -usage: lstm [-d N_DAYS] [-i N_INPUTS] [--epochs N_EPOCHS] [-e S_END_DATE] [--loops N_LOOPS] [-v VALID] +usage: lstm [-d N_DAYS] [-i N_INPUTS] [--epochs N_EPOCHS] [-e S_END_DATE] [--loops N_LOOPS] [-v VALID] [--lr LEARNING_RATE] [--no_shuffle] ``` 1D Convolutional Neural Net: @@ -259,4 +259,4 @@ usage: lstm [-d N_DAYS] [-i N_INPUTS] [--epochs N_EPOCHS] [-e S_END_DATE] [--loo * --batch_size: batch size for model training, should not be used unless advanced user. Default None. * --loops: number of loops to iterate and train models. Default 1. * --lr : learning rate for optimizer - * --no_shuffle : split validation data in time_ordered way instead of random. \ No newline at end of file + * --no_shuffle : split validation data in time_ordered way instead of random. diff --git a/gamestonk_terminal/prediction_techniques/arima_view.py b/gamestonk_terminal/common/prediction_techniques/arima_view.py similarity index 99% rename from gamestonk_terminal/prediction_techniques/arima_view.py rename to gamestonk_terminal/common/prediction_techniques/arima_view.py index 32f53e7a6ae..d08478b6995 100644 --- a/gamestonk_terminal/prediction_techniques/arima_view.py +++ b/gamestonk_terminal/common/prediction_techniques/arima_view.py @@ -17,7 +17,7 @@ from gamestonk_terminal.helper_funcs import ( get_next_stock_market_days, plot_autoscale, ) -from gamestonk_terminal.prediction_techniques.pred_helper import ( +from gamestonk_terminal.common.prediction_techniques.pred_helper import ( print_pretty_prediction, price_prediction_backtesting_color, print_prediction_kpis, diff --git a/gamestonk_terminal/prediction_techniques/ets_view.py b/gamestonk_terminal/common/prediction_techniques/ets_view.py similarity index 99% rename from gamestonk_terminal/prediction_techniques/ets_view.py rename to gamestonk_terminal/common/prediction_techniques/ets_view.py index 43f863480f9..45c74d2cb51 100644 --- a/gamestonk_terminal/prediction_techniques/ets_view.py +++ b/gamestonk_terminal/common/prediction_techniques/ets_view.py @@ -18,7 +18,7 @@ from gamestonk_terminal.helper_funcs import ( get_next_stock_market_days, plot_autoscale, ) -from gamestonk_terminal.prediction_techniques.pred_helper import ( +from gamestonk_terminal.common.prediction_techniques.pred_helper import ( print_pretty_prediction, price_prediction_backtesting_color, print_prediction_kpis, diff --git a/gamestonk_terminal/prediction_techniques/knn_view.py b/gamestonk_terminal/common/prediction_techniques/knn_view.py similarity index 98% rename from gamestonk_terminal/prediction_techniques/knn_view.py rename to gamestonk_terminal/common/prediction_techniques/knn_view.py index 90776120d7b..9d39cf2fdd6 100644 --- a/gamestonk_terminal/prediction_techniques/knn_view.py +++ b/gamestonk_terminal/common/prediction_techniques/knn_view.py @@ -12,7 +12,7 @@ from gamestonk_terminal.helper_funcs import ( valid_date, get_next_stock_market_days, ) -from gamestonk_terminal.prediction_techniques.pred_helper import ( +from gamestonk_terminal.common.prediction_techniques.pred_helper import ( print_pretty_prediction, prepare_scale_train_valid_test, plot_data_predictions, diff --git a/gamestonk_terminal/prediction_techniques/neural_networks_view.py b/gamestonk_terminal/common/prediction_techniques/neural_networks_view.py similarity index 99% rename from gamestonk_terminal/prediction_techniques/neural_networks_view.py rename to gamestonk_terminal/common/prediction_techniques/neural_networks_view.py index 4d446b00a09..e54e4dded8a 100644 --- a/gamestonk_terminal/prediction_techniques/neural_networks_view.py +++ b/gamestonk_terminal/common/prediction_techniques/neural_networks_view.py @@ -28,7 +28,7 @@ from tensorflow.keras.optimizers import ( SGD, ) from gamestonk_terminal.helper_funcs import get_next_stock_market_days -from gamestonk_terminal.prediction_techniques.pred_helper import ( +from gamestonk_terminal.common.prediction_techniques.pred_helper import ( prepare_scale_train_valid_test, forecast, plot_data_predictions, diff --git a/gamestonk_terminal/prediction_techniques/pred_helper.py b/gamestonk_terminal/common/prediction_techniques/pred_helper.py similarity index 100% rename from gamestonk_terminal/prediction_techniques/pred_helper.py rename to gamestonk_terminal/common/prediction_techniques/pred_helper.py diff --git a/gamestonk_terminal/prediction_techniques/regression_view.py b/gamestonk_terminal/common/prediction_techniques/regression_view.py similarity index 99% rename from gamestonk_terminal/prediction_techniques/regression_view.py rename to gamestonk_terminal/common/prediction_techniques/regression_view.py index e5ba49cea96..3e2cec3f15a 100644 --- a/gamestonk_terminal/prediction_techniques/regression_view.py +++ b/gamestonk_terminal/common/prediction_techniques/regression_view.py @@ -21,7 +21,7 @@ from gamestonk_terminal.helper_funcs import ( plot_autoscale, ) -from gamestonk_terminal.prediction_techniques.pred_helper import ( +from gamestonk_terminal.common.prediction_techniques.pred_helper import ( print_pretty_prediction, price_prediction_backtesting_color, print_prediction_kpis, diff --git a/gamestonk_terminal/residuals_analysis/residuals_api.py b/gamestonk_terminal/common/residuals_analysis/residuals_api.py similarity index 100% rename from gamestonk_terminal/residuals_analysis/residuals_api.py rename to gamestonk_terminal/common/residuals_analysis/residuals_api.py index 4b62ddf53c1..89e3117b754 100644 --- a/gamestonk_terminal/residuals_analysis/residuals_api.py +++ b/gamestonk_terminal/common/residuals_analysis/residuals_api.py @@ -3,13 +3,13 @@ __docformat__ = "numpy" import argparse from typing import List +from collections import OrderedDict from matplotlib import pyplot as plt import pandas as pd from pandas.plotting import register_matplotlib_converters import seaborn as sns import scipy.stats as stats import statsmodels.api as sm -from collections import OrderedDict import matplotlib.gridspec as gridspec from statsmodels.graphics.gofplots import qqplot from statsmodels.tsa.stattools import adfuller, kpss, bds diff --git a/gamestonk_terminal/residuals_analysis/residuals_model.py b/gamestonk_terminal/common/residuals_analysis/residuals_model.py similarity index 95% rename from gamestonk_terminal/residuals_analysis/residuals_model.py rename to gamestonk_terminal/common/residuals_analysis/residuals_model.py index 44b65fb9acd..cdbf260d38a 100644 --- a/gamestonk_terminal/residuals_analysis/residuals_model.py +++ b/gamestonk_terminal/common/residuals_analysis/residuals_model.py @@ -42,13 +42,12 @@ def naive( try: ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: - return + return "", None, list() - naive = pd.Series(stock.values[:-1], index=stock[1:].index) + model = pd.Series(stock.values[:-1], index=stock[1:].index) model_name = "Naive" - model = naive - residuals = stock[1:].values - naive.values + residuals = stock[1:].values - model.values return model_name, model, residuals @@ -116,7 +115,7 @@ def arima( try: ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: - return + return "", None, list() if ns_parser.s_order: t_order = tuple(int(ord) for ord in list(ns_parser.s_order)) diff --git a/gamestonk_terminal/technical_analysis/README.md b/gamestonk_terminal/common/technical_analysis/README.md similarity index 100% rename from gamestonk_terminal/technical_analysis/README.md rename to gamestonk_terminal/common/technical_analysis/README.md diff --git a/gamestonk_terminal/technical_analysis/custom_indicators_view.py b/gamestonk_terminal/common/technical_analysis/custom_indicators_view.py similarity index 100% rename from gamestonk_terminal/technical_analysis/custom_indicators_view.py rename to gamestonk_terminal/common/technical_analysis/custom_indicators_view.py diff --git a/gamestonk_terminal/technical_analysis/momentum.py b/gamestonk_terminal/common/technical_analysis/momentum.py similarity index 100% rename from gamestonk_terminal/technical_analysis/momentum.py rename to gamestonk_terminal/common/technical_analysis/momentum.py diff --git a/gamestonk_terminal/technical_analysis/overlap.py b/gamestonk_terminal/common/technical_analysis/overlap.py similarity index 100% rename from gamestonk_terminal/technical_analysis/overlap.py rename to gamestonk_terminal/common/technical_analysis/overlap.py diff --git a/gamestonk_terminal/technical_analysis/trend_indicators.py b/gamestonk_terminal/common/technical_analysis/trend_indicators.py similarity index 100% rename from gamestonk_terminal/technical_analysis/trend_indicators.py rename to gamestonk_terminal/common/technical_analysis/trend_indicators.py diff --git a/gamestonk_terminal/technical_analysis/trendline_api.py b/gamestonk_terminal/common/technical_analysis/trendline_api.py similarity index 100% rename from gamestonk_terminal/technical_analysis/trendline_api.py rename to gamestonk_terminal/common/technical_analysis/trendline_api.py diff --git a/gamestonk_terminal/technical_analysis/volatility.py b/gamestonk_terminal/common/technical_analysis/volatility.py similarity index 100% rename from gamestonk_terminal/technical_analysis/volatility.py rename to gamestonk_terminal/common/technical_analysis/volatility.py diff --git a/gamestonk_terminal/technical_analysis/volume.py b/gamestonk_terminal/common/technical_analysis/volume.py similarity index 100% rename from gamestonk_terminal/technical_analysis/volume.py rename to gamestonk_terminal/common/technical_analysis/volume.py diff --git a/gamestonk_terminal/config_terminal.py b/gamestonk_terminal/config_terminal.py index 58469a4562b..67caab8b276 100644 --- a/gamestonk_terminal/config_terminal.py +++ b/gamestonk_terminal/config_terminal.py @@ -5,6 +5,9 @@ env_files = [f for f in os.listdir() if f.endswith(".env")] if env_files: load_dotenv(env_files[0]) +# Choose one of: stocks, options, crypto, economy, etf, portfolio, forex +DEFAULT_CONTEXT = "" + # By default the jupyter notebook will be run on port 8888 PAPERMILL_NOTEBOOK_REPORT_PORT = "8888" diff --git a/gamestonk_terminal/cryptocurrency/binance/binance_controller.py b/gamestonk_terminal/cryptocurrency/binance/binance_controller.py index 55943482af4..3b29dc81f70 100644 --- a/gamestonk_terminal/cryptocurrency/binance/binance_controller.py +++ b/gamestonk_terminal/cryptocurrency/binance/binance_controller.py @@ -9,7 +9,7 @@ from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.helper_funcs import get_flair from gamestonk_terminal.menu import session from gamestonk_terminal.cryptocurrency.binance import binance_model -from gamestonk_terminal.technical_analysis import ta_controller +from gamestonk_terminal.cryptocurrency.technical_analysis import ta_controller class BinanceController: @@ -53,7 +53,7 @@ class BinanceController: print(" book show order book") print(" candle show candles") print(" balance show coin balance") - print(" ta open technical analysis menu") + print("> ta open technical analysis menu") print("") def switch(self, an_input: str): @@ -162,7 +162,6 @@ class BinanceController: ticker=self.current_coin, start=self.current_df.index[0], interval="", - context="(crypto)>(bin)", ) print("") if quit is not None: diff --git a/gamestonk_terminal/cryptocurrency/binance/binance_model.py b/gamestonk_terminal/cryptocurrency/binance/binance_model.py index a31ee41999b..5787fdcea62 100644 --- a/gamestonk_terminal/cryptocurrency/binance/binance_model.py +++ b/gamestonk_terminal/cryptocurrency/binance/binance_model.py @@ -10,7 +10,7 @@ from binance.client import Client from binance.exceptions import BinanceAPIException from tabulate import tabulate from gamestonk_terminal.helper_funcs import check_positive -from gamestonk_terminal.main_helper import parse_known_args_and_warn +from gamestonk_terminal.helper_funcs import parse_known_args_and_warn import gamestonk_terminal.config_terminal as cfg from gamestonk_terminal.cryptocurrency.binance.binance_view import ( plot_order_book, diff --git a/gamestonk_terminal/cryptocurrency/binance/binance_view.py b/gamestonk_terminal/cryptocurrency/binance/binance_view.py index 86e77576b2f..a26064d437a 100644 --- a/gamestonk_terminal/cryptocurrency/binance/binance_view.py +++ b/gamestonk_terminal/cryptocurrency/binance/binance_view.py @@ -5,7 +5,7 @@ import numpy as np import matplotlib.pyplot as plt import mplfinance as mpf import pandas as pd -from gamestonk_terminal.main_helper import plot_autoscale +from gamestonk_terminal.helper_funcs import plot_autoscale from gamestonk_terminal.config_plot import PLOT_DPI from gamestonk_terminal.feature_flags import USE_ION as ion diff --git a/gamestonk_terminal/cryptocurrency/coingecko/pycoingecko_controller.py b/gamestonk_terminal/cryptocurrency/coingecko/pycoingecko_controller.py index ec349035a7a..798814600c5 100644 --- a/gamestonk_terminal/cryptocurrency/coingecko/pycoingecko_controller.py +++ b/gamestonk_terminal/cryptocurrency/coingecko/pycoingecko_controller.py @@ -9,7 +9,7 @@ from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.helper_funcs import get_flair from gamestonk_terminal.menu import session from gamestonk_terminal.cryptocurrency.coingecko import pycoingecko_view -from gamestonk_terminal.technical_analysis import ta_controller +from gamestonk_terminal.cryptocurrency.technical_analysis import ta_controller class GeckoController: @@ -90,7 +90,7 @@ class GeckoController: print(f"Loaded coin: {self.current_coin}") print("") print(" chart price chart for loaded coin") - print(" ta yechnical analysis menu for loaded coin") + print("> ta technical analysis menu for loaded coin") print(" info nasic information about loaded coin") print(" market market stats about loaded coin") print(" ath all time high related stats for loaded coin") @@ -301,7 +301,6 @@ class GeckoController: ticker=self.current_coin.coin_symbol, start=self.current_df.index[0], interval="", - context="(crypto)>(cg)", ) print("") if quit is not None: diff --git a/gamestonk_terminal/cryptocurrency/coinpaprika/coinpaprika_controller.py b/gamestonk_terminal/cryptocurrency/coinpaprika/coinpaprika_controller.py index 287d3a2db9e..9ac4c58429e 100644 --- a/gamestonk_terminal/cryptocurrency/coinpaprika/coinpaprika_controller.py +++ b/gamestonk_terminal/cryptocurrency/coinpaprika/coinpaprika_controller.py @@ -11,7 +11,7 @@ from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.helper_funcs import get_flair from gamestonk_terminal.menu import session from gamestonk_terminal.cryptocurrency.coinpaprika import coinpaprika_view -from gamestonk_terminal.technical_analysis import ta_controller +from gamestonk_terminal.cryptocurrency.technical_analysis import ta_controller class PaprikaController: @@ -232,7 +232,6 @@ class PaprikaController: ticker=self.current_coin, start=self.current_df.index[0], interval="", - context="(crypto)>(cp)", ) print("") if quit is not None: diff --git a/gamestonk_terminal/cryptocurrency/coinpaprika/coinpaprika_view.py b/gamestonk_terminal/cryptocurrency/coinpaprika/coinpaprika_view.py index d47a99bc29b..e1989dcd56e 100644 --- a/gamestonk_terminal/cryptocurrency/coinpaprika/coinpaprika_view.py +++ b/gamestonk_terminal/cryptocurrency/coinpaprika/coinpaprika_view.py @@ -3,8 +3,6 @@ __docformat__ = "numpy" import argparse from typing import List -from json.decoder import JSONDecodeError - import difflib from tabulate import tabulate from pandas.plotting import register_matplotlib_converters @@ -13,7 +11,7 @@ import mplfinance as mpf import pandas as pd from gamestonk_terminal.helper_funcs import parse_known_args_and_warn, check_positive -from gamestonk_terminal.main_helper import plot_autoscale +from gamestonk_terminal.helper_funcs import plot_autoscale from gamestonk_terminal.feature_flags import USE_ION as ion import gamestonk_terminal.cryptocurrency.coinpaprika.coinpaprika_model as paprika from gamestonk_terminal.cryptocurrency.cryptocurrency_helpers import ( @@ -70,14 +68,9 @@ CURRENCIES = [ "ARS", "ISK", ] -try: - PLATFORMS = paprika.get_all_contract_platforms()["platform_id"].tolist() - COINS = paprika.get_list_of_coins() - COINS_DCT = dict(zip(COINS.id, COINS.symbol)) - # see https://github.com/GamestonkTerminal/GamestonkTerminal/pull/562#issuecomment-887842888 - # EXCHANGES = paprika.get_list_of_exchanges() -except JSONDecodeError: - print("JSON Error loading from coinpaprika") + +# see https://github.com/GamestonkTerminal/GamestonkTerminal/pull/562#issuecomment-887842888 +# EXCHANGES = paprika.get_list_of_exchanges() def global_market(other_args: List[str]): @@ -774,7 +767,7 @@ def contracts(other_args: List[str]): dest="platform", default="eth-ethereum", type=str, - choices=PLATFORMS, + choices=paprika.get_all_contract_platforms()["platform_id"].tolist(), ) parser.add_argument( "-t", @@ -1449,6 +1442,8 @@ def load(other_args: List[str]): if not ns_parser: return + COINS = paprika.get_list_of_coins() + COINS_DCT = dict(zip(COINS.id, COINS.symbol)) coin_id, _ = paprika.validate_coin(ns_parser.coin, COINS_DCT) if coin_id: diff --git a/gamestonk_terminal/cryptocurrency/crypto_controller.py b/gamestonk_terminal/cryptocurrency/crypto_controller.py index 20fb5e2f5ed..cd4b5ed4473 100644 --- a/gamestonk_terminal/cryptocurrency/crypto_controller.py +++ b/gamestonk_terminal/cryptocurrency/crypto_controller.py @@ -13,6 +13,7 @@ from gamestonk_terminal.cryptocurrency.binance import binance_controller from gamestonk_terminal.cryptocurrency.coingecko import pycoingecko_controller from gamestonk_terminal.cryptocurrency import finbrain_crypto_view from gamestonk_terminal.cryptocurrency.coinpaprika import coinpaprika_controller +from gamestonk_terminal.cryptocurrency.report import report_controller class CryptoController: @@ -23,13 +24,23 @@ class CryptoController: "help", "q", "quit", + ] + + CHOICES_COMMAND = [ + "finbrain", + ] + + CHOICES_MENUS = [ "cg", "bin", "cmc", - "finbrain", "cp", + "report", ] + CHOICES += CHOICES_COMMAND + CHOICES += CHOICES_MENUS + def __init__(self): """CONSTRUCTOR""" @@ -41,7 +52,10 @@ class CryptoController: print( "https://github.com/GamestonkTerminal/GamestonkTerminal/tree/main/gamestonk_terminal/cryptocurrency" ) - print("\nCryptocurrency:") + print("") + print(">> CRYPTO <<") + print("") + print("What do you want to do?") print(" cls clear screen") print(" ?/help show this menu again") print(" q quit this menu, and shows back to main menu") @@ -53,6 +67,7 @@ class CryptoController: print("> cmc Coinmarketcap menu") print("> bin Binance menu with order book, candles, ta.. ") print("> cp CoinPaprika menu") + print("> report generate automatic report") print("") def switch(self, an_input: str): @@ -126,6 +141,15 @@ class CryptoController: return True print("") + def call_report(self, _): + """Process report command""" + ret = report_controller.menu() + + if ret is False: + self.print_help() + else: + return True + def menu(): crypto_controller = CryptoController() diff --git a/gamestonk_terminal/cryptocurrency/finbrain_crypto_view.py b/gamestonk_terminal/cryptocurrency/finbrain_crypto_view.py index 14a605dd98f..a26565d5939 100644 --- a/gamestonk_terminal/cryptocurrency/finbrain_crypto_view.py +++ b/gamestonk_terminal/cryptocurrency/finbrain_crypto_view.py @@ -8,7 +8,7 @@ from gamestonk_terminal.helper_funcs import ( parse_known_args_and_warn, ) from gamestonk_terminal import feature_flags as gtff -from gamestonk_terminal.behavioural_analysis.finbrain_view import ( +from gamestonk_terminal.common.behavioural_analysis.finbrain_view import ( get_sentiment, plot_sentiment, sentiment_coloring, diff --git a/gamestonk_terminal/papermill/README.md b/gamestonk_terminal/cryptocurrency/report/README.md similarity index 99% rename from gamestonk_terminal/papermill/README.md rename to gamestonk_terminal/cryptocurrency/report/README.md index f0449ca4e76..0e88202ac37 100644 --- a/gamestonk_terminal/papermill/README.md +++ b/gamestonk_terminal/cryptocurrency/report/README.md @@ -11,7 +11,7 @@ Command | Template | Example `dp` | [Dark Pool](/notebooks/templates/dark_pool.ipynb) | [Dark Pool](/notebooks/examples/amc_dark_pool_20210728_235316.html) `cm` | [Crypto Market](/notebooks/templates/crypto_market.ipynb) | [Crypto Market](/notebooks/examples/crypto_market_20210729_001530.html) - + ## How to run the report 1. In [config_terminal](/gamestonk_terminal/config_terminal.py) you may need to change your `PAPERMILL_NOTEBOOK_REPORT_PORT` from `8888`. If the notebook generation fails, it is likely that the port selected is not the correct one. @@ -36,11 +36,10 @@ extension = ".ipynb" * You're now ready to write your own notes 6. Once you're happy with your report, you can either: - * Re-run the last cell (potentially changing output from `.html` with: + * Re-run the last cell (potentially changing output from `.html` with: ``` folder = "notebooks/reports/" extension = ".ipynb" !jupyter nbconvert {folder + report_name + extension} --to html --no-input ``` * Or, on the toolbar click on "File" -> "Download as" -> Select your preferred option (e.g. HTML) - diff --git a/gamestonk_terminal/backtesting/__init__.py b/gamestonk_terminal/cryptocurrency/report/__init__.py similarity index 100% rename from gamestonk_terminal/backtesting/__init__.py rename to gamestonk_terminal/cryptocurrency/report/__init__.py diff --git a/gamestonk_terminal/papermill/crypto_market_view.py b/gamestonk_terminal/cryptocurrency/report/crypto_market_view.py similarity index 100% rename from gamestonk_terminal/papermill/crypto_market_view.py rename to gamestonk_terminal/cryptocurrency/report/crypto_market_view.py diff --git a/gamestonk_terminal/cryptocurrency/report/report_controller.py b/gamestonk_terminal/cryptocurrency/report/report_controller.py new file mode 100644 index 00000000000..d68a24f24d3 --- /dev/null +++ b/gamestonk_terminal/cryptocurrency/report/report_controller.py @@ -0,0 +1,151 @@ +"""Papermill Controller Module""" +__docformat__ = "numpy" + +import argparse +import os +from typing import List +import subprocess +from prompt_toolkit.completion import NestedCompleter +from gamestonk_terminal.cryptocurrency.report import crypto_market_view + +from gamestonk_terminal import feature_flags as gtff +from gamestonk_terminal.menu import session +from gamestonk_terminal.helper_funcs import get_flair +from gamestonk_terminal import config_terminal + +# pylint: disable=R1732 + + +class ReportController: + """Report Controller class""" + + CHOICES = [ + "cls", + "?", + "help", + "q", + "quit", + ] + + CHOICES_COMMANDS = [ + "ov", + ] + + CHOICES += CHOICES_COMMANDS + + def __init__(self): + """Constructor""" + self.report_parser = argparse.ArgumentParser(add_help=False, prog="report") + self.report_parser.add_argument( + "cmd", + choices=self.CHOICES, + ) + + def switch(self, an_input: str, proc: subprocess.Popen): + """Process and dispatch input + + Parameters + ------- + an_input : str + string with input arguments + proc : subprocess.Popen + subprocess that calls jupyter notebook for report generation + + Returns + ------- + True, False or None + False - quit the menu + True - quit the program + None - continue in the menu + """ + + # Empty command + if not an_input: + print("") + return None + + (known_args, other_args) = self.report_parser.parse_known_args(an_input.split()) + + # Help menu again + if known_args.cmd == "?": + print_help() + return None + + # Clear screen + if known_args.cmd == "cls": + os.system("cls||clear") + return None + + return getattr( + self, "call_" + known_args.cmd, lambda: "Command not recognized!" + )(other_args, proc) + + def call_help(self, *_): + """Process Help command""" + print_help() + + def call_q(self, _, proc): + """Process Q command - quit the menu""" + proc.kill() + return False + + def call_quit(self, _, proc): + """Process Quit command - quit the program""" + proc.kill() + return True + + def call_ov(self, other_args: List[str], _): + """Process ov command""" + crypto_market_view.crypto_market_report(other_args) + + +def print_help(): + """Print help""" + print( + "https://github.com/GamestonkTerminal/GamestonkTerminal/tree/main/gamestonk_terminal/cryptocurrency/report" + ) + print("\nReports:") + print(" cls clear screen") + print(" ?/help show this menu again") + print(" q quit this menu, and shows back to main menu") + print(" quit quit to abandon program") + print("") + print(" ov generate crypto overview report") + print("") + + +def menu(): + """Report Menu""" + report_controller = ReportController() + report_controller.call_help(None) + + # Initialize jupyter notebook + cmd = f"jupyter notebook --port={config_terminal.PAPERMILL_NOTEBOOK_REPORT_PORT}" + proc = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT + ) + + while True: + # Get input command from user + if session and gtff.USE_PROMPT_TOOLKIT: + completer = NestedCompleter.from_nested_dict( + {c: None for c in report_controller.CHOICES} + ) + an_input = session.prompt( + f"{get_flair()} (crypto)>(report)> ", + completer=completer, + ) + else: + an_input = input(f"{get_flair()} (crypto)>(report)> ") + + try: + process_input = report_controller.switch(an_input, proc) + except SystemExit: + print("The command selected doesn't exist\n") + continue + + if process_input is False: + return False + + if process_input is True: + return True diff --git a/gamestonk_terminal/cryptocurrency/technical_analysis/ta_controller.py b/gamestonk_terminal/cryptocurrency/technical_analysis/ta_controller.py new file mode 100644 index 00000000000..156f8e3192b --- /dev/null +++ b/gamestonk_terminal/cryptocurrency/technical_analysis/ta_controller.py @@ -0,0 +1,239 @@ +"""Technical Analysis Controller Module""" +__docformat__ = "numpy" + +import argparse +import os +from typing import List +from datetime import datetime +import pandas as pd +import matplotlib.pyplot as plt +from prompt_toolkit.completion import NestedCompleter + +from gamestonk_terminal import feature_flags as gtff +from gamestonk_terminal.helper_funcs import get_flair +from gamestonk_terminal.menu import session + +from gamestonk_terminal.common.technical_analysis import ( + custom_indicators_view, + momentum, + overlap, + trend_indicators, + volatility, + volume, +) + + +class TechnicalAnalysisController: + """Technical Analysis Controller class""" + + # Command choices + CHOICES = [ + "cls", + "?", + "help", + "q", + "quit", + "ema", + "sma", + "vwap", + "cci", + "macd", + "rsi", + "stoch", + "adx", + "aroon", + "bbands", + "ad", + "obv", + "fib", + ] + + def __init__( + self, + ticker: str, + start: datetime, + interval: str, + stock: pd.DataFrame, + ): + """Constructor""" + self.ticker = ticker + self.start = start + self.interval = interval + self.stock = stock + + self.ta_parser = argparse.ArgumentParser(add_help=False, prog="ta") + self.ta_parser.add_argument( + "cmd", + choices=self.CHOICES, + ) + + def print_help(self): + """Print help""" + print( + "https://github.com/GamestonkTerminal/GamestonkTerminal/tree/main/gamestonk_terminal/technical_analysis" + ) + s_intraday = (f"Intraday {self.interval }", "Daily")[self.interval == "1440min"] + + if self.start: + print( + f"\n{s_intraday} Stock: {self.ticker} (from {self.start.strftime('%Y-%m-%d')})" + ) + else: + print(f"\n{s_intraday} Stock: {self.ticker}") + + print("\nTechnical Analysis:") + print(" cls clear screen") + print(" ?/help show this menu again") + print(" q quit this menu, and shows back to main menu") + print(" quit quit to abandon program") + print("") + print("overlap:") + print(" ema exponential moving average") + print(" sma simple moving average") + print(" vwap volume weighted average price") + print("momentum:") + print(" cci commodity channel index") + print(" macd moving average convergence/divergence") + print(" rsi relative strength index") + print(" stoch stochastic oscillator") + print("trend:") + print(" adx average directional movement index") + print(" aroon aroon indicator") + print("volatility:") + print(" bbands bollinger bands") + print("volume:") + print(" ad accumulation/distribution line values") + print(" obv on balance volume") + print("custom:") + print(" fib fibonocci retracement") + print("") + + def switch(self, an_input: str): + """Process and dispatch input + + Returns + ------- + True, False or None + False - quit the menu + True - quit the program + None - continue in the menu + """ + + # Empty command + if not an_input: + print("") + return None + + (known_args, other_args) = self.ta_parser.parse_known_args(an_input.split()) + + # Help menu again + if known_args.cmd == "?": + self.print_help() + return None + + # Clear screen + if known_args.cmd == "cls": + os.system("cls||clear") + return None + + return getattr( + self, "call_" + known_args.cmd, lambda: "Command not recognized!" + )(other_args) + + def call_help(self, _): + """Process Help command""" + self.print_help() + + def call_q(self, _): + """Process Q command - quit the menu""" + return False + + def call_quit(self, _): + """Process Quit command - quit the program""" + return True + + def call_ema(self, other_args: List[str]): + """Process ema command""" + overlap.ema(other_args, self.ticker, self.interval, self.stock) + + def call_sma(self, other_args: List[str]): + """Process sma command""" + overlap.sma(other_args, self.ticker, self.interval, self.stock) + + def call_vwap(self, other_args: List[str]): + """Process vwap command""" + overlap.vwap(other_args, self.ticker, self.interval, self.stock) + + def call_cci(self, other_args: List[str]): + """Process cci command""" + momentum.cci(other_args, self.ticker, self.interval, self.stock) + + def call_macd(self, other_args: List[str]): + """Process macd command""" + momentum.macd(other_args, self.ticker, self.interval, self.stock) + + def call_rsi(self, other_args: List[str]): + """Process rsi command""" + momentum.rsi(other_args, self.ticker, self.interval, self.stock) + + def call_stoch(self, other_args: List[str]): + """Process stoch command""" + momentum.stoch(other_args, self.ticker, self.interval, self.stock) + + def call_adx(self, other_args: List[str]): + """Process adx command""" + trend_indicators.adx(other_args, self.ticker, self.interval, self.stock) + + def call_aroon(self, other_args: List[str]): + """Process aroon command""" + trend_indicators.aroon(other_args, self.ticker, self.interval, self.stock) + + def call_bbands(self, other_args: List[str]): + """Process bbands command""" + volatility.bbands(other_args, self.ticker, self.interval, self.stock) + + def call_ad(self, other_args: List[str]): + """Process ad command""" + volume.ad(other_args, self.ticker, self.interval, self.stock) + + def call_obv(self, other_args: List[str]): + """Process obv command""" + volume.obv(other_args, self.ticker, self.interval, self.stock) + + def call_fib(self, other_args: List[str]): + """Process fib command""" + custom_indicators_view.fibinocci_retracement( + other_args, self.stock, self.ticker + ) + + +def menu(ticker: str, start: datetime, interval: str, stock: pd.DataFrame): + """Technical Analysis Menu""" + + ta_controller = TechnicalAnalysisController(ticker, start, interval, stock) + ta_controller.call_help(None) + + while True: + # Get input command from user + if session and gtff.USE_PROMPT_TOOLKIT: + completer = NestedCompleter.from_nested_dict( + {c: None for c in ta_controller.CHOICES} + ) + an_input = session.prompt( + f"{get_flair()} (crypto)>(ta)> ", + completer=completer, + ) + else: + an_input = input(f"{get_flair()} (crypto)>(ta)> ") + + try: + plt.close("all") + + process_input = ta_controller.switch(an_input) + + if process_input is not None: + return process_input + + except SystemExit: + print("The command selected doesn't exist\n") + continue diff --git a/gamestonk_terminal/economy/__init__.py b/gamestonk_terminal/economy/__init__.py index e19b8205271..4b9d25b0789 100644 --- a/gamestonk_terminal/economy/__init__.py +++ b/gamestonk_terminal/economy/__init__.py @@ -1 +1 @@ -from . import econ_controller # noqa: F401 +from . import economy_controller # noqa: F401 diff --git a/gamestonk_terminal/economy/econ_controller.py b/gamestonk_terminal/economy/economy_controller.py similarity index 91% rename from gamestonk_terminal/economy/econ_controller.py rename to gamestonk_terminal/economy/economy_controller.py index 12d4ae2f0d1..887284bcf54 100644 --- a/gamestonk_terminal/economy/econ_controller.py +++ b/gamestonk_terminal/economy/economy_controller.py @@ -12,6 +12,9 @@ from gamestonk_terminal.economy import fred_view from gamestonk_terminal.economy import finnhub_view from gamestonk_terminal.economy import cnn_view from gamestonk_terminal.economy import wsj_view +from gamestonk_terminal.economy.report import report_controller + +# pylint: disable=R1710 class EconomyController: @@ -19,11 +22,14 @@ class EconomyController: # Command choices CHOICES = [ - "?", "cls", + "?", "help", "q", "quit", + ] + + CHOICES_COMMANDS = [ "events", "fred", "vixcls", @@ -47,9 +53,16 @@ class EconomyController: "currencies", ] + CHOICES_MENUS = [ + "report", + ] + + CHOICES += CHOICES_COMMANDS + CHOICES += CHOICES_MENUS + def __init__(self): """Constructor""" - self.econ_parser = argparse.ArgumentParser(add_help=False, prog="econ") + self.econ_parser = argparse.ArgumentParser(add_help=False, prog="economy") self.econ_parser.add_argument( "cmd", choices=self.CHOICES, @@ -61,7 +74,10 @@ class EconomyController: print( "https://github.com/GamestonkTerminal/GamestonkTerminal/tree/main/gamestonk_terminal/economy" ) - print("\nEconomic Data:") + print("") + print(">> ECONOMY <<") + print("") + print("What do you want to do?") print(" cls clear screen") print(" ?/help show this menu again") print(" q quit this menu, and shows back to main menu") @@ -92,7 +108,8 @@ class EconomyController: print(" glbonds global bonds overview") print(" currencies currency overview") print("") - return + print("> report generate automatic report") + print("") def switch(self, an_input: str): """Process and dispatch input @@ -218,6 +235,15 @@ class EconomyController: """Process curremcies command""" wsj_view.display_currencies(other_args) + def call_report(self, _): + """Process report command""" + ret = report_controller.menu() + + if ret is False: + self.print_help() + else: + return True + def menu(): """Econ Menu""" @@ -234,11 +260,11 @@ def menu(): ) an_input = session.prompt( - f"{get_flair()} (econ)> ", + f"{get_flair()} (economy)> ", completer=completer, ) else: - an_input = input(f"{get_flair()} (econ)> ") + an_input = input(f"{get_flair()} (economy)> ") try: process_input = econ_controller.switch(an_input) diff --git a/gamestonk_terminal/economy/fred_view.py b/gamestonk_terminal/economy/fred_view.py index e89462d9b17..e5dbdd142ef 100644 --- a/gamestonk_terminal/economy/fred_view.py +++ b/gamestonk_terminal/economy/fred_view.py @@ -185,6 +185,7 @@ def display_fred(other_args: List[str], choice: str): if gtff.USE_ION: plt.ion() plt.show() + print("") except SystemExit: print("") diff --git a/gamestonk_terminal/economy/report/README.md b/gamestonk_terminal/economy/report/README.md new file mode 100644 index 00000000000..0e88202ac37 --- /dev/null +++ b/gamestonk_terminal/economy/report/README.md @@ -0,0 +1,45 @@ +# PAPERMILL + +This menu has a different concept from remaining menus. It has 2 main goals: + - Generate a personalised report. + - Allow the user to write notes on that notebook (report), as if it was his personal investment diary. + +Command | Template | Example +------ | --------|---- +`dd` | [Due Diligence Template](/notebooks/templates/due_diligence.ipynb) | [Due Diligence Example](/notebooks/examples/aapl_due_diligence_20210729_001048.html) +`econ` | [Economy Template](/notebooks/templates/econ_data.ipynb) | [Economy Example](/notebooks/examples/econ_data_20210729_001227.html) +`dp` | [Dark Pool](/notebooks/templates/dark_pool.ipynb) | [Dark Pool](/notebooks/examples/amc_dark_pool_20210728_235316.html) +`cm` | [Crypto Market](/notebooks/templates/crypto_market.ipynb) | [Crypto Market](/notebooks/examples/crypto_market_20210729_001530.html) + + +## How to run the report + +1. In [config_terminal](/gamestonk_terminal/config_terminal.py) you may need to change your `PAPERMILL_NOTEBOOK_REPORT_PORT` from `8888`. If the notebook generation fails, it is likely that the port selected is not the correct one. + +2. Start the terminal with `python terminal.py` + +3. Select `mill` and select one of the available reports generation, e.g. `econ` + +4. This should prompt you with a filled notebok with name: `report_name_date_time.ipynb`. E.g. `econ_data_20210725_193517.ipynb` + +5. Due to the last cell of the notebook, the report is saved by default as `.html`. E.g. `econ_data_20210725_193517.html` +``` +folder = "notebooks/reports/" +extension = ".ipynb" +!jupyter nbconvert {folder + report_name + extension} --to html --no-input +``` + +6. You can now write your own personal notes on the notebook. By doing: + * Click on the notebook cell that you are interested in writing your notes + * On the toolbar click on "+" to add a new cell + * On the tooblar click on "Cell" -> "Cell Type" -> "Markdown" + * You're now ready to write your own notes + +6. Once you're happy with your report, you can either: + * Re-run the last cell (potentially changing output from `.html` with: + ``` + folder = "notebooks/reports/" + extension = ".ipynb" + !jupyter nbconvert {folder + report_name + extension} --to html --no-input + ``` + * Or, on the toolbar click on "File" -> "Download as" -> Select your preferred option (e.g. HTML) diff --git a/gamestonk_terminal/papermill/econ_data_helper.py b/gamestonk_terminal/economy/report/econ_data_helper.py similarity index 97% rename from gamestonk_terminal/papermill/econ_data_helper.py rename to gamestonk_terminal/economy/report/econ_data_helper.py index d4ab70f8226..cf1bfb13e7a 100644 --- a/gamestonk_terminal/papermill/econ_data_helper.py +++ b/gamestonk_terminal/economy/report/econ_data_helper.py @@ -7,7 +7,7 @@ from datetime import datetime, timedelta import pandas as pd import mplfinance as mpf -from gamestonk_terminal.technical_analysis import trendline_api as trend +from gamestonk_terminal.common.technical_analysis import trendline_api as trend # pylint: disable=too-many-arguments diff --git a/gamestonk_terminal/papermill/econ_data_view.py b/gamestonk_terminal/economy/report/econ_data_view.py similarity index 100% rename from gamestonk_terminal/papermill/econ_data_view.py rename to gamestonk_terminal/economy/report/econ_data_view.py diff --git a/gamestonk_terminal/economy/report/report_controller.py b/gamestonk_terminal/economy/report/report_controller.py new file mode 100644 index 00000000000..5db06767ea3 --- /dev/null +++ b/gamestonk_terminal/economy/report/report_controller.py @@ -0,0 +1,151 @@ +"""Papermill Controller Module""" +__docformat__ = "numpy" + +import argparse +import os +from typing import List +import subprocess +from prompt_toolkit.completion import NestedCompleter +from gamestonk_terminal.economy.report import econ_data_view + +from gamestonk_terminal import feature_flags as gtff +from gamestonk_terminal.menu import session +from gamestonk_terminal.helper_funcs import get_flair +from gamestonk_terminal import config_terminal + +# pylint: disable=R1732 + + +class ReportController: + """Report Controller class""" + + CHOICES = [ + "cls", + "?", + "help", + "q", + "quit", + ] + + CHOICES_COMMANDS = [ + "ov", + ] + + CHOICES += CHOICES_COMMANDS + + def __init__(self): + """Constructor""" + self.report_parser = argparse.ArgumentParser(add_help=False, prog="report") + self.report_parser.add_argument( + "cmd", + choices=self.CHOICES, + ) + + def switch(self, an_input: str, proc: subprocess.Popen): + """Process and dispatch input + + Parameters + ------- + an_input : str + string with input arguments + proc : subprocess.Popen + subprocess that calls jupyter notebook for report generation + + Returns + ------- + True, False or None + False - quit the menu + True - quit the program + None - continue in the menu + """ + + # Empty command + if not an_input: + print("") + return None + + (known_args, other_args) = self.report_parser.parse_known_args(an_input.split()) + + # Help menu again + if known_args.cmd == "?": + print_help() + return None + + # Clear screen + if known_args.cmd == "cls": + os.system("cls||clear") + return None + + return getattr( + self, "call_" + known_args.cmd, lambda: "Command not recognized!" + )(other_args, proc) + + def call_help(self, *_): + """Process Help command""" + print_help() + + def call_q(self, _, proc): + """Process Q command - quit the menu""" + proc.kill() + return False + + def call_quit(self, _, proc): + """Process Quit command - quit the program""" + proc.kill() + return True + + def call_ov(self, other_args: List[str], _): + """Process ov command""" + econ_data_view.economy_data_report(other_args) + + +def print_help(): + """Print help""" + print( + "https://github.com/GamestonkTerminal/GamestonkTerminal/tree/main/gamestonk_terminal/economy/report" + ) + print("\nReports:") + print(" cls clear screen") + print(" ?/help show this menu again") + print(" q quit this menu, and shows back to main menu") + print(" quit quit to abandon program") + print("") + print(" ov generate economy overview report") + print("") + + +def menu(): + """Report Menu""" + report_controller = ReportController() + report_controller.call_help(None) + + # Initialize jupyter notebook + cmd = f"jupyter notebook --port={config_terminal.PAPERMILL_NOTEBOOK_REPORT_PORT}" + proc = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT + ) + + while True: + # Get input command from user + if session and gtff.USE_PROMPT_TOOLKIT: + completer = NestedCompleter.from_nested_dict( + {c: None for c in report_controller.CHOICES} + ) + an_input = session.prompt( + f"{get_flair()} (economy)>(report)> ", + completer=completer, + ) + else: + an_input = input(f"{get_flair()} (economy)>(report)> ") + + try: + process_input = report_controller.switch(an_input, proc) + except SystemExit: + print("The command selected doesn't exist\n") + continue + + if process_input is False: + return False + + if process_input is True: + return True diff --git a/gamestonk_terminal/etf/etf_controller.py b/gamestonk_terminal/etf/etf_controller.py index f76af703ae1..7de9aa21654 100644 --- a/gamestonk_terminal/etf/etf_controller.py +++ b/gamestonk_terminal/etf/etf_controller.py @@ -21,12 +21,17 @@ from gamestonk_terminal.etf import wsj_view class ETFController: + """ETF Controller class""" + CHOICES = [ "cls", "?", "help", "q", "quit", + ] + + CHOICES_COMMANDS = [ "web", "search", "overview", @@ -38,9 +43,10 @@ class ETFController: "active", ] - def __init__(self): - """CONSTRUCTOR""" + CHOICES += CHOICES_COMMANDS + def __init__(self): + """Constructor""" self.etf_parser = argparse.ArgumentParser(add_help=False, prog="etf") self.etf_parser.add_argument("cmd", choices=self.CHOICES) @@ -49,7 +55,10 @@ class ETFController: print( "https://github.com/GamestonkTerminal/GamestonkTerminal/tree/main/gamestonk_terminal/etf" ) - print("\nETF:") + print("") + print(">> ETF <<") + print("") + print("What do you want to do?") print(" cls clear screen") print(" ?/help show this menu again") print(" q quit this menu, and shows back to main menu") @@ -61,7 +70,7 @@ class ETFController: print(" holdings get top holdings for ETF") print(" compare compare overview of multiple ETF") print(" screener screen etfs based on overview data") - print("\n Wall St. Journal") + print("\nWall St. Journal") print(" gainers show top gainers") print(" decliners show top decliners") print(" active show most active") diff --git a/gamestonk_terminal/forex/behavioural_analysis/ba_controller.py b/gamestonk_terminal/forex/behavioural_analysis/ba_controller.py new file mode 100644 index 00000000000..211d17d94ae --- /dev/null +++ b/gamestonk_terminal/forex/behavioural_analysis/ba_controller.py @@ -0,0 +1,201 @@ +"""Behavioural Analysis Controller Module""" +__docformat__ = "numpy" + +import argparse +import os +from typing import List +from datetime import datetime +from prompt_toolkit.completion import NestedCompleter + +from gamestonk_terminal import feature_flags as gtff +from gamestonk_terminal.helper_funcs import get_flair +from gamestonk_terminal.menu import session +from gamestonk_terminal.common.behavioural_analysis import ( + google_view, +) + + +class BehaviouralAnalysisController: + """Behavioural Analysis Controller class""" + + # Command choices + CHOICES = [ + "?", + "cls", + "help", + "q", + "quit", + ] + + CHOICES_COMMANDS = [ + "infer", + "sentiment", + "mentions", + "regions", + "queries", + "rise", + ] + + CHOICES += CHOICES_COMMANDS + + def __init__(self, ticker: str, start: datetime): + """Constructor""" + self.ticker = ticker + self.start = start + self.ba_parser = argparse.ArgumentParser(add_help=False, prog="ba") + self.ba_parser.add_argument( + "cmd", + choices=self.CHOICES, + ) + + @staticmethod + def print_help(): + """Print help""" + print( + "https://github.com/GamestonkTerminal/GamestonkTerminal/tree/main/gamestonk_terminal/behavioural_analysis" + ) + print("\nBehavioural Analysis:") + print(" cls clear screen") + print(" ?/help show this menu again") + print(" q quit this menu, and shows back to main menu") + print(" quit quit to abandon program") + print("") + print("Twitter:") + print(" infer infer about stock's sentiment from latest tweets") + print(" sentiment in-depth sentiment prediction from tweets over time") + print("") + print("Google:") + print(" mentions interest over time based on stock's mentions") + print(" regions regions that show highest interest in stock") + print(" queries top related queries with this stock") + print(" rise top rising related queries with stock") + print("") + + def switch(self, an_input: str): + """Process and dispatch input + + Returns + ------- + True, False or None + False - quit the menu + True - quit the program + None - continue in the menu + """ + # Empty command + if not an_input: + print("") + return None + + (known_args, other_args) = self.ba_parser.parse_known_args(an_input.split()) + + # Help menu again + if known_args.cmd == "?": + self.print_help() + return None + + # Clear screen + if known_args.cmd == "cls": + os.system("cls||clear") + return None + + return getattr( + self, "call_" + known_args.cmd, lambda: "Command not recognized!" + )(other_args) + + def call_help(self, _): + """Process Help command""" + self.print_help() + + def call_q(self, _): + """Process Q command - quit the menu""" + return False + + def call_quit(self, _): + """Process Quit command - quit the program""" + return True + + def call_mentions(self, other_args: List[str]): + """Process mentions command""" + google_view.mentions(other_args, self.ticker, self.start) + + def call_regions(self, other_args: List[str]): + """Process regions command""" + google_view.regions(other_args, self.ticker) + + def call_queries(self, other_args: List[str]): + """Process queries command""" + google_view.queries(other_args, self.ticker) + + def call_rise(self, other_args: List[str]): + """Process rise command""" + google_view.rise(other_args, self.ticker) + + def call_infer(self, other_args: List[str]): + """Process infer command""" + if not gtff.ENABLE_PREDICT: + print("Predict is not enabled in feature_flags.py") + print("Twitter inference menu is disabled", "\n") + return + + try: + # pylint: disable=import-outside-toplevel + from gamestonk_terminal.common.behavioural_analysis import twitter_view + except ModuleNotFoundError as e: + print("Optional packages need to be installed") + print(e, "\n") + return + except Exception as e: + print(e, "\n") + return + + twitter_view.inference(other_args, self.ticker) + + def call_sentiment(self, other_args: List[str]): + """Process sentiment command""" + if not gtff.ENABLE_PREDICT: + print("Predict is not enabled in feature_flags.py") + print("Twitter inference menu is disabled", "\n") + return + + try: + # pylint: disable=import-outside-toplevel + from gamestonk_terminal.common.behavioural_analysis import twitter_view + except ModuleNotFoundError as e: + print("Optional packages need to be installed") + print(e, "\n") + return + except Exception as e: + print(e, "\n") + return + + twitter_view.sentiment(other_args, self.ticker) + + +def menu(ticker: str, start: datetime): + """Behavioural Analysis Menu""" + + ba_controller = BehaviouralAnalysisController(ticker, start) + ba_controller.call_help(None) + + while True: + # Get input command from user + if session and gtff.USE_PROMPT_TOOLKIT: + completer = NestedCompleter.from_nested_dict( + {c: None for c in ba_controller.CHOICES} + ) + an_input = session.prompt( + f"{get_flair()} (forex)>(ba)> ", + completer=completer, + ) + else: + an_input = input(f"{get_flair()} (forex)>(ba)> ") + + try: + process_input = ba_controller.switch(an_input) + + if process_input is not None: + return process_input + + except SystemExit: + print("The command selected doesn't exist\n") + continue diff --git a/gamestonk_terminal/exploratory_data_analysis/eda_controller.py b/gamestonk_terminal/forex/exploratory_data_analysis/eda_controller.py similarity index 97% rename from gamestonk_terminal/exploratory_data_analysis/eda_controller.py rename to gamestonk_terminal/forex/exploratory_data_analysis/eda_controller.py index f9937a6b8df..15e37c30bd7 100644 --- a/gamestonk_terminal/exploratory_data_analysis/eda_controller.py +++ b/gamestonk_terminal/forex/exploratory_data_analysis/eda_controller.py @@ -8,7 +8,7 @@ from datetime import datetime import pandas as pd from matplotlib import pyplot as plt from prompt_toolkit.completion import NestedCompleter -from gamestonk_terminal.exploratory_data_analysis import eda_api +from gamestonk_terminal.common.exploratory_data_analysis import eda_api from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.helper_funcs import get_flair from gamestonk_terminal.menu import session @@ -182,11 +182,11 @@ def menu(ticker: str, start: datetime, interval: str, stock: pd.DataFrame): {c: None for c in eda_controller.CHOICES} ) an_input = session.prompt( - f"{get_flair()} (eda)> ", + f"{get_flair()} (forex)>(eda)> ", completer=completer, ) else: - an_input = input(f"{get_flair()} (eda)> ") + an_input = input(f"{get_flair()} (forex)>(eda)> ") try: plt.close("all") diff --git a/gamestonk_terminal/forex/fx_controller.py b/gamestonk_terminal/forex/forex_controller.py similarity index 90% rename from gamestonk_terminal/forex/fx_controller.py rename to gamestonk_terminal/forex/forex_controller.py index d67e8686c56..d4870471dcd 100644 --- a/gamestonk_terminal/forex/fx_controller.py +++ b/gamestonk_terminal/forex/forex_controller.py @@ -8,16 +8,17 @@ from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.menu import session from gamestonk_terminal.forex import fx_view from gamestonk_terminal import config_terminal as cfg -from gamestonk_terminal.due_diligence import news_view, reddit_view -from gamestonk_terminal.behavioural_analysis import ba_controller -from gamestonk_terminal.exploratory_data_analysis import eda_controller +# from gamestonk_terminal.stocks.due_diligence import news_view, reddit_view + +from gamestonk_terminal.forex.exploratory_data_analysis import eda_controller +from gamestonk_terminal.forex.behavioural_analysis import ba_controller account = cfg.OANDA_ACCOUNT class ForexController: - """Oanda Controller class""" + """Forex Controller class""" CHOICES = [ "cls", @@ -25,6 +26,9 @@ class ForexController: "help", "q", "quit", + ] + + CHOICES_COMMANDS = [ "price", "summary", "list", @@ -39,15 +43,21 @@ class ForexController: "candles", "pending", "calendar", - "news", - "reddit", + # "news", + # "reddit", + ] + + CHOICES_MENUS = [ "eda", "ba", ] + CHOICES += CHOICES_COMMANDS + CHOICES += CHOICES_MENUS + def __init__(self): """Construct Data""" - self.fx_parser = argparse.ArgumentParser(add_help=False, prog="fx") + self.fx_parser = argparse.ArgumentParser(add_help=False, prog="forex") self.fx_parser.add_argument( "cmd", choices=self.CHOICES, @@ -76,7 +86,7 @@ class ForexController: print("") print(f"Loaded instrument: {self.instrument if self.instrument else ''}") print("") - print(" load load an instrument to use") + print(" load load an instrument to use") if self.instrument: print(" candles show candles") print(" price shows price for selected instrument") @@ -87,6 +97,7 @@ class ForexController: print( " reddit search reddit for posts about the loaded instrument" ) + print("") print( "> eda exploratory data analysis, e.g.: decompose, cusum, residuals analysis" ) @@ -193,13 +204,7 @@ class ForexController: """Call calendar""" fx_view.calendar(self.instrument, other_args) - def call_news(self, other_args: List[str]): - """Call news [News API]""" - news_view.news(other_args, self.instrument) - - def call_reddit(self, other_args: List[str]): - instrument = fx_view.format_instrument(self.instrument, " ") - reddit_view.due_diligence(other_args, instrument) + # TODO: Add news and reddit commands back def call_eda(self, _): try: @@ -223,7 +228,7 @@ class ForexController: def menu(): - """Oanda Menu""" + """Forex Menu""" fx_controller = ForexController() fx_controller.call_help(None) while True: @@ -233,11 +238,11 @@ def menu(): ) an_input = session.prompt( - f"{get_flair()} (fx)> ", + f"{get_flair()} (forex)> ", completer=completer, ) else: - an_input = input(f"{get_flair()} (fx)> ") + an_input = input(f"{get_flair()} (forex)> ") try: process_input = fx_controller.switch(an_input) diff --git a/gamestonk_terminal/options/op_controller.py b/gamestonk_terminal/options/options_controller.py similarity index 93% rename from gamestonk_terminal/options/op_controller.py rename to gamestonk_terminal/options/options_controller.py index 00e46dd7b6b..7d97b9a3bc8 100644 --- a/gamestonk_terminal/options/op_controller.py +++ b/gamestonk_terminal/options/options_controller.py @@ -28,13 +28,15 @@ from gamestonk_terminal.menu import session class OptionsController: """Options Controller class.""" - # Command choices CHOICES = [ "cls", "?", "help", "q", "quit", + ] + + CHOICES_COMMANDS = [ "disp", "scr", "calc", @@ -52,19 +54,15 @@ class OptionsController: "unu", ] - def __init__(self, ticker: str): - """Construct data.""" - self.ticker = ticker - if self.ticker: - if TRADIER_TOKEN == "REPLACE_ME": - self.expiry_dates = yfinance_model.option_expirations(self.ticker) - else: - self.expiry_dates = tradier_model.option_expirations(self.ticker) - else: - self.expiry_dates = [] + CHOICES += CHOICES_COMMANDS + def __init__(self): + """Construct data.""" + self.ticker = "" + self.expiry_dates = [] self.selected_date = "" - self.op_parser = argparse.ArgumentParser(add_help=False, prog="op") + + self.op_parser = argparse.ArgumentParser(add_help=False, prog="options") self.op_parser.add_argument( "cmd", choices=self.CHOICES, @@ -308,18 +306,10 @@ class OptionsController: syncretism_view.historical_greeks(self.ticker, self.selected_date, other_args) -def menu(ticker: str): +def menu(): """Options Menu.""" - - try: - op_controller = OptionsController(ticker) - op_controller.call_help(None) - except IndexError: - print("No options found for " + ticker) - print("") - process_input = False - return process_input - + op_controller = OptionsController() + op_controller.call_help(None) while True: # Get input command from user if session and gtff.USE_PROMPT_TOOLKIT: @@ -327,11 +317,11 @@ def menu(ticker: str): {c: None for c in op_controller.CHOICES} ) an_input = session.prompt( - f"{get_flair()} (op)> ", + f"{get_flair()} (options)> ", completer=completer, ) else: - an_input = input(f"{get_flair()} (op)> ") + an_input = input(f"{get_flair()} (options)> ") try: plt.close("all") diff --git a/gamestonk_terminal/papermill/__init__.py b/gamestonk_terminal/papermill/__init__.py deleted file mode 100644 index 5791b68bd19..00000000000 --- a/gamestonk_terminal/papermill/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import papermill_controller # noqa: F401 diff --git a/gamestonk_terminal/brokers/README.md b/gamestonk_terminal/portfolio/brokers/README.md similarity index 99% rename from gamestonk_terminal/brokers/README.md rename to gamestonk_terminal/portfolio/brokers/README.md index 845ba6a5441..56af1f2a3d5 100644 --- a/gamestonk_terminal/brokers/README.md +++ b/gamestonk_terminal/portfolio/brokers/README.md @@ -122,7 +122,7 @@ usage: alphist [-p --period] [-t --timeframe] * -p/--period The duration of the data in \ + \, such as 1D, where can be D for day, W for week, M for month and A for year. Defaults to 1M * -t/--timeframe The resolution of time window. 1Min, 5Min, 15Min, 1H, or 1D. If omitted, 1Min for less than 7 days period, 15Min for less than 30 days, or otherwise 1D. - + ## ALLY In order to access your Ally Invest account through the API, you must first acquire a key from diff --git a/gamestonk_terminal/behavioural_analysis/__init__.py b/gamestonk_terminal/portfolio/brokers/__init__.py similarity index 100% rename from gamestonk_terminal/behavioural_analysis/__init__.py rename to gamestonk_terminal/portfolio/brokers/__init__.py diff --git a/gamestonk_terminal/brokers/ally_api.py b/gamestonk_terminal/portfolio/brokers/ally_api.py similarity index 93% rename from gamestonk_terminal/brokers/ally_api.py rename to gamestonk_terminal/portfolio/brokers/ally_api.py index 7c9ccad3fef..e55545d76f8 100644 --- a/gamestonk_terminal/brokers/ally_api.py +++ b/gamestonk_terminal/portfolio/brokers/ally_api.py @@ -3,7 +3,7 @@ import numpy as np import ally import yfinance as yf from termcolor import colored -from gamestonk_terminal.brokers.brokers_helpers import ally_positions_to_df +from gamestonk_terminal.portfolio.brokers.brokers_helpers import ally_positions_to_df # pylint: disable=no-member diff --git a/gamestonk_terminal/brokers/alp_api.py b/gamestonk_terminal/portfolio/brokers/alp_api.py similarity index 97% rename from gamestonk_terminal/brokers/alp_api.py rename to gamestonk_terminal/portfolio/brokers/alp_api.py index 86e307ebdf6..c3a7e6f608c 100644 --- a/gamestonk_terminal/brokers/alp_api.py +++ b/gamestonk_terminal/portfolio/brokers/alp_api.py @@ -12,7 +12,7 @@ from gamestonk_terminal.helper_funcs import ( plot_autoscale, ) from gamestonk_terminal import feature_flags as gtff -from gamestonk_terminal.brokers.brokers_helpers import ( +from gamestonk_terminal.portfolio.brokers.brokers_helpers import ( alpaca_positions_to_df, ) diff --git a/gamestonk_terminal/brokers/bro_controller.py b/gamestonk_terminal/portfolio/brokers/bro_controller.py similarity index 96% rename from gamestonk_terminal/brokers/bro_controller.py rename to gamestonk_terminal/portfolio/brokers/bro_controller.py index 2b3100931fc..89a0d22bb52 100644 --- a/gamestonk_terminal/brokers/bro_controller.py +++ b/gamestonk_terminal/portfolio/brokers/bro_controller.py @@ -11,13 +11,13 @@ from prompt_toolkit.completion import NestedCompleter from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.helper_funcs import get_flair from gamestonk_terminal.menu import session -from gamestonk_terminal.brokers import ( +from gamestonk_terminal.portfolio.brokers import ( rh_api, alp_api, ally_api, ) -from gamestonk_terminal.brokers.degiro import degiro_controller -from gamestonk_terminal.brokers.brokers_helpers import ( +from gamestonk_terminal.portfolio.brokers.degiro import degiro_controller +from gamestonk_terminal.portfolio.brokers.brokers_helpers import ( merge_brokers_holdings, print_brokers_holdings, ) @@ -240,11 +240,11 @@ def menu(): {c: None for c in bro_controller.CHOICES} ) an_input = session.prompt( - f"{get_flair()} (bro)> ", + f"{get_flair()} (portfolio)>(bro)> ", completer=completer, ) else: - an_input = input(f"{get_flair()} (bro)> ") + an_input = input(f"{get_flair()} (portfolio)>(bro)> ") try: process_input = bro_controller.switch(an_input) diff --git a/gamestonk_terminal/brokers/brokers_helpers.py b/gamestonk_terminal/portfolio/brokers/brokers_helpers.py similarity index 100% rename from gamestonk_terminal/brokers/brokers_helpers.py rename to gamestonk_terminal/portfolio/brokers/brokers_helpers.py diff --git a/gamestonk_terminal/brokers/degiro/README.md b/gamestonk_terminal/portfolio/brokers/degiro/README.md similarity index 100% rename from gamestonk_terminal/brokers/degiro/README.md rename to gamestonk_terminal/portfolio/brokers/degiro/README.md diff --git a/gamestonk_terminal/brokers/degiro/degiro_controller.py b/gamestonk_terminal/portfolio/brokers/degiro/degiro_controller.py similarity index 99% rename from gamestonk_terminal/brokers/degiro/degiro_controller.py rename to gamestonk_terminal/portfolio/brokers/degiro/degiro_controller.py index e853b1bc828..5ada9abebd0 100644 --- a/gamestonk_terminal/brokers/degiro/degiro_controller.py +++ b/gamestonk_terminal/portfolio/brokers/degiro/degiro_controller.py @@ -14,7 +14,7 @@ from gamestonk_terminal.helper_funcs import ( parse_known_args_and_warn, ) from gamestonk_terminal.menu import session -from gamestonk_terminal.brokers.degiro.degiro_view import DegiroView +from gamestonk_terminal.portfolio.brokers.degiro.degiro_view import DegiroView class DegiroController: diff --git a/gamestonk_terminal/brokers/degiro/degiro_model.py b/gamestonk_terminal/portfolio/brokers/degiro/degiro_model.py similarity index 100% rename from gamestonk_terminal/brokers/degiro/degiro_model.py rename to gamestonk_terminal/portfolio/brokers/degiro/degiro_model.py diff --git a/gamestonk_terminal/brokers/degiro/degiro_view.py b/gamestonk_terminal/portfolio/brokers/degiro/degiro_view.py similarity index 99% rename from gamestonk_terminal/brokers/degiro/degiro_view.py rename to gamestonk_terminal/portfolio/brokers/degiro/degiro_view.py index 1bd831bb727..ec621cfa10c 100644 --- a/gamestonk_terminal/brokers/degiro/degiro_view.py +++ b/gamestonk_terminal/portfolio/brokers/degiro/degiro_view.py @@ -14,7 +14,7 @@ from degiro_connector.trading.pb.trading_pb2 import ( ) # IMPORTATION INTERNAL -from gamestonk_terminal.brokers.degiro.degiro_model import DegiroModel +from gamestonk_terminal.portfolio.brokers.degiro.degiro_model import DegiroModel # pylint: disable=no-member diff --git a/gamestonk_terminal/brokers/rh_api.py b/gamestonk_terminal/portfolio/brokers/rh_api.py similarity index 98% rename from gamestonk_terminal/brokers/rh_api.py rename to gamestonk_terminal/portfolio/brokers/rh_api.py index 57c6ca52c25..b2c646a5ebb 100644 --- a/gamestonk_terminal/brokers/rh_api.py +++ b/gamestonk_terminal/portfolio/brokers/rh_api.py @@ -16,7 +16,7 @@ from gamestonk_terminal.helper_funcs import ( ) from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.config_terminal import RH_USERNAME as user, RH_PASSWORD as pw -from gamestonk_terminal.brokers.brokers_helpers import rh_positions_to_df +from gamestonk_terminal.portfolio.brokers.brokers_helpers import rh_positions_to_df register_matplotlib_converters() diff --git a/gamestonk_terminal/portfolio_analysis/README.md b/gamestonk_terminal/portfolio/portfolio_analysis/README.md similarity index 100% rename from gamestonk_terminal/portfolio_analysis/README.md rename to gamestonk_terminal/portfolio/portfolio_analysis/README.md diff --git a/gamestonk_terminal/brokers/__init__.py b/gamestonk_terminal/portfolio/portfolio_analysis/__init__.py similarity index 100% rename from gamestonk_terminal/brokers/__init__.py rename to gamestonk_terminal/portfolio/portfolio_analysis/__init__.py diff --git a/gamestonk_terminal/portfolio_analysis/pa_controller.py b/gamestonk_terminal/portfolio/portfolio_analysis/pa_controller.py similarity index 95% rename from gamestonk_terminal/portfolio_analysis/pa_controller.py rename to gamestonk_terminal/portfolio/portfolio_analysis/pa_controller.py index bc04d01ece0..53f2027fb3a 100644 --- a/gamestonk_terminal/portfolio_analysis/pa_controller.py +++ b/gamestonk_terminal/portfolio/portfolio_analysis/pa_controller.py @@ -9,7 +9,7 @@ from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.helper_funcs import get_flair from gamestonk_terminal.menu import session -from gamestonk_terminal.portfolio_analysis import portfolio_parser +from gamestonk_terminal.portfolio.portfolio_analysis import portfolio_parser class PortfolioController: @@ -123,11 +123,11 @@ def menu(): {c: None for c in pa_controller.CHOICES} ) an_input = session.prompt( - f"{get_flair()} (pa)> ", + f"{get_flair()} (portfolio)>(pa)> ", completer=completer, ) else: - an_input = input(f"{get_flair()} (pa)> ") + an_input = input(f"{get_flair()} (portfolio)>(pa)> ") try: process_input = pa_controller.switch(an_input) diff --git a/gamestonk_terminal/portfolio_analysis/portfolio_parser.py b/gamestonk_terminal/portfolio/portfolio_analysis/portfolio_parser.py similarity index 100% rename from gamestonk_terminal/portfolio_analysis/portfolio_parser.py rename to gamestonk_terminal/portfolio/portfolio_analysis/portfolio_parser.py diff --git a/gamestonk_terminal/portfolio_analysis/portfolios/my_portfolio.csv b/gamestonk_terminal/portfolio/portfolio_analysis/portfolios/my_portfolio.csv similarity index 100% rename from gamestonk_terminal/portfolio_analysis/portfolios/my_portfolio.csv rename to gamestonk_terminal/portfolio/portfolio_analysis/portfolios/my_portfolio.csv diff --git a/gamestonk_terminal/portfolio/portfolio_controller.py b/gamestonk_terminal/portfolio/portfolio_controller.py new file mode 100644 index 00000000000..506bfe859b9 --- /dev/null +++ b/gamestonk_terminal/portfolio/portfolio_controller.py @@ -0,0 +1,167 @@ +import argparse +import os +from prompt_toolkit.completion import NestedCompleter + +from gamestonk_terminal.helper_funcs import get_flair + +from gamestonk_terminal.menu import session +from gamestonk_terminal import feature_flags as gtff + +from gamestonk_terminal.portfolio.brokers import bro_controller +from gamestonk_terminal.portfolio.portfolio_analysis import pa_controller +from gamestonk_terminal.portfolio.portfolio_optimization import po_controller + +# pylint: disable=R1710 + + +class PortfolioController: + """Portfolio Controller class""" + + CHOICES = [ + "cls", + "?", + "help", + "q", + "quit", + ] + + CHOICES_MENUS = [ + "load", + "quote", + "candle", + "view", + ] + + CHOICES_MENUS = [ + "bro", + "pa", + "po", + ] + + CHOICES += CHOICES_MENUS + + def __init__(self): + """Constructor""" + self.port_parser = argparse.ArgumentParser(add_help=False, prog="portfolio") + self.port_parser.add_argument( + "cmd", + choices=self.CHOICES, + ) + self.completer = NestedCompleter.from_nested_dict( + {c: None for c in self.CHOICES} + ) + + def print_help(self): + """Print help""" + help_text = """https://github.com/GamestonkTerminal/GamestonkTerminal/tree/main/gamestonk_terminal/portfolio + +>> PORTFOLIO << + +What do you want to do? + cls clear screen + ?/help show this menu again + q quit this menu, and shows back to main menu + quit quit to abandon the program + +> bro brokers holdings, \t\t supports: robinhood, alpaca, ally +> pa portfolio analysis, \t\t analyses your custom portfolio +> po portfolio optimization, \t optimal portfolio weights from pyportfolioopt + """ + print(help_text) + + def switch(self, an_input: str): + """Process and dispatch input + + Returns + ------- + True, False, or None + False - quit the menu + True - quit the program + None - continue in the menu + """ + + # Empty command + if not an_input: + print("") + return None + + (known_args, other_args) = self.port_parser.parse_known_args(an_input.split()) + + # Help menu again + if known_args.cmd == "?": + self.print_help() + return None + + # Clear screen + if known_args.cmd == "cls": + os.system("cls||clear") + return None + + return getattr( + self, "call_" + known_args.cmd, lambda: "command not recognized!" + )(other_args) + + def call_help(self, _): + """Process Help Command""" + self.print_help() + + def call_q(self, _): + """Process Q command - quit the menu""" + return False + + def call_quit(self, _): + """Process Quit command - exit the program""" + return True + + # MENUS + def call_bro(self, _): + """Process bro command""" + ret = bro_controller.menu() + if ret is False: + self.print_help() + else: + return True + + def call_pa(self, _): + """Process pa command""" + ret = pa_controller.menu() + if ret is False: + self.print_help() + else: + return True + + def call_po(self, _): + """Process po command""" + ret = po_controller.menu() + if ret is False: + self.print_help() + else: + return True + + +def menu(): + """Portfolio Menu""" + portfolio_controller = PortfolioController() + portfolio_controller.call_help(None) + while True: + if session and gtff.USE_PROMPT_TOOLKIT: + completer = NestedCompleter.from_nested_dict( + {c: None for c in portfolio_controller.CHOICES} + ) + + an_input = session.prompt( + f"{get_flair()} (portfolio)> ", + completer=completer, + ) + else: + an_input = input(f"{get_flair()} (portfolio)> ") + + try: + process_input = portfolio_controller.switch(an_input) + + if process_input is not None: + return process_input + + except SystemExit: + print("The command selected doesn't exit\n") + continue diff --git a/gamestonk_terminal/portfolio_optimization/README.md b/gamestonk_terminal/portfolio/portfolio_optimization/README.md similarity index 100% rename from gamestonk_terminal/portfolio_optimization/README.md rename to gamestonk_terminal/portfolio/portfolio_optimization/README.md diff --git a/gamestonk_terminal/comparison_analysis/__init__.py b/gamestonk_terminal/portfolio/portfolio_optimization/__init__.py similarity index 100% rename from gamestonk_terminal/comparison_analysis/__init__.py rename to gamestonk_terminal/portfolio/portfolio_optimization/__init__.py diff --git a/gamestonk_terminal/portfolio_optimization/optimizer_helper.py b/gamestonk_terminal/portfolio/portfolio_optimization/optimizer_helper.py similarity index 100% rename from gamestonk_terminal/portfolio_optimization/optimizer_helper.py rename to gamestonk_terminal/portfolio/portfolio_optimization/optimizer_helper.py diff --git a/gamestonk_terminal/portfolio_optimization/optimizer_view.py b/gamestonk_terminal/portfolio/portfolio_optimization/optimizer_view.py similarity index 99% rename from gamestonk_terminal/portfolio_optimization/optimizer_view.py rename to gamestonk_terminal/portfolio/portfolio_optimization/optimizer_view.py index 5054b6b40af..6ac131df8d5 100644 --- a/gamestonk_terminal/portfolio_optimization/optimizer_view.py +++ b/gamestonk_terminal/portfolio/portfolio_optimization/optimizer_view.py @@ -15,7 +15,7 @@ from gamestonk_terminal.helper_funcs import ( plot_autoscale, check_non_negative, ) -from gamestonk_terminal.portfolio_optimization.optimizer_helper import ( +from gamestonk_terminal.portfolio.portfolio_optimization.optimizer_helper import ( process_stocks, prepare_efficient_frontier, pie_chart_weights, diff --git a/gamestonk_terminal/portfolio_optimization/po_controller.py b/gamestonk_terminal/portfolio/portfolio_optimization/po_controller.py similarity index 94% rename from gamestonk_terminal/portfolio_optimization/po_controller.py rename to gamestonk_terminal/portfolio/portfolio_optimization/po_controller.py index cc29459ebcc..bb79b440916 100644 --- a/gamestonk_terminal/portfolio_optimization/po_controller.py +++ b/gamestonk_terminal/portfolio/portfolio_optimization/po_controller.py @@ -9,7 +9,7 @@ from prompt_toolkit.completion import NestedCompleter from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.helper_funcs import get_flair, parse_known_args_and_warn from gamestonk_terminal.menu import session -from gamestonk_terminal.portfolio_optimization import optimizer_view +from gamestonk_terminal.portfolio.portfolio_optimization import optimizer_view class PortfolioOptimization: @@ -37,17 +37,12 @@ class PortfolioOptimization: ] # pylint: disable=dangerous-default-value - def __init__( - self, - tickers: List[str], - ): - """ - Construct Portfolio Optimization - """ + def __init__(self): + """Construct Portfolio Optimization""" self.po_parser = argparse.ArgumentParser(add_help=False, prog="po") self.po_parser.add_argument("cmd", choices=self.CHOICES) - self.tickers = list(set(tickers)) + self.tickers = list() @staticmethod def print_help(tickers: List[str]): @@ -273,13 +268,11 @@ class PortfolioOptimization: print(e, "\n") -def menu(tickers: List[str]): +def menu(): """Portfolio Optimization Menu""" - if tickers == [""]: - tickers = [] plt.close("all") - po_controller = PortfolioOptimization(tickers) - po_controller.call_help(tickers) + po_controller = PortfolioOptimization() + po_controller.call_help([]) while True: # Get input command from user @@ -288,11 +281,11 @@ def menu(tickers: List[str]): {c: None for c in po_controller.CHOICES} ) an_input = session.prompt( - f"{get_flair()} (po)> ", + f"{get_flair()} (portfolio)>(po)> ", completer=completer, ) else: - an_input = input(f"{get_flair()} (po)> ") + an_input = input(f"{get_flair()} (portfolio)>(po)> ") try: plt.close("all") diff --git a/gamestonk_terminal/resource_collection/README.md b/gamestonk_terminal/resources/README.md similarity index 99% rename from gamestonk_terminal/resource_collection/README.md rename to gamestonk_terminal/resources/README.md index f065660eee1..a863f0cfd20 100644 --- a/gamestonk_terminal/resource_collection/README.md +++ b/gamestonk_terminal/resources/README.md @@ -69,4 +69,3 @@ usage: learn ``` Captura de ecrã 2021-05-01, às 21 16 07 - diff --git a/gamestonk_terminal/resource_collection/rc_controller.py b/gamestonk_terminal/resources/resources_controller.py similarity index 92% rename from gamestonk_terminal/resource_collection/rc_controller.py rename to gamestonk_terminal/resources/resources_controller.py index 45aa699d735..2e787715502 100644 --- a/gamestonk_terminal/resource_collection/rc_controller.py +++ b/gamestonk_terminal/resources/resources_controller.py @@ -20,6 +20,9 @@ class ResourceCollectionController: "help", "q", "quit", + ] + + CHOICES_COMMANDS = [ "hfletters", "arxiv", "finra", @@ -28,9 +31,11 @@ class ResourceCollectionController: "learn", ] + CHOICES += CHOICES_COMMANDS + def __init__(self): """Constructor""" - self.rc_parser = argparse.ArgumentParser(add_help=False, prog="rc") + self.rc_parser = argparse.ArgumentParser(add_help=False, prog="resources") self.rc_parser.add_argument( "cmd", choices=self.CHOICES, @@ -40,9 +45,12 @@ class ResourceCollectionController: def print_help(): """Print help""" print( - "https://github.com/GamestonkTerminal/GamestonkTerminal/tree/main/gamestonk_terminal/resource_collection" + "https://github.com/GamestonkTerminal/GamestonkTerminal/tree/main/gamestonk_terminal/resources" ) - print("\nResources:") + print("") + print(">> RESOURCES <<") + print("") + print("What do you want to do?") print(" cls clear screen") print(" ?/help show this menu again") print(" q quit this menu, and shows back to main menu") @@ -147,11 +155,11 @@ def menu(): {c: None for c in rc_controller.CHOICES} ) an_input = session.prompt( - f"{get_flair()} (rc)> ", + f"{get_flair()} (resources)> ", completer=completer, ) else: - an_input = input(f"{get_flair()} (rc)> ") + an_input = input(f"{get_flair()} (resources)> ") try: process_input = rc_controller.switch(an_input) diff --git a/gamestonk_terminal/backtesting/README.md b/gamestonk_terminal/stocks/backtesting/README.md similarity index 92% rename from gamestonk_terminal/backtesting/README.md rename to gamestonk_terminal/stocks/backtesting/README.md index ee38b09b63a..eef4b416f39 100644 --- a/gamestonk_terminal/backtesting/README.md +++ b/gamestonk_terminal/stocks/backtesting/README.md @@ -1,11 +1,11 @@ # Backtesting -This menu aims to apply backtesting strategies regarding a pre-loaded ticker, and the usage of the following commands along with an example will be exploited below. Note that this is currently just a simple logic (i.e price comparisons). These strategies should not be used immediately and should be researched, improved and further tested on your own. +This menu aims to apply backtesting strategies regarding a pre-loaded ticker, and the usage of the following commands along with an example will be exploited below. Note that this is currently just a simple logic (i.e price comparisons). These strategies should not be used immediately and should be researched, improved and further tested on your own. * [ema](#ema) * buy when price exceeds EMA(l) -* [ema_cross](#ema_cross) - * buy when EMA(short) > EMA(long) +* [ema_cross](#ema_cross) + * buy when EMA(short) > EMA(long) * [rsi](#rsi) * buy when RSI < low and sell when RSI > high @@ -27,7 +27,7 @@ This strategy buys when price > EMA(l). ### ema_cross ```` -usage: ema_cross [-l] [-s] [--spy] [--no_bench] [--no_short] +usage: ema_cross [-l] [-s] [--spy] [--no_bench] [--no_short] ```` This strategy goes long when EMA(short) > EMA(long) and goes short when EMA(short) < EMA(long). It provides the option to go long only through the --no_short flag. @@ -43,7 +43,7 @@ This strategy goes long when EMA(short) > EMA(long) and goes short when EMA(shor ### rsi ```` -usage: rsi [-u] [-l] [-p] [--spy] [--no_bench] [--no_short] +usage: rsi [-u] [-l] [-p] [--spy] [--no_bench] [--no_short] ```` This strategy goes long when the RSI is "oversold" - defined as the low parameter. It goes short when the RSI is "overbought" - defined as the high (upper) parameter diff --git a/gamestonk_terminal/due_diligence/__init__.py b/gamestonk_terminal/stocks/backtesting/__init__.py similarity index 100% rename from gamestonk_terminal/due_diligence/__init__.py rename to gamestonk_terminal/stocks/backtesting/__init__.py diff --git a/gamestonk_terminal/backtesting/bt_controller.py b/gamestonk_terminal/stocks/backtesting/bt_controller.py similarity index 95% rename from gamestonk_terminal/backtesting/bt_controller.py rename to gamestonk_terminal/stocks/backtesting/bt_controller.py index 988e6474c7b..6631fc433d6 100644 --- a/gamestonk_terminal/backtesting/bt_controller.py +++ b/gamestonk_terminal/stocks/backtesting/bt_controller.py @@ -17,7 +17,7 @@ from gamestonk_terminal.menu import session # Save current matplotlib backend default_backend = mpl.get_backend() # pylint: disable=wrong-import-position -from gamestonk_terminal.backtesting import bt_view # noqa: E402 +from gamestonk_terminal.stocks.backtesting import bt_view # noqa: E402 # Restore backend matplotlib used mpl.use(default_backend) @@ -127,11 +127,11 @@ def menu(ticker: str, start: Union[str, datetime]): {c: None for c in bt_controller.CHOICES} ) an_input = session.prompt( - f"{get_flair()} (bt)> ", + f"{get_flair()} (stocks)>(bt)> ", completer=completer, ) else: - an_input = input(f"{get_flair()} (bt)> ") + an_input = input(f"{get_flair()} (stocks)>(bt)> ") try: plt.close("all") diff --git a/gamestonk_terminal/backtesting/bt_helper.py b/gamestonk_terminal/stocks/backtesting/bt_helper.py similarity index 100% rename from gamestonk_terminal/backtesting/bt_helper.py rename to gamestonk_terminal/stocks/backtesting/bt_helper.py diff --git a/gamestonk_terminal/backtesting/bt_view.py b/gamestonk_terminal/stocks/backtesting/bt_view.py similarity index 98% rename from gamestonk_terminal/backtesting/bt_view.py rename to gamestonk_terminal/stocks/backtesting/bt_view.py index 6cbfece31d4..a37dfad5098 100644 --- a/gamestonk_terminal/backtesting/bt_view.py +++ b/gamestonk_terminal/stocks/backtesting/bt_view.py @@ -8,7 +8,11 @@ import pandas as pd import bt import pandas_ta as ta from gamestonk_terminal.helper_funcs import check_positive, parse_known_args_and_warn -from gamestonk_terminal.backtesting.bt_helper import buy_and_hold, plot_bt, get_data +from gamestonk_terminal.stocks.backtesting.bt_helper import ( + buy_and_hold, + plot_bt, + get_data, +) np.seterr(divide="ignore") diff --git a/gamestonk_terminal/stocks/behavioural_analysis/README.md b/gamestonk_terminal/stocks/behavioural_analysis/README.md new file mode 100644 index 00000000000..0fba235a7ef --- /dev/null +++ b/gamestonk_terminal/stocks/behavioural_analysis/README.md @@ -0,0 +1,363 @@ +# BEHAVIOURAL ANALYSIS + +This menu aims to extrapolate behavioural analysis regarding a pre-loaded ticker, and the usage of the following commands along with an example will be exploited below. + + * [finbrain](#finbrain) + - sentiment from 15+ major news headlines + * [stats](#stats) + - sentiment stats including comparison with sector + +[REDDIT](#REDDIT) + * [wsb](#wsb) + - show what WSB gang is up to in subreddit wallstreetbets + * [watchlist](#watchlist) + - show other users watchlist + * [popular](#popular) + - show popular tickers + * [spac_c](#spac_c) + - show other users spacs announcements from subreddit SPACs community + * [spac](#spac) + - show other users spacs announcements from other subs + +[STOCKTWITS](#STOCKTWITS) + * [bullbear](#bullbear) + - estimate quick sentiment from last 30 messages on board + * [messages](#messages) + - output up to the 30 last messages on the board + * [trending](#trending) + - trending stocks + * [stalker](#stalker) + - stalk stocktwits user's last messages + +[TWITTER](#TWITTER) + * [infer](#infer) + - infer about stock's sentiment from latest tweets + * [sentiment](#sentiment) + - in-depth sentiment prediction from tweets over time + +[GOOGLE](#GOOGLE) + * [mentions](#mentions) + - interest over time based on stock's mentions + * [regions](#regions) + - regions that show highest interest in stock + * [queries](#queries) + - top related queries with this stock + * [rise](#rise) + - top rising related queries with stock + +[SENTIMENT INVESTOR](#SENTIMENTINVESTOR) + * [metrics](#metrics) + - core social sentiment metrics for this stock + * [social](#social) + - social media figures for stock popularity + * [historical](#historical) + - plot the past week of data for a selected metric + +## finbrain +``` +usage: finbrain +``` +FinBrain collects the news headlines from 15+ major financial news sources on a daily basis and analyzes them to generate sentiment scores for more than 4500 US stocks. FinBrain Technologies develops deep learning algorithms for financial analysis and prediction, which currently serves traders from more than 150 countries all around the world. [Source: See https://finbrain.tech] + +![finbrain2](https://user-images.githubusercontent.com/25267873/111629515-49c97000-87e9-11eb-92a6-a9eebb4b4bd9.png) + +Captura de ecrã 2021-03-18, às 12 53 31 + + +## stats +``` +usage: stats +``` +Sentiment stats which displays buzz, news score, articles last week, articles weekly average, bullish vs bearish percentages, sector average bullish percentage, and sector average news score. [Source: https://finnhub.io] + +Captura de ecrã 2021-05-03, às 15 26 09 + + +# REDDIT + +## wsb +``` +usage: wsb [-l N_LIMIT] [-n] +``` +Print what WSB gang are up to in subreddit wallstreetbets. [Source: Reddit] + * -l : limit of posts to print. Default 10. + * -n : new flag, if true the posts retrieved are based on being more recent rather than their score. Default False. + +wsb + + +## watchlist +``` +usage: watchlist [-l N_LIMIT] +``` +Print other users watchlist. [Source: Reddit] + * -l : limit of posts to print. Default 5. + +watchlist + + +## popular +``` +usage: popular [-l N_LIMIT] [-s S_SUBREDDIT] [-d N_DAYS] +``` +Print latest popular tickers. [Source: Reddit] + * -l : limit of posts retrieved per sub reddit. Default 50. + * -s : subreddits to look for tickers, e.g. pennystocks,stocks. Default: pennystocks, RobinHoodPennyStocks, Daytrading, StockMarket, stocks, investing, wallstreetbets. + +popular + + +## spac_c +``` +usage: spac_c [-l N_LIMIT] [-p] +``` +Print other users SPACs announcement under subreddit 'SPACs'. [Source: Reddit] + * -l : limit of posts with SPACs retrieved. Default 10. + * -p : popular flag, if true the posts retrieved are based on score rather than time. Default False. + +spac_c + + +## spac +``` +usage: spac [-h] [-l N_LIMIT] [-d N_DAYS] +``` +Print other users SPACs announcement under subreddit 'SPACs'. [Source: Reddit] + * -l : limit of posts with SPACs retrieved. Default 5. + +spac + + +# STOCKTWITS + +## bullbear +``` +usage: bullbear [-t S_TICKER] +``` +Print bullbear sentiment based on last 30 messages on the board. Also prints the watchlist_count. [Source: Stocktwits] + * -t : ticker to gather sentiment from. + +sentiment + + +## messages +``` +usage: messages [-t S_TICKER] [-l N_LIM] +``` +Print up to 30 of the last messages on the board. [Source: Stocktwits] + * -t : get board messages from this ticker. Default pre-loaded. + * -l : limit messages shown. Default 30. + +messages + + +## trending +``` +usage: trending +``` +Stocks trending. [Source: Stocktwits] + +trending + + +## stalker +``` +usage: stalker [-u S_USER] [-l N_LIM] +``` +Print up to the last 30 messages of a user. [Source: Stocktwits] + * -u : username. Default newsfilter. + * -l : limit messages shown. Default 30. + +stalker + + +# TWITTER +Uses VADER sentiment. VADER (Valence Aware Dictionary and sEntiment Reasoner) is a lexicon and rule-based sentiment analysis +tool that is specifically attuned to sentiments expressed in social media. + +The output of VADER analysis : +``` +The compound score is computed by summing the valence scores of each word in the lexicon, adjusted according to the +rules, and then normalized to be between -1 (most extreme negative) and +1 (most extreme positive). This is the most +useful metric if you want a single unidimensional measure of sentiment for a given sentence. Calling it a 'normalized, + weighted composite score' is accurate. +``` +A sample tweet is shown below along with what the VADER polarity scores are. + +```' +Have some $SENS 🚀🏆\n👉FDA approval coming very soon, 👉News is out, amazing test results. \n👉Very high short +interest rate. \n👉Major short squeeze coming. \n\n$amc $gme $nakd $ctrm $tsla $aapl $oeg $aht $bbby $bb $fsr $spce + https://t.co/B0cPhufpA2' +``` + +This gives the following scores: +```python +created_at Thu Jun 03 20:37:54 +text Have some $SENS 🚀🏆\n👉FDA approval coming very... +sentiment 0.872 +positive 0.177 +negative 0 +neutral 0.823 +``` + +Note that both functions use twitters v2 endpoint, which only gives 7 days of historical data. It also requires at least 10 tweets be pulled. + +## infer +``` +usage: infer [-n N_NUM] +``` +Print quick sentiment inference from last tweets that contain the ticker. This model splits the text into character-level tokens and uses theVADER model to make predictions. + * -n : num of latest tweets to infer from. Default 100. + + +## sentiment +``` +usage: sentiment [-n N_NUM] [-d N_DAYS_PAST] +``` +Plot in-depth sentiment extracted from tweets from last days that contain pre-defined ticker. This model splits the text into character-level tokens and uses the VADER model to make predictions. + * -n : num of tweets to extract per hour. Default 15. + * -d : num of days in the past to extract tweets. Default 6. Max 6 + +# GOOGLE + +## mentions +``` +usage: mentions [-s S_START] +``` +Plot weekly bars of stock's interest over time. other users watchlist. [Source: Google] + * -s : starting date (format YYYY-MM-DD) from when we are interested in stock's mentions. Default: the one provided in main menu. + +![gme](https://user-images.githubusercontent.com/25267873/108776894-e9813e80-755a-11eb-8b7e-654124c0ef8f.png) + + +## regions +``` +usage: regions [-n N_NUM] +``` +Plot bars of regions based on stock's interest. [Source: Google] + * -n : number of regions to plot that show highest interest. Default 10. + +![regions](https://user-images.githubusercontent.com/25267873/108776889-e8e8a800-755a-11eb-8bcc-fcf7b6156f50.png) + + +## queries +``` +usage: queries [-n N_NUM] +``` +Print top related queries with this stock's query. [Source: Google] + * -n : number of top related queries to print. Default 10. + +Captura de ecrã 2021-02-22, às 22 15 16 + + +## rise +``` +usage: rise [-n N_NUM] +``` +Print top rising related queries with this stock's query. [Source: Google] + * -n : number of top rising related queries to print. Default 10. + +Captura de ecrã 2021-02-22, às 22 21 21 + +# SENTIMENTINVESTOR + +> **[Sentiment Investor](https://sentimentinvestor.com)** analyzes data from four major social media platforms to +> generate hourly metrics on over 2,000 stocks. Sentiment provides volume and +> sentiment metrics powered by proprietary NLP models. + +## Metric definitions + +### AHI (Absolute Hype Index) + +AHI is a measure of how much people are talking about a stock on social media. +It is calculated by dividing the total number of mentions for the chosen stock +on a social network by the mean number of mentions any stock receives on that +social medium. + +### RHI (Relative Hype Index) + +RHI is a measure of whether people are talking about a stock more or less than +usual, calculated by dividing the mean AHI for the past day by the mean AHI for +for the past week for that stock. + +### Sentiment Score + +Sentiment score is the percentage of people talking positively about the stock. +For each social network the number of positive posts/comments is divided by the +total number of both positive and negative posts/comments. + +### SGP (Standard General Perception) + +SGP is a measure of whether people are more or less positive about a stock than +usual. It is calculated by averaging the past day of sentiment values and then +dividing it by the average of the past week of sentiment values. + +## metrics + +``` +usage: metrics [-h] [ticker] +``` + +The `metrics` command presents the four core metrics provided by Sentiment Investor, +including AHI, RHI, sentiment and SGP, as described above. + +Optional arguments: +- [optional, positional] ticker + ticker to use instead of the loaded one +- `-h`, `--help` + show this help message + +Example output: + +![`metrics NFLX` command output](https://user-images.githubusercontent.com/8385172/127154566-1af3c274-c521-426b-8580-2ae714c2c1ca.png) + +## social + +``` +usage: social [-h] [ticker] +``` + +The `social` command prints the raw data for a given stock, including the number +of mentions it has received on social media in the last hour and the sentiment +score of those comments. + +Optional arguments: +- [optional, positional] ticker + ticker to use instead of the loaded one +- `-h`, `--help` + show this help message + +Example output: + +![`social AAPL` command output](https://user-images.githubusercontent.com/8385172/127154775-13b1a81d-f5d2-4768-bf7e-bca8886f6d24.png) + +## historical + +``` +usage: historical [-t TICKER] [-s [{date,value}]] [-d [{asc,desc}]] [-h] [{sentiment,AHI,RHI,SGP}] +``` + +The `historical` command plots the past week of data for a selected +SentimentInvestor core metric, one of: +[AHI](#ahi), [RHI](#ahi), [sentiment](#sentiment) or [SGP](#SGP). +It also outputs a sorted table of the mean value for that metric for each day. + +Positional arguments: +- one of `sentiment`, `AHI`, `RHI` or `SGP` + (optional) the metric to plot (default: `sentiment`) + +Optional arguments: +- `-t`, `--ticker TICKER` + ticker for which to fetch data +- `-s`, `--sort [{date,value}]` + the parameter to sort output table by +- `-d`, `--direction [{asc,desc}]` + the direction to sort the output table +- `-h`, `--help` + show this help message + +Example output: + +![`historical -t GME RHI` plot output](https://user-images.githubusercontent.com/8385172/126782509-bfc21dbb-2fe6-4cd4-a384-018eb41ac8f3.png) + +![`historical -t NFLX -s value -d asc RHI` command output](https://user-images.githubusercontent.com/8385172/127157236-7818a635-4394-4372-9673-2834b32811af.png) diff --git a/gamestonk_terminal/fundamental_analysis/__init__.py b/gamestonk_terminal/stocks/behavioural_analysis/__init__.py similarity index 100% rename from gamestonk_terminal/fundamental_analysis/__init__.py rename to gamestonk_terminal/stocks/behavioural_analysis/__init__.py diff --git a/gamestonk_terminal/behavioural_analysis/ba_controller.py b/gamestonk_terminal/stocks/behavioural_analysis/ba_controller.py similarity index 95% rename from gamestonk_terminal/behavioural_analysis/ba_controller.py rename to gamestonk_terminal/stocks/behavioural_analysis/ba_controller.py index 3be9557a052..1c42dbaec40 100644 --- a/gamestonk_terminal/behavioural_analysis/ba_controller.py +++ b/gamestonk_terminal/stocks/behavioural_analysis/ba_controller.py @@ -10,7 +10,7 @@ from prompt_toolkit.completion import NestedCompleter from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.helper_funcs import get_flair from gamestonk_terminal.menu import session -from gamestonk_terminal.behavioural_analysis import ( +from gamestonk_terminal.common.behavioural_analysis import ( google_view, reddit_view, stocktwits_view, @@ -216,7 +216,7 @@ class BehaviouralAnalysisController: try: # pylint: disable=import-outside-toplevel - from gamestonk_terminal.behavioural_analysis import twitter_view + from gamestonk_terminal.common.behavioural_analysis import twitter_view except ModuleNotFoundError as e: print("Optional packages need to be installed") print(e, "\n") @@ -236,7 +236,7 @@ class BehaviouralAnalysisController: try: # pylint: disable=import-outside-toplevel - from gamestonk_terminal.behavioural_analysis import twitter_view + from gamestonk_terminal.common.behavioural_analysis import twitter_view except ModuleNotFoundError as e: print("Optional packages need to be installed") print(e, "\n") @@ -268,15 +268,12 @@ class BehaviouralAnalysisController: sentimentinvestor_view.historical(self.ticker, other_args) -def menu(ticker: str, start: datetime, context: str = ""): +def menu(ticker: str, start: datetime): """Behavioural Analysis Menu""" ba_controller = BehaviouralAnalysisController(ticker, start) ba_controller.call_help(None) - if context: - context = f"({context})>" - while True: # Get input command from user if session and gtff.USE_PROMPT_TOOLKIT: @@ -284,11 +281,11 @@ def menu(ticker: str, start: datetime, context: str = ""): {c: None for c in ba_controller.CHOICES} ) an_input = session.prompt( - f"{get_flair()} {context}(ba)> ", + f"{get_flair()} (stocks)>(ba)> ", completer=completer, ) else: - an_input = input(f"{get_flair()} {context}(ba)> ") + an_input = input(f"{get_flair()} (stocks)>(ba)> ") try: process_input = ba_controller.switch(an_input) diff --git a/gamestonk_terminal/comparison_analysis/README.md b/gamestonk_terminal/stocks/comparison_analysis/README.md similarity index 100% rename from gamestonk_terminal/comparison_analysis/README.md rename to gamestonk_terminal/stocks/comparison_analysis/README.md diff --git a/gamestonk_terminal/portfolio_analysis/__init__.py b/gamestonk_terminal/stocks/comparison_analysis/__init__.py similarity index 100% rename from gamestonk_terminal/portfolio_analysis/__init__.py rename to gamestonk_terminal/stocks/comparison_analysis/__init__.py diff --git a/gamestonk_terminal/comparison_analysis/ca_controller.py b/gamestonk_terminal/stocks/comparison_analysis/ca_controller.py similarity index 96% rename from gamestonk_terminal/comparison_analysis/ca_controller.py rename to gamestonk_terminal/stocks/comparison_analysis/ca_controller.py index c22b19acbac..da4ac472b7b 100644 --- a/gamestonk_terminal/comparison_analysis/ca_controller.py +++ b/gamestonk_terminal/stocks/comparison_analysis/ca_controller.py @@ -15,13 +15,15 @@ from prompt_toolkit.completion import NestedCompleter from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal import config_terminal as cfg from gamestonk_terminal.helper_funcs import get_flair, parse_known_args_and_warn -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.stocks.comparison_analysis import yahoo_finance_view +from gamestonk_terminal.stocks.comparison_analysis import market_watch_view +from gamestonk_terminal.stocks.comparison_analysis import finbrain_view +from gamestonk_terminal.stocks.comparison_analysis import finviz_compare_view +from gamestonk_terminal.portfolio.portfolio_optimization import po_controller from gamestonk_terminal.menu import session +# pylint: disable=E1121 + class ComparisonAnalysisController: """Comparison Analysis Controller class""" @@ -413,11 +415,11 @@ def menu(ticker: str, start: datetime, interval: str, stock: pd.DataFrame): {c: None for c in ca_controller.CHOICES} ) an_input = session.prompt( - f"{get_flair()} (ca)> ", + f"{get_flair()} (stocks)>(ca)> ", completer=completer, ) else: - an_input = input(f"{get_flair()} (ca)> ") + an_input = input(f"{get_flair()} (stocks)>(ca)> ") try: plt.close("all") diff --git a/gamestonk_terminal/comparison_analysis/finbrain_view.py b/gamestonk_terminal/stocks/comparison_analysis/finbrain_view.py similarity index 100% rename from gamestonk_terminal/comparison_analysis/finbrain_view.py rename to gamestonk_terminal/stocks/comparison_analysis/finbrain_view.py diff --git a/gamestonk_terminal/comparison_analysis/finviz_compare_view.py b/gamestonk_terminal/stocks/comparison_analysis/finviz_compare_view.py similarity index 100% rename from gamestonk_terminal/comparison_analysis/finviz_compare_view.py rename to gamestonk_terminal/stocks/comparison_analysis/finviz_compare_view.py diff --git a/gamestonk_terminal/comparison_analysis/market_watch_view.py b/gamestonk_terminal/stocks/comparison_analysis/market_watch_view.py similarity index 100% rename from gamestonk_terminal/comparison_analysis/market_watch_view.py rename to gamestonk_terminal/stocks/comparison_analysis/market_watch_view.py diff --git a/gamestonk_terminal/comparison_analysis/yahoo_finance_view.py b/gamestonk_terminal/stocks/comparison_analysis/yahoo_finance_view.py similarity index 100% rename from gamestonk_terminal/comparison_analysis/yahoo_finance_view.py rename to gamestonk_terminal/stocks/comparison_analysis/yahoo_finance_view.py diff --git a/gamestonk_terminal/discovery/README.md b/gamestonk_terminal/stocks/discovery/README.md similarity index 100% rename from gamestonk_terminal/discovery/README.md rename to gamestonk_terminal/stocks/discovery/README.md diff --git a/gamestonk_terminal/discovery/__init__.py b/gamestonk_terminal/stocks/discovery/__init__.py similarity index 100% rename from gamestonk_terminal/discovery/__init__.py rename to gamestonk_terminal/stocks/discovery/__init__.py diff --git a/gamestonk_terminal/discovery/alpha_vantage_view.py b/gamestonk_terminal/stocks/discovery/alpha_vantage_view.py similarity index 100% rename from gamestonk_terminal/discovery/alpha_vantage_view.py rename to gamestonk_terminal/stocks/discovery/alpha_vantage_view.py diff --git a/gamestonk_terminal/discovery/ark_model.py b/gamestonk_terminal/stocks/discovery/ark_model.py similarity index 100% rename from gamestonk_terminal/discovery/ark_model.py rename to gamestonk_terminal/stocks/discovery/ark_model.py diff --git a/gamestonk_terminal/discovery/ark_view.py b/gamestonk_terminal/stocks/discovery/ark_view.py similarity index 97% rename from gamestonk_terminal/discovery/ark_view.py rename to gamestonk_terminal/stocks/discovery/ark_view.py index 8631a70c064..2e413573489 100644 --- a/gamestonk_terminal/discovery/ark_view.py +++ b/gamestonk_terminal/stocks/discovery/ark_view.py @@ -13,7 +13,7 @@ from gamestonk_terminal.helper_funcs import ( ) from gamestonk_terminal import feature_flags as gtff -from gamestonk_terminal.discovery import ark_model +from gamestonk_terminal.stocks.discovery import ark_model def direction_color_red_green(val: str) -> str: diff --git a/gamestonk_terminal/discovery/disc_controller.py b/gamestonk_terminal/stocks/discovery/disc_controller.py similarity index 98% rename from gamestonk_terminal/discovery/disc_controller.py rename to gamestonk_terminal/stocks/discovery/disc_controller.py index 0063306a8a3..65f384eeacf 100644 --- a/gamestonk_terminal/discovery/disc_controller.py +++ b/gamestonk_terminal/stocks/discovery/disc_controller.py @@ -9,7 +9,7 @@ from prompt_toolkit.completion import NestedCompleter from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.helper_funcs import get_flair from gamestonk_terminal.menu import session -from gamestonk_terminal.discovery import ( +from gamestonk_terminal.stocks.discovery import ( alpha_vantage_view, ark_view, fidelity_view, @@ -281,11 +281,11 @@ def menu(): ) an_input = session.prompt( - f"{get_flair()} (disc)> ", + f"{get_flair()} (stocks)>(disc)> ", completer=completer, ) else: - an_input = input(f"{get_flair()} (disc)> ") + an_input = input(f"{get_flair()} (stocks)>(disc)> ") try: plt.close("all") diff --git a/gamestonk_terminal/discovery/fidelity_model.py b/gamestonk_terminal/stocks/discovery/fidelity_model.py similarity index 100% rename from gamestonk_terminal/discovery/fidelity_model.py rename to gamestonk_terminal/stocks/discovery/fidelity_model.py diff --git a/gamestonk_terminal/discovery/fidelity_view.py b/gamestonk_terminal/stocks/discovery/fidelity_view.py similarity index 98% rename from gamestonk_terminal/discovery/fidelity_view.py rename to gamestonk_terminal/stocks/discovery/fidelity_view.py index 926ec940b86..379cf812749 100644 --- a/gamestonk_terminal/discovery/fidelity_view.py +++ b/gamestonk_terminal/stocks/discovery/fidelity_view.py @@ -14,7 +14,7 @@ from gamestonk_terminal.helper_funcs import ( ) from gamestonk_terminal import feature_flags as gtff -from gamestonk_terminal.discovery import fidelity_model +from gamestonk_terminal.stocks.discovery import fidelity_model def buy_sell_ratio_color_red_green(val: str) -> str: diff --git a/gamestonk_terminal/discovery/finnhub_view.py b/gamestonk_terminal/stocks/discovery/finnhub_view.py similarity index 100% rename from gamestonk_terminal/discovery/finnhub_view.py rename to gamestonk_terminal/stocks/discovery/finnhub_view.py diff --git a/gamestonk_terminal/discovery/finra_ats_view.py b/gamestonk_terminal/stocks/discovery/finra_ats_view.py similarity index 100% rename from gamestonk_terminal/discovery/finra_ats_view.py rename to gamestonk_terminal/stocks/discovery/finra_ats_view.py diff --git a/gamestonk_terminal/discovery/finviz_view.py b/gamestonk_terminal/stocks/discovery/finviz_view.py similarity index 100% rename from gamestonk_terminal/discovery/finviz_view.py rename to gamestonk_terminal/stocks/discovery/finviz_view.py diff --git a/gamestonk_terminal/discovery/marketbeat_model.py b/gamestonk_terminal/stocks/discovery/marketbeat_model.py similarity index 100% rename from gamestonk_terminal/discovery/marketbeat_model.py rename to gamestonk_terminal/stocks/discovery/marketbeat_model.py diff --git a/gamestonk_terminal/discovery/marketbeat_view.py b/gamestonk_terminal/stocks/discovery/marketbeat_view.py similarity index 98% rename from gamestonk_terminal/discovery/marketbeat_view.py rename to gamestonk_terminal/stocks/discovery/marketbeat_view.py index 57a87412b58..3a71410fdd4 100644 --- a/gamestonk_terminal/discovery/marketbeat_view.py +++ b/gamestonk_terminal/stocks/discovery/marketbeat_view.py @@ -10,7 +10,7 @@ from gamestonk_terminal.helper_funcs import ( check_positive, parse_known_args_and_warn, ) -from gamestonk_terminal.discovery import marketbeat_model +from gamestonk_terminal.stocks.discovery import marketbeat_model def ratings_view(other_args: List[str]): diff --git a/gamestonk_terminal/discovery/seeking_alpha_model.py b/gamestonk_terminal/stocks/discovery/seeking_alpha_model.py similarity index 100% rename from gamestonk_terminal/discovery/seeking_alpha_model.py rename to gamestonk_terminal/stocks/discovery/seeking_alpha_model.py diff --git a/gamestonk_terminal/discovery/seeking_alpha_view.py b/gamestonk_terminal/stocks/discovery/seeking_alpha_view.py similarity index 98% rename from gamestonk_terminal/discovery/seeking_alpha_view.py rename to gamestonk_terminal/stocks/discovery/seeking_alpha_view.py index fe0484c6e0b..93df0aaea47 100644 --- a/gamestonk_terminal/discovery/seeking_alpha_view.py +++ b/gamestonk_terminal/stocks/discovery/seeking_alpha_view.py @@ -11,7 +11,7 @@ from gamestonk_terminal.helper_funcs import ( valid_date, ) -from gamestonk_terminal.discovery import seeking_alpha_model +from gamestonk_terminal.stocks.discovery import seeking_alpha_model def earnings_release_dates_view(other_args: List[str]): diff --git a/gamestonk_terminal/discovery/sentimentinvestor_view.py b/gamestonk_terminal/stocks/discovery/sentimentinvestor_view.py similarity index 100% rename from gamestonk_terminal/discovery/sentimentinvestor_view.py rename to gamestonk_terminal/stocks/discovery/sentimentinvestor_view.py diff --git a/gamestonk_terminal/discovery/short_interest_model.py b/gamestonk_terminal/stocks/discovery/short_interest_model.py similarity index 100% rename from gamestonk_terminal/discovery/short_interest_model.py rename to gamestonk_terminal/stocks/discovery/short_interest_model.py diff --git a/gamestonk_terminal/discovery/short_interest_view.py b/gamestonk_terminal/stocks/discovery/short_interest_view.py similarity index 97% rename from gamestonk_terminal/discovery/short_interest_view.py rename to gamestonk_terminal/stocks/discovery/short_interest_view.py index 64c1bc54db4..204958aad20 100644 --- a/gamestonk_terminal/discovery/short_interest_view.py +++ b/gamestonk_terminal/stocks/discovery/short_interest_view.py @@ -9,7 +9,7 @@ from gamestonk_terminal.helper_funcs import ( parse_known_args_and_warn, ) -from gamestonk_terminal.discovery import short_interest_model +from gamestonk_terminal.stocks.discovery import short_interest_model def high_short_interest_view(other_args: List[str]): diff --git a/gamestonk_terminal/discovery/simply_wallst_view.py b/gamestonk_terminal/stocks/discovery/simply_wallst_view.py similarity index 100% rename from gamestonk_terminal/discovery/simply_wallst_view.py rename to gamestonk_terminal/stocks/discovery/simply_wallst_view.py diff --git a/gamestonk_terminal/discovery/spachero_view.py b/gamestonk_terminal/stocks/discovery/spachero_view.py similarity index 100% rename from gamestonk_terminal/discovery/spachero_view.py rename to gamestonk_terminal/stocks/discovery/spachero_view.py diff --git a/gamestonk_terminal/discovery/stockgrid_view.py b/gamestonk_terminal/stocks/discovery/stockgrid_view.py similarity index 100% rename from gamestonk_terminal/discovery/stockgrid_view.py rename to gamestonk_terminal/stocks/discovery/stockgrid_view.py diff --git a/gamestonk_terminal/discovery/unusual_whales_view.py b/gamestonk_terminal/stocks/discovery/unusual_whales_view.py similarity index 100% rename from gamestonk_terminal/discovery/unusual_whales_view.py rename to gamestonk_terminal/stocks/discovery/unusual_whales_view.py diff --git a/gamestonk_terminal/discovery/yahoo_finance_view.py b/gamestonk_terminal/stocks/discovery/yahoo_finance_view.py similarity index 100% rename from gamestonk_terminal/discovery/yahoo_finance_view.py rename to gamestonk_terminal/stocks/discovery/yahoo_finance_view.py diff --git a/gamestonk_terminal/due_diligence/README.md b/gamestonk_terminal/stocks/due_diligence/README.md similarity index 98% rename from gamestonk_terminal/due_diligence/README.md rename to gamestonk_terminal/stocks/due_diligence/README.md index 1218e92e227..40d9fb36e89 100644 --- a/gamestonk_terminal/due_diligence/README.md +++ b/gamestonk_terminal/stocks/due_diligence/README.md @@ -202,7 +202,7 @@ usage: ftd [-s START] [-e END] [-n N_NUM] [--raw] [--export {csv,json,xlsx}] The fails-to-deliver data collected by SEC. Fails to deliver on a given day are a cumulative number of all fails outstanding until that day, plus new fails that occur that day, less fails that settle that day. See . Note that FTD is 1 month delayed. [Source: SEC] -* -n : number of latest fails-to-deliver being printed. Default 0. Overrules start and end FTD datetime. +* -n : number of latest fails-to-deliver being printed. Default 0. Overrules start and end FTD datetime. * -s : start of datetime to see FTD. Default 20 days in past. * -e : end of datetime to see FTD. Default today. * --raw : Print raw data. @@ -218,7 +218,7 @@ usage: shortvol [-n NUM] [-r] ``` Shows price vs short interest volume. [Source: Stockgrid] -* -r: Flag to print raw data instead. +* -r: Flag to print raw data instead. * -n: Number of last open market days to show. Default: 120, but if -r is set it's 10. * --export: Save dataframe as a csv file. Default: false. @@ -234,7 +234,7 @@ usage: darkpos [-n NUM] [-r] ``` Shows Net Short Vol. vs Position. [Source: Stockgrid] -* -r: Flag to print raw data instead. +* -r: Flag to print raw data instead. * -n: Number of last open market days to show. Default: 120, but if -r is set it's 10. * --export: Save dataframe as a csv file. Default: false. diff --git a/gamestonk_terminal/portfolio_optimization/__init__.py b/gamestonk_terminal/stocks/due_diligence/__init__.py similarity index 100% rename from gamestonk_terminal/portfolio_optimization/__init__.py rename to gamestonk_terminal/stocks/due_diligence/__init__.py diff --git a/gamestonk_terminal/due_diligence/business_insider_view.py b/gamestonk_terminal/stocks/due_diligence/business_insider_view.py similarity index 100% rename from gamestonk_terminal/due_diligence/business_insider_view.py rename to gamestonk_terminal/stocks/due_diligence/business_insider_view.py diff --git a/gamestonk_terminal/due_diligence/csimarket_view.py b/gamestonk_terminal/stocks/due_diligence/csimarket_view.py similarity index 100% rename from gamestonk_terminal/due_diligence/csimarket_view.py rename to gamestonk_terminal/stocks/due_diligence/csimarket_view.py diff --git a/gamestonk_terminal/due_diligence/dd_controller.py b/gamestonk_terminal/stocks/due_diligence/dd_controller.py similarity index 89% rename from gamestonk_terminal/due_diligence/dd_controller.py rename to gamestonk_terminal/stocks/due_diligence/dd_controller.py index c738a314e6b..ec23f2ddf2d 100644 --- a/gamestonk_terminal/due_diligence/dd_controller.py +++ b/gamestonk_terminal/stocks/due_diligence/dd_controller.py @@ -7,18 +7,20 @@ from typing import List from pandas.core.frame import DataFrame from prompt_toolkit.completion import NestedCompleter -from gamestonk_terminal.due_diligence import business_insider_view as bi_view -from gamestonk_terminal.due_diligence import financial_modeling_prep_view as fmp_view -from gamestonk_terminal.due_diligence import finviz_view as fvz_view -from gamestonk_terminal.due_diligence import market_watch_view as mw_view -from gamestonk_terminal.due_diligence import quandl_view as q_view -from gamestonk_terminal.due_diligence import reddit_view as r_view -from gamestonk_terminal.due_diligence import news_view -from gamestonk_terminal.due_diligence import finra_view -from gamestonk_terminal.due_diligence import sec_view -from gamestonk_terminal.due_diligence import stockgrid_dd_view as sg_view -from gamestonk_terminal.due_diligence import finnhub_view -from gamestonk_terminal.due_diligence import csimarket_view +from gamestonk_terminal.stocks.due_diligence import business_insider_view as bi_view +from gamestonk_terminal.stocks.due_diligence import ( + financial_modeling_prep_view as fmp_view, +) +from gamestonk_terminal.stocks.due_diligence import finviz_view as fvz_view +from gamestonk_terminal.stocks.due_diligence import market_watch_view as mw_view +from gamestonk_terminal.stocks.due_diligence import quandl_view as q_view +from gamestonk_terminal.stocks.due_diligence import reddit_view as r_view +from gamestonk_terminal.stocks.due_diligence import news_view +from gamestonk_terminal.stocks.due_diligence import finra_view +from gamestonk_terminal.stocks.due_diligence import sec_view +from gamestonk_terminal.stocks.due_diligence import stockgrid_dd_view as sg_view +from gamestonk_terminal.stocks.due_diligence import finnhub_view +from gamestonk_terminal.stocks.due_diligence import csimarket_view from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.helper_funcs import get_flair from gamestonk_terminal.menu import session @@ -274,11 +276,11 @@ def menu(ticker: str, start: str, interval: str, stock: DataFrame): ) an_input = session.prompt( - f"{get_flair()} (dd)> ", + f"{get_flair()} (stocks)>(dd)> ", completer=completer, ) else: - an_input = input(f"{get_flair()} (dd)> ") + an_input = input(f"{get_flair()} (stocks)>(dd)> ") try: process_input = dd_controller.switch(an_input) diff --git a/gamestonk_terminal/due_diligence/financial_modeling_prep_view.py b/gamestonk_terminal/stocks/due_diligence/financial_modeling_prep_view.py similarity index 100% rename from gamestonk_terminal/due_diligence/financial_modeling_prep_view.py rename to gamestonk_terminal/stocks/due_diligence/financial_modeling_prep_view.py diff --git a/gamestonk_terminal/due_diligence/finnhub_view.py b/gamestonk_terminal/stocks/due_diligence/finnhub_view.py similarity index 100% rename from gamestonk_terminal/due_diligence/finnhub_view.py rename to gamestonk_terminal/stocks/due_diligence/finnhub_view.py diff --git a/gamestonk_terminal/due_diligence/finra_view.py b/gamestonk_terminal/stocks/due_diligence/finra_view.py similarity index 100% rename from gamestonk_terminal/due_diligence/finra_view.py rename to gamestonk_terminal/stocks/due_diligence/finra_view.py diff --git a/gamestonk_terminal/due_diligence/finviz_view.py b/gamestonk_terminal/stocks/due_diligence/finviz_view.py similarity index 100% rename from gamestonk_terminal/due_diligence/finviz_view.py rename to gamestonk_terminal/stocks/due_diligence/finviz_view.py diff --git a/gamestonk_terminal/due_diligence/info_sean_seah.txt b/gamestonk_terminal/stocks/due_diligence/info_sean_seah.txt similarity index 99% rename from gamestonk_terminal/due_diligence/info_sean_seah.txt rename to gamestonk_terminal/stocks/due_diligence/info_sean_seah.txt index 573a3808c9e..4e0fc967196 100644 --- a/gamestonk_terminal/due_diligence/info_sean_seah.txt +++ b/gamestonk_terminal/stocks/due_diligence/info_sean_seah.txt @@ -45,4 +45,4 @@ I totally agree to keep away from IPOs. The deals are stacked against retail inv “In an IPO, the investment banker has all the knowledge and information about the business and is offering the uninformed a price he sets. It is very unlikely that he will offer a bargain price. I’d rather wait for the stock to be trading for some time and confirm its performance. And when Mr Market misprices it, this is when I go in to get the bargain. But not at IPO, it does not make sense.” --- Choose businesses not dependent on talented people or the management -“We want to avoid businesses whose performance will drop when a group of people leaves because they lose their competitive advantage. This kind of competitive advantage is not at all durable. Instead, we want to buy businesses that even a fool can run, because someday one will.” \ No newline at end of file +“We want to avoid businesses whose performance will drop when a group of people leaves because they lose their competitive advantage. This kind of competitive advantage is not at all durable. Instead, we want to buy businesses that even a fool can run, because someday one will.” diff --git a/gamestonk_terminal/due_diligence/market_watch_view.py b/gamestonk_terminal/stocks/due_diligence/market_watch_view.py similarity index 100% rename from gamestonk_terminal/due_diligence/market_watch_view.py rename to gamestonk_terminal/stocks/due_diligence/market_watch_view.py diff --git a/gamestonk_terminal/due_diligence/news_view.py b/gamestonk_terminal/stocks/due_diligence/news_view.py similarity index 100% rename from gamestonk_terminal/due_diligence/news_view.py rename to gamestonk_terminal/stocks/due_diligence/news_view.py diff --git a/gamestonk_terminal/due_diligence/quandl_view.py b/gamestonk_terminal/stocks/due_diligence/quandl_view.py similarity index 100% rename from gamestonk_terminal/due_diligence/quandl_view.py rename to gamestonk_terminal/stocks/due_diligence/quandl_view.py diff --git a/gamestonk_terminal/due_diligence/reddit_view.py b/gamestonk_terminal/stocks/due_diligence/reddit_view.py similarity index 100% rename from gamestonk_terminal/due_diligence/reddit_view.py rename to gamestonk_terminal/stocks/due_diligence/reddit_view.py diff --git a/gamestonk_terminal/due_diligence/sec_view.py b/gamestonk_terminal/stocks/due_diligence/sec_view.py similarity index 100% rename from gamestonk_terminal/due_diligence/sec_view.py rename to gamestonk_terminal/stocks/due_diligence/sec_view.py diff --git a/gamestonk_terminal/due_diligence/stockgrid_dd_view.py b/gamestonk_terminal/stocks/due_diligence/stockgrid_dd_view.py similarity index 100% rename from gamestonk_terminal/due_diligence/stockgrid_dd_view.py rename to gamestonk_terminal/stocks/due_diligence/stockgrid_dd_view.py diff --git a/gamestonk_terminal/exploratory_data_analysis/README.md b/gamestonk_terminal/stocks/exploratory_data_analysis/README.md similarity index 99% rename from gamestonk_terminal/exploratory_data_analysis/README.md rename to gamestonk_terminal/stocks/exploratory_data_analysis/README.md index 244d1079d4b..a82c3b02159 100644 --- a/gamestonk_terminal/exploratory_data_analysis/README.md +++ b/gamestonk_terminal/stocks/exploratory_data_analysis/README.md @@ -132,5 +132,3 @@ Auto-Correlation and Partial Auto-Correlation Functions for diff and diff diff s * -l : maximum lags to display in plots. Default 40. ![acf](https://user-images.githubusercontent.com/25267873/112733336-637c5d00-8f37-11eb-9aae-38e75dff9ad2.png) - - diff --git a/gamestonk_terminal/prediction_techniques/__init__.py b/gamestonk_terminal/stocks/exploratory_data_analysis/__init__.py similarity index 100% rename from gamestonk_terminal/prediction_techniques/__init__.py rename to gamestonk_terminal/stocks/exploratory_data_analysis/__init__.py diff --git a/gamestonk_terminal/stocks/exploratory_data_analysis/eda_controller.py b/gamestonk_terminal/stocks/exploratory_data_analysis/eda_controller.py new file mode 100644 index 00000000000..592f0af1044 --- /dev/null +++ b/gamestonk_terminal/stocks/exploratory_data_analysis/eda_controller.py @@ -0,0 +1,201 @@ +"""Exploratory Data Analysis Controller Module""" +__docformat__ = "numpy" + +import argparse +import os +from typing import List +from datetime import datetime +import pandas as pd +from matplotlib import pyplot as plt +from prompt_toolkit.completion import NestedCompleter +from gamestonk_terminal.common.exploratory_data_analysis import eda_api +from gamestonk_terminal import feature_flags as gtff +from gamestonk_terminal.helper_funcs import get_flair +from gamestonk_terminal.menu import session + + +class EdaController: + """EDA Controller class""" + + # Command choices + CHOICES = [ + "?", + "cls", + "help", + "q", + "quit", + "summary", + "hist", + "cdf", + "bwy", + "bwm", + "rolling", + "decompose", + "cusum", + "acf", + ] + + def __init__( + self, + ticker: str, + start: datetime, + interval: str, + stock: pd.DataFrame, + ): + """Constructor""" + self.stock = stock + self.ticker = ticker + self.start = start + self.interval = interval + self.stats_parser = argparse.ArgumentParser(add_help=False, prog="stats") + self.stats_parser.add_argument( + "cmd", + choices=self.CHOICES, + ) + + def print_help(self): + """Print help""" + print( + "https://github.com/GamestonkTerminal/" + "GamestonkTerminal/tree/main/gamestonk_terminal/exploratory_data_analysis" + ) + s_intraday = (f"Intraday {self.interval}", "Daily")[self.interval == "1440min"] + + if self.start: + print( + f"\n{s_intraday} Stock: {self.ticker} (from {self.start.strftime('%Y-%m-%d')})" + ) + else: + print(f"\n{s_intraday} Stock: {self.ticker}") + + print("\nExploratory Data Analysis:") + print(" cls clear screen") + print(" ?/help show this menu again") + print(" q quit this menu, and shows back to main menu") + print(" quit quit to abandon program") + print("") + print(" summary brief summary statistics") + print(" hist histogram with density plot") + print(" cdf cumulative distribution function") + print(" bwy box and whisker yearly plot") + print(" bwm box and whisker monthly plot") + print(" rolling rolling mean and std deviation") + print(" decompose decomposition in cyclic-trend, season, and residuals") + print(" cusum detects abrupt changes using cumulative sum algorithm") + print(" acf (partial) auto-correlation function differentials") + print("") + return + + def switch(self, an_input: str): + """Process and dispatch input + + Returns + ------- + True, False or None + False - quit the menu + True - quit the program + None - continue in the menu + """ + + # Empty command + if not an_input: + print("") + return None + + (known_args, other_args) = self.stats_parser.parse_known_args(an_input.split()) + + # Help menu again + if known_args.cmd == "?": + self.print_help() + return None + + # Clear screen + if known_args.cmd == "cls": + os.system("cls||clear") + return None + + return getattr( + self, "call_" + known_args.cmd, lambda: "Command not recognized!" + )(other_args) + + def call_help(self, _): + """Process Help command""" + self.print_help() + + def call_q(self, _): + """Process Q command - quit the menu""" + return False + + def call_quit(self, _): + """Process Quit command - quit the program""" + return True + + def call_summary(self, other_args: List[str]): + """Process summary command""" + eda_api.summary(other_args, self.stock) + + def call_hist(self, other_args: List[str]): + """Process hist command""" + eda_api.hist(other_args, self.ticker, self.stock, self.start) + + def call_cdf(self, other_args: List[str]): + """Process cdf command""" + eda_api.cumulative_distribution_function( + other_args, self.ticker, self.stock, self.start + ) + + def call_bwy(self, other_args: List[str]): + """Process bwy command""" + eda_api.bwy(other_args, self.ticker, self.stock, self.start) + + def call_bwm(self, other_args: List[str]): + """Process bwm command""" + eda_api.bwm(other_args, self.ticker, self.stock, self.start) + + def call_rolling(self, other_args: List[str]): + """Process rolling command""" + eda_api.rolling(other_args, self.ticker, self.stock) + + def call_decompose(self, other_args: List[str]): + """Process decompose command""" + eda_api.decompose(other_args, self.ticker, self.stock) + + def call_cusum(self, other_args: List[str]): + """Process cusum command""" + eda_api.cusum(other_args, self.stock) + + def call_acf(self, other_args: List[str]): + """Process acf command""" + eda_api.acf(other_args, self.ticker, self.stock, self.start) + + +def menu(ticker: str, start: datetime, interval: str, stock: pd.DataFrame): + """Statistics Menu""" + + eda_controller = EdaController(ticker, start, interval, stock) + eda_controller.call_help(None) + + while True: + # Get input command from user + if session and gtff.USE_PROMPT_TOOLKIT: + completer = NestedCompleter.from_nested_dict( + {c: None for c in eda_controller.CHOICES} + ) + an_input = session.prompt( + f"{get_flair()} (stocks)>(eda)> ", + completer=completer, + ) + else: + an_input = input(f"{get_flair()} (stocks)>(eda)> ") + + try: + plt.close("all") + + process_input = eda_controller.switch(an_input) + + if process_input is not None: + return process_input + + except SystemExit: + print("The command selected doesn't exist\n") + continue diff --git a/gamestonk_terminal/fundamental_analysis/README.md b/gamestonk_terminal/stocks/fundamental_analysis/README.md similarity index 99% rename from gamestonk_terminal/fundamental_analysis/README.md rename to gamestonk_terminal/stocks/fundamental_analysis/README.md index 04c3ec12f08..1b82a2f4f5c 100644 --- a/gamestonk_terminal/fundamental_analysis/README.md +++ b/gamestonk_terminal/stocks/fundamental_analysis/README.md @@ -156,4 +156,3 @@ usage: fraud Fraud indicators allow a user to understand the likelihood that a business is committing fraud or will go bankrupt in the near future. These indidactors use financial ratios based on reported financial statements. - diff --git a/gamestonk_terminal/technical_analysis/__init__.py b/gamestonk_terminal/stocks/fundamental_analysis/__init__.py similarity index 100% rename from gamestonk_terminal/technical_analysis/__init__.py rename to gamestonk_terminal/stocks/fundamental_analysis/__init__.py diff --git a/gamestonk_terminal/fundamental_analysis/av_view.py b/gamestonk_terminal/stocks/fundamental_analysis/av_view.py similarity index 99% rename from gamestonk_terminal/fundamental_analysis/av_view.py rename to gamestonk_terminal/stocks/fundamental_analysis/av_view.py index eaec66c8ec8..dc7d601c9d1 100644 --- a/gamestonk_terminal/fundamental_analysis/av_view.py +++ b/gamestonk_terminal/stocks/fundamental_analysis/av_view.py @@ -9,7 +9,7 @@ from alpha_vantage.fundamentaldata import FundamentalData import pandas as pd from gamestonk_terminal import config_terminal as cfg -from gamestonk_terminal.fundamental_analysis.fa_helper import clean_df_index +from gamestonk_terminal.stocks.fundamental_analysis.fa_helper import clean_df_index from gamestonk_terminal.helper_funcs import ( check_positive, long_number_format, diff --git a/gamestonk_terminal/fundamental_analysis/business_insider_view.py b/gamestonk_terminal/stocks/fundamental_analysis/business_insider_view.py similarity index 100% rename from gamestonk_terminal/fundamental_analysis/business_insider_view.py rename to gamestonk_terminal/stocks/fundamental_analysis/business_insider_view.py diff --git a/gamestonk_terminal/fundamental_analysis/fa_controller.py b/gamestonk_terminal/stocks/fundamental_analysis/fa_controller.py similarity index 96% rename from gamestonk_terminal/fundamental_analysis/fa_controller.py rename to gamestonk_terminal/stocks/fundamental_analysis/fa_controller.py index d35aafa4336..0ce544c79e6 100644 --- a/gamestonk_terminal/fundamental_analysis/fa_controller.py +++ b/gamestonk_terminal/stocks/fundamental_analysis/fa_controller.py @@ -6,12 +6,12 @@ import os from typing import List from prompt_toolkit.completion import NestedCompleter -from gamestonk_terminal.fundamental_analysis import business_insider_view -from gamestonk_terminal.fundamental_analysis.financial_modeling_prep import ( +from gamestonk_terminal.stocks.fundamental_analysis import business_insider_view +from gamestonk_terminal.stocks.fundamental_analysis.financial_modeling_prep import ( fmp_controller, fmp_view, ) -from gamestonk_terminal.fundamental_analysis import ( +from gamestonk_terminal.stocks.fundamental_analysis import ( finviz_view, yahoo_finance_view, av_view, @@ -308,11 +308,11 @@ def menu(ticker: str, start: str, interval: str): ) an_input = session.prompt( - f"{get_flair()} (fa)> ", + f"{get_flair()} (stocks)>(fa)> ", completer=completer, ) else: - an_input = input(f"{get_flair()} (fa)> ") + an_input = input(f"{get_flair()} (stocks)>(fa)> ") try: process_input = fa_controller.switch(an_input) diff --git a/gamestonk_terminal/fundamental_analysis/fa_helper.py b/gamestonk_terminal/stocks/fundamental_analysis/fa_helper.py similarity index 100% rename from gamestonk_terminal/fundamental_analysis/fa_helper.py rename to gamestonk_terminal/stocks/fundamental_analysis/fa_helper.py diff --git a/gamestonk_terminal/fundamental_analysis/financial_modeling_prep/README.md b/gamestonk_terminal/stocks/fundamental_analysis/financial_modeling_prep/README.md similarity index 100% rename from gamestonk_terminal/fundamental_analysis/financial_modeling_prep/README.md rename to gamestonk_terminal/stocks/fundamental_analysis/financial_modeling_prep/README.md diff --git a/gamestonk_terminal/fundamental_analysis/financial_modeling_prep/fmp_controller.py b/gamestonk_terminal/stocks/fundamental_analysis/financial_modeling_prep/fmp_controller.py similarity index 98% rename from gamestonk_terminal/fundamental_analysis/financial_modeling_prep/fmp_controller.py rename to gamestonk_terminal/stocks/fundamental_analysis/financial_modeling_prep/fmp_controller.py index 030a9430a61..dcff2f64553 100644 --- a/gamestonk_terminal/fundamental_analysis/financial_modeling_prep/fmp_controller.py +++ b/gamestonk_terminal/stocks/fundamental_analysis/financial_modeling_prep/fmp_controller.py @@ -6,7 +6,9 @@ import os from typing import List from prompt_toolkit.completion import NestedCompleter -from gamestonk_terminal.fundamental_analysis.financial_modeling_prep import fmp_view +from gamestonk_terminal.stocks.fundamental_analysis.financial_modeling_prep import ( + fmp_view, +) from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.helper_funcs import ( get_flair, diff --git a/gamestonk_terminal/fundamental_analysis/financial_modeling_prep/fmp_view.py b/gamestonk_terminal/stocks/fundamental_analysis/financial_modeling_prep/fmp_view.py similarity index 99% rename from gamestonk_terminal/fundamental_analysis/financial_modeling_prep/fmp_view.py rename to gamestonk_terminal/stocks/fundamental_analysis/financial_modeling_prep/fmp_view.py index b66a38b7063..6b7c60330eb 100644 --- a/gamestonk_terminal/fundamental_analysis/financial_modeling_prep/fmp_view.py +++ b/gamestonk_terminal/stocks/fundamental_analysis/financial_modeling_prep/fmp_view.py @@ -8,7 +8,7 @@ import pandas as pd import valinvest import FundamentalAnalysis as fa # Financial Modeling Prep from gamestonk_terminal import config_terminal as cfg -from gamestonk_terminal.fundamental_analysis.fa_helper import clean_df_index +from gamestonk_terminal.stocks.fundamental_analysis.fa_helper import clean_df_index from gamestonk_terminal.helper_funcs import ( long_number_format, check_positive, diff --git a/gamestonk_terminal/fundamental_analysis/finviz_view.py b/gamestonk_terminal/stocks/fundamental_analysis/finviz_view.py similarity index 100% rename from gamestonk_terminal/fundamental_analysis/finviz_view.py rename to gamestonk_terminal/stocks/fundamental_analysis/finviz_view.py diff --git a/gamestonk_terminal/fundamental_analysis/key_metrics_explained.txt b/gamestonk_terminal/stocks/fundamental_analysis/key_metrics_explained.txt similarity index 99% rename from gamestonk_terminal/fundamental_analysis/key_metrics_explained.txt rename to gamestonk_terminal/stocks/fundamental_analysis/key_metrics_explained.txt index f462d2f8b08..7e5388d7c1d 100644 --- a/gamestonk_terminal/fundamental_analysis/key_metrics_explained.txt +++ b/gamestonk_terminal/stocks/fundamental_analysis/key_metrics_explained.txt @@ -17,7 +17,7 @@ PRICE TO BOOK RATIO (P/B) Also known as the price to equity ratio, the price-to-book ratio is a fundamental analysis indicator that compares the book value of a stock to its market value. By showing the difference between the stock’s market value and the value the company has stated in its financial books, P/B helps investors determine whether the stock is under or overvalued relative to its book value. It is the theoretical value of a company if it will be liquidated. Value investors often look for low P/B multiples when searching for bargain-priced stocks. RETURN ON EQUITY (ROE) -ROE is a profitability ratio that signifies the rate of return a shareholder receives for the portion of their investment in that company. It measures how well a company generates positive returns to its shareholders’ investment. Since profit is an actual driver of stock prices, separating out the profits earned with shareholder equity is actually a pretty good indicator of the financial health of a company and fair value of its stock. +ROE is a profitability ratio that signifies the rate of return a shareholder receives for the portion of their investment in that company. It measures how well a company generates positive returns to its shareholders’ investment. Since profit is an actual driver of stock prices, separating out the profits earned with shareholder equity is actually a pretty good indicator of the financial health of a company and fair value of its stock. DIVIDEND PAYOUT RATIO (DPR) As you know, companies pay a part of their profits to their shareholders in the form of dividends. But it’s also important to know how well the company’s earnings support those dividend payments. This is what the Dividend Payout Ratio is all about. It tells you what portion of net income a company returns to its shareholders, as well as how much it sets aside for growth, cash reserve, and debt repayments. @@ -32,4 +32,4 @@ DEBT-TO-EQUITY RATIO (D/E) The debt to equity ratio is the last fundamental analysis indicator on this list. It measures the relationship between a company’s borrowed capital and the capital provided by its shareholders. Investors can use it to determine how a company finances its assets. The debt-to-equity ratio (D/E) helps investors evaluate the financial leverage of a company, signalling just how much shareholder’s equity can fulfil obligations to creditors should the business encounter financial hardship. Beta -Beta is a measurement of how reactive a stock is, compared to the overall market, generally defined as the S&P 500. A beta of 1 indicates that a stock tends to move in line with the S&P 500 -- that is, a 5% upward move in the index should produce roughly the same move in the stock. A beta of less than 1 indicates that a stock is less reactive to market swings, while a beta of more than 1 indicates a more volatile stock. For example, if a stock's beta is 0.4, a 10% move in the S&P 500 should theoretically produce a 4% swing in the stock. And a negative beta indicates that a stock tends to move in the opposite direction of the market. Beta can be found in most stock quotes, and it will give you an idea of how much volatility you're taking on before you buy a stock. \ No newline at end of file +Beta is a measurement of how reactive a stock is, compared to the overall market, generally defined as the S&P 500. A beta of 1 indicates that a stock tends to move in line with the S&P 500 -- that is, a 5% upward move in the index should produce roughly the same move in the stock. A beta of less than 1 indicates that a stock is less reactive to market swings, while a beta of more than 1 indicates a more volatile stock. For example, if a stock's beta is 0.4, a 10% move in the S&P 500 should theoretically produce a 4% swing in the stock. And a negative beta indicates that a stock tends to move in the opposite direction of the market. Beta can be found in most stock quotes, and it will give you an idea of how much volatility you're taking on before you buy a stock. diff --git a/gamestonk_terminal/fundamental_analysis/market_watch_model.py b/gamestonk_terminal/stocks/fundamental_analysis/market_watch_model.py similarity index 100% rename from gamestonk_terminal/fundamental_analysis/market_watch_model.py rename to gamestonk_terminal/stocks/fundamental_analysis/market_watch_model.py diff --git a/gamestonk_terminal/fundamental_analysis/market_watch_view.py b/gamestonk_terminal/stocks/fundamental_analysis/market_watch_view.py similarity index 99% rename from gamestonk_terminal/fundamental_analysis/market_watch_view.py rename to gamestonk_terminal/stocks/fundamental_analysis/market_watch_view.py index 5d7b2f02391..75013d9eef5 100644 --- a/gamestonk_terminal/fundamental_analysis/market_watch_view.py +++ b/gamestonk_terminal/stocks/fundamental_analysis/market_watch_view.py @@ -9,7 +9,7 @@ import argparse from typing import List import pandas as pd -from gamestonk_terminal.fundamental_analysis import market_watch_model as mwm +from gamestonk_terminal.stocks.fundamental_analysis import market_watch_model as mwm from gamestonk_terminal.helper_funcs import ( parse_known_args_and_warn, patch_pandas_text_adjustment, diff --git a/gamestonk_terminal/fundamental_analysis/yahoo_finance_view.py b/gamestonk_terminal/stocks/fundamental_analysis/yahoo_finance_view.py similarity index 99% rename from gamestonk_terminal/fundamental_analysis/yahoo_finance_view.py rename to gamestonk_terminal/stocks/fundamental_analysis/yahoo_finance_view.py index d0eaa43b002..41d76c5a168 100644 --- a/gamestonk_terminal/fundamental_analysis/yahoo_finance_view.py +++ b/gamestonk_terminal/stocks/fundamental_analysis/yahoo_finance_view.py @@ -8,7 +8,7 @@ import webbrowser import yfinance as yf import pandas as pd -from gamestonk_terminal.fundamental_analysis.fa_helper import clean_df_index +from gamestonk_terminal.stocks.fundamental_analysis.fa_helper import clean_df_index from gamestonk_terminal.helper_funcs import ( long_number_format, parse_known_args_and_warn, diff --git a/gamestonk_terminal/fundamental_analysis/yield_curve_model.py b/gamestonk_terminal/stocks/fundamental_analysis/yield_curve_model.py similarity index 100% rename from gamestonk_terminal/fundamental_analysis/yield_curve_model.py rename to gamestonk_terminal/stocks/fundamental_analysis/yield_curve_model.py diff --git a/gamestonk_terminal/government/README.md b/gamestonk_terminal/stocks/government/README.md similarity index 98% rename from gamestonk_terminal/government/README.md rename to gamestonk_terminal/stocks/government/README.md index fd0f83fc9d3..8fc7549ed9e 100644 --- a/gamestonk_terminal/government/README.md +++ b/gamestonk_terminal/stocks/government/README.md @@ -1,6 +1,6 @@ # GOVERNMENT -This menu aims to get some insights regarding government data, and the usage of the following commands along with an example will be exploited below. +This menu aims to get some insights regarding government data, and the usage of the following commands along with an example will be exploited below. This data has been provided by [quiverquant](https://www.quiverquant.com). * [last_congress](#last_congress) @@ -26,9 +26,9 @@ This data has been provided by [quiverquant](https://www.quiverquant.com). * [sum_contracts](#sum_contracts) * plot sum of last government contracts * [qtr_contracts](#qtr_contracts) - * quarterly government contracts best regression + * quarterly government contracts best regression * [top_lobbying](#top_lobbying) - * top corporate lobbying tickers + * top corporate lobbying tickers #### WITH TICKER PROVIDED @@ -202,7 +202,7 @@ Top lobbying spent. [Source: www.quiverquant.com] ![top_lobbying](https://user-images.githubusercontent.com/25267873/120707733-9e0ff200-c4b2-11eb-9430-552d92f3fc74.png) -#### WITH TICKER PROVIDED +#### WITH TICKER PROVIDED ## raw_congress ```text @@ -310,4 +310,3 @@ Lobbying details. [Source: www.quiverquant.com] * -l : Last corporate lobbying details. Default: 10. Captura de ecrã 2021-06-03, às 21 25 02 - diff --git a/gamestonk_terminal/government/gov_controller.py b/gamestonk_terminal/stocks/government/gov_controller.py similarity index 98% rename from gamestonk_terminal/government/gov_controller.py rename to gamestonk_terminal/stocks/government/gov_controller.py index a7821c077b0..fddf3282388 100644 --- a/gamestonk_terminal/government/gov_controller.py +++ b/gamestonk_terminal/stocks/government/gov_controller.py @@ -9,7 +9,7 @@ from prompt_toolkit.completion import NestedCompleter from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.helper_funcs import get_flair from gamestonk_terminal.menu import session -from gamestonk_terminal.government import quiverquant_view +from gamestonk_terminal.stocks.government import quiverquant_view class GovController: @@ -250,11 +250,11 @@ def menu(ticker: str): {c: None for c in gov_controller.CHOICES} ) an_input = session.prompt( - f"{get_flair()} (gov)> ", + f"{get_flair()} (stocks)>(gov)> ", completer=completer, ) else: - an_input = input(f"{get_flair()} (gov)> ") + an_input = input(f"{get_flair()} (stocks)>(gov)> ") try: plt.close("all") diff --git a/gamestonk_terminal/government/quiverquant_model.py b/gamestonk_terminal/stocks/government/quiverquant_model.py similarity index 100% rename from gamestonk_terminal/government/quiverquant_model.py rename to gamestonk_terminal/stocks/government/quiverquant_model.py diff --git a/gamestonk_terminal/government/quiverquant_view.py b/gamestonk_terminal/stocks/government/quiverquant_view.py similarity index 99% rename from gamestonk_terminal/government/quiverquant_view.py rename to gamestonk_terminal/stocks/government/quiverquant_view.py index a69238d2355..786d095b840 100644 --- a/gamestonk_terminal/government/quiverquant_view.py +++ b/gamestonk_terminal/stocks/government/quiverquant_view.py @@ -6,7 +6,7 @@ from sklearn import linear_model import pandas as pd from matplotlib import pyplot as plt import matplotlib.dates as mdates -from gamestonk_terminal.government import quiverquant_model +from gamestonk_terminal.stocks.government import quiverquant_model from gamestonk_terminal.helper_funcs import ( parse_known_args_and_warn, check_positive, diff --git a/gamestonk_terminal/insider/README.md b/gamestonk_terminal/stocks/insider/README.md similarity index 100% rename from gamestonk_terminal/insider/README.md rename to gamestonk_terminal/stocks/insider/README.md diff --git a/gamestonk_terminal/insider/insider_controller.py b/gamestonk_terminal/stocks/insider/insider_controller.py similarity index 98% rename from gamestonk_terminal/insider/insider_controller.py rename to gamestonk_terminal/stocks/insider/insider_controller.py index 6e7637b2b71..e5d6d8bb6df 100644 --- a/gamestonk_terminal/insider/insider_controller.py +++ b/gamestonk_terminal/stocks/insider/insider_controller.py @@ -9,7 +9,7 @@ from prompt_toolkit.completion import NestedCompleter from gamestonk_terminal.helper_funcs import get_flair, parse_known_args_and_warn from gamestonk_terminal.menu import session from gamestonk_terminal import feature_flags as gtff -from gamestonk_terminal.insider import openinsider_view +from gamestonk_terminal.stocks.insider import openinsider_view presets_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), "presets/") @@ -373,11 +373,11 @@ def menu(): {c: None for c in ins_controller.CHOICES} ) an_input = session.prompt( - f"{get_flair()} (ins)> ", + f"{get_flair()} (stocks)>(ins)> ", completer=completer, ) else: - an_input = input(f"{get_flair()} (ins)> ") + an_input = input(f"{get_flair()} (stocks)>(ins)> ") try: process_input = ins_controller.switch(an_input) diff --git a/gamestonk_terminal/insider/openinsider_model.py b/gamestonk_terminal/stocks/insider/openinsider_model.py similarity index 100% rename from gamestonk_terminal/insider/openinsider_model.py rename to gamestonk_terminal/stocks/insider/openinsider_model.py diff --git a/gamestonk_terminal/insider/openinsider_view.py b/gamestonk_terminal/stocks/insider/openinsider_view.py similarity index 99% rename from gamestonk_terminal/insider/openinsider_view.py rename to gamestonk_terminal/stocks/insider/openinsider_view.py index 3fb2ac65618..a3bbbf1fa11 100644 --- a/gamestonk_terminal/insider/openinsider_view.py +++ b/gamestonk_terminal/stocks/insider/openinsider_view.py @@ -13,7 +13,7 @@ from gamestonk_terminal.helper_funcs import ( parse_known_args_and_warn, patch_pandas_text_adjustment, ) -from gamestonk_terminal.insider.openinsider_model import ( +from gamestonk_terminal.stocks.insider.openinsider_model import ( get_open_insider_link, get_open_insider_data, ) diff --git a/gamestonk_terminal/insider/presets/template.ini b/gamestonk_terminal/stocks/insider/presets/template.ini similarity index 99% rename from gamestonk_terminal/insider/presets/template.ini rename to gamestonk_terminal/stocks/insider/presets/template.ini index 9637a10e075..db8aef9c98e 100644 --- a/gamestonk_terminal/insider/presets/template.ini +++ b/gamestonk_terminal/stocks/insider/presets/template.ini @@ -62,7 +62,7 @@ COO = CFO = GC = VP = -# 'Officer' inclues all of the above: COB, CEO, Pres, COO, CFO, GC, VP +# 'Officer' includes all of the above: COB, CEO, Pres, COO, CFO, GC, VP Officer = Director = 10PctOwn = diff --git a/gamestonk_terminal/stocks/insider/presets/test.py b/gamestonk_terminal/stocks/insider/presets/test.py new file mode 100644 index 00000000000..1b02b20ef0f --- /dev/null +++ b/gamestonk_terminal/stocks/insider/presets/test.py @@ -0,0 +1,513 @@ +# flake8: noqa +# pylint: disable=line-too-long + +d_industry = { + "All Sectors (except Funds)": "sic1=-1&sicl=100&sich=9999", + "Agriculture, Forestry, Fish": "sic1=1&sic2=1&sicl=100&sich=199", + "Agriculture, Forestry, Fish -> Crops": "sic1=1&sic2=1&sicl=100&sich=199", + "Agriculture, Forestry, Fish -> Livestock & Animal Specialties": "sic1=1&sic2=2&sicl=200&sich=699", + "Agriculture, Forestry, Fish -> Agriculture Services": "sic1=1&sic2=7&sicl=700&sich=799", + "Agriculture, Forestry, Fish -> Forestry": "sic1=1&sic2=8&sicl=800&sich=899", + "Agriculture, Forestry, Fish -> Fishing, Hunting & Trapping": "sic1=1&sic2=9&sicl=900&sich=999", + "Mining": "sic1=10&sic2=0&sicl=1000&sich=1499", + "Mining -> Metal Mining": "sic1=10&sic2=10&sic3=1000&sicl=1000&sich=1039", + "Mining -> Metal Mining -> Gold & Silver Ores": "sic1=10&sic2=10&sic3=1040&sicl=1040&sich=1089", + "Mining -> Metal Mining -> Miscellaneous Metal Ores": "sic1=10&sic2=10&sic3=1090&sicl=1090&sich=1219", + "Mining -> Coal Mining": "sic1=10&sic2=12&sic3=0&sicl=1200&sich=1299", + "Mining -> Coal Mining -> Bituminous Coal & Lignite Mining": "sic1=10&sic2=12&sic3=1220&sicl=1220&sich=1220", + "Mining -> Coal Mining -> Bituminous Coal & Lignite Surfac": "sic1=10&sic2=12&sic3=1221&sicl=1221&sich=1310", + "Mining -> Oil & Gas Extraction": "sic1=10&sic2=13&sic3=0&sicl=1300&sich=1399", + "Mining -> Oil & Gas Extraction -> Crude Petroleum & Natural Gas": "sic1=10&sic2=13&sic3=1311&sicl=1311&sich=1380", + "Mining -> Oil & Gas Extraction -> Drilling Oil & Gas Wells": "sic1=10&sic2=13&sic3=1381&sicl=1381&sich=1381", + "Mining -> Oil & Gas Extraction -> Oil & Gas Field Exploration Serv": "sic1=10&sic2=13&sic3=1382&sicl=1382&sich=1388", + "Mining -> Oil & Gas Extraction -> Oil & Gas Field Services": "sic1=10&sic2=13&sic3=1389&sicl=1389&sich=1399", + "Mining -> Mining Non-metallic Minerals": "sic1=10&sic2=14&sicl=1400&sich=1519", + "Construction": "sic1=15&sic2=0&sicl=1500&sich=1799", + "Construction -> General Contractors & Builders": "sic1=15&sic2=15&sicl=1500&sich=1599", + "Construction -> General Contractors & Builders -> Residential Bldg Contractors": "sic1=15&sic2=15&sic3=1520&sicl=1520&sich=1530", + "Construction -> General Contractors & Builders -> Operative Builders": "sic1=15&sic2=15&sic3=1531&sicl=1531&sich=1539", + "Construction -> General Contractors & Builders -> Nonresidential Bldg Contractors": "sic1=15&sic2=15&sic3=1540&sicl=1540&sich=1599", + "Construction -> Heavy Construction": "sic1=15&sic2=16&sic3=0&sicl=1600&sich=1699", + "Construction -> Heavy Construction -> Heavy Construction Non-Bldg Cont": "sic1=15&sic2=16&sic3=1600&sicl=1600&sich=1622", + "Construction -> Heavy Construction -> Water, Sewer, Pipeline, Comm & P": "sic1=15&sic2=16&sic3=1623&sicl=1623&sich=1699", + "Construction -> Special Trade Contractors": "sic1=15&sic2=17&sic3=0&sicl=1700&sich=1999", + "Construction -> Special Trade Contractors -> Special Trade Contractors": "sic1=15&sic2=17&sic3=1700&sicl=1700&sich=1730", + "Construction -> Special Trade Contractors -> Electrical Work": "sic1=15&sic2=17&sic3=1731&sicl=1731&sich=1999", + "Manufacturing": "sic1=20&sic2=0&sicl=2000&sich=3999", + "Manufacturing -> Food": "sic1=20&sic2=20&sic3=0&sicl=2000&sich=2099", + "Manufacturing -> Food -> Food & Kindred Products": "sic1=20&sic2=20&sic3=2000&sicl=2000&sich=2010", + "Manufacturing -> Food -> Meat Packing Plants": "sic1=20&sic2=20&sic3=2011&sicl=2011&sich=2012", + "Manufacturing -> Food -> Sausage & Other Prepared Meat P": "sic1=20&sic2=20&sic3=2013&sicl=2013&sich=2014", + "Manufacturing -> Food -> Poultry Slaughtering & Processin": "sic1=20&sic2=20&sic3=2015&sicl=2015&sich=2019", + "Manufacturing -> Food -> Dairy Products": "sic1=20&sic2=20&sic3=2020&sicl=2020&sich=2023", + "Manufacturing -> Food -> Ice Cream & Froze Desserts": "sic1=20&sic2=20&sic3=2024&sicl=2024&sich=2029", + "Manufacturing -> Food -> Canned, Frozen & Preservd Fruit": "sic1=20&sic2=20&sic3=2030&sicl=2030&sich=2032", + "Manufacturing -> Food -> Canned, Fruits, Veg, Preserves": "sic1=20&sic2=20&sic3=2033&sicl=2033&sich=2039", + "Manufacturing -> Food -> Grain Mill Products": "sic1=20&sic2=20&sic3=2040&sicl=2040&sich=2049", + "Manufacturing -> Food -> Bakery Products": "sic1=20&sic2=20&sic3=2050&sicl=2050&sich=2051", + "Manufacturing -> Food -> Cookies & Crackers": "sic1=20&sic2=20&sic3=2052&sicl=2052&sich=2059", + "Manufacturing -> Food -> Sugar & Confectionery Products": "sic1=20&sic2=20&sic3=2060&sicl=2060&sich=2069", + "Manufacturing -> Food -> Fats & Oils": "sic1=20&sic2=20&sic3=2070&sicl=2070&sich=2079", + "Manufacturing -> Food -> Beverages": "sic1=20&sic2=20&sic3=2080&sicl=2080&sich=2081", + "Manufacturing -> Food -> Malt Beverages": "sic1=20&sic2=20&sic3=2082&sicl=2082&sich=2085", + "Manufacturing -> Food -> Bottled & Canned Soft Drinks & C": "sic1=20&sic2=20&sic3=2086&sicl=2086&sich=2089", + "Manufacturing -> Food -> Miscellaneous Food Preparations": "sic1=20&sic2=20&sic3=2090&sicl=2090&sich=2091", + "Manufacturing -> Food -> Prepared Fresh or Frozen Fish &": "sic1=20&sic2=20&sic3=2092&sicl=2092&sich=2099", + "Manufacturing -> Tobacco": "sic1=20&sic2=21&sic3=0&sicl=2100&sich=2199", + "Manufacturing -> Tobacco -> Tobacco Products": "sic1=20&sic2=21&sic3=2100&sicl=2100&sich=2110", + "Manufacturing -> Tobacco -> Cigarettes": "sic1=20&sic2=21&sic3=2111&sicl=2111&sich=2199", + "Manufacturing -> Textile Mill Products": "sic1=20&sic2=22&sic3=0&sicl=2200&sich=2299", + "Manufacturing -> Textile Mill Products -> Textile Mill Products": "sic1=20&sic2=22&sic3=2200&sicl=2200&sich=2210", + "Manufacturing -> Textile Mill Products -> Broadwoven Fabric Mills, Cotton": "sic1=20&sic2=22&sic3=2211&sicl=2211&sich=2220", + "Manufacturing -> Textile Mill Products -> Broadwoven Fabric Mills, Man Mad": "sic1=20&sic2=22&sic3=2221&sicl=2221&sich=2249", + "Manufacturing -> Textile Mill Products -> Knitting Mills": "sic1=20&sic2=22&sic3=2250&sicl=2250&sich=2252", + "Manufacturing -> Textile Mill Products -> Knit Outerwear Mills": "sic1=20&sic2=22&sic3=2253&sicl=2253&sich=2272", + "Manufacturing -> Textile Mill Products -> Carpets & Rugs": "sic1=20&sic2=22&sic3=2273&sicl=2273&sich=2299", + "Manufacturing -> Apparel": "sic1=20&sic2=23&sic3=0&sicl=2300&sich=2399", + "Manufacturing -> Apparel -> Other Finishd Prods of": "sic1=20&sic2=23&sic3=2300&sicl=2300&sich=2319", + "Manufacturing -> Apparel -> Men’s & Boy’s Furnishgs, Work Cl": "sic1=20&sic2=23&sic3=2320&sicl=2320&sich=2329", + "Manufacturing -> Apparel -> Women’s, Misses’, & Juniors Oute": "sic1=20&sic2=23&sic3=2330&sicl=2330&sich=2339", + "Manufacturing -> Apparel -> Women’s, Misses’, Children’s & l": "sic1=20&sic2=23&sic3=2340&sicl=2340&sich=2389", + "Manufacturing -> Apparel -> Miscellaneous Fabric": "sic1=20&sic2=23&sic3=2390&sicl=2390&sich=2399", + "Manufacturing -> Lumber": "sic1=20&sic2=24&sic3=0&sicl=2400&sich=2499", + "Manufacturing -> Lumber -> Lumber & Wood Products (No Furni)": "sic1=20&sic2=24&sic3=2400&sicl=2400&sich=2420", + "Manufacturing -> Lumber -> Sawmills & Planting Mills, Gener": "sic1=20&sic2=24&sic3=2421&sicl=2421&sich=2429", + "Manufacturing -> Lumber -> Millwood, Veneer, Plywood & Str": "sic1=20&sic2=24&sic3=2430&sicl=2430&sich=2450", + "Manufacturing -> Lumber -> Mobile Homes": "sic1=20&sic2=24&sic3=2451&sicl=2451&sich=2451", + "Manufacturing -> Lumber -> Prefabricated Wood Bldgs & Compo": "sic1=20&sic2=24&sic3=2452&sicl=2452&sich=2509", + "Manufacturing -> Furniture": "sic1=20&sic2=25&sic3=0&sicl=2500&sich=2599", + "Manufacturing -> Furniture -> Household Furniture": "sic1=20&sic2=25&sic3=2510&sicl=2510&sich=2510", + "Manufacturing -> Furniture -> Wood Household Furniture, (no Up)": "sic1=20&sic2=25&sic3=2511&sicl=2511&sich=2519", + "Manufacturing -> Furniture -> Office Furniture": "sic1=20&sic2=25&sic3=2520&sicl=2520&sich=2521", + "Manufacturing -> Furniture -> Office Furniture (No Wood)": "sic1=20&sic2=25&sic3=2522&sicl=2522&sich=2530", + "Manufacturing -> Furniture -> Public Bldg & Related Furniture": "sic1=20&sic2=25&sic3=2531&sicl=2531&sich=2539", + "Manufacturing -> Furniture -> Partitions, Shelvg, Lockers & O": "sic1=20&sic2=25&sic3=2540&sicl=2540&sich=2589", + "Manufacturing -> Furniture -> Miscellaneous Furniture & Fixtur": "sic1=20&sic2=25&sic3=2590&sicl=2590&sich=2599", + "Manufacturing -> Paper": "sic1=20&sic2=26&sic3=0&sicl=2600&sich=2699", + "Manufacturing -> Paper -> Papers & Allied Products": "sic1=20&sic2=26&sic3=2600&sicl=2600&sich=2610", + "Manufacturing -> Paper -> Pulp Mills": "sic1=20&sic2=26&sic3=2611&sicl=2611&sich=2620", + "Manufacturing -> Paper -> Paper Mills": "sic1=20&sic2=26&sic3=2621&sicl=2621&sich=2630", + "Manufacturing -> Paper -> Paperboard Mills": "sic1=20&sic2=26&sic3=2631&sicl=2631&sich=2649", + "Manufacturing -> Paper -> Paperboard Containers & Boxes": "sic1=20&sic2=26&sic3=2650&sicl=2650&sich=2669", + "Manufacturing -> Paper -> Converted Paper & Paperboard Pro": "sic1=20&sic2=26&sic3=2670&sicl=2670&sich=2672", + "Manufacturing -> Paper -> Plastics, Foils & Coated Paper Ba": "sic1=20&sic2=26&sic3=2673&sicl=2673&sich=2710", + "Manufacturing -> Printing & Publishing": "sic1=20&sic2=27&sic3=0&sicl=2700&sich=2799", + "Manufacturing -> Printing & Publishing -> Newspapers: Publishing or Publis": "sic1=20&sic2=27&sic3=2711&sicl=2711&sich=2720", + "Manufacturing -> Printing & Publishing -> Periodicals: Publishing or Publi": "sic1=20&sic2=27&sic3=2721&sicl=2721&sich=2730", + "Manufacturing -> Printing & Publishing -> Books: Publishing or Publishing": "sic1=20&sic2=27&sic3=2731&sicl=2731&sich=2731", + "Manufacturing -> Printing & Publishing -> Book Printing": "sic1=20&sic2=27&sic3=2732&sicl=2732&sich=2740", + "Manufacturing -> Printing & Publishing -> Miscellaneous Publishing": "sic1=20&sic2=27&sic3=2741&sicl=2741&sich=2749", + "Manufacturing -> Printing & Publishing -> Commercial Printing": "sic1=20&sic2=27&sic3=2750&sicl=2750&sich=2760", + "Manufacturing -> Printing & Publishing -> Manifold Business Forms": "sic1=20&sic2=27&sic3=2761&sicl=2761&sich=2770", + "Manufacturing -> Printing & Publishing -> Greeting Cards": "sic1=20&sic2=27&sic3=2771&sicl=2771&sich=2779", + "Manufacturing -> Printing & Publishing -> Blankbooks, Looseleaf Binders &": "sic1=20&sic2=27&sic3=2780&sicl=2780&sich=2789", + "Manufacturing -> Printing & Publishing ->Service Industries For The Print": "sic1=20&sic2=27&sic3=2790&sicl=2790&sich=2799", + "Manufacturing -> Chemicals": "sic1=20&sic2=28&sic3=0&sicl=2800&sich=2899", + "Manufacturing -> Chemicals -> Chemicals & Allied Products": "sic1=20&sic2=28&sic3=2800&sicl=2800&sich=2809", + "Manufacturing -> Chemicals -> Industrial Inorganic Chemicals": "sic1=20&sic2=28&sic3=2810&sicl=2810&sich=2819", + "Manufacturing -> Chemicals -> Plastic Material, Synth Resin/Ru": "sic1=20&sic2=28&sic3=2820&sicl=2820&sich=2820", + "Manufacturing -> Chemicals -> Plastic Material, Synth Resins": "sic1=20&sic2=28&sic3=2821&sicl=2821&sich=2832", + "Manufacturing -> Chemicals -> Medicinal Chemicals & Botanical": "sic1=20&sic2=28&sic3=2833&sicl=2833&sich=2833", + "Manufacturing -> Chemicals -> Pharmaceutical Preparations": "sic1=20&sic2=28&sic3=2834&sicl=2834&sich=2834", + "Manufacturing -> Chemicals -> In Vitro & In Vito Diagnostic Su": "sic1=20&sic2=28&sic3=2835&sicl=2835&sich=2835", + "Manufacturing -> Chemicals -> Biological Products ,(No Diagnos": "sic1=20&sic2=28&sic3=2836&sicl=2836&sich=2839", + "Manufacturing -> Chemicals -> Soap, Detergents, Cleaning, Perf": "sic1=20&sic2=28&sic3=2840&sicl=2840&sich=2841", + "Manufacturing -> Chemicals -> Specialty Cleaning, Polishing &": "sic1=20&sic2=28&sic3=2842&sicl=2842&sich=2843", + "Manufacturing -> Chemicals -> Perfumes, Cosmetics & Other Toil": "sic1=20&sic2=28&sic3=2844&sicl=2844&sich=2850", + "Manufacturing -> Chemicals -> Paints, Varnishes, Lacquers, Ena": "sic1=20&sic2=28&sic3=2851&sicl=2851&sich=2859", + "Manufacturing -> Chemicals -> Industrial Organic Chemicals": "sic1=20&sic2=28&sic3=2860&sicl=2860&sich=2869", + "Manufacturing -> Chemicals ->Agriculture Chemicals": "sic1=20&sic2=28&sic3=2870&sicl=2870&sich=2889", + "Manufacturing -> Chemicals -> Miscellaneous Chemical Products": "sic1=20&sic2=28&sic3=2890&sicl=2890&sich=2890", + "Manufacturing -> Chemicals -> Adhesives & Sealants": "sic1=20&sic2=28&sic3=2891&sicl=2891&sich=2910", + "Manufacturing -> Petroleum Refining": "sic1=20&sic2=29&sic3=0&sicl=2900&sich=2999", + "Manufacturing -> Petroleum Refining -> Petroleum Refining": "sic1=20&sic2=29&sic3=2911&sicl=2911&sich=2949", + "Manufacturing -> Petroleum Refining -> Asphalt Paving & Roofing Materia": "sic1=20&sic2=29&sic3=2950&sicl=2950&sich=2989", + "Manufacturing -> Petroleum Refining -> Miscellaneous Products of Petrol": "sic1=20&sic2=29&sic3=2990&sicl=2990&sich=3010", + "Manufacturing -> Rubber & Plastic": "sic1=20&sic2=30&sic3=0&sicl=3000&sich=3099", + "Manufacturing -> Rubber & Plastic -> Tires & Inner Tubes": "sic1=20&sic2=30&sic3=3011&sicl=3011&sich=3020", + "Manufacturing -> Rubber & Plastic -> Rubber & Plastics Footwear": "sic1=20&sic2=30&sic3=3021&sicl=3021&sich=3049", + "Manufacturing -> Rubber & Plastic -> Gaskets & Packg & Sealg Devices &": "sic1=20&sic2=30&sic3=3050&sicl=3050&sich=3059", + "Manufacturing -> Rubber & Plastic -> Fabricated Rubber Products": "sic1=20&sic2=30&sic3=3060&sicl=3060&sich=3079", + "Manufacturing -> Rubber & Plastic -> Miscellaneous Plastics Products": "sic1=20&sic2=30&sic3=3080&sicl=3080&sich=3080", + "Manufacturing -> Rubber & Plastic -> Unsupported Plastics Film & Shee": "sic1=20&sic2=30&sic3=3081&sicl=3081&sich=3085", + "Manufacturing -> Rubber & Plastic -> Plastics Foam Products": "sic1=20&sic2=30&sic3=3086&sicl=3086&sich=3088", + "Manufacturing -> Rubber & Plastic -> Plastics Products": "sic1=20&sic2=30&sic3=3089&sicl=3089&sich=3099", + "Manufacturing -> Leather": "sic1=20&sic2=31&sic3=0&sicl=3100&sich=3199", + "Manufacturing -> Leather -> Leather Products": "sic1=20&sic2=31&sic3=3100&sicl=3100&sich=3139", + "Manufacturing -> Leather -> Footwear, (No Rubber)": "sic1=20&sic2=31&sic3=3140&sicl=3140&sich=3210", + "Manufacturing -> Stone, Clay, Glass & Concrete": "sic1=20&sic2=32&sic3=0&sicl=3200&sich=3299", + "Manufacturing -> Stone, Clay, Glass & Concrete -> Flat Glass": "sic1=20&sic2=32&sic3=3211&sicl=3211&sich=3219", + "Manufacturing -> Stone, Clay, Glass & Concrete -> Glass & Glasswear, Pressed or Bl": "sic1=20&sic2=32&sic3=3220&sicl=3220&sich=3220", + "Manufacturing -> Stone, Clay, Glass & Concrete -> Glass Containers": "sic1=20&sic2=32&sic3=3221&sicl=3221&sich=3230", + "Manufacturing -> Stone, Clay, Glass & Concrete -> Glass Products Made of Purchase": "sic1=20&sic2=32&sic3=3231&sicl=3231&sich=3240", + "Manufacturing -> Stone, Clay, Glass & Concrete -> Cements, Hydrallic": "sic1=20&sic2=32&sic3=3241&sicl=3241&sich=3249", + "Manufacturing -> Stone, Clay, Glass & Concrete -> Structural Clay Products": "sic1=20&sic2=32&sic3=3250&sicl=3250&sich=3259", + "Manufacturing -> Stone, Clay, Glass & Concrete -> Pottery & Related Products": "sic1=20&sic2=32&sic3=3260&sicl=3260&sich=3269", + "Manufacturing -> Stone, Clay, Glass & Concrete -> Concreate, Gypsum & Plaster Produ": "sic1=20&sic2=32&sic3=3270&sicl=3270&sich=3271", + "Manufacturing -> Stone, Clay, Glass & Concrete -> Concrete Products, Except Block": "sic1=20&sic2=32&sic3=3272&sicl=3272&sich=3280", + "Manufacturing -> Stone, Clay, Glass & Concrete -> Cut Stone & Stone Products": "sic1=20&sic2=32&sic3=3281&sicl=3281&sich=3289", + "Manufacturing -> Stone, Clay, Glass & Concrete -> Abrasive, Asbestos & Misc Nonmet": "sic1=20&sic2=32&sic3=3290&sicl=3290&sich=3309", + "Manufacturing -> Primary Metal": "sic1=20&sic2=33&sic3=0&sicl=3300&sich=3399", + "Manufacturing -> Primary Metal -> Steel Works, Blast Furnaces & Ro": "sic1=20&sic2=33&sic3=3310&sicl=3310&sich=3311", + "Manufacturing -> Primary Metal -> Steel Works, Blast Furnaces & R": "sic1=20&sic2=33&sic3=3312&sicl=3312&sich=3316", + "Manufacturing -> Primary Metal -> Steel Pipe & Tubes": "sic1=20&sic2=33&sic3=3317&sicl=3317&sich=3319", + "Manufacturing -> Primary Metal -> Iron & Steel Foundries": "sic1=20&sic2=33&sic3=3320&sicl=3320&sich=3329", + "Manufacturing -> Primary Metal -> Primary Smelting & Refining of N": "sic1=20&sic2=33&sic3=3330&sicl=3330&sich=3333", + "Manufacturing -> Primary Metal -> Primary Production of Aluminium": "sic1=20&sic2=33&sic3=3334&sicl=3334&sich=3340", + "Manufacturing -> Primary Metal -> Secondary Smelting & Refining of": "sic1=20&sic2=33&sic3=3341&sicl=3341&sich=3349", + "Manufacturing -> Primary Metal -> Rolling Drawing & Extruding of N": "sic1=20&sic2=33&sic3=3350&sicl=3350&sich=3356", + "Manufacturing -> Primary Metal -> Drawing & Insulating of Non Ferro": "sic1=20&sic2=33&sic3=3357&sicl=3357&sich=3359", + "Manufacturing -> Primary Metal -> Nonferrous Foundries (Castings)": "sic1=20&sic2=33&sic3=3360&sicl=3360&sich=3389", + "Manufacturing -> Primary Metal -> Miscellaneous Primary Metal Prod": "sic1=20&sic2=33&sic3=3390&sicl=3390&sich=3410", + "Manufacturing -> Fabricated Metal Products": "sic1=20&sic2=34&sic3=0&sicl=3400&sich=3499", + "Manufacturing -> Fabricated Metal Products -> Metal Cans": "sic1=20&sic2=34&sic3=3411&sicl=3411&sich=3411", + "Manufacturing -> Fabricated Metal Products -> Metal Shipping Barrels, Drums, K": "sic1=20&sic2=34&sic3=3412&sicl=3412&sich=3419", + "Manufacturing -> Fabricated Metal Products -> Cutlery, Handtools & General Har": "sic1=20&sic2=34&sic3=3420&sicl=3420&sich=3429", + "Manufacturing -> Fabricated Metal Products -> Hearing Equip, Except Elec & War": "sic1=20&sic2=34&sic3=3430&sicl=3430&sich=3432", + "Manufacturing -> Fabricated Metal Products -> Heating Equipment, Except Electr": "sic1=20&sic2=34&sic3=3433&sicl=3433&sich=3439", + "Manufacturing -> Fabricated Metal Products -> Fabricated Structural Metal Prod": "sic1=20&sic2=34&sic3=3440&sicl=3440&sich=3441", + "Manufacturing -> Fabricated Metal Products -> Metal Doors, Sash, Frames, Moldi": "sic1=20&sic2=34&sic3=3442&sicl=3442&sich=3442", + "Manufacturing -> Fabricated Metal Products -> Fabricated Plate Work (Boiler Sh": "sic1=20&sic2=34&sic3=3443&sicl=3443&sich=3443", + "Manufacturing -> Fabricated Metal Products -> Sheet Metal Work": "sic1=20&sic2=34&sic3=3444&sicl=3444&sich=3447", + "Manufacturing -> Fabricated Metal Products -> Prefabricated Metal Buildings &": "sic1=20&sic2=34&sic3=3448&sicl=3448&sich=3450", + "Manufacturing -> Fabricated Metal Products -> Screw Machine Products": "sic1=20&sic2=34&sic3=3451&sicl=3451&sich=3451", + "Manufacturing -> Fabricated Metal Products -> Bolts, Nuts, Screws, Rivets & Wa": "sic1=20&sic2=34&sic3=3452&sicl=3452&sich=3459", + "Manufacturing -> Fabricated Metal Products -> Metal Forgings & Stampings": "sic1=20&sic2=34&sic3=3460&sicl=3460&sich=3469", + "Manufacturing -> Fabricated Metal Products -> Coating, Engraving & Allied Serv": "sic1=20&sic2=34&sic3=3470&sicl=3470&sich=3479", + "Manufacturing -> Fabricated Metal Products -> Ordnance & Accessories, (No Vehi": "sic1=20&sic2=34&sic3=3480&sicl=3480&sich=3489", + "Manufacturing -> Fabricated Metal Products -> Miscellaneous Fabricated Metal P": "sic1=20&sic2=34&sic3=3490&sicl=3490&sich=3509", + "Manufacturing -> Ind Machinery & Computers": "sic1=20&sic2=35&sicl=3500&sich=3599", + "Manufacturing -> Ind Machinery & Computers -> Engines & Turbines": "sic1=20&sic2=35&sic3=3510&sicl=3510&sich=3522", + "Manufacturing -> Ind Machinery & Computers -> Farm Machinery & Equipment": "sic1=20&sic2=35&sic3=3523&sicl=3523&sich=3523", + "Manufacturing -> Ind Machinery & Computers -> Lawn & Garden Tractors & Home La": "sic1=20&sic2=35&sic3=3524&sicl=3524&sich=3529", + "Manufacturing -> Ind Machinery & Computers -> Construction, Mining & Materials": "sic1=20&sic2=35&sic3=3530&sicl=3530&sich=3530", + "Manufacturing -> Ind Machinery & Computers -> Construction Machinery & Equip": "sic1=20&sic2=35&sic3=3531&sicl=3531&sich=3531", + "Manufacturing -> Ind Machinery & Computers -> Mining Machinery & Equip (No Oil": "sic1=20&sic2=35&sic3=3532&sicl=3532&sich=3532", + "Manufacturing -> Ind Machinery & Computers -> Oil & Gas Field Machinery & Equi": "sic1=20&sic2=35&sic3=3533&sicl=3533&sich=3536", + "Manufacturing -> Ind Machinery & Computers -> Industrial Trucks, Tractors, Tra": "sic1=20&sic2=35&sic3=3537&sicl=3537&sich=3539", + "Manufacturing -> Ind Machinery & Computers -> Metalworking Machinery & Equipment": "sic1=20&sic2=35&sic3=3540&sicl=3540&sich=3540", + "Manufacturing -> Ind Machinery & Computers -> Machine Tools, Metal Cutting Typ": "sic1=20&sic2=35&sic3=3541&sicl=3541&sich=3549", + "Manufacturing -> Ind Machinery & Computers -> Special Industry Machinery (No M": "sic1=20&sic2=35&sic3=3550&sicl=3550&sich=3554", + "Manufacturing -> Ind Machinery & Computers -> Printing Trades Machinery & Equi": "sic1=20&sic2=35&sic3=3555&sicl=3555&sich=3558", + "Manufacturing -> Ind Machinery & Computers -> Special Industry Machinery": "sic1=20&sic2=35&sic3=3559&sicl=3559&sich=3559", + "Manufacturing -> Ind Machinery & Computers -> General Industrial Machinery & E": "sic1=20&sic2=35&sic3=3560&sicl=3560&sich=3560", + "Manufacturing -> Ind Machinery & Computers -> Pumps & Pumping Equipment": "sic1=20&sic2=35&sic3=3561&sicl=3561&sich=3561", + "Manufacturing -> Ind Machinery & Computers -> Ball & Roller Bearings": "sic1=20&sic2=35&sic3=3562&sicl=3562&sich=3563", + "Manufacturing -> Ind Machinery & Computers -> Industrial & Commercial Fans & B": "sic1=20&sic2=35&sic3=3564&sicl=3564&sich=3566", + "Manufacturing -> Ind Machinery & Computers -> Industrial Process Furnaces & Ov": "sic1=20&sic2=35&sic3=3567&sicl=3567&sich=3568", + # "Manufacturing -> Ind Machinery & Computers -> General Industrial Machinery & E": "sic1=20&sic2=35&sic3=3569&sicl=3569&sich=3569", + "Manufacturing -> Ind Machinery & Computers -> Computer & Office Equipment": "sic1=20&sic2=35&sic3=3570&sicl=3570&sich=3570", + "Manufacturing -> Ind Machinery & Computers -> Electronic Computers": "sic1=20&sic2=35&sic3=3571&sicl=3571&sich=3571", + "Manufacturing -> Ind Machinery & Computers -> Computer Storage Devices": "sic1=20&sic2=35&sic3=3572&sicl=3572&sich=3574", + "Manufacturing -> Ind Machinery & Computers -> Computer Terminals": "sic1=20&sic2=35&sic3=3575&sicl=3575&sich=3575", + "Manufacturing -> Ind Machinery & Computers -> Computer Communications Equipmen": "sic1=20&sic2=35&sic3=3576&sicl=3576&sich=3576", + "Manufacturing -> Ind Machinery & Computers -> Computer Peripheral Equipment": "sic1=20&sic2=35&sic3=3577&sicl=3577&sich=3577", + "Manufacturing -> Ind Machinery & Computers -> Calculating & Accounting Machine": "sic1=20&sic2=35&sic3=3578&sicl=3578&sich=3578", + "Manufacturing -> Ind Machinery & Computers -> Office Machines": "sic1=20&sic2=35&sic3=3579&sicl=3579&sich=3579", + "Manufacturing -> Ind Machinery & Computers -> Refrigeration & Service Industry": "sic1=20&sic2=35&sic3=3580&sicl=3580&sich=3584", + "Manufacturing -> Ind Machinery & Computers -> Air-Cond & Warm Air Heatg Equip": "sic1=20&sic2=35&sic3=3585&sicl=3585&sich=3589", + "Manufacturing -> Ind Machinery & Computers -> Misc Industrial & Commercial Mac": "sic1=20&sic2=35&sic3=3590&sicl=3590&sich=3599", + "Manufacturing -> Electronics": "sic1=20&sic2=36&sic3=0&sicl=3600&sich=3699", + "Manufacturing -> Electronics -> Electronic & Other Electrical Eq": "sic1=20&sic2=36&sic3=3600&sicl=3600&sich=3611", + "Manufacturing -> Electronics -> Power, Distribution & Specialty": "sic1=20&sic2=36&sic3=3612&sicl=3612&sich=3612", + "Manufacturing -> Electronics -> Switchgear & Switchboard Apparat": "sic1=20&sic2=36&sic3=3613&sicl=3613&sich=3619", + "Manufacturing -> Electronics -> Electrical Industrial Apparatus": "sic1=20&sic2=36&sic3=3620&sicl=3620&sich=3620", + "Manufacturing -> Electronics -> Motors & Generators": "sic1=20&sic2=36&sic3=3621&sicl=3621&sich=3629", + "Manufacturing -> Electronics -> Household Appliances": "sic1=20&sic2=36&sic3=3630&sicl=3630&sich=3633", + "Manufacturing -> Electronics -> Electric Housewares & Fans": "sic1=20&sic2=36&sic3=3634&sicl=3634&sich=3639", + "Manufacturing -> Electronics -> Electric Lighting & Wiring Equip": "sic1=20&sic2=36&sic3=3640&sicl=3640&sich=3650", + "Manufacturing -> Electronics -> Household Audio & Video Equipmen": "sic1=20&sic2=36&sic3=3651&sicl=3651&sich=3651", + "Manufacturing -> Electronics -> Phonograph Records & Prerecorded": "sic1=20&sic2=36&sic3=3652&sicl=3652&sich=3660", + "Manufacturing -> Electronics -> Telephone & Telegraph Apparatus": "sic1=20&sic2=36&sic3=3661&sicl=3661&sich=3662", + "Manufacturing -> Electronics -> Radio & Tv Broadcasting & Commun": "sic1=20&sic2=36&sic3=3663&sicl=3663&sich=3668", + "Manufacturing -> Electronics -> Communications Equipment": "sic1=20&sic2=36&sic3=3669&sicl=3669&sich=3669", + "Manufacturing -> Electronics -> Electronic Components & Accessor": "sic1=20&sic2=36&sic3=3670&sicl=3670&sich=3671", + "Manufacturing -> Electronics -> Printed Circuit Boards": "sic1=20&sic2=36&sic3=3672&sicl=3672&sich=3673", + "Manufacturing -> Electronics -> Semiconductors & Related Devices": "sic1=20&sic2=36&sic3=3674&sicl=3674&sich=3676", + "Manufacturing -> Electronics -> Electronic Coils & Transformers &": "sic1=20&sic2=36&sic3=3677&sicl=3677&sich=3677", + "Manufacturing -> Electronics -> Electronic Connectors": "sic1=20&sic2=36&sic3=3678&sicl=3678&sich=3678", + "Manufacturing -> Electronics -> Electronic Components": "sic1=20&sic2=36&sic3=3679&sicl=3679&sich=3689", + "Manufacturing -> Electronics -> Miscellaneous Electrical Machine": "sic1=20&sic2=36&sic3=3690&sicl=3690&sich=3694", + "Manufacturing -> Electronics -> Magnetic & Optical Recording Med": "sic1=20&sic2=36&sic3=3695&sicl=3695&sich=3710", + "Manufacturing -> Transportation Equipment": "sic1=20&sic2=37&sic3=0&sicl=3700&sich=3799", + "Manufacturing -> Transportation Equipment -> Motor Vehicles & Passenger Car B": "sic1=20&sic2=37&sic3=3711&sicl=3711&sich=3712", + "Manufacturing -> Transportation Equipment -> Truck & Bus Bodies": "sic1=20&sic2=37&sic3=3713&sicl=3713&sich=3713", + "Manufacturing -> Transportation Equipment -> Motor Vehicle Parts & Accessorie": "sic1=20&sic2=37&sic3=3714&sicl=3714&sich=3714", + "Manufacturing -> Transportation Equipment -> Truck Trailers": "sic1=20&sic2=37&sic3=3715&sicl=3715&sich=3715", + "Manufacturing -> Transportation Equipment -> Motor Homes": "sic1=20&sic2=37&sic3=3716&sicl=3716&sich=3719", + "Manufacturing -> Transportation Equipment -> Aircraft & Parts": "sic1=20&sic2=37&sic3=3720&sicl=3720&sich=3720", + "Manufacturing -> Transportation Equipment -> Aircraft": "sic1=20&sic2=37&sic3=3721&sicl=3721&sich=3723", + "Manufacturing -> Transportation Equipment -> Aircraft Engines & Engine Parts": "sic1=20&sic2=37&sic3=3724&sicl=3724&sich=3727", + "Manufacturing -> Transportation Equipment -> Aircraft Parts & Auxiliary Equip": "sic1=20&sic2=37&sic3=3728&sicl=3728&sich=3729", + "Manufacturing -> Transportation Equipment -> Ship & Boat Building & Repairing": "sic1=20&sic2=37&sic3=3730&sicl=3730&sich=3742", + "Manufacturing -> Transportation Equipment -> Railroad Equipment": "sic1=20&sic2=37&sic3=3743&sicl=3743&sich=3750", + "Manufacturing -> Transportation Equipment -> Motorcycles, Bicycles & Parts": "sic1=20&sic2=37&sic3=3751&sicl=3751&sich=3759", + "Manufacturing -> Transportation Equipment -> Guided Missiles & Space Vehicles": "sic1=20&sic2=37&sic3=3760&sicl=3760&sich=3789", + "Manufacturing -> Transportation Equipment -> Miscellaneous Transportation Equ": "sic1=20&sic2=37&sic3=3790&sicl=3790&sich=3811", + "Manufacturing -> Specialty Instruments": "sic1=20&sic2=38&sicl=3800&sich=3899", + "Manufacturing -> Specialty Instruments -> Search, Detection, Navagation, G": "sic1=20&sic2=38&sic3=3812&sicl=3812&sich=3820", + "Manufacturing -> Specialty Instruments -> Laboratory Apparatus & Furniture": "sic1=20&sic2=38&sic3=3821&sicl=3821&sich=3821", + "Manufacturing -> Specialty Instruments -> Auto Controls For Regulating Res": "sic1=20&sic2=38&sic3=3822&sicl=3822&sich=3822", + "Manufacturing -> Specialty Instruments -> Industrial Instruments For Measu": "sic1=20&sic2=38&sic3=3823&sicl=3823&sich=3823", + "Manufacturing -> Specialty Instruments -> Totalizing Fluid & Counti": "sic1=20&sic2=38&sic3=3824&sicl=3824&sich=3824", + "Manufacturing -> Specialty Instruments -> Instruments For Meas & Testing o": "sic1=20&sic2=38&sic3=3825&sicl=3825&sich=3825", + "Manufacturing -> Specialty Instruments -> Laboratory Analytical Instrument": "sic1=20&sic2=38&sic3=3826&sicl=3826&sich=3826", + "Manufacturing -> Specialty Instruments -> Optical Instruments & Lenses": "sic1=20&sic2=38&sic3=3827&sicl=3827&sich=3828", + "Manufacturing -> Specialty Instruments -> Measuring & Controlling Devices": "sic1=20&sic2=38&sic3=3829&sicl=3829&sich=3840", + "Manufacturing -> Specialty Instruments -> Surgical & Medical Instruments &": "sic1=20&sic2=38&sic3=3841&sicl=3841&sich=3841", + "Manufacturing -> Specialty Instruments -> Orthopedic, Prosthetic & Surgica": "sic1=20&sic2=38&sic3=3842&sicl=3842&sich=3842", + "Manufacturing -> Specialty Instruments -> Dental Equipment & Supplies": "sic1=20&sic2=38&sic3=3843&sicl=3843&sich=3843", + "Manufacturing -> Specialty Instruments -> X-Ray Apparatus & Tubes & Relate": "sic1=20&sic2=38&sic3=3844&sicl=3844&sich=3844", + "Manufacturing -> Specialty Instruments -> Electromedical & Electrotherapeu": "sic1=20&sic2=38&sic3=3845&sicl=3845&sich=3850", + "Manufacturing -> Specialty Instruments -> Ophthalmic Goods": "sic1=20&sic2=38&sic3=3851&sicl=3851&sich=3860", + "Manufacturing -> Specialty Instruments -> Photographic Equipment & Supplie": "sic1=20&sic2=38&sic3=3861&sicl=3861&sich=3872", + "Manufacturing -> Specialty Instruments -> Watches, Clocks, Clockwork Opera": "sic1=20&sic2=38&sic3=3873&sicl=3873&sich=3909", + "Manufacturing -> Miscellaneous Manufacturing": "sic1=20&sic2=39&sic3=0&sicl=3900&sich=3999", + "Manufacturing -> Miscellaneous Manufacturing -> Jewelry, Silverware & Plated War": "sic1=20&sic2=39&sic3=3910&sicl=3910&sich=3910", + "Manufacturing -> Miscellaneous Manufacturing -> Jewelry, Precious Metal": "sic1=20&sic2=39&sic3=3911&sicl=3911&sich=3930", + "Manufacturing -> Miscellaneous Manufacturing -> Musical Instruments": "sic1=20&sic2=39&sic3=3931&sicl=3931&sich=3941", + "Manufacturing -> Miscellaneous Manufacturing -> Dolls & Stuffed Toys": "sic1=20&sic2=39&sic3=3942&sicl=3942&sich=3943", + "Manufacturing -> Miscellaneous Manufacturing -> Games, Toys & Children’s Vehicle": "sic1=20&sic2=39&sic3=3944&sicl=3944&sich=3948", + "Manufacturing -> Miscellaneous Manufacturing -> Sporting & Athletic Goods": "sic1=20&sic2=39&sic3=3949&sicl=3949&sich=3949", + "Manufacturing -> Miscellaneous Manufacturing -> Pens, Pencils & Other Artists’ M": "sic1=20&sic2=39&sic3=3950&sicl=3950&sich=3959", + "Manufacturing -> Miscellaneous Manufacturing -> Costumes Jewelry & Novelties": "sic1=20&sic2=39&sic3=3960&sicl=3960&sich=3989", + "Manufacturing -> Miscellaneous Manufacturing -> Miscellaneous Manufacturing Indu": "sic1=20&sic2=39&sic3=3990&sicl=3990&sich=4010", + "Transportation & Utilities": "sic1=40&sic2=0&sicl=4000&sich=4999", + "Transportation & Utilities -> Railroads": "sic1=40&sic2=40&sicl=4000&sich=4099", + "Transportation & Utilities -> Railroads -> Railroads, Line-Haul Operating": "sic1=40&sic2=40&sic3=4011&sicl=4011&sich=4012", + "Transportation & Utilities -> Railroads -> Railroad Switching & Terminal Es": "sic1=40&sic2=40&sic3=4013&sicl=4013&sich=4099", + "Transportation & Utilities -> Passenger Road Transportation": "sic1=40&sic2=41&sicl=4100&sich=4209", + "Transportation & Utilities -> Road Freight Transportation": "sic1=40&sic2=42&sic3=0&sicl=4200&sich=4299", + "Transportation & Utilities -> Road Freight Transportation -> Trucking & Courier Services (No": "sic1=40&sic2=42&sic3=4210&sicl=4210&sich=4212", + "Transportation & Utilities -> Road Freight Transportation -> Trucking (No Local)": "sic1=40&sic2=42&sic3=4213&sicl=4213&sich=4219", + "Transportation & Utilities -> Road Freight Transportation -> Public Warehousing & Storage": "sic1=40&sic2=42&sic3=4220&sicl=4220&sich=4230", + "Transportation & Utilities -> Road Freight Transportation -> Terminal Maintenance Facilities": "sic1=40&sic2=42&sic3=4231&sicl=4231&sich=4399", + "Transportation & Utilities -> USPS": "sic1=40&sic2=43&sicl=4300&sich=4399", + "Transportation & Utilities -> Water Transportation": "sic1=40&sic2=44&sic3=0&sicl=4400&sich=4499", + "Transportation & Utilities -> Water Transportation -> Water Transportation": "sic1=40&sic2=44&sic3=4400&sicl=4400&sich=4411", + "Transportation & Utilities -> Water Transportation -> Deep Sea Foreign Transportation": "sic1=40&sic2=44&sic3=4412&sicl=4412&sich=4511", + "Transportation & Utilities -> Air Transportation": "sic1=40&sic2=45&sic3=0&sicl=4500&sich=4599", + "Transportation & Utilities -> Air Transportation -> Air Transportation, Scheduled": "sic1=40&sic2=45&sic3=4512&sicl=4512&sich=4512", + "Transportation & Utilities -> Air Transportation -> Air Courier Services": "sic1=40&sic2=45&sic3=4513&sicl=4513&sich=4521", + "Transportation & Utilities -> Air Transportation -> Air Transportation, Nonscheduled": "sic1=40&sic2=45&sic3=4522&sicl=4522&sich=4580", + "Transportation & Utilities -> Air Transportation -> Airports, Flying Fields & Airpor": "sic1=40&sic2=45&sic3=4581&sicl=4581&sich=4609", + "Transportation & Utilities -> Pipelines": "sic1=40&sic2=46&sicl=4610&sich=4699", + "Transportation & Utilities -> Transportation Services": "sic1=40&sic2=47&sic3=0&sicl=4700&sich=4799", + "Transportation & Utilities -> Transportation Services -> Transportation Services": "sic1=40&sic2=47&sic3=4700&sicl=4700&sich=4730", + "Transportation & Utilities -> Transportation Services -> Arrangement of Transportation of": "sic1=40&sic2=47&sic3=4731&sicl=4731&sich=4811", + "Transportation & Utilities -> Communications": "sic1=40&sic2=48&sic3=0&sicl=4800&sich=4899", + "Transportation & Utilities -> Communications -> Radiotelephone Communications": "sic1=40&sic2=48&sic3=4812&sicl=4812&sich=4812", + "Transportation & Utilities -> Communications -> Telephone Communications (No Rad": "sic1=40&sic2=48&sic3=4813&sicl=4813&sich=4821", + "Transportation & Utilities -> Communications -> Telegraph & Other Message Commun": "sic1=40&sic2=48&sic3=4822&sicl=4822&sich=4831", + "Transportation & Utilities -> Communications -> Radio Broadcasting Stations": "sic1=40&sic2=48&sic3=4832&sicl=4832&sich=4832", + "Transportation & Utilities -> Communications -> Television Broadcasting Stations": "sic1=40&sic2=48&sic3=4833&sicl=4833&sich=4840", + "Transportation & Utilities -> Communications -> Cable & Other Pay Television Ser": "sic1=40&sic2=48&sic3=4841&sicl=4841&sich=4898", + "Transportation & Utilities -> Communications -> Communications Services": "sic1=40&sic2=48&sic3=4899&sicl=4899&sich=4899", + "Transportation & Utilities -> Electric, Gas, & Sanitary Svcs": "sic1=40&sic2=49&sic3=0&sicl=4900&sich=4999", + "Transportation & Utilities -> Electric, Gas, & Sanitary Svcs -> Electric, Gas, & Sanitary Svcs": "sic1=40&sic2=49&sic3=4900&sicl=4900&sich=4910", + "Transportation & Utilities -> Electric, Gas, & Sanitary Svcs -> Electric Services": "sic1=40&sic2=49&sic3=4911&sicl=4911&sich=4921", + "Transportation & Utilities -> Electric, Gas, & Sanitary Svcs -> Natural Gas Transmission": "sic1=40&sic2=49&sic3=4922&sicl=4922&sich=4922", + "Transportation & Utilities -> Electric, Gas, & Sanitary Svcs -> Natural Gas Transmission & Distr": "sic1=40&sic2=49&sic3=4923&sicl=4923&sich=4923", + "Transportation & Utilities -> Electric, Gas, & Sanitary Svcs -> Natural Gas Distribution": "sic1=40&sic2=49&sic3=4924&sicl=4924&sich=4930", + "Transportation & Utilities -> Electric, Gas, & Sanitary Svcs -> Electric & Other Services Combin": "sic1=40&sic2=49&sic3=4931&sicl=4931&sich=4931", + "Transportation & Utilities -> Electric, Gas, & Sanitary Svcs -> Gas & Other Services Combined": "sic1=40&sic2=49&sic3=4932&sicl=4932&sich=4940", + "Transportation & Utilities -> Electric, Gas, & Sanitary Svcs -> Water Supply": "sic1=40&sic2=49&sic3=4941&sicl=4941&sich=4949", + "Transportation & Utilities -> Electric, Gas, & Sanitary Svcs -> Sanitary Services": "sic1=40&sic2=49&sic3=4950&sicl=4950&sich=4952", + "Transportation & Utilities -> Electric, Gas, & Sanitary Svcs -> Refuse Systems": "sic1=40&sic2=49&sic3=4953&sicl=4953&sich=4954", + "Transportation & Utilities -> Electric, Gas, & Sanitary Svcs -> Hazardous Waste Management": "sic1=40&sic2=49&sic3=4955&sicl=4955&sich=4960", + "Transportation & Utilities -> Electric, Gas, & Sanitary Svcs -> Steam & Air-Conditioning Supply": "sic1=40&sic2=49&sic3=4961&sicl=4961&sich=4990", + "Transportation & Utilities -> Electric, Gas, & Sanitary Svcs -> Cogeneration Services & Small Po": "sic1=40&sic2=49&sic3=4991&sicl=4991&sich=4999", + "Wholesale Trade": "sic1=50&sic2=0&sicl=5000&sich=5199", + "Wholesale Trade -> Durable Goods -> Durable Goods": "sic1=50&sic2=50&sic3=5000&sicl=5000&sich=5009", + "Wholesale Trade -> Durable Goods -> Motor Vehicles & Motor Vehicle P": "sic1=50&sic2=50&sic3=5010&sicl=5010&sich=5012", + "Wholesale Trade -> Durable Goods -> Motor Vehicles Supplies & New Par": "sic1=50&sic2=50&sic3=5013&sicl=5013&sich=5019", + "Wholesale Trade -> Durable Goods -> Furniture & Home Furnishings": "sic1=50&sic2=50&sic3=5020&sicl=5020&sich=5029", + "Wholesale Trade -> Durable Goods -> Lumber & Other Construction Mate": "sic1=50&sic2=50&sic3=5030&sicl=5030&sich=5030", + "Wholesale Trade -> Durable Goods -> Lumber, Plywood, Millwork & Wood": "sic1=50&sic2=50&sic3=5031&sicl=5031&sich=5039", + "Wholesale Trade -> Durable Goods -> Professional & Commercial Equipm": "sic1=50&sic2=50&sic3=5040&sicl=5040&sich=5044", + "Wholesale Trade -> Durable Goods -> Computers & Peripheral Equipment": "sic1=50&sic2=50&sic3=5045&sicl=5045&sich=5046", + "Wholesale Trade -> Durable Goods -> Medical, Dental & Hospital Equip": "sic1=50&sic2=50&sic3=5047&sicl=5047&sich=5049", + "Wholesale Trade -> Durable Goods -> Metals & Minerals (No Petroleum)": "sic1=50&sic2=50&sic3=5050&sicl=5050&sich=5050", + "Wholesale Trade -> Durable Goods -> Metals Services Centers & Offices": "sic1=50&sic2=50&sic3=5051&sicl=5051&sich=5062", + "Wholesale Trade -> Durable Goods -> Electrical Apparatus & Equipment": "sic1=50&sic2=50&sic3=5063&sicl=5063&sich=5063", + "Wholesale Trade -> Durable Goods -> Electrical Appliances, Tv & Radi": "sic1=50&sic2=50&sic3=5064&sicl=5064&sich=5064", + "Wholesale Trade -> Durable Goods -> Electronic Parts & Equipment": "sic1=50&sic2=50&sic3=5065&sicl=5065&sich=5069", + "Wholesale Trade -> Durable Goods -> Hardware & Plumbing & Heating Eq": "sic1=50&sic2=50&sic3=5070&sicl=5070&sich=5071", + "Wholesale Trade -> Durable Goods -> Hardware": "sic1=50&sic2=50&sic3=5072&sicl=5072&sich=5079", + "Wholesale Trade -> Durable Goods -> Machinery, Equipment & Supplies": "sic1=50&sic2=50&sic3=5080&sicl=5080&sich=5081", + "Wholesale Trade -> Durable Goods -> Construction & Mining (No Petro)": "sic1=50&sic2=50&sic3=5082&sicl=5082&sich=5083", + "Wholesale Trade -> Durable Goods -> Industrial Machinery & Equipment": "sic1=50&sic2=50&sic3=5084&sicl=5084&sich=5089", + "Wholesale Trade -> Durable Goods -> Misc Durable Goods": "sic1=50&sic2=50&sic3=5090&sicl=5090&sich=5093", + "Wholesale Trade -> Durable Goods -> Jewelry, Watches, Precious Stone": "sic1=50&sic2=50&sic3=5094&sicl=5094&sich=5098", + # "Wholesale Trade -> Durable Goods -> Durable Goods": "sic1=50&sic2=50&sic3=5099&sicl=5099&sich=5109", + "Wholesale Trade -> Nondurable Goods": "sic1=50&sic2=51&sic3=0&sicl=5100&sich=5199", + "Wholesale Trade -> Nondurable Goods -> Paper & Paper Products": "sic1=50&sic2=51&sic3=5110&sicl=5110&sich=5121", + "Wholesale Trade -> Nondurable Goods -> Drugs, Proprietaries & Druggists": "sic1=50&sic2=51&sic3=5122&sicl=5122&sich=5129", + "Wholesale Trade -> Nondurable Goods -> Apparel, Piece Goods & Notions": "sic1=50&sic2=51&sic3=5130&sicl=5130&sich=5139", + "Wholesale Trade -> Nondurable Goods -> Groceries & Related Products": "sic1=50&sic2=51&sic3=5140&sicl=5140&sich=5140", + "Wholesale Trade -> Nondurable Goods -> Groceries, General Line": "sic1=50&sic2=51&sic3=5141&sicl=5141&sich=5149", + "Wholesale Trade -> Nondurable Goods -> Farm Product Raw Materials": "sic1=50&sic2=51&sic3=5150&sicl=5150&sich=5159", + "Wholesale Trade -> Nondurable Goods -> Chemicals & Allied Products": "sic1=50&sic2=51&sic3=5160&sicl=5160&sich=5170", + "Wholesale Trade -> Nondurable Goods -> Petroleum Bulk Stations & Termin": "sic1=50&sic2=51&sic3=5171&sicl=5171&sich=5171", + "Wholesale Trade -> Nondurable Goods -> Petroleum & Petroleum Products (": "sic1=50&sic2=51&sic3=5172&sicl=5172&sich=5179", + "Wholesale Trade -> Nondurable Goods -> Beer, Wine & Distilled Alcoholic": "sic1=50&sic2=51&sic3=5180&sicl=5180&sich=5189", + "Wholesale Trade -> Nondurable Goods -> Miscellaneous Nondurable Goods": "sic1=50&sic2=51&sic3=5190&sicl=5190&sich=5199", + "Retail Trade": "sic1=52&sic2=0&sicl=5200&sich=5999", + "Retail Trade -> Building Materials": "sic1=52&sic2=52&sic3=0&sicl=5200&sich=5299", + "Retail Trade -> Building Materials -> Building Materials, Hardware, Ga": "sic1=52&sic2=52&sic3=5200&sicl=5200&sich=5210", + "Retail Trade -> Building Materials -> Lumber & Other Buildings Material": "sic1=52&sic2=52&sic3=5211&sicl=5211&sich=5270", + "Retail Trade -> Building Materials -> Mobile Home Dealers": "sic1=52&sic2=52&sic3=5271&sicl=5271&sich=5310", + "Retail Trade -> General Merchandise": "sic1=52&sic2=53&sicl=5300&sich=5399", + "Retail Trade -> General Merchandise -> Department Stores": "sic1=52&sic2=53&sic3=5311&sicl=5311&sich=5330", + "Retail Trade -> General Merchandise -> Variety Stores": "sic1=52&sic2=53&sic3=5331&sicl=5331&sich=5398", + "Retail Trade -> General Merchandise -> Misc General Merchandise Stores": "sic1=52&sic2=53&sic3=5399&sicl=5399&sich=5399", + "Retail Trade -> Grocery": "sic1=52&sic2=54&sic3=0&sicl=5400&sich=5499", + "Retail Trade -> Grocery -> Food Stores": "sic1=52&sic2=54&sic3=5400&sicl=5400&sich=5410", + "Retail Trade -> Grocery -> Grocery Stores": "sic1=52&sic2=54&sic3=5411&sicl=5411&sich=5411", + "Retail Trade -> Grocery -> Convenience Stores": "sic1=52&sic2=54&sic3=5412&sicl=5412&sich=5499", + "Retail Trade -> Auto Dealers & Service Stations": "sic1=52&sic2=55&sic3=0&sicl=5500&sich=5599", + "Retail Trade -> Auto Dealers & Service Stations -> Auto Dealers & Gasoline Stations": "sic1=52&sic2=55&sic3=5500&sicl=5500&sich=5530", + "Retail Trade -> Auto Dealers & Service Stations -> Auto & Home Supply Stores": "sic1=52&sic2=55&sic3=5531&sicl=5531&sich=5599", + "Retail Trade -> Apparel & Accessory Stores": "sic1=52&sic2=56&sic3=0&sicl=5600&sich=5699", + "Retail Trade -> Apparel & Accessory Stores -> Apparel & Accessory Stores": "sic1=52&sic2=56&sic3=5600&sicl=5600&sich=5620", + "Retail Trade -> Apparel & Accessory Stores -> Women’s Clothing Stores": "sic1=52&sic2=56&sic3=5621&sicl=5621&sich=5650", + "Retail Trade -> Apparel & Accessory Stores -> Family Clothing Stores": "sic1=52&sic2=56&sic3=5651&sicl=5651&sich=5660", + "Retail Trade -> Apparel & Accessory Stores -> Shoe Stores": "sic1=52&sic2=56&sic3=5661&sicl=5661&sich=5699", + "Retail Trade -> Home Furniture": "sic1=52&sic2=57&sic3=0&sicl=5700&sich=5799", + "Retail Trade -> Home Furniture -> Home Furniture, Furnishings & Eq": "sic1=52&sic2=57&sic3=5700&sicl=5700&sich=5711", + "Retail Trade -> Home Furniture -> Furniture Stores": "sic1=52&sic2=57&sic3=5712&sicl=5712&sich=5730", + "Retail Trade -> Home Furniture -> Ratio, Tv & Consumer Electronics": "sic1=52&sic2=57&sic3=5731&sicl=5731&sich=5733", + "Retail Trade -> Home Furniture -> Computer & Computer Software Sto": "sic1=52&sic2=57&sic3=5734&sicl=5734&sich=5734", + "Retail Trade -> Home Furniture -> Record & Prerecord Tape Stores": "sic1=52&sic2=57&sic3=5735&sicl=5735&sich=5809", + "Retail Trade -> Eating & Drinking Places": "sic1=52&sic2=58&sic3=0&sicl=5800&sich=5899", + "Retail Trade -> Eating & Drinking Places -> Eating & Drinking Places": "sic1=52&sic2=58&sic3=5810&sicl=5810&sich=5811", + "Retail Trade -> Eating & Drinking Places -> Eating Places": "sic1=52&sic2=58&sic3=5812&sicl=5812&sich=5899", + "Retail Trade -> Miscellaneous Retail": "sic1=52&sic2=59&sic3=0&sicl=5900&sich=5999", + "Retail Trade -> Miscellaneous Retail -> Miscellaneous Retail": "sic1=52&sic2=59&sic3=5900&sicl=5900&sich=5911", + "Retail Trade -> Miscellaneous Retail -> Drug Stores & Proprietary Stores": "sic1=52&sic2=59&sic3=5912&sicl=5912&sich=5939", + "Retail Trade -> Miscellaneous Retail -> Miscellaneous Shopping Goods Sto": "sic1=52&sic2=59&sic3=5940&sicl=5940&sich=5943", + "Retail Trade -> Miscellaneous Retail -> Jewelry Stores": "sic1=52&sic2=59&sic3=5944&sicl=5944&sich=5944", + "Retail Trade -> Miscellaneous Retail -> Hobby, Toy & Game Shops": "sic1=52&sic2=59&sic3=5945&sicl=5945&sich=5959", + "Retail Trade -> Miscellaneous Retail -> Nonstore Retailers": "sic1=52&sic2=59&sic3=5960&sicl=5960&sich=5960", + "Retail Trade -> Miscellaneous Retail -> Catalog & Mail-Order Houses": "sic1=52&sic2=59&sic3=5961&sicl=5961&sich=5989", + "Retail Trade -> Miscellaneous Retail -> Retail Stores": "sic1=52&sic2=59&sic3=5990&sicl=5990&sich=6020", + "Financial": "sic1=60&sic2=0&sicl=6000&sich=6799", + "Financial -> Depository Institutions": "sic1=60&sic2=60&sicl=6000&sich=6099", + "Financial -> Depository Institutions -> National Commercial Banks": "sic1=60&sic2=60&sic3=6021&sicl=6021&sich=6021", + "Financial -> Depository Institutions -> State Commercial Banks": "sic1=60&sic2=60&sic3=6022&sicl=6022&sich=6028", + "Financial -> Depository Institutions -> Commercial Banks": "sic1=60&sic2=60&sic3=6029&sicl=6029&sich=6034", + "Financial -> Depository Institutions -> Savings Institution, Federally C": "sic1=60&sic2=60&sic3=6035&sicl=6035&sich=6035", + "Financial -> Depository Institutions -> Savings Institution, Not Federa": "sic1=60&sic2=60&sic3=6036&sicl=6036&sich=6098", + "Financial -> Depository Institutions -> Functions Related to Despository": "sic1=60&sic2=60&sic3=6099&sicl=6099&sich=6110", + "Financial -> Non-depository Credit Inst": "sic1=60&sic2=61&sic3=0&sicl=6100&sich=6199", + "Financial -> Non-depository Credit Inst -> Federal & Federally-Sponsored Cr": "sic1=60&sic2=61&sic3=6111&sicl=6111&sich=6140", + "Financial -> Non-depository Credit Inst -> Personal Credit Institutions": "sic1=60&sic2=61&sic3=6141&sicl=6141&sich=6152", + "Financial -> Non-depository Credit Inst -> Short-Term Business Credit Insti": "sic1=60&sic2=61&sic3=6153&sicl=6153&sich=6158", + "Financial -> Non-depository Credit Inst -> Miscellaneous Business Credit In": "sic1=60&sic2=61&sic3=6159&sicl=6159&sich=6161", + "Financial -> Non-depository Credit Inst -> Mortgage Bankers & Loan Correspo": "sic1=60&sic2=61&sic3=6162&sicl=6162&sich=6162", + "Financial -> Non-depository Credit Inst -> Loan Brokers": "sic1=60&sic2=61&sic3=6163&sicl=6163&sich=6171", + "Financial -> Non-depository Credit Inst -> Finance Lessors": "sic1=60&sic2=61&sic3=6172&sicl=6172&sich=6188", + "Financial -> Non-depository Credit Inst -> Asset-Backed Securities": "sic1=60&sic2=61&sic3=6189&sicl=6189&sich=6198", + "Financial -> Non-depository Credit Inst -> Finance Services": "sic1=60&sic2=61&sic3=6199&sicl=6199&sich=6199", + "Financial -> Security & Commodity Brokers": "sic1=60&sic2=62&sic3=0&sicl=6200&sich=6299", + "Financial -> Security & Commodity Brokers -> Security & Commodity Brokers, De": "sic1=60&sic2=62&sic3=6200&sicl=6200&sich=6210", + "Financial -> Security & Commodity Brokers -> Security Brokers, Dealers & Flot": "sic1=60&sic2=62&sic3=6211&sicl=6211&sich=6220", + "Financial -> Security & Commodity Brokers -> Commodity Contracts Brokers & De": "sic1=60&sic2=62&sic3=6221&sicl=6221&sich=6281", + "Financial -> Security & Commodity Brokers -> Investment Advice": "sic1=60&sic2=62&sic3=6282&sicl=6282&sich=6310", + "Financial -> Insurance Carriers": "sic1=60&sic2=63&sic3=0&sicl=6300&sich=6399", + "Financial -> Insurance Carriers -> Life Insurance": "sic1=60&sic2=63&sic3=6311&sicl=6311&sich=6320", + "Financial -> Insurance Carriers -> Accident & Health Insurance": "sic1=60&sic2=63&sic3=6321&sicl=6321&sich=6323", + "Financial -> Insurance Carriers -> Hospital & Medical Service Plans": "sic1=60&sic2=63&sic3=6324&sicl=6324&sich=6330", + "Financial -> Insurance Carriers -> Fire, Marine & Casualty Insuranc": "sic1=60&sic2=63&sic3=6331&sicl=6331&sich=6350", + "Financial -> Insurance Carriers -> Surety Insurance": "sic1=60&sic2=63&sic3=6351&sicl=6351&sich=6360", + "Financial -> Insurance Carriers -> Title Insurance": "sic1=60&sic2=63&sic3=6361&sicl=6361&sich=6398", + "Financial -> Insurance Carriers -> Insurance Carriers": "sic1=60&sic2=63&sic3=6399&sicl=6399&sich=6410", + "Financial -> Insurance Agents": "sic1=60&sic2=64&sicl=6411&sich=6499", + "Financial -> Real Estate": "sic1=60&sic2=65&sic3=0&sicl=6500&sich=6699", + "Financial -> Real Estate -> Real Estate": "sic1=60&sic2=65&sic3=6500&sicl=6500&sich=6509", + "Financial -> Real Estate -> Real Estate Operators (No Develo": "sic1=60&sic2=65&sic3=6510&sicl=6510&sich=6511", + "Financial -> Real Estate -> Operators of Nonresidential Buil": "sic1=60&sic2=65&sic3=6512&sicl=6512&sich=6512", + "Financial -> Real Estate -> Operators of Apartment Buildings": "sic1=60&sic2=65&sic3=6513&sicl=6513&sich=6518", + "Financial -> Real Estate -> Lessors of Real Property": "sic1=60&sic2=65&sic3=6519&sicl=6519&sich=6530", + "Financial -> Real Estate -> Real Estate Agents & Managers": "sic1=60&sic2=65&sic3=6531&sicl=6531&sich=6531", + "Financial -> Real Estate -> Real Estate Dealers (For Their O": "sic1=60&sic2=65&sic3=6532&sicl=6532&sich=6551", + "Financial -> Real Estate -> Land Subdividers & Developers (N": "sic1=60&sic2=65&sic3=6552&sicl=6552&sich=6769", + "Financial -> Holding & Investment Offices": "sic1=60&sic2=67&sic3=0&sicl=6700&sich=6999", + "Financial -> Holding & Investment Offices -> Blank Checks": "sic1=60&sic2=67&sic3=6770&sicl=6770&sich=6791", + "Financial -> Holding & Investment Offices -> Oil Royalty Traders": "sic1=60&sic2=67&sic3=6792&sicl=6792&sich=6793", + "Financial -> Holding & Investment Offices -> Patent Owners & Lessors": "sic1=60&sic2=67&sic3=6794&sicl=6794&sich=6794", + "Financial -> Holding & Investment Offices -> Mineral Royalty Traders": "sic1=60&sic2=67&sic3=6795&sicl=6795&sich=6797", + "Financial -> Holding & Investment Offices -> Real Estate Investment Trusts": "sic1=60&sic2=67&sic3=6798&sicl=6798&sich=6798", + "Financial -> Holding & Investment Offices -> Investors": "sic1=60&sic2=67&sic3=6799&sicl=6799&sich=6999", + "Services": "sic1=70&sic2=0&sicl=7000&sich=8999", + "Services -> Hotels": "sic1=70&sic2=70&sic3=0&sicl=7000&sich=7199", + "Services -> Hotels -> Hotels, Rooming Houses, Camps &": "sic1=70&sic2=70&sic3=7000&sicl=7000&sich=7010", + "Services -> Hotels -> Hotels & Motels": "sic1=70&sic2=70&sic3=7011&sicl=7011&sich=7199", + "Services -> Personal Services": "sic1=70&sic2=72&sicl=7200&sich=7309", + "Services -> Business Services": "sic1=70&sic2=73&sic3=0&sicl=7300&sich=7499", + "Services -> Business Services -> Advertising": "sic1=70&sic2=73&sic3=7310&sicl=7310&sich=7310", + "Services -> Business Services -> Advertising Agencies": "sic1=70&sic2=73&sic3=7311&sicl=7311&sich=7319", + "Services -> Business Services -> Consumer Credit Reporting, Colle": "sic1=70&sic2=73&sic3=7320&sicl=7320&sich=7329", + "Services -> Business Services -> Mailing, Reproduction, Commercia": "sic1=70&sic2=73&sic3=7330&sicl=7330&sich=7330", + "Services -> Business Services -> Direct Mail Advertising Services": "sic1=70&sic2=73&sic3=7331&sicl=7331&sich=7339", + "Services -> Business Services -> To Dwellings & Other Buildings": "sic1=70&sic2=73&sic3=7340&sicl=7340&sich=7349", + "Services -> Business Services -> Miscellaneous Equipment Rental &": "sic1=70&sic2=73&sic3=7350&sicl=7350&sich=7358", + "Services -> Business Services -> Equipment Rental & Leasing": "sic1=70&sic2=73&sic3=7359&sicl=7359&sich=7360", + "Services -> Business Services -> Employment Agencies": "sic1=70&sic2=73&sic3=7361&sicl=7361&sich=7362", + "Services -> Business Services -> Help Supply Services": "sic1=70&sic2=73&sic3=7363&sicl=7363&sich=7369", + "Services -> Business Services -> Computer Programming, Data Proce": "sic1=70&sic2=73&sic3=7370&sicl=7370&sich=7370", + "Services -> Business Services -> Computer Programming Services": "sic1=70&sic2=73&sic3=7371&sicl=7371&sich=7371", + "Services -> Business Services -> Prepackaged Software": "sic1=70&sic2=73&sic3=7372&sicl=7372&sich=7372", + "Services -> Business Services -> Computer Integrated Systems Desi": "sic1=70&sic2=73&sic3=7373&sicl=7373&sich=7373", + "Services -> Business Services -> Computer Processing & Data Prepa": "sic1=70&sic2=73&sic3=7374&sicl=7374&sich=7376", + "Services -> Business Services -> Computer Rental & Leasing": "sic1=70&sic2=73&sic3=7377&sicl=7377&sich=7379", + "Services -> Business Services -> Miscellaneous Business Services": "sic1=70&sic2=73&sic3=7380&sicl=7380&sich=7380", + "Services -> Business Services -> Detective, Guard & Armored Car S": "sic1=70&sic2=73&sic3=7381&sicl=7381&sich=7383", + "Services -> Business Services -> Photofinishing Laboratories": "sic1=70&sic2=73&sic3=7384&sicl=7384&sich=7384", + "Services -> Business Services -> Telephone Interconnect Systems": "sic1=70&sic2=73&sic3=7385&sicl=7385&sich=7388", + "Services -> Business Services -> Business Services": "sic1=70&sic2=73&sic3=7389&sicl=7389&sich=7499", + "Services -> Automotive Repair": "sic1=70&sic2=75&sic3=0&sicl=7500&sich=7599", + "Services -> Automotive Repair -> Automotive Repair, Services & Pa": "sic1=70&sic2=75&sic3=7500&sicl=7500&sich=7509", + "Services -> Automotive Repair -> Auto Rental & Leasing (No Driver": "sic1=70&sic2=75&sic3=7510&sicl=7510&sich=7599", + "Services -> Miscellaneous Repair": "sic1=70&sic2=76&sicl=7600&sich=7811", + "Services -> Motion Pictures": "sic1=70&sic2=78&sic3=0&sicl=7800&sich=7899", + "Services -> Motion Pictures -> Motion Picture & Video Tape Prod": "sic1=70&sic2=78&sic3=7812&sicl=7812&sich=7818", + "Services -> Motion Pictures -> Allied to Motion Picture Product": "sic1=70&sic2=78&sic3=7819&sicl=7819&sich=7821", + "Services -> Motion Pictures -> Motion Picture & Video Tape Dist": "sic1=70&sic2=78&sic3=7822&sicl=7822&sich=7828", + "Services -> Motion Pictures -> Allied to Motion Picture Distrib": "sic1=70&sic2=78&sic3=7829&sicl=7829&sich=7829", + "Services -> Motion Pictures -> Motion Picture Theaters": "sic1=70&sic2=78&sic3=7830&sicl=7830&sich=7840", + "Services -> Motion Pictures -> Video Tape Rental": "sic1=70&sic2=78&sic3=7841&sicl=7841&sich=7899", + "Services -> Amusement & Rec Svcs": "sic1=70&sic2=79&sic3=0&sicl=7900&sich=7999", + "Services -> Amusement & Rec Svcs -> Amusement Recreation Services": "sic1=70&sic2=79&sic3=7900&sicl=7900&sich=7947", + "Services -> Amusement & Rec Svcs -> Racing, Including Track Operatio": "sic1=70&sic2=79&sic3=7948&sicl=7948&sich=7989", + "Services -> Amusement & Rec Svcs -> Miscellaneous Amusement & Recrea": "sic1=70&sic2=79&sic3=7990&sicl=7990&sich=7996", + "Services -> Amusement & Rec Svcs -> Membership Sports & Recreation C": "sic1=70&sic2=79&sic3=7997&sicl=7997&sich=7999", + "Services -> Health Services": "sic1=70&sic2=80&sic3=0&sicl=8000&sich=8099", + "Services -> Health Services -> Health Services": "sic1=70&sic2=80&sic3=8000&sicl=8000&sich=8010", + "Services -> Health Services -> Offices & Clinics of Doctors of": "sic1=70&sic2=80&sic3=8011&sicl=8011&sich=8049", + "Services -> Health Services -> Nursing & Personal Care Faciliti": "sic1=70&sic2=80&sic3=8050&sicl=8050&sich=8050", + "Services -> Health Services -> Skilled Nursing Care Facilities": "sic1=70&sic2=80&sic3=8051&sicl=8051&sich=8059", + "Services -> Health Services -> Hospitals": "sic1=70&sic2=80&sic3=8060&sicl=8060&sich=8061", + "Services -> Health Services -> General Medical & Surgical Hospi": "sic1=70&sic2=80&sic3=8062&sicl=8062&sich=8070", + "Services -> Health Services -> Medical Laboratories": "sic1=70&sic2=80&sic3=8071&sicl=8071&sich=8081", + "Services -> Health Services -> Home Health Care Services": "sic1=70&sic2=80&sic3=8082&sicl=8082&sich=8089", + "Services -> Health Services -> Misc Health & Allied Services": "sic1=70&sic2=80&sic3=8090&sicl=8090&sich=8092", + "Services -> Health Services -> Specialty Outpatient Facilities": "sic1=70&sic2=80&sic3=8093&sicl=8093&sich=8110", + "Services -> Legal Services": "sic1=70&sic2=81&sicl=8111&sich=8199", + "Services -> Educational Services": "sic1=70&sic2=82&sicl=8200&sich=8299", + "Services -> Social Services": "sic1=70&sic2=83&sic3=0&sicl=8300&sich=8399", + "Services -> Social Services -> Social Services": "sic1=70&sic2=83&sic3=8300&sicl=8300&sich=8350", + "Services -> Social Services -> Child Day Care Services": "sic1=70&sic2=83&sic3=8351&sicl=8351&sich=8599", + "Services -> Museums": "sic1=70&sic2=84&sicl=8400&sich=8599", + "Services -> Membership Organizations": "sic1=70&sic2=86&sicl=8600&sich=8699", + "Services -> Engr, Acct, Rsrch, Mgmt Svcs": "sic1=70&sic2=87&sic3=0&sicl=8700&sich=8899", + "Services -> Engr, Acct, Rsrch, Mgmt Svcs -> Engineering, Accounting, Research": "sic1=70&sic2=87&sic3=8700&sicl=8700&sich=8710", + "Services -> Engr, Acct, Rsrch, Mgmt Svcs -> Engineering Services": "sic1=70&sic2=87&sic3=8711&sicl=8711&sich=8730", + "Services -> Engr, Acct, Rsrch, Mgmt Svcs -> Commercial Physical & Biological": "sic1=70&sic2=87&sic3=8731&sicl=8731&sich=8733", + "Services -> Engr, Acct, Rsrch, Mgmt Svcs -> Testing Laboratories": "sic1=70&sic2=87&sic3=8734&sicl=8734&sich=8740", + "Services -> Engr, Acct, Rsrch, Mgmt Svcs -> Management Services": "sic1=70&sic2=87&sic3=8741&sicl=8741&sich=8741", + "Services -> Engr, Acct, Rsrch, Mgmt Svcs -> Management Consulting Services": "sic1=70&sic2=87&sic3=8742&sicl=8742&sich=8743", + "Services -> Engr, Acct, Rsrch, Mgmt Svcs -> Facilities Support Management Se": "sic1=70&sic2=87&sic3=8744&sicl=8744&sich=8879", + "Services -> Miscellaneous Services": "sic1=70&sic2=89&sicl=8900&sich=9720", + "Closed-End Funds": "sic1=0&sicl=0&sich=99", +} diff --git a/gamestonk_terminal/insider/presets/whales.ini b/gamestonk_terminal/stocks/insider/presets/whales.ini similarity index 99% rename from gamestonk_terminal/insider/presets/whales.ini rename to gamestonk_terminal/stocks/insider/presets/whales.ini index 4d3ab3ae9b3..f6ef2296a0b 100644 --- a/gamestonk_terminal/insider/presets/whales.ini +++ b/gamestonk_terminal/stocks/insider/presets/whales.ini @@ -62,7 +62,7 @@ COO = CFO = GC = VP = -# 'Officer' inclues all of the above: COB, CEO, Pres, COO, CFO, GC, VP +# 'Officer' includes all of the above: COB, CEO, Pres, COO, CFO, GC, VP Officer = Director = 10PctOwn = diff --git a/gamestonk_terminal/stocks/prediction_techniques/README.md b/gamestonk_terminal/stocks/prediction_techniques/README.md new file mode 100644 index 00000000000..ff7369ac9dd --- /dev/null +++ b/gamestonk_terminal/stocks/prediction_techniques/README.md @@ -0,0 +1,262 @@ +# PREDICTION TECHNIQUES + +This menu aims to predict the share price of a pre-loaded stock, and the usage of the following commands along with an example will be exploited below. See [How to fune-tuning a NN model](FUNE-TUNING-NN-models.md). + + * [ets](#ets) + - Exponential Smoothing (e.g. Holt-Winters) + * [knn](#knn) + - k-Nearest Neighbors + * [linear](#linear) + - linear regression (polynomial 1) + * [quadratic](#quadratic) + - quadratic regression (polynomial 2) + * [cubic](#cubic) + - cubic regression (polynomial 3) + * [regression](#regression) + - regression (other polynomial) + * [arima](#arima) + - autoregressive integrated moving average + * [mlp](#mlp) + - MultiLayer Perceptron + * [rnn](#rnn) + - Recurrent Neural Network + - Contains a [looping example](#looping) + * [lstm](#lstm) + - Long-Short Term Memory + - Contains a [backtesting example](#backtesting) + * [conv1d](#conv1d) + - 1D Convolutional Neural Net + +**Note:** _Use this at your own discretion. All of these prediciton techniques rely solely on the closing price of the stock. This means that there are several factors that the models aren't aware of at the time of prediction, and may - drastically - move the price up or down. Examples are: news, analyst price targets, reddit post, tweets from Elon Musk, and so on._ + +**Note 2:** _[Enabling GPU acceleration for TensorFlow requires CUDA setup](README-gpu-accel.md) and will probably not provide any speedup unless you are building large custom models._ + + + +## ets +``` +usage: ets [-t TREND] [-s SEASONAL] [-p SEASONAL_PERIODS] [-d N_DAYS] +``` +Exponential Smoothing (based on trend+seasonality, see https://otexts.com/fpp2/taxonomy.html): + * -t : trend component: N: None, A: Additive, Ad: Additive Damped. Default N. + * -s : seasonality component: N: None, A: Additive, M: Multiplicative. Default N. + * -p : seasonal periods. Default 5. + * -d : prediction days. Default 5. + * -e : end date (format YYYY-MM-DD) of the stock - Backtesting. Default None. + +![ets_pltr](https://user-images.githubusercontent.com/25267873/110266847-97a6d280-7fb6-11eb-997e-0b598abc713b.png) + +## knn +``` +usage: knn [-i N_INPUTS] [-d N_DAYS] [-n N_NEIGHBORS] +``` +k-Nearest Neighbors: + * -i : number of days to use for prediction. Default 40. + * -d : prediction days. Default 5. + * -n : number of neighbors to use on the algorithm. Default 20. + * -e : end date (format YYYY-MM-DD) of the stock - Backtesting. Default None. + +![knn](https://user-images.githubusercontent.com/25267873/108604942-d169bd80-73a8-11eb-9021-6f787cbd41e3.png) + +## linear +``` +usage: linear [-i N_INPUTS] [-d N_DAYS] +usage: regression -p 1 [-i N_INPUTS] [-d N_DAYS] +``` +Linear Regression (p=1): + * -i : number of days to use for prediction. Default 40. + * -d : prediction days. Default 5. + * -e : end date (format YYYY-MM-DD) of the stock - Backtesting. Default None. + +![linear](https://user-images.githubusercontent.com/25267873/108604948-d3cc1780-73a8-11eb-860f-49274a34038b.png) + +## quadratic +``` +usage: quadratic [-i N_INPUTS] [-d N_DAYS] +usage: regression -p 2 [-i N_INPUTS] [-d N_DAYS] +``` +Quadratic Regression (p=2): + * -i : number of days to use for prediction. Default 40. + * -d : prediction days. Default 5. + * -e : end date (format YYYY-MM-DD) of the stock - Backtesting. Default None. + +![quadratic](https://user-images.githubusercontent.com/25267873/108604935-cca50980-73a8-11eb-9af1-bba807203cc6.png) + +## cubic +``` +usage: cubic [-i N_INPUTS] [-d N_DAYS] +usage: regression -p 3 [-i N_INPUTS] [-d N_DAYS] +``` +Cubic Regression (p=3): + * -i : number of days to use for prediction. Default 40. + * -d : prediction days. Default 5. + * -e : end date (format YYYY-MM-DD) of the stock - Backtesting. Default None. + +![cubic](https://user-images.githubusercontent.com/25267873/108604941-d169bd80-73a8-11eb-9220-84a7013e1283.png) + +## regression +``` +usage: regression -p N_POLYNOMIAL [-i N_INPUTS] [-d N_DAYS] +``` +Regression: + * -i : number of days to use for prediction. Default 40. + * -d : prediction days. Default 5. + * -p : polynomial associated with regression. Required. + * -e : end date (format YYYY-MM-DD) of the stock - Backtesting. Default None. + +![regression](https://user-images.githubusercontent.com/25267873/108604946-d3338100-73a8-11eb-9e99-fa526fb56672.png) + +## arima +``` +usage: arima [-d N_DAYS] [-i {aic,aicc,bic,hqic,oob}] [-s] [-r] [-o S_ORDER] +``` +Auto-Regressive Integrated Moving Average: + * -d : prediciton days. Default 5. + * -i : information criteria - used if auto_arima library is invoked. Default aic. + * -s : weekly seasonality flag. Default False. + * -r : results about ARIMA summary flag. Default False. + * -o : arima model order. If the model order is defined, auto_arima is not invoked, deeming information criteria useless.
Example: `-o 5,1,4` where: + * p = 5 : order (number of time lags) of the autoregressive model. + * d = 1 : degree of differencing (the number of times the data have had past values subtracted). + * q = 4 : order of the moving-average model. + * -e : end date (format YYYY-MM-DD) of the stock - Backtesting. Default None. + +![arima](https://user-images.githubusercontent.com/25267873/108604947-d3cc1780-73a8-11eb-9dbb-53b959ae7947.png) + +## mlp +``` +usage: mlp [-d N_DAYS] [-i N_INPUTS] [--epochs N_EPOCHS] [-e S_END_DATE] [--loops N_LOOPS] [-v VALID] + [--lr LEARNING_RATE] [--no_shuffle] +``` +MulitLayer Perceptron: + * -d : prediciton days. Default 5. + * -i : number of days to use for prediction. Default 40. + * --epochs : number of training epochs. Default 200. + * -v : validation split. Default 0.1 + * -e : end date (format YYYY-MM-DD) of the stock - Backtesting. Default None. + * --xla_cpu: if present, will enable XLA for CPU (overrides environment variables during run). + * --xla_gpu: if present, will enable XLA for GPU (overrides environment variables during run). + * --force_allow_gpu_growth: if true, will force TensorFlow to allow GPU memory usage to grow as needed. Otherwise will allocate 100% of available GPU memory when CUDA is set up. Default true. + * --batch_size: batch size for model training, should not be used unless advanced user. Default None. + * --lr : learning rate for optimizer + * --loops: number of loops to iterate and train models. Default 1. + * --no_shuffle : split validation data in time_ordered way instead of random. + +Due to the complexity of defining a model through command line, one can define it in: [config_neural_network_models.txt](/config_neural_network_models.py) +``` +MultiLayer_Perceptron \ + = [ {'Dense': + {'units':50, 'activation':'relu'} }, + {'Dense': + {'units':100, 'activation':'relu'} }, + {'Dense': + {'units':80, 'activation':'relu'} }, + {'Dense': + {'units':30, 'activation':'relu'} }, + {'Dense': + {'activation':'relu'} }] +``` + +![mlp](https://user-images.githubusercontent.com/25267873/108604944-d2025400-73a8-11eb-9ab6-52972160cd2a.png) + +## rnn +``` +usage: rnn [-d N_DAYS] [-i N_INPUTS] [--epochs N_EPOCHS] [-p {normalization,standardization,none}] + [-l {mae,mape,mse,msle}] [-e S_END_DATE] [--loops N_LOOPS] [-v VALID] [--lr LEARNING_RATE] [--no_shuffle] +``` +Recurrent Neural Network: + * -d : prediciton days. Default 5. + * -i : number of days to use for prediction. Default 40. + * --epochs : number of training epochs. Default 200. + * -v : validation split. Default 0.1 + * -e : end date (format YYYY-MM-DD) of the stock - Backtesting. Default None. + * --xla_cpu: if present, will enable XLA for CPU (overrides environment variables during run). + * --xla_gpu: if present, will enable XLA for GPU (overrides environment variables during run). + * --force_allow_gpu_growth: if true, will force TensorFlow to allow GPU memory usage to grow as needed. Otherwise will allocate 100% of available GPU memory when CUDA is set up. Default true. + * --batch_size: batch size for model training, should not be used unless advanced user. Default None. + * --loops: number of loops to iterate and train models. Default 1. + * --lr : learning rate for optimizer + * --no_shuffle : split validation data in time_ordered way instead of random. + +Due to the complexity of defining a model through command line, one can define it in: [config_neural_network_models.txt](/config_neural_network_models.py) +``` +Recurrent_Neural_Network \ + = [ {'SimpleRNN': + {'units':100, 'activation':'linear', 'return_sequences':True} }, + {'SimpleRNN': + {'units':50, 'activation':'linear', 'return_sequences':True} }, + {'Dropout': + {'rate':0.2} }, + {'SimpleRNN': + {'units':21, 'activation':'linear', 'return_sequences':False} }, + {'Dense': + {'activation':'relu'} }] +``` + +![rnn](https://user-images.githubusercontent.com/25267873/108604940-d0d12700-73a8-11eb-837e-a5aa128942d9.png) + +### Looping Example + +![loops](https://user-images.githubusercontent.com/25267873/111932423-479b3600-8ab5-11eb-9d0b-7210d5f02e83.png) + +Captura de ecrã 2021-03-22, às 02 14 38 + + +## lstm +``` +usage: lstm [-d N_DAYS] [-i N_INPUTS] [--epochs N_EPOCHS] [-e S_END_DATE] [--loops N_LOOPS] [-v VALID] + [--lr LEARNING_RATE] [--no_shuffle] +``` +Long-Short Term Memory: + * -d : prediction days. Default 5. + * -i : number of days to use for prediction. Default 40. + * --epochs : number of training epochs. Default 200. + * -v : validation split. Default 0.1 + * -e : end date (format YYYY-MM-DD) of the stock - Backtesting. Default None. + * --xla_cpu: if present, will enable XLA for CPU (overrides environment variables during run). + * --xla_gpu: if present, will enable XLA for GPU (overrides environment variables during run). + * --force_allow_gpu_growth: if true, will force TensorFlow to allow GPU memory usage to grow as needed. Otherwise will allocate 100% of available GPU memory when CUDA is set up. Default true. + * --batch_size: batch size for model training, should not be used unless advanced user. Default None. + * --loops: number of loops to iterate and train models. Default 1 + * --lr : learning rate for optimizer + * --no_shuffle : split validation data in time_ordered way instead of random. + +Due to the complexity of defining a model through command line, one can define it in: [config_neural_network_models.py](/config_neural_network_models.py) +``` +Long_Short_Term_Memory \ + = [ {'LSTM': + {'units':25, 'activation':'tanh', 'return_sequences':True} }, + {'LSTM': + {'units':15, 'activation':'tanh', 'return_sequences':False} }, + {'Dense': + {'activation':'relu'} }] +``` + +![lstm](https://user-images.githubusercontent.com/25267873/108604943-d2025400-73a8-11eb-83c5-edb4a2121cba.png) + +### Backtesting Example + +![appl_pred](https://user-images.githubusercontent.com/25267873/111053156-4173dc80-8459-11eb-9fcb-e81211961743.png) + +![apple_error](https://user-images.githubusercontent.com/25267873/111053157-420c7300-8459-11eb-8c37-fb1b5208d635.png) + +Captura de ecrã 2021-03-14, às 00 06 51 + +## conv1d +``` +usage: lstm [-d N_DAYS] [-i N_INPUTS] [--epochs N_EPOCHS] [-e S_END_DATE] [--loops N_LOOPS] [-v VALID] +[--lr LEARNING_RATE] [--no_shuffle] +``` +1D Convolutional Neural Net: + * -d : prediction days. Default 5. + * -i : number of days to use for prediction. Default 40. + * --epochs : number of training epochs. Default 50. + * -v : validation split. Default 0.1 + * -e : end date (format YYYY-MM-DD) of the stock - Backtesting. Default None. + * --xla_cpu: if present, will enable XLA for CPU (overrides environment variables during run). + * --xla_gpu: if present, will enable XLA for GPU (overrides environment variables during run). + * --force_allow_gpu_growth: if true, will force TensorFlow to allow GPU memory usage to grow as needed. Otherwise will allocate 100% of available GPU memory when CUDA is set up. Default true. + * --batch_size: batch size for model training, should not be used unless advanced user. Default None. + * --loops: number of loops to iterate and train models. Default 1. + * --lr : learning rate for optimizer + * --no_shuffle : split validation data in time_ordered way instead of random. diff --git a/gamestonk_terminal/stocks/prediction_techniques/__init__.py b/gamestonk_terminal/stocks/prediction_techniques/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/gamestonk_terminal/prediction_techniques/pred_controller.py b/gamestonk_terminal/stocks/prediction_techniques/pred_controller.py similarity index 97% rename from gamestonk_terminal/prediction_techniques/pred_controller.py rename to gamestonk_terminal/stocks/prediction_techniques/pred_controller.py index f91843206f9..0397b9d4c2c 100644 --- a/gamestonk_terminal/prediction_techniques/pred_controller.py +++ b/gamestonk_terminal/stocks/prediction_techniques/pred_controller.py @@ -12,7 +12,7 @@ from prompt_toolkit.completion import NestedCompleter from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.helper_funcs import get_flair from gamestonk_terminal.menu import session -from gamestonk_terminal.prediction_techniques import ( +from gamestonk_terminal.common.prediction_techniques import ( arima_view, ets_view, knn_view, @@ -205,11 +205,11 @@ def menu(ticker: str, start: datetime, interval: str, stock: pd.DataFrame): {c: None for c in pred_controller.CHOICES} ) an_input = session.prompt( - f"{get_flair()} (pred)> ", + f"{get_flair()} (stocks)>(pred)> ", completer=completer, ) else: - an_input = input(f"{get_flair()} (pred)> ") + an_input = input(f"{get_flair()} (stocks)>(pred)> ") try: plt.close("all") diff --git a/gamestonk_terminal/stocks/report/README.md b/gamestonk_terminal/stocks/report/README.md new file mode 100644 index 00000000000..0e88202ac37 --- /dev/null +++ b/gamestonk_terminal/stocks/report/README.md @@ -0,0 +1,45 @@ +# PAPERMILL + +This menu has a different concept from remaining menus. It has 2 main goals: + - Generate a personalised report. + - Allow the user to write notes on that notebook (report), as if it was his personal investment diary. + +Command | Template | Example +------ | --------|---- +`dd` | [Due Diligence Template](/notebooks/templates/due_diligence.ipynb) | [Due Diligence Example](/notebooks/examples/aapl_due_diligence_20210729_001048.html) +`econ` | [Economy Template](/notebooks/templates/econ_data.ipynb) | [Economy Example](/notebooks/examples/econ_data_20210729_001227.html) +`dp` | [Dark Pool](/notebooks/templates/dark_pool.ipynb) | [Dark Pool](/notebooks/examples/amc_dark_pool_20210728_235316.html) +`cm` | [Crypto Market](/notebooks/templates/crypto_market.ipynb) | [Crypto Market](/notebooks/examples/crypto_market_20210729_001530.html) + + +## How to run the report + +1. In [config_terminal](/gamestonk_terminal/config_terminal.py) you may need to change your `PAPERMILL_NOTEBOOK_REPORT_PORT` from `8888`. If the notebook generation fails, it is likely that the port selected is not the correct one. + +2. Start the terminal with `python terminal.py` + +3. Select `mill` and select one of the available reports generation, e.g. `econ` + +4. This should prompt you with a filled notebok with name: `report_name_date_time.ipynb`. E.g. `econ_data_20210725_193517.ipynb` + +5. Due to the last cell of the notebook, the report is saved by default as `.html`. E.g. `econ_data_20210725_193517.html` +``` +folder = "notebooks/reports/" +extension = ".ipynb" +!jupyter nbconvert {folder + report_name + extension} --to html --no-input +``` + +6. You can now write your own personal notes on the notebook. By doing: + * Click on the notebook cell that you are interested in writing your notes + * On the toolbar click on "+" to add a new cell + * On the tooblar click on "Cell" -> "Cell Type" -> "Markdown" + * You're now ready to write your own notes + +6. Once you're happy with your report, you can either: + * Re-run the last cell (potentially changing output from `.html` with: + ``` + folder = "notebooks/reports/" + extension = ".ipynb" + !jupyter nbconvert {folder + report_name + extension} --to html --no-input + ``` + * Or, on the toolbar click on "File" -> "Download as" -> Select your preferred option (e.g. HTML) diff --git a/gamestonk_terminal/stocks/report/__init__.py b/gamestonk_terminal/stocks/report/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/gamestonk_terminal/papermill/dark_pool_view.py b/gamestonk_terminal/stocks/report/dark_pool_view.py similarity index 100% rename from gamestonk_terminal/papermill/dark_pool_view.py rename to gamestonk_terminal/stocks/report/dark_pool_view.py diff --git a/gamestonk_terminal/papermill/due_diligence_view.py b/gamestonk_terminal/stocks/report/due_diligence_view.py similarity index 100% rename from gamestonk_terminal/papermill/due_diligence_view.py rename to gamestonk_terminal/stocks/report/due_diligence_view.py diff --git a/gamestonk_terminal/papermill/papermill_controller.py b/gamestonk_terminal/stocks/report/report_controller.py similarity index 63% rename from gamestonk_terminal/papermill/papermill_controller.py rename to gamestonk_terminal/stocks/report/report_controller.py index 6416775d019..3558d70d2df 100644 --- a/gamestonk_terminal/papermill/papermill_controller.py +++ b/gamestonk_terminal/stocks/report/report_controller.py @@ -5,31 +5,41 @@ import argparse import os from typing import List import subprocess - -from gamestonk_terminal.papermill import ( - crypto_market_view, +from prompt_toolkit.completion import NestedCompleter +from gamestonk_terminal.stocks.report import ( dark_pool_view, due_diligence_view, - econ_data_view, ) +from gamestonk_terminal import feature_flags as gtff +from gamestonk_terminal.menu import session from gamestonk_terminal.helper_funcs import get_flair from gamestonk_terminal import config_terminal # pylint: disable=R1732 -class PapermillController: - """Papermill Controller class""" +class ReportController: + """Report Controller class""" + + CHOICES = [ + "cls", + "?", + "help", + "q", + "quit", + ] + + CHOICES_COMMANDS = ["dp", "dd"] + + CHOICES += CHOICES_COMMANDS def __init__(self): """Constructor""" - self.papermill_parser = argparse.ArgumentParser( - add_help=False, prog="papermill" - ) - self.papermill_parser.add_argument( + self.report_parser = argparse.ArgumentParser(add_help=False, prog="report") + self.report_parser.add_argument( "cmd", - choices=["cls", "?", "help", "q", "quit", "dd", "econ", "dp", "cm"], + choices=self.CHOICES, ) def switch(self, an_input: str, proc: subprocess.Popen): @@ -55,13 +65,11 @@ class PapermillController: print("") return None - (known_args, other_args) = self.papermill_parser.parse_known_args( - an_input.split() - ) + (known_args, other_args) = self.report_parser.parse_known_args(an_input.split()) # Help menu again if known_args.cmd == "?": - print_papermill() + print_help() return None # Clear screen @@ -75,7 +83,7 @@ class PapermillController: def call_help(self, *_): """Process Help command""" - print_papermill() + print_help() def call_q(self, _, proc): """Process Q command - quit the menu""" @@ -87,45 +95,35 @@ class PapermillController: proc.kill() return True - def call_dd(self, other_args: List[str], _): - """Process DD command""" - due_diligence_view.due_diligence_report(other_args) - - def call_econ(self, other_args: List[str], _): - """Process Econ command""" - econ_data_view.economy_data_report(other_args) - def call_dp(self, other_args: List[str], _): - """Process DP command""" + """Process dp command""" dark_pool_view.dark_pool_report(other_args) - def call_cm(self, other_args: List[str], _): - """Process CM command""" - crypto_market_view.crypto_market_report(other_args) + def call_dd(self, other_args: List[str], _): + """Process dd command""" + due_diligence_view.due_diligence_report(other_args) -def print_papermill(): +def print_help(): """Print help""" print( - "https://github.com/GamestonkTerminal/GamestonkTerminal/tree/main/gamestonk_terminal/papermill" + "https://github.com/GamestonkTerminal/GamestonkTerminal/tree/main/gamestonk_terminal/stocks/report" ) - print("\nPapermill Reports:") + print("\nReports:") print(" cls clear screen") print(" ?/help show this menu again") print(" q quit this menu, and shows back to main menu") print(" quit quit to abandon program") print("") - print(" dd generate DUE DILIGENCE report") - print(" econ generate ECONOMIC DATA summary") - print(" dp generate DARK POOL report") - print(" cm generate CRYPTO MARKET report") + print(" dp generate dark pool report") + print(" dd generate due diligence report") print("") -def papermill_menu(): - """Papermill Menu""" - pc = PapermillController() - print_papermill() +def menu(): + """Report Menu""" + report_controller = ReportController() + report_controller.call_help(None) # Initialize jupyter notebook cmd = f"jupyter notebook --port={config_terminal.PAPERMILL_NOTEBOOK_REPORT_PORT}" @@ -135,10 +133,19 @@ def papermill_menu(): while True: # Get input command from user - an_input = input(f"{get_flair()} (mill)> ") + if session and gtff.USE_PROMPT_TOOLKIT: + completer = NestedCompleter.from_nested_dict( + {c: None for c in report_controller.CHOICES} + ) + an_input = session.prompt( + f"{get_flair()} (stocks)>(report)> ", + completer=completer, + ) + else: + an_input = input(f"{get_flair()} (stocks)>(report)> ") try: - process_input = pc.switch(an_input, proc) + process_input = report_controller.switch(an_input, proc) except SystemExit: print("The command selected doesn't exist\n") continue diff --git a/gamestonk_terminal/research/README.md b/gamestonk_terminal/stocks/research/README.md similarity index 99% rename from gamestonk_terminal/research/README.md rename to gamestonk_terminal/stocks/research/README.md index e32f91071cb..21f9f5c7be4 100644 --- a/gamestonk_terminal/research/README.md +++ b/gamestonk_terminal/stocks/research/README.md @@ -3,7 +3,7 @@ This menu aims to investigate a stock from a website of reference. The list of the supported websites is displayed below.
- + Command|Website ----|---- `macroaxis` |www.macroaxis.com diff --git a/gamestonk_terminal/research/res_controller.py b/gamestonk_terminal/stocks/research/res_controller.py similarity index 98% rename from gamestonk_terminal/research/res_controller.py rename to gamestonk_terminal/stocks/research/res_controller.py index f4bab461e14..8c71c14400f 100644 --- a/gamestonk_terminal/research/res_controller.py +++ b/gamestonk_terminal/stocks/research/res_controller.py @@ -235,11 +235,11 @@ def menu(ticker: str, start: datetime, interval: str): {c: None for c in res_controller.CHOICES} ) an_input = session.prompt( - f"{get_flair()} (res)> ", + f"{get_flair()} (stocks)>(res)> ", completer=completer, ) else: - an_input = input(f"{get_flair()} (res)> ") + an_input = input(f"{get_flair()} (stocks)>(res)> ") try: process_input = res_controller.switch(an_input) diff --git a/gamestonk_terminal/residuals_analysis/README.md b/gamestonk_terminal/stocks/residuals_analysis/README.md similarity index 99% rename from gamestonk_terminal/residuals_analysis/README.md rename to gamestonk_terminal/stocks/residuals_analysis/README.md index da660b318db..1afdb9785f8 100644 --- a/gamestonk_terminal/residuals_analysis/README.md +++ b/gamestonk_terminal/stocks/residuals_analysis/README.md @@ -32,7 +32,7 @@ This menu aims to perform residual analysis on a pre-loaded stock in order to do usage: pick [-m MODEL] ``` -Pick model to fit to stock data. +Pick model to fit to stock data. Currently supported: **Naive**, **ARIMA** diff --git a/gamestonk_terminal/residuals_analysis/ra_controller.py b/gamestonk_terminal/stocks/residuals_analysis/ra_controller.py similarity index 97% rename from gamestonk_terminal/residuals_analysis/ra_controller.py rename to gamestonk_terminal/stocks/residuals_analysis/ra_controller.py index 01a762ee575..2ab66b39410 100644 --- a/gamestonk_terminal/residuals_analysis/ra_controller.py +++ b/gamestonk_terminal/stocks/residuals_analysis/ra_controller.py @@ -8,8 +8,7 @@ from datetime import datetime import pandas as pd from matplotlib import pyplot as plt from prompt_toolkit.completion import NestedCompleter -from gamestonk_terminal.residuals_analysis import residuals_api -from gamestonk_terminal.residuals_analysis import residuals_model +from gamestonk_terminal.common.residuals_analysis import residuals_api, residuals_model from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.helper_funcs import get_flair from gamestonk_terminal.menu import session @@ -265,11 +264,11 @@ def menu(ticker: str, start: datetime, interval: str, stock: pd.DataFrame): {c: None for c in ra_controller.CHOICES} ) an_input = session.prompt( - f"{get_flair()} (ra)> ", + f"{get_flair()} (stocks)>(ra)> ", completer=completer, ) else: - an_input = input(f"{get_flair()} (ra)> ") + an_input = input(f"{get_flair()} (stocks)>(ra)> ") try: plt.close("all") diff --git a/gamestonk_terminal/screener/README.md b/gamestonk_terminal/stocks/screener/README.md similarity index 99% rename from gamestonk_terminal/screener/README.md rename to gamestonk_terminal/stocks/screener/README.md index becbe574d4b..fa9062796a8 100644 --- a/gamestonk_terminal/screener/README.md +++ b/gamestonk_terminal/stocks/screener/README.md @@ -219,7 +219,7 @@ Prints list of available signals. [Source: Finviz] Goes to the portfolio menu with list of passed stocks. In order to pass the stocks, just type the tickers of interest, no commas. ``` -usage: po ticker1 ticker2 ... +usage: po ticker1 ticker2 ... ``` ```` diff --git a/gamestonk_terminal/screener/finviz_model.py b/gamestonk_terminal/stocks/screener/finviz_model.py similarity index 100% rename from gamestonk_terminal/screener/finviz_model.py rename to gamestonk_terminal/stocks/screener/finviz_model.py diff --git a/gamestonk_terminal/screener/finviz_view.py b/gamestonk_terminal/stocks/screener/finviz_view.py similarity index 98% rename from gamestonk_terminal/screener/finviz_view.py rename to gamestonk_terminal/stocks/screener/finviz_view.py index 60cbd086494..e78bdaf3697 100644 --- a/gamestonk_terminal/screener/finviz_view.py +++ b/gamestonk_terminal/stocks/screener/finviz_view.py @@ -6,12 +6,12 @@ from typing import List import os from datetime import datetime import pandas as pd -from gamestonk_terminal.papermill import due_diligence_view +from gamestonk_terminal.stocks.report import due_diligence_view from gamestonk_terminal.helper_funcs import ( parse_known_args_and_warn, check_positive, ) -from gamestonk_terminal.screener.finviz_model import ( +from gamestonk_terminal.stocks.screener.finviz_model import ( d_signals, presets_path, get_screener_data, diff --git a/gamestonk_terminal/screener/presets/5pct_above_low.ini b/gamestonk_terminal/stocks/screener/presets/5pct_above_low.ini similarity index 100% rename from gamestonk_terminal/screener/presets/5pct_above_low.ini rename to gamestonk_terminal/stocks/screener/presets/5pct_above_low.ini diff --git a/gamestonk_terminal/screener/presets/README.md b/gamestonk_terminal/stocks/screener/presets/README.md similarity index 95% rename from gamestonk_terminal/screener/presets/README.md rename to gamestonk_terminal/stocks/screener/presets/README.md index 1e53d0dc6d6..1cdb73020a4 100644 --- a/gamestonk_terminal/screener/presets/README.md +++ b/gamestonk_terminal/stocks/screener/presets/README.md @@ -20,7 +20,7 @@ ## How to add presets -1. Go to the folder GamestonkTerminal/gamestonk_terminal/screener/presets. +1. Go to the folder GamestonkTerminal/gamestonk_terminal/screener/presets. 2. There should be a `README.md` file and multiple `.ini` files. One of these `.ini` files should be named `template.ini`. @@ -31,11 +31,11 @@ 2 -5. Open the file you just renamed (e.g. `my_own_filter.ini`), and set the parameters you want to filter. +5. Open the file you just renamed (e.g. `my_own_filter.ini`), and set the parameters you want to filter. 3 -6. It may be useful to play with the main source https://finviz.com/screener.ashx since you can tweak these and understand how they influence the outcome of the filtered stocks. +6. It may be useful to play with the main source https://finviz.com/screener.ashx since you can tweak these and understand how they influence the outcome of the filtered stocks. 4 @@ -89,7 +89,7 @@ * **Author of preset:** Traceabl3 * **Contact:** swing the bullroarer -* **ABOUT:** High Yield Dividend stonks that are at-or-near their lowest price. Inverse Head and shoulders pattern recognized. +* **ABOUT:** High Yield Dividend stonks that are at-or-near their lowest price. Inverse Head and shoulders pattern recognized. --- @@ -105,7 +105,7 @@ * **Author of preset:** Traceabl3 * **Contact:** hit me on my skytel pager -* **Description:** Cheap stonks that are oversold: under 10% above the low, and oversold on the RSI. +* **Description:** Cheap stonks that are oversold: under 10% above the low, and oversold on the RSI. --- @@ -122,7 +122,7 @@ * **Author of preset:** Traceabl3 * **Contact:** flip the pigeons -* **Description:** Golden Cross when the 50 day moves above the 200 day from below. +* **Description:** Golden Cross when the 50 day moves above the 200 day from below. --- @@ -162,18 +162,12 @@ * **Author of preset:** Traceabl3 * **Contact:** wave the white flag -* **Description:** Too many indicators indicating an impending downturn. +* **Description:** Too many indicators indicating an impending downturn. --- ## undervalue * **Author of preset:** Traceabl3 -* **Contact:** message on tor browser. +* **Contact:** message on tor browser. * **Description:** Potential Undervalued stocks - - - - - - diff --git a/gamestonk_terminal/screener/presets/analyst_strong_buy.ini b/gamestonk_terminal/stocks/screener/presets/analyst_strong_buy.ini similarity index 100% rename from gamestonk_terminal/screener/presets/analyst_strong_buy.ini rename to gamestonk_terminal/stocks/screener/presets/analyst_strong_buy.ini diff --git a/gamestonk_terminal/screener/presets/break_out_stocks.ini b/gamestonk_terminal/stocks/screener/presets/break_out_stocks.ini similarity index 100% rename from gamestonk_terminal/screener/presets/break_out_stocks.ini rename to gamestonk_terminal/stocks/screener/presets/break_out_stocks.ini diff --git a/gamestonk_terminal/screener/presets/buffett_like.ini b/gamestonk_terminal/stocks/screener/presets/buffett_like.ini similarity index 100% rename from gamestonk_terminal/screener/presets/buffett_like.ini rename to gamestonk_terminal/stocks/screener/presets/buffett_like.ini diff --git a/gamestonk_terminal/screener/presets/bull_runs_over_10pct.ini b/gamestonk_terminal/stocks/screener/presets/bull_runs_over_10pct.ini similarity index 100% rename from gamestonk_terminal/screener/presets/bull_runs_over_10pct.ini rename to gamestonk_terminal/stocks/screener/presets/bull_runs_over_10pct.ini diff --git a/gamestonk_terminal/screener/presets/channel_up_and_low_debt_and_sma_50and200.ini b/gamestonk_terminal/stocks/screener/presets/channel_up_and_low_debt_and_sma_50and200.ini similarity index 100% rename from gamestonk_terminal/screener/presets/channel_up_and_low_debt_and_sma_50and200.ini rename to gamestonk_terminal/stocks/screener/presets/channel_up_and_low_debt_and_sma_50and200.ini diff --git a/gamestonk_terminal/screener/presets/cheap_bottom_dividend.ini b/gamestonk_terminal/stocks/screener/presets/cheap_bottom_dividend.ini similarity index 100% rename from gamestonk_terminal/screener/presets/cheap_bottom_dividend.ini rename to gamestonk_terminal/stocks/screener/presets/cheap_bottom_dividend.ini diff --git a/gamestonk_terminal/screener/presets/cheap_dividend.ini b/gamestonk_terminal/stocks/screener/presets/cheap_dividend.ini similarity index 100% rename from gamestonk_terminal/screener/presets/cheap_dividend.ini rename to gamestonk_terminal/stocks/screener/presets/cheap_dividend.ini diff --git a/gamestonk_terminal/screener/presets/cheap_oversold.ini b/gamestonk_terminal/stocks/screener/presets/cheap_oversold.ini similarity index 100% rename from gamestonk_terminal/screener/presets/cheap_oversold.ini rename to gamestonk_terminal/stocks/screener/presets/cheap_oversold.ini diff --git a/gamestonk_terminal/screener/presets/continued_momentum_scan.ini b/gamestonk_terminal/stocks/screener/presets/continued_momentum_scan.ini similarity index 100% rename from gamestonk_terminal/screener/presets/continued_momentum_scan.ini rename to gamestonk_terminal/stocks/screener/presets/continued_momentum_scan.ini diff --git a/gamestonk_terminal/screener/presets/death_cross.ini b/gamestonk_terminal/stocks/screener/presets/death_cross.ini similarity index 100% rename from gamestonk_terminal/screener/presets/death_cross.ini rename to gamestonk_terminal/stocks/screener/presets/death_cross.ini diff --git a/gamestonk_terminal/screener/presets/golden_cross.ini b/gamestonk_terminal/stocks/screener/presets/golden_cross.ini similarity index 100% rename from gamestonk_terminal/screener/presets/golden_cross.ini rename to gamestonk_terminal/stocks/screener/presets/golden_cross.ini diff --git a/gamestonk_terminal/screener/presets/golden_cross_penny.ini b/gamestonk_terminal/stocks/screener/presets/golden_cross_penny.ini similarity index 100% rename from gamestonk_terminal/screener/presets/golden_cross_penny.ini rename to gamestonk_terminal/stocks/screener/presets/golden_cross_penny.ini diff --git a/gamestonk_terminal/screener/presets/growth_stocks.ini b/gamestonk_terminal/stocks/screener/presets/growth_stocks.ini similarity index 100% rename from gamestonk_terminal/screener/presets/growth_stocks.ini rename to gamestonk_terminal/stocks/screener/presets/growth_stocks.ini diff --git a/gamestonk_terminal/screener/presets/heavy_inst_ins.ini b/gamestonk_terminal/stocks/screener/presets/heavy_inst_ins.ini similarity index 100% rename from gamestonk_terminal/screener/presets/heavy_inst_ins.ini rename to gamestonk_terminal/stocks/screener/presets/heavy_inst_ins.ini diff --git a/gamestonk_terminal/screener/presets/high_vol_and_low_debt.ini b/gamestonk_terminal/stocks/screener/presets/high_vol_and_low_debt.ini similarity index 100% rename from gamestonk_terminal/screener/presets/high_vol_and_low_debt.ini rename to gamestonk_terminal/stocks/screener/presets/high_vol_and_low_debt.ini diff --git a/gamestonk_terminal/screener/presets/modified_dreman.ini b/gamestonk_terminal/stocks/screener/presets/modified_dreman.ini similarity index 100% rename from gamestonk_terminal/screener/presets/modified_dreman.ini rename to gamestonk_terminal/stocks/screener/presets/modified_dreman.ini diff --git a/gamestonk_terminal/screener/presets/modified_neff.ini b/gamestonk_terminal/stocks/screener/presets/modified_neff.ini similarity index 100% rename from gamestonk_terminal/screener/presets/modified_neff.ini rename to gamestonk_terminal/stocks/screener/presets/modified_neff.ini diff --git a/gamestonk_terminal/screener/presets/news_scanner.ini b/gamestonk_terminal/stocks/screener/presets/news_scanner.ini similarity index 100% rename from gamestonk_terminal/screener/presets/news_scanner.ini rename to gamestonk_terminal/stocks/screener/presets/news_scanner.ini diff --git a/gamestonk_terminal/screener/presets/oversold.ini b/gamestonk_terminal/stocks/screener/presets/oversold.ini similarity index 100% rename from gamestonk_terminal/screener/presets/oversold.ini rename to gamestonk_terminal/stocks/screener/presets/oversold.ini diff --git a/gamestonk_terminal/screener/presets/oversold_under_3dol.ini b/gamestonk_terminal/stocks/screener/presets/oversold_under_3dol.ini similarity index 100% rename from gamestonk_terminal/screener/presets/oversold_under_3dol.ini rename to gamestonk_terminal/stocks/screener/presets/oversold_under_3dol.ini diff --git a/gamestonk_terminal/screener/presets/oversold_under_5dol.ini b/gamestonk_terminal/stocks/screener/presets/oversold_under_5dol.ini similarity index 100% rename from gamestonk_terminal/screener/presets/oversold_under_5dol.ini rename to gamestonk_terminal/stocks/screener/presets/oversold_under_5dol.ini diff --git a/gamestonk_terminal/screener/presets/potential_reversals.ini b/gamestonk_terminal/stocks/screener/presets/potential_reversals.ini similarity index 100% rename from gamestonk_terminal/screener/presets/potential_reversals.ini rename to gamestonk_terminal/stocks/screener/presets/potential_reversals.ini diff --git a/gamestonk_terminal/screener/presets/recent_growth_and_support.ini b/gamestonk_terminal/stocks/screener/presets/recent_growth_and_support.ini similarity index 100% rename from gamestonk_terminal/screener/presets/recent_growth_and_support.ini rename to gamestonk_terminal/stocks/screener/presets/recent_growth_and_support.ini diff --git a/gamestonk_terminal/screener/presets/rosenwald.ini b/gamestonk_terminal/stocks/screener/presets/rosenwald.ini similarity index 100% rename from gamestonk_terminal/screener/presets/rosenwald.ini rename to gamestonk_terminal/stocks/screener/presets/rosenwald.ini diff --git a/gamestonk_terminal/screener/presets/rosenwald_gtfo.ini b/gamestonk_terminal/stocks/screener/presets/rosenwald_gtfo.ini similarity index 100% rename from gamestonk_terminal/screener/presets/rosenwald_gtfo.ini rename to gamestonk_terminal/stocks/screener/presets/rosenwald_gtfo.ini diff --git a/gamestonk_terminal/screener/presets/sexy_year.ini b/gamestonk_terminal/stocks/screener/presets/sexy_year.ini similarity index 100% rename from gamestonk_terminal/screener/presets/sexy_year.ini rename to gamestonk_terminal/stocks/screener/presets/sexy_year.ini diff --git a/gamestonk_terminal/screener/presets/short_squeeze_scan.ini b/gamestonk_terminal/stocks/screener/presets/short_squeeze_scan.ini similarity index 100% rename from gamestonk_terminal/screener/presets/short_squeeze_scan.ini rename to gamestonk_terminal/stocks/screener/presets/short_squeeze_scan.ini diff --git a/gamestonk_terminal/screener/presets/simplistic_momentum_scanner_under_7dol.ini b/gamestonk_terminal/stocks/screener/presets/simplistic_momentum_scanner_under_7dol.ini similarity index 100% rename from gamestonk_terminal/screener/presets/simplistic_momentum_scanner_under_7dol.ini rename to gamestonk_terminal/stocks/screener/presets/simplistic_momentum_scanner_under_7dol.ini diff --git a/gamestonk_terminal/screener/presets/stocks_strong_support_levels.ini b/gamestonk_terminal/stocks/screener/presets/stocks_strong_support_levels.ini similarity index 100% rename from gamestonk_terminal/screener/presets/stocks_strong_support_levels.ini rename to gamestonk_terminal/stocks/screener/presets/stocks_strong_support_levels.ini diff --git a/gamestonk_terminal/screener/presets/template.ini b/gamestonk_terminal/stocks/screener/presets/template.ini similarity index 100% rename from gamestonk_terminal/screener/presets/template.ini rename to gamestonk_terminal/stocks/screener/presets/template.ini diff --git a/gamestonk_terminal/screener/presets/top_performers_all.ini b/gamestonk_terminal/stocks/screener/presets/top_performers_all.ini similarity index 100% rename from gamestonk_terminal/screener/presets/top_performers_all.ini rename to gamestonk_terminal/stocks/screener/presets/top_performers_all.ini diff --git a/gamestonk_terminal/screener/presets/top_performers_healthcare.ini b/gamestonk_terminal/stocks/screener/presets/top_performers_healthcare.ini similarity index 100% rename from gamestonk_terminal/screener/presets/top_performers_healthcare.ini rename to gamestonk_terminal/stocks/screener/presets/top_performers_healthcare.ini diff --git a/gamestonk_terminal/screener/presets/top_performers_tech.ini b/gamestonk_terminal/stocks/screener/presets/top_performers_tech.ini similarity index 100% rename from gamestonk_terminal/screener/presets/top_performers_tech.ini rename to gamestonk_terminal/stocks/screener/presets/top_performers_tech.ini diff --git a/gamestonk_terminal/screener/presets/under_15dol_stocks.ini b/gamestonk_terminal/stocks/screener/presets/under_15dol_stocks.ini similarity index 100% rename from gamestonk_terminal/screener/presets/under_15dol_stocks.ini rename to gamestonk_terminal/stocks/screener/presets/under_15dol_stocks.ini diff --git a/gamestonk_terminal/screener/presets/undervalue.ini b/gamestonk_terminal/stocks/screener/presets/undervalue.ini similarity index 100% rename from gamestonk_terminal/screener/presets/undervalue.ini rename to gamestonk_terminal/stocks/screener/presets/undervalue.ini diff --git a/gamestonk_terminal/screener/presets/unusual_volume.ini b/gamestonk_terminal/stocks/screener/presets/unusual_volume.ini similarity index 100% rename from gamestonk_terminal/screener/presets/unusual_volume.ini rename to gamestonk_terminal/stocks/screener/presets/unusual_volume.ini diff --git a/gamestonk_terminal/screener/presets/value_stocks.ini b/gamestonk_terminal/stocks/screener/presets/value_stocks.ini similarity index 100% rename from gamestonk_terminal/screener/presets/value_stocks.ini rename to gamestonk_terminal/stocks/screener/presets/value_stocks.ini diff --git a/gamestonk_terminal/screener/presets/weak_support_and_top_performers.ini b/gamestonk_terminal/stocks/screener/presets/weak_support_and_top_performers.ini similarity index 100% rename from gamestonk_terminal/screener/presets/weak_support_and_top_performers.ini rename to gamestonk_terminal/stocks/screener/presets/weak_support_and_top_performers.ini diff --git a/gamestonk_terminal/screener/screener_controller.py b/gamestonk_terminal/stocks/screener/screener_controller.py similarity index 96% rename from gamestonk_terminal/screener/screener_controller.py rename to gamestonk_terminal/stocks/screener/screener_controller.py index 365f3800697..d6524ad5c4d 100644 --- a/gamestonk_terminal/screener/screener_controller.py +++ b/gamestonk_terminal/stocks/screener/screener_controller.py @@ -13,12 +13,14 @@ from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.helper_funcs import ( parse_known_args_and_warn, ) -from gamestonk_terminal.screener import finviz_view -from gamestonk_terminal.screener import yahoo_finance_view -from gamestonk_terminal.portfolio_optimization import po_controller +from gamestonk_terminal.stocks.screener import finviz_view +from gamestonk_terminal.stocks.screener import yahoo_finance_view +from gamestonk_terminal.portfolio.portfolio_optimization import po_controller presets_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), "presets/") +# pylint: disable=E1121 + class ScreenerController: """Screener Controller class""" @@ -301,11 +303,11 @@ def menu(): {c: None for c in scr_controller.CHOICES} ) an_input = session.prompt( - f"{get_flair()} (scr)> ", + f"{get_flair()} (stocks)>(scr)> ", completer=completer, ) else: - an_input = input(f"{get_flair()} (scr)> ") + an_input = input(f"{get_flair()} (stocks)>(scr)> ") try: plt.close("all") diff --git a/gamestonk_terminal/screener/yahoo_finance_view.py b/gamestonk_terminal/stocks/screener/yahoo_finance_view.py similarity index 99% rename from gamestonk_terminal/screener/yahoo_finance_view.py rename to gamestonk_terminal/stocks/screener/yahoo_finance_view.py index 544a228a509..fbf7c064b0a 100644 --- a/gamestonk_terminal/screener/yahoo_finance_view.py +++ b/gamestonk_terminal/stocks/screener/yahoo_finance_view.py @@ -8,7 +8,7 @@ from pandas.plotting import register_matplotlib_converters import matplotlib.pyplot as plt import yfinance as yf from finvizfinance.screener import ticker -from gamestonk_terminal.screener import finviz_view +from gamestonk_terminal.stocks.screener import finviz_view from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.helper_funcs import ( parse_known_args_and_warn, diff --git a/gamestonk_terminal/stocks/stocks_controller.py b/gamestonk_terminal/stocks/stocks_controller.py new file mode 100644 index 00000000000..d6f55b6485b --- /dev/null +++ b/gamestonk_terminal/stocks/stocks_controller.py @@ -0,0 +1,479 @@ +import argparse +import os +from typing import List +import pandas as pd +from prompt_toolkit.completion import NestedCompleter + +from gamestonk_terminal.helper_funcs import get_flair + +from gamestonk_terminal.helper_funcs import b_is_stock_market_open +from gamestonk_terminal.menu import session +from gamestonk_terminal import feature_flags as gtff + +from gamestonk_terminal.stocks.stocks_helper import clear, load, view, candle, quote + +from gamestonk_terminal.stocks.discovery import disc_controller +from gamestonk_terminal.stocks.screener import screener_controller +from gamestonk_terminal.stocks.insider import insider_controller +from gamestonk_terminal.stocks.government import gov_controller +from gamestonk_terminal.stocks.due_diligence import dd_controller +from gamestonk_terminal.stocks.fundamental_analysis import fa_controller +from gamestonk_terminal.stocks.research import res_controller +from gamestonk_terminal.stocks.comparison_analysis import ca_controller +from gamestonk_terminal.stocks.backtesting import bt_controller +from gamestonk_terminal.stocks.technical_analysis import ta_controller +from gamestonk_terminal.stocks.behavioural_analysis import ba_controller +from gamestonk_terminal.stocks.residuals_analysis import ra_controller +from gamestonk_terminal.stocks.exploratory_data_analysis import eda_controller +from gamestonk_terminal.stocks.report import report_controller + +# pylint: disable=R1710 + + +class StocksController: + """Stocks Controller class""" + + # To hold suffix for Yahoo Finance + suffix = "" + + CHOICES = [ + "cls", + "?", + "help", + "q", + "quit", + ] + + CHOICES_COMMANDS = [ + "load", + "quote", + "candle", + "view", + ] + + CHOICES_MENUS = [ + "ta", + "ba", + "eda", + "pred", + "ra", + "disc", + "scr", + "ins", + "gov", + "res", + "fa", + "bt", + "dd", + "ca", + "report", + ] + + CHOICES += CHOICES_COMMANDS + CHOICES += CHOICES_MENUS + + def __init__(self): + """Constructor""" + self.stocks_parser = argparse.ArgumentParser(add_help=False, prog="stocks") + self.stocks_parser.add_argument( + "cmd", + choices=self.CHOICES, + ) + self.completer = NestedCompleter.from_nested_dict( + {c: None for c in self.CHOICES} + ) + + self.stock = pd.DataFrame() + self.ticker = "" + self.start = "" + self.interval = "1440min" + + def print_help(self): + """Print help""" + help_text = """https://github.com/GamestonkTerminal/GamestonkTerminal/tree/main/gamestonk_terminal/stocks + +>> STOCKS << + +What do you want to do? + cls clear screen + ?/help show this menu again + q quit this menu, and shows back to main menu + quit quit to abandon the program + """ + s_intraday = (f"Intraday {self.interval}", "Daily")[self.interval == "1440min"] + if self.ticker and self.start: + help_text += f"\n{s_intraday} Stock: {self.ticker} (from {self.start.strftime('%Y-%m-%d')})\n" + elif self.ticker: + help_text += f"\n{s_intraday} Stock: {self.ticker}\n" + else: + help_text += "\nStock: ?\n" + + help_text += f"Market {('CLOSED', 'OPEN')[b_is_stock_market_open()]}.\n" + + help_text += """ + clear clear a specific stock ticker from analysis + load load a specific stock ticker for analysis + quote view the current price for a specific stock ticker + candle view a candle chart for a specific stock ticker + view view and load a specific stock ticker for technical analysis + +> disc discover trending stocks, \t e.g. map, sectors, high short interest +> scr screener stocks, \t\t e.g. overview/performance, using preset filters +> gov government menu, \t\t house trading, contracts, corporate lobbying +> dd in-depth due-diligence, \t e.g.: news, analyst, shorts, insider, sec +> fa fundamental analysis, \t e.g.: income, balance, cash, earnings +> res research web page, \t e.g.: macroaxis, yahoo finance, fool +> ca comparison analysis, \t e.g.: historical, correlation, financials +> bt strategy backtester, \t e.g.: simple ema, ema cross, rsi strategies +> ta technical analysis, \t e.g.: ema, macd, rsi, adx, bbands, obv +> ba behavioural analysis, \t from: reddit, stocktwits, twitter, google +> eda exploratory data analysis,\t e.g.: decompose, cusum, residuals analysis +> ra residuals analysis, \t e.g.: model fit, qqplot, hypothesis test +> pred prediction techniques, \t e.g.: regression, arima, rnn, lstm +> report generate automatic report, \t e.g.: dark pool, due diligence + """ + print(help_text) + + def switch(self, an_input: str): + """Process and dispatch input + + Returns + ------- + True, False, or None + False - quit the menu + True - quit the program + None - continue in the menu + """ + + # Empty command + if not an_input: + print("") + return None + + (known_args, other_args) = self.stocks_parser.parse_known_args(an_input.split()) + + # Help menu again + if known_args.cmd == "?": + self.print_help() + return None + + # Clear screen + if known_args.cmd == "cls": + os.system("cls||clear") + return None + + return getattr( + self, "call_" + known_args.cmd, lambda: "command not recognized!" + )(other_args) + + def call_help(self, _): + """Process Help Command""" + self.print_help() + + def call_q(self, _): + """Process Q command - quit the menu""" + return False + + def call_quit(self, _): + """Process Quit command - exit the program""" + return True + + # COMMANDS + def call_clear(self, other_args: List[str]): + """Process clear command""" + self.ticker, self.start, self.interval, self.stock = clear( + other_args, self.ticker, self.start, self.interval, self.stock + ) + + def call_load(self, other_args: List[str]): + """Process load command""" + self.ticker, self.start, self.interval, self.stock = load( + other_args, self.ticker, self.start, self.interval, self.stock + ) + if "." in self.ticker: + self.ticker, self.suffix = self.ticker.split(".") + else: + self.suffix = "" + + def call_quote(self, other_args: List[str]): + """Process quote command""" + quote( + other_args, self.ticker + "." + self.suffix if self.suffix else self.ticker + ) + + def call_candle(self, other_args: List[str]): + """Process candle command""" + candle( + self.ticker + "." + self.suffix if self.suffix else self.ticker, + other_args, + ) + + def call_view(self, other_args: List[str]): + """Process view command""" + view(other_args, self.ticker, self.interval, self.stock) + + # MENUS + def call_disc(self, _): + """Process disc command""" + ret = disc_controller.menu() + if ret is False: + self.print_help() + else: + return True + + def call_scr(self, _): + """Process scr command""" + ret = screener_controller.menu() + if ret is False: + self.print_help() + else: + return True + + def call_ins(self, _): + """Process ins command""" + ret = insider_controller.menu() + if ret is False: + self.print_help() + else: + return True + + def call_gov(self, _): + """Process gov command""" + ret = gov_controller.menu(self.ticker) + if ret is False: + self.print_help() + else: + return True + + def call_report(self, _): + """Process report command""" + ret = report_controller.menu() + + if ret is False: + self.print_help() + else: + return True + + def call_res(self, _): + """Process res command""" + if not self.ticker: + print("Use 'load ' prior to this command!", "\n") + return + + ret = res_controller.menu( + self.ticker, + self.start, + self.interval, + ) + + if ret is False: + self.print_help() + else: + return True + + def call_dd(self, _): + """Process dd command""" + if not self.ticker: + print("Use 'load ' prior to this command!", "\n") + return + + ret = dd_controller.menu( + self.ticker, + self.start, + self.interval, + self.stock, + ) + + if ret is False: + self.print_help() + else: + return True + + def call_ca(self, _): + """Process ca command""" + if not self.ticker: + print("Use 'load ' prior to this command!", "\n") + return + + ret = ca_controller.menu(self.ticker, self.start, self.interval, self.stock) + + if ret is False: + self.print_help() + else: + return True + + def call_fa(self, _): + """Process fa command""" + if not self.ticker: + print("Use 'load ' prior to this command!", "\n") + return + + ret = fa_controller.menu( + self.ticker, + self.start, + self.interval, + ) + + if ret is False: + self.print_help() + else: + return True + + def call_bt(self, _): + """Process bt command""" + if not self.ticker: + print("Use 'load ' prior to this command!", "\n") + return + + ret = bt_controller.menu( + self.ticker, + self.start, + ) + + if ret is False: + self.print_help() + else: + return True + + def call_ta(self, _): + """Process ta command""" + if not self.ticker: + print("Use 'load ' prior to this command!", "\n") + return + + ret = ta_controller.menu( + self.ticker, + self.start, + self.interval, + self.stock, + ) + + if ret is False: + self.print_help() + else: + return True + + def call_ba(self, _): + """Process ba command""" + if not self.ticker: + print("Use 'load ' prior to this command!", "\n") + return + + ret = ba_controller.menu( + self.ticker, + self.start, + ) + + if ret is False: + self.print_help() + else: + return True + + def call_ra(self, _): + """Process ra command""" + if not self.ticker: + print("Use 'load ' prior to this command!", "\n") + return + + ret = ra_controller.menu( + self.ticker, + self.start, + self.interval, + self.stock, + ) + + if ret is False: + self.print_help() + else: + return True + + def call_eda(self, _): + """Process eda command""" + if not self.ticker: + print("Use 'load ' prior to this command!", "\n") + return + + if self.interval != "1440min": + # TODO: This menu should work regardless of data being daily or not! + print("Load daily data to use this menu!", "\n") + return + + ret = eda_controller.menu( + self.ticker, + self.start, + self.interval, + self.stock, + ) + + if ret is False: + self.print_help() + else: + return True + + def call_pred(self, _): + """Process pred command""" + if not gtff.ENABLE_PREDICT: + print( + "Predict is disabled. Check ENABLE_PREDICT flag on feature_flags.py", + "\n", + ) + return + + if not self.ticker: + print("Use 'load ' prior to this command!", "\n") + return + + if self.interval != "1440min": + # TODO: This menu should work regardless of data being daily or not! + print("Load daily data to use this menu!", "\n") + return + + try: + # pylint: disable=import-outside-toplevel + from gamestonk_terminal.stocks.prediction_techniques import pred_controller + except ModuleNotFoundError as e: + print("One of the optional packages seems to be missing: ", e, "\n") + return + except Exception as e: + print(e, "\n") + return + + ret = pred_controller.menu( + self.ticker, + self.start, + self.interval, + self.stock, + ) + + if ret is False: + self.print_help() + else: + return True + + +def menu(): + """Stocks Menu""" + stocks_controller = StocksController() + stocks_controller.call_help(None) + while True: + if session and gtff.USE_PROMPT_TOOLKIT: + completer = NestedCompleter.from_nested_dict( + {c: None for c in stocks_controller.CHOICES} + ) + + an_input = session.prompt( + f"{get_flair()} (stocks)> ", + completer=completer, + ) + else: + an_input = input(f"{get_flair()} (stocks)> ") + + try: + process_input = stocks_controller.switch(an_input) + + if process_input is not None: + return process_input + + except SystemExit: + print("The command selected doesn't exit\n") + continue diff --git a/gamestonk_terminal/main_helper.py b/gamestonk_terminal/stocks/stocks_helper.py similarity index 57% rename from gamestonk_terminal/main_helper.py rename to gamestonk_terminal/stocks/stocks_helper.py index b3cca1f15db..8d5346d632f 100644 --- a/gamestonk_terminal/main_helper.py +++ b/gamestonk_terminal/stocks/stocks_helper.py @@ -2,44 +2,29 @@ __docformat__ = "numpy" import argparse from typing import List -import os -import sys -import subprocess -import random from datetime import datetime, timedelta -import hashlib -import requests -from colorama import Fore, Style import matplotlib.pyplot as plt from numpy.core.fromnumeric import transpose import pandas as pd from alpha_vantage.timeseries import TimeSeries -import quandl import mplfinance as mpf import yfinance as yf -from coinmarketcapapi import CoinMarketCapAPI, CoinMarketCapAPIError import pytz import pyEX -from pyEX.common.exception import PyEXception from tabulate import tabulate -import praw -from prawcore.exceptions import ResponseException - -# import git # pylint: disable=no-member,too-many-branches,C0302 from gamestonk_terminal.helper_funcs import ( valid_date, - plot_view_stock, parse_known_args_and_warn, plot_autoscale, ) +from gamestonk_terminal import config_plot as cfgPlot from gamestonk_terminal import config_terminal as cfg from gamestonk_terminal import feature_flags as gtff -from gamestonk_terminal import thought_of_the_day as thought -from gamestonk_terminal.technical_analysis import trendline_api as trend +from gamestonk_terminal.common.technical_analysis import trendline_api as trend def clear( @@ -655,383 +640,81 @@ def view(other_args: List[str], s_ticker: str, s_interval: str, df_stock: pd.Dat return -# pylint: disable=too-many-statements +def plot_view_stock(df: pd.DataFrame, symbol: str, interval: str): + """ + Plot the loaded stock dataframe + Parameters + ---------- + df: Dataframe + Dataframe of prices and volumnes + symbol: str + Symbol of ticker + interval: str + Stock data resolution for plotting purposes - -def check_api_keys(): - """Check api keys and if they are supplied""" - - key_dict = {} - if cfg.API_KEY_ALPHAVANTAGE == "REPLACE_ME": # pragma: allowlist secret - key_dict["ALPHA_VANTAGE"] = "Not defined" - else: - df = TimeSeries( - key=cfg.API_KEY_ALPHAVANTAGE, output_format="pandas" - ).get_intraday(symbol="AAPL") - if df[0].empty: - key_dict["ALPHA_VANTAGE"] = "defined, test failed" - else: - key_dict["ALPHA_VANTAGE"] = "defined, test passed" - - if cfg.API_KEY_FINANCIALMODELINGPREP == "REPLACE_ME": # pragma: allowlist secret - key_dict["FINANCIAL_MODELING_PREP"] = "Not defined" - else: - r = requests.get( - f"https://financialmodelingprep.com/api/v3/profile/AAPL?apikey={cfg.API_KEY_FINANCIALMODELINGPREP}" - ) - if r.status_code in [403, 401]: - key_dict["FINANCIAL_MODELING_PREP"] = "defined, test failed" - elif r.status_code == 200: - key_dict["FINANCIAL_MODELING_PREP"] = "defined, test passed" - else: - key_dict["FINANCIAL_MODELING_PREP"] = "defined, test inconclusive" - - if cfg.API_KEY_QUANDL == "REPLACE_ME": # pragma: allowlist secret - key_dict["QUANDL"] = "Not defined" - else: - try: - quandl.save_key(cfg.API_KEY_QUANDL) - quandl.get_table( - "ZACKS/FC", - paginate=True, - ticker=["AAPL", "MSFT"], - per_end_date={"gte": "2015-01-01"}, - qopts={"columns": ["ticker", "per_end_date"]}, - ) - key_dict["QUANDL"] = "defined, test passed" - except quandl.errors.quandl_error.ForbiddenError: - key_dict["QUANDL"] = "defined, test failed" - - if cfg.API_POLYGON_KEY == "REPLACE_ME": - key_dict["POLYGON"] = "Not defined" - else: - r = requests.get( - f"https://api.polygon.io/v2/aggs/ticker/AAPL/range/1/day/2020-06-01/2020-06-17?apiKey={cfg.API_POLYGON_KEY}" - ) - if r.status_code in [403, 401]: - key_dict["POLYGON"] = "defined, test failed" - elif r.status_code == 200: - key_dict["POLYGON"] = "defined, test passed" - else: - key_dict["POLYGON"] = "defined, test inconclusive" - - if cfg.API_FRED_KEY == "REPLACE_ME": - key_dict["FRED"] = "Not defined" - else: - r = requests.get( - f"https://api.stlouisfed.org/fred/series?series_id=GNPCA&api_key={cfg.API_FRED_KEY}" - ) - if r.status_code in [403, 401, 400]: - key_dict["FRED"] = "defined, test failed" - elif r.status_code == 200: - key_dict["FRED"] = "defined, test passed" - else: - key_dict["FRED"] = "defined, test inconclusive" - - if cfg.API_NEWS_TOKEN == "REPLACE_ME": - key_dict["NEWSAPI"] = "Not defined" - else: - r = requests.get( - f"https://newsapi.org/v2/everything?q=keyword&apiKey={cfg.API_NEWS_TOKEN}" - ) - if r.status_code in [401, 403]: - key_dict["NEWSAPI"] = "defined, test failed" - elif r.status_code == 200: - key_dict["NEWSAPI"] = "defined, test passed" - else: - key_dict["NEWSAPI"] = "defined, test inconclusive" - - if cfg.TRADIER_TOKEN == "REPLACE_ME": - key_dict["TRADIER"] = "Not defined" - else: - r = requests.get( - "https://sandbox.tradier.com/v1/markets/quotes", - params={"symbols": "AAPL"}, - headers={ - "Authorization": f"Bearer {cfg.TRADIER_TOKEN}", - "Accept": "application/json", - }, - ) - if r.status_code in [401, 403]: - key_dict["TRADIER"] = "defined, test failed" - elif r.status_code == 200: - key_dict["TRADIER"] = "defined, test passed" - else: - key_dict["TRADIER"] = "defined, test inconclusive" - - if cfg.API_CMC_KEY == "REPLACE_ME": - key_dict["COINMARKETCAP"] = "Not defined" - else: - cmc = CoinMarketCapAPI(cfg.API_CMC_KEY) - try: - cmc.exchange_info() - key_dict["COINMARKETCAP"] = "defined, test passed" - except CoinMarketCapAPIError: - key_dict["COINMARKETCAP"] = "defined, test failed" - - if cfg.API_FINNHUB_KEY == "REPLACE_ME": - key_dict["FINNHUB"] = "Not defined" - else: - r = r = requests.get( - f"https://finnhub.io/api/v1/quote?symbol=AAPL&token={cfg.API_FINNHUB_KEY}" - ) - if r.status_code in [403, 401, 400]: - key_dict["FINNHUB"] = "defined, test failed" - elif r.status_code == 200: - key_dict["FINNHUB"] = "defined, test passed" - else: - key_dict["FINNHUB"] = "defined, test inconclusive" - - if cfg.API_IEX_TOKEN == "REPLACE_ME": - key_dict["IEXCLOUD"] = "Not defined" - else: - try: - pyEX.Client(api_token=cfg.API_IEX_TOKEN, version="v1") - key_dict["IEXCLOUD"] = "defined, test passed" - except PyEXception: - key_dict["IEXCLOUD"] = "defined, test failed" - - # Reddit - reddit_keys = [ - cfg.API_REDDIT_CLIENT_ID, - cfg.API_REDDIT_CLIENT_SECRET, - cfg.API_REDDIT_USERNAME, - cfg.API_REDDIT_PASSWORD, - cfg.API_REDDIT_USER_AGENT, - ] - if "REPLACE_ME" in reddit_keys: - key_dict["REDDIT"] = "Not defined" - else: - praw_api = praw.Reddit( - client_id=cfg.API_REDDIT_CLIENT_ID, - client_secret=cfg.API_REDDIT_CLIENT_SECRET, - username=cfg.API_REDDIT_USERNAME, - user_agent=cfg.API_REDDIT_USER_AGENT, - password=cfg.API_REDDIT_PASSWORD, - ) - - try: - praw_api.user.me() - key_dict["REDDIT"] = "defined, test passed" - except ResponseException: - key_dict["REDDIT"] = "defined, test failed" - - # Twitter keys - twitter_keys = [ - cfg.API_TWITTER_KEY, - cfg.API_TWITTER_SECRET_KEY, - cfg.API_TWITTER_BEARER_TOKEN, - ] - if "REPLACE_ME" in twitter_keys: - key_dict["TWITTER"] = "Not defined" - else: - params = { - "query": "(\\$AAPL) (lang:en)", - "max_results": "10", - "tweet.fields": "created_at,lang", - } - r = requests.get( - "https://api.twitter.com/2/tweets/search/recent", - params=params, # type: ignore - headers={"authorization": "Bearer " + cfg.API_TWITTER_BEARER_TOKEN}, - ) - if r.status_code == 200: - key_dict["TWITTER"] = "defined, test passed" - elif r.status_code in [401, 403]: - key_dict["TWITTER"] = "defined, test failed" - else: - key_dict["TWITTER"] = "defined, test inconclusive" - - # Robinhood keys - rh_keys = [cfg.RH_USERNAME, cfg.RH_PASSWORD] - if "REPLACE_ME" in rh_keys: - key_dict["ROBINHOOD"] = "Not defined" - else: - key_dict["ROBINHOOD"] = "defined, not tested" - # Degiro keys - dg_keys = [cfg.DG_USERNAME, cfg.DG_PASSWORD, cfg.DG_TOTP_SECRET] - if "REPLACE_ME" in dg_keys: - key_dict["DEGIRO"] = "Not defined" - else: - key_dict["DEGIRO"] = "defined, not tested" - # OANDA keys - oanda_keys = [cfg.OANDA_TOKEN, cfg.OANDA_ACCOUNT] - if "REPLACE_ME" in oanda_keys: - key_dict["OANDA"] = "Not defined" - else: - key_dict["OANDA"] = "defined, not tested" - # Binance keys - bn_keys = [cfg.API_BINANCE_KEY, cfg.API_BINANCE_SECRET] - if "REPLACE_ME" in bn_keys: - key_dict["BINANCE"] = "Not defined" - else: - key_dict["BINANCE"] = "defined, not tested" - - # SentimentInvestor keys - si_keys = [cfg.API_SENTIMENTINVESTOR_KEY, cfg.API_SENTIMENTINVESTOR_TOKEN] - if "REPLACE_ME" in si_keys: - key_dict["SENTIMENT_INVESTOR"] = "Not defined" - else: - account = requests.get( - f"https://api.sentimentinvestor.com/v4/account" - f"?token={cfg.API_SENTIMENTINVESTOR_TOKEN}&key={cfg.API_SENTIMENTINVESTOR_KEY}" - ) - if account.ok and account.json().get("success", False): - key_dict["SENTIMENT_INVESTOR"] = "Defined, test passed" - else: - key_dict["SENTIMENT_INVESTOR"] = "Defined, test unsuccessful" - - print( - tabulate( - pd.DataFrame(key_dict.items()), - showindex=False, - headers=[], - tablefmt="fancy_grid", - ), - "\n", - ) - - -def print_goodbye(): - """Prints a goodbye message when quitting the terminal""" - goodbye_msg = [ - "An informed ape, is a strong ape. ", - "Remember that stonks only go up. ", - "Diamond hands. ", - "Apes together strong. ", - "This is our way. ", - "Keep the spacesuit ape, we haven't reached the moon yet. ", - "I am not a cat. I'm an ape. ", - "We like the terminal. ", - ] - - goodbye_hr = datetime.now().hour - if goodbye_hr < 5: - goodbye_msg_time = "Go get some rest soldier!" - elif goodbye_hr < 11: - goodbye_msg_time = "Rise and shine baby!" - elif goodbye_hr < 17: - goodbye_msg_time = "Enjoy your day!" - elif goodbye_hr < 23: - goodbye_msg_time = "Tomorrow's another day!" - else: - goodbye_msg_time = "Go get some rest soldier!" - - print( - goodbye_msg[random.randint(0, len(goodbye_msg) - 1)] + goodbye_msg_time + "\n" - ) - - -def sha256sum(filename): - h = hashlib.sha256() - b = bytearray(128 * 1024) - mv = memoryview(b) - with open(filename, "rb", buffering=0) as f: - for n in iter(lambda: f.readinto(mv), 0): - h.update(mv[:n]) - return h.hexdigest() - - -def update_terminal(): - """Updates the terminal by running git pull in the directory. Runs poetry install if needed""" - poetry_hash = sha256sum("poetry.lock") - - completed_process = subprocess.run("git pull", shell=True, check=False) - if completed_process.returncode != 0: - return completed_process.returncode - - new_poetry_hash = sha256sum("poetry.lock") - - if poetry_hash == new_poetry_hash: - print("Great, seems like poetry hasn't been updated!") - return completed_process.returncode - print( - "Seems like more modules have been added, grab a coke, this may take a while." - ) - - completed_process = subprocess.run("poetry install", shell=True, check=False) - if completed_process.returncode != 0: - return completed_process.returncode - - return 0 - - -def about_us(): - """Prints an about us section""" - print( - f"\n{Fore.GREEN}Thanks for using Gamestonk Terminal. This is our way!{Style.RESET_ALL}\n" - "\n" - f"{Fore.CYAN}Join our community on discord: {Style.RESET_ALL}https://discord.gg/Up2QGbMKHY\n" - f"{Fore.CYAN}Follow our twitter for updates: {Style.RESET_ALL}https://twitter.com/gamestonkt\n" - f"{Fore.CYAN}Access our landing page: {Style.RESET_ALL}https://gamestonkterminal.vercel.app\n" - "\n" - f"{Fore.YELLOW}Author:{Style.RESET_ALL} DidierRLopes\n" - f"{Fore.YELLOW}Main Devs:{Style.RESET_ALL} jmaslek, aia\n" - "\n" - f"{Fore.YELLOW}Main Contributors:{Style.RESET_ALL}\n" - f"{Fore.MAGENTA}Working towards a GUI using Qt:{Style.RESET_ALL} piiq, hinxx\n" - f"{Fore.MAGENTA}Working on our landing page:{Style.RESET_ALL} jose-donato, crspy, martiaaz\n" - f"{Fore.MAGENTA}Managing Twitter account:{Style.RESET_ALL} Meghan Hone\n" - f"{Fore.MAGENTA}Responsible by developing Forex menu:{Style.RESET_ALL} alokan\n" - f"{Fore.MAGENTA}Degiro's integration:{Style.RESET_ALL} Chavithra, Deel18\n" - f"{Fore.MAGENTA}Preset screeners:{Style.RESET_ALL} Traceabl3\n" - "\n" - f"{Fore.YELLOW}Partnerships:{Style.RESET_ALL}\n" - f"{Fore.CYAN}FinBrain: {Style.RESET_ALL}https://finbrain.tech\n" - f"{Fore.CYAN}Quiver Quantitative: {Style.RESET_ALL}https://www.quiverquant.com\n" - f"{Fore.CYAN}Ops.Syncretism: {Style.RESET_ALL}https://ops.syncretism.io/api.html\n" - f"{Fore.CYAN}SentimentInvestor: {Style.RESET_ALL}https://sentimentinvestor.com\n" - f"\n{Fore.RED}" - "DISCLAIMER: Trading in financial instruments involves high risks including the risk of losing some, " - "or all, of your investment amount, and may not be suitable for all investors. Before deciding to trade in " - "financial instrument you should be fully informed of the risks and costs associated with trading the financial " - "markets, carefully consider your investment objectives, level of experience, and risk appetite, and seek " - "professional advice where needed. The data contained in Gamestonk Terminal (GST) is not necessarily accurate. " - "GST and any provider of the data contained in this website will not accept liability for any loss or damage " - "as a result of your trading, or your reliance on the information displayed." - f"\n{Style.RESET_ALL}" - ) - - -def bootup(): - # Enable VT100 Escape Sequence for WINDOWS 10 Ver. 1607 - if sys.platform == "win32": - os.system("") + """ + df.sort_index(ascending=True, inplace=True) + bar_colors = ["r" if x[1].Open < x[1].Close else "g" for x in df.iterrows()] try: - if os.name == "nt": - # pylint: disable=E1101 - sys.stdin.reconfigure(encoding="utf-8") - # pylint: disable=E1101 - sys.stdout.reconfigure(encoding="utf-8") - except Exception as e: - print(e, "\n") - - # Print first welcome message and help - print("\nWelcome to Gamestonk Terminal Beta") - - # The commit has was commented out because the terminal was crashing due to git import for multiple users - # ({str(git.Repo('.').head.commit)[:7]}) - - if gtff.ENABLE_THOUGHTS_DAY: - print("-------------------") - try: - thought.get_thought_of_the_day() - except Exception as e: - print(e) - print("") - - -def reset(): - """Resets the terminal. Allows for checking code or keys without quitting""" - print("resetting...") - plt.close("all") - completed_process = subprocess.run("python terminal.py", shell=True, check=False) - if completed_process.returncode != 0: - completed_process = subprocess.run( - "python3 terminal.py", shell=True, check=False + fig, ax = plt.subplots( + 2, + 1, + gridspec_kw={"height_ratios": [3, 1]}, + figsize=plot_autoscale(), + dpi=cfgPlot.PLOT_DPI, ) - if completed_process.returncode != 0: - print("Unfortunately, resetting wasn't possible!\n") + except Exception as e: + print(e) + print( + "Encountered an error trying to open a chart window. Check your X server configuration." + ) + return - return completed_process.returncode + # In order to make nice Volume plot, make the bar width = interval + if interval == "1440min": + bar_width = timedelta(days=1) + title_string = "Daily" + else: + bar_width = timedelta(minutes=int(interval.split("m")[0])) + title_string = f"{int(interval.split('m')[0])} min" + + ax[0].yaxis.tick_right() + if "Adj Close" in df.columns: + ax[0].plot(df.index, df["Adj Close"], c=cfgPlot.VIEW_COLOR) + else: + ax[0].plot(df.index, df["Close"], c=cfgPlot.VIEW_COLOR) + ax[0].set_xlim(df.index[0], df.index[-1]) + ax[0].set_xticks([]) + ax[0].yaxis.set_label_position("right") + ax[0].set_ylabel("Share Price ($)") + ax[0].grid(axis="y", color="gainsboro", linestyle="-", linewidth=0.5) + + ax[0].spines["top"].set_visible(False) + ax[0].spines["left"].set_visible(False) + ax[1].bar( + df.index, df.Volume / 1_000_000, color=bar_colors, alpha=0.8, width=bar_width + ) + ax[1].set_xlim(df.index[0], df.index[-1]) + ax[1].yaxis.tick_right() + ax[1].yaxis.set_label_position("right") + ax[1].set_ylabel("Volume (1M)") + ax[1].grid(axis="y", color="gainsboro", linestyle="-", linewidth=0.5) + ax[1].spines["top"].set_visible(False) + ax[1].spines["left"].set_visible(False) + ax[1].set_xlabel("Time") + fig.suptitle( + symbol + " " + title_string, + size=20, + x=0.15, + y=0.95, + fontfamily="serif", + fontstyle="italic", + ) + if gtff.USE_ION: + plt.ion() + fig.tight_layout(pad=2) + plt.setp(ax[1].get_xticklabels(), rotation=20, horizontalalignment="right") + + plt.show() + print("") diff --git a/gamestonk_terminal/stocks/technical_analysis/README.md b/gamestonk_terminal/stocks/technical_analysis/README.md new file mode 100644 index 00000000000..9eb21bd0891 --- /dev/null +++ b/gamestonk_terminal/stocks/technical_analysis/README.md @@ -0,0 +1,212 @@ +# TECHNICAL ANALYSIS + +This menu aims to perform a technical analysis on a pre-loaded ticker chart, and the usage of the following commands along with an example will be exploited below. + + * [view](#view) + - view historical data and trendlines [Finviz] + * [summary](#summary) + - technical summary report [FinBrain API] + * [recom](#recom) + - recommendation based on Technical Indicators [Tradingview API] + * [pr](#pr) + - pattern recognition [Finnhub] + +[OVERLAP](#OVERLAP) + * [ema](#ema) + - exponential moving average + * [sma](#sma) + - simple moving average + * [vwap](#vwap) + - volume weighted average price + +[MOMENTUM](#MOMENTUM) + * [cci](#cci) + - commodity channel index + * [macd](#macd) + - moving average convergence/divergence + * [rsi](#rsi) + - relative strength index + * [stoch](#stoch) + - stochastic oscillator + +[TREND](#TREND) + * [adx](#adx) + - average directional movement index + * [aroon](#aroon) + - aroon indicator + +[VOLATILITY](#VOLATILITY) + * [bbands](#bbands) + - bollinger bands + +[VOLUME](#VOLUME) + * [ad](#ad) + - Accumulation/distribution line values + * [obv](#obv) + - on balance volume + +[CUSTOM](#CUSTOM) + * [fib](#fib) + - Shows fibonocci levels + + +**S/O to https://github.com/twopirllc/pandas-ta** _Owing to this library, it is fairly easy to add other technical indicators. So, let us know if there's any other that you would like._ + +## view +``` +usage: view +``` + +View historical price with trendlines. [Source: Finviz] + +![aapl](https://user-images.githubusercontent.com/25267873/113757843-02107700-970b-11eb-99ab-eb9b1312547f.png) + + +## summary +``` +usage: summary +``` + +Technical summary report provided by FinBrain's API. FinBrain Technologies develops deep learning algorithms for financial analysis and prediction, which currently serves traders from more than 150 countries all around the world. [Source: https://finbrain.tech] + +Captura de ecrã 2021-03-29, às 00 31 29 + + +## recom +``` +usage: recom [-s {crypto,forex,cfd}] [-e EXCHANGE] [-i {1M,1W,1d,4h,1h,15m,5m,1m}] +``` + +Print tradingview recommendation based on technical indicators. [Source: https://pypi.org/project/tradingview-ta/] + +* -s : screener. Default america. +* -e : exchange, e.g. NASDAQ, NYSE. Default uses Alpha Vantage to get this information from ticker +* -i : interval. Default is showing all of different intervals. + +Captura de ecrã 2021-03-31, às 00 14 41 + + +## pr +``` +usage: pr [-r {1,5,15,30,60,D,W,M}] +``` +Display pattern recognition signals on the data. [Source: https://finnhub.io] + +* -r : Plot resolution to look for pattern signals. Default 'D'. + +![pr](https://user-images.githubusercontent.com/25267873/116812520-06338700-ab47-11eb-8db4-8f5e940507ed.png) + +Captura de ecrã 2021-05-02, às 02 27 10 + + +# OVERLAP + +## ema +``` +usage: ema [-l N_LENGTH] [-o N_OFFSET] +``` +![ema](https://user-images.githubusercontent.com/25267873/108602300-33bac200-7399-11eb-971a-f23f7097aba3.png) + + +## sma +``` +usage: sma [-l L_LENGTH] [-o N_OFFSET] +``` +![sma](https://user-images.githubusercontent.com/25267873/108602304-36b5b280-7399-11eb-86fe-d490fb32aaff.png) + + +## vwap +VWAP is available for intraday data. This plots the most recent day only. +``` +usage: vwap [-o N_OFFSET] +``` +![vwap](https://user-images.githubusercontent.com/18151143/127217340-0f38bafd-fc16-4be4-a80a-6b89913559f5.png) + + +# MOMENTUM + +## cci +``` +usage: cci [-l N_LENGTH] [-s N_SCALAR] [-o N_OFFSET] +``` +![cci](https://user-images.githubusercontent.com/25267873/108602745-96ad5880-739b-11eb-9e86-a1706c3ecb1f.png) + + +## macd +``` +usage: macd [-f N_FAST] [-s N_SLOW] [--signal N_SIGNAL] [-o N_OFFSET] +``` +![macd](https://user-images.githubusercontent.com/25267873/108602739-92813b00-739b-11eb-8a4e-8fa7ed66b2b6.png) + + +## rsi +``` +usage: rsi [-l N_LENGTH] [-s N_SCALAR] [-d N_DRIFT] [-o N_OFFSET] +``` +![rsi](https://user-images.githubusercontent.com/25267873/108602743-957c2b80-739b-11eb-9d0d-6f530b3abb91.png) + + +## stoch +``` +usage: stoch [-k N_FASTKPERIOD] [-d N_SLOWDPERIOD] [--slowkperiod N_SLOWKPERIOD] [-o N_OFFSET] +``` +![stoch](https://user-images.githubusercontent.com/25267873/108602744-9614c200-739b-11eb-8e4d-2cdc9981cb67.png) + + +# TREND + +## adx +``` +usage: adx [-l N_LENGTH] [-s N_SCALAR] [-d N_DRIFT] [-o N_OFFSET] +``` +![adx](https://user-images.githubusercontent.com/25267873/108602991-2bfd1c80-739d-11eb-973f-b836c1b839e6.png) + + +## aroon +``` +usage: aroon [-l N_LENGTH] [-s N_SCALAR] [-o N_OFFSET] +``` +![aroon](https://user-images.githubusercontent.com/25267873/108602987-2b648600-739d-11eb-9a90-154145190595.png) + + +# VOLATILITY + +## bbands +``` +usage: bbands [-h] [-l N_LENGTH] [-s N_STD] [-m S_MAMODE] [-o N_OFFSET] +``` +![bbands](https://user-images.githubusercontent.com/25267873/108602984-28699580-739d-11eb-9b82-2683a9840145.png) + + +# VOLUME + +## ad +``` +usage: ad [-o N_OFFSET] [--open] +``` +![ad](https://user-images.githubusercontent.com/18151143/127217265-73415705-3321-478f-b5a0-3ae1487c74ac.png) + + +## obv +``` +usage: obv [-o N_OFFSET] +``` +![obv](https://user-images.githubusercontent.com/18151143/127217286-d73c1079-1b84-4da9-a5d4-39f4eb2d6b1b.png) + +# CUSTOM + +## fib +Shows fibonocci levels +```python +usage: fib [-p PERIOD] [--start] [--end] +``` +* -p/--period: Number of days to lookback for retracement. Default = 120. +* --start: Allows for custom selection of min point. +* --end : Allows for custom selection of max point. + +The fibonocci retracement works by looking at a minimum and maximum point. Between these values, there is typically support/resistance at +23.5 %, 38.2%, 50% and 61.8%. Those values follow the golden ratio from the fibonocci sequence. + +The `--start` and `--end` flags allow the user to select dates for the min and max points as your retracement levels. Both flags are required if using. + +![Fib1](https://user-images.githubusercontent.com/18151143/127217240-0b4cd88b-8fd3-484f-941e-b02a0efe08dd.png) diff --git a/gamestonk_terminal/stocks/technical_analysis/__init__.py b/gamestonk_terminal/stocks/technical_analysis/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/gamestonk_terminal/technical_analysis/finbrain_view.py b/gamestonk_terminal/stocks/technical_analysis/finbrain_view.py similarity index 100% rename from gamestonk_terminal/technical_analysis/finbrain_view.py rename to gamestonk_terminal/stocks/technical_analysis/finbrain_view.py diff --git a/gamestonk_terminal/technical_analysis/finnhub_view.py b/gamestonk_terminal/stocks/technical_analysis/finnhub_view.py similarity index 100% rename from gamestonk_terminal/technical_analysis/finnhub_view.py rename to gamestonk_terminal/stocks/technical_analysis/finnhub_view.py diff --git a/gamestonk_terminal/technical_analysis/finviz_view.py b/gamestonk_terminal/stocks/technical_analysis/finviz_view.py similarity index 100% rename from gamestonk_terminal/technical_analysis/finviz_view.py rename to gamestonk_terminal/stocks/technical_analysis/finviz_view.py diff --git a/gamestonk_terminal/technical_analysis/ta_controller.py b/gamestonk_terminal/stocks/technical_analysis/ta_controller.py similarity index 78% rename from gamestonk_terminal/technical_analysis/ta_controller.py rename to gamestonk_terminal/stocks/technical_analysis/ta_controller.py index 3190cd791fe..6d50f82841f 100644 --- a/gamestonk_terminal/technical_analysis/ta_controller.py +++ b/gamestonk_terminal/stocks/technical_analysis/ta_controller.py @@ -12,16 +12,20 @@ from prompt_toolkit.completion import NestedCompleter from gamestonk_terminal import feature_flags as gtff from gamestonk_terminal.helper_funcs import get_flair from gamestonk_terminal.menu import session -from gamestonk_terminal.technical_analysis import momentum as ta_momentum -from gamestonk_terminal.technical_analysis import overlap as ta_overlap -from gamestonk_terminal.technical_analysis import trend_indicators as ta_trend -from gamestonk_terminal.technical_analysis import volatility as ta_volatility -from gamestonk_terminal.technical_analysis import volume as ta_volume -from gamestonk_terminal.technical_analysis import finbrain_view -from gamestonk_terminal.technical_analysis import tradingview_view -from gamestonk_terminal.technical_analysis import finviz_view -from gamestonk_terminal.technical_analysis import finnhub_view -from gamestonk_terminal.technical_analysis import custom_indicators_view +from gamestonk_terminal.stocks.technical_analysis import ( + finviz_view, + finbrain_view, + finnhub_view, + tradingview_view, +) +from gamestonk_terminal.common.technical_analysis import ( + custom_indicators_view, + momentum, + overlap, + trend_indicators, + volatility, + volume, +) class TechnicalAnalysisController: @@ -86,7 +90,7 @@ class TechnicalAnalysisController: else: print(f"\n{s_intraday} Stock: {self.ticker}") - print("\nTechnical Analysis:") # https://github.com/twopirllc/pandas-ta + print("\nTechnical Analysis:") print(" cls clear screen") print(" ?/help show this menu again") print(" q quit this menu, and shows back to main menu") @@ -164,6 +168,7 @@ class TechnicalAnalysisController: """Process Quit command - quit the program""" return True + # SPECIFIC def call_view(self, other_args: List[str]): """Process view command""" finviz_view.view(other_args, self.ticker) @@ -180,58 +185,54 @@ class TechnicalAnalysisController: """Process pr command""" finnhub_view.pattern_recognition_view(other_args, self.ticker) - # OVERLAP + # COMMON def call_ema(self, other_args: List[str]): """Process ema command""" - ta_overlap.ema(other_args, self.ticker, self.interval, self.stock) + overlap.ema(other_args, self.ticker, self.interval, self.stock) def call_sma(self, other_args: List[str]): """Process sma command""" - ta_overlap.sma(other_args, self.ticker, self.interval, self.stock) + overlap.sma(other_args, self.ticker, self.interval, self.stock) def call_vwap(self, other_args: List[str]): """Process vwap command""" - ta_overlap.vwap(other_args, self.ticker, self.interval, self.stock) + overlap.vwap(other_args, self.ticker, self.interval, self.stock) - # MOMENTUM def call_cci(self, other_args: List[str]): """Process cci command""" - ta_momentum.cci(other_args, self.ticker, self.interval, self.stock) + momentum.cci(other_args, self.ticker, self.interval, self.stock) def call_macd(self, other_args: List[str]): """Process macd command""" - ta_momentum.macd(other_args, self.ticker, self.interval, self.stock) + momentum.macd(other_args, self.ticker, self.interval, self.stock) def call_rsi(self, other_args: List[str]): """Process rsi command""" - ta_momentum.rsi(other_args, self.ticker, self.interval, self.stock) + momentum.rsi(other_args, self.ticker, self.interval, self.stock) def call_stoch(self, other_args: List[str]): """Process stoch command""" - ta_momentum.stoch(other_args, self.ticker, self.interval, self.stock) + momentum.stoch(other_args, self.ticker, self.interval, self.stock) - # TREND def call_adx(self, other_args: List[str]): """Process adx command""" - ta_trend.adx(other_args, self.ticker, self.interval, self.stock) + trend_indicators.adx(other_args, self.ticker, self.interval, self.stock) def call_aroon(self, other_args: List[str]): """Process aroon command""" - ta_trend.aroon(other_args, self.ticker, self.interval, self.stock) + trend_indicators.aroon(other_args, self.ticker, self.interval, self.stock) - # VOLATILITY def call_bbands(self, other_args: List[str]): """Process bbands command""" - ta_volatility.bbands(other_args, self.ticker, self.interval, self.stock) + volatility.bbands(other_args, self.ticker, self.interval, self.stock) - # VOLUME def call_ad(self, other_args: List[str]): """Process ad command""" - ta_volume.ad(other_args, self.ticker, self.interval, self.stock) + volume.ad(other_args, self.ticker, self.interval, self.stock) def call_obv(self, other_args: List[str]): """Process obv command""" - ta_volume.obv(other_args, self.ticker, self.interval, self.stock) + volume.obv(other_args, self.ticker, self.interval, self.stock) def call_fib(self, other_args: List[str]): """Process fib command""" @@ -240,17 +241,12 @@ class TechnicalAnalysisController: ) -def menu( - ticker: str, start: datetime, interval: str, stock: pd.DataFrame, context: str = "" -): +def menu(ticker: str, start: datetime, interval: str, stock: pd.DataFrame): """Technical Analysis Menu""" ta_controller = TechnicalAnalysisController(ticker, start, interval, stock) ta_controller.call_help(None) - if context: - context = f"{context}>" - while True: # Get input command from user if session and gtff.USE_PROMPT_TOOLKIT: @@ -258,11 +254,11 @@ def menu( {c: None for c in ta_controller.CHOICES} ) an_input = session.prompt( - f"{get_flair()} {context}(ta)> ", + f"{get_flair()} (stocks)>(ta)> ", completer=completer, ) else: - an_input = input(f"{get_flair()} {context}(ta)> ") + an_input = input(f"{get_flair()} (stocks)>(ta)> ") try: plt.close("all") diff --git a/gamestonk_terminal/technical_analysis/tradingview_view.py b/gamestonk_terminal/stocks/technical_analysis/tradingview_view.py similarity index 100% rename from gamestonk_terminal/technical_analysis/tradingview_view.py rename to gamestonk_terminal/stocks/technical_analysis/tradingview_view.py diff --git a/gamestonk_terminal/terminal_helper.py b/gamestonk_terminal/terminal_helper.py new file mode 100644 index 00000000000..01f77f6e105 --- /dev/null +++ b/gamestonk_terminal/terminal_helper.py @@ -0,0 +1,410 @@ +"""Terminal helper""" +__docformat__ = "numpy" +import os +import sys +import subprocess +import random +from datetime import datetime +import hashlib +import requests +from colorama import Fore, Style +import matplotlib.pyplot as plt +import pandas as pd +from alpha_vantage.timeseries import TimeSeries +import quandl +from coinmarketcapapi import CoinMarketCapAPI, CoinMarketCapAPIError +import pyEX +from pyEX.common.exception import PyEXception +from tabulate import tabulate +import praw +from prawcore.exceptions import ResponseException + +# import git + +# pylint: disable=no-member,too-many-branches,C0302 + +from gamestonk_terminal import config_terminal as cfg +from gamestonk_terminal import feature_flags as gtff +from gamestonk_terminal import thought_of_the_day as thought + + +# pylint: disable=too-many-statements + + +def check_api_keys(): + """Check api keys and if they are supplied""" + + key_dict = {} + if cfg.API_KEY_ALPHAVANTAGE == "REPLACE_ME": # pragma: allowlist secret + key_dict["ALPHA_VANTAGE"] = "Not defined" + else: + df = TimeSeries( + key=cfg.API_KEY_ALPHAVANTAGE, output_format="pandas" + ).get_intraday(symbol="AAPL") + if df[0].empty: + key_dict["ALPHA_VANTAGE"] = "defined, test failed" + else: + key_dict["ALPHA_VANTAGE"] = "defined, test passed" + + if cfg.API_KEY_FINANCIALMODELINGPREP == "REPLACE_ME": # pragma: allowlist secret + key_dict["FINANCIAL_MODELING_PREP"] = "Not defined" + else: + r = requests.get( + f"https://financialmodelingprep.com/api/v3/profile/AAPL?apikey={cfg.API_KEY_FINANCIALMODELINGPREP}" + ) + if r.status_code in [403, 401]: + key_dict["FINANCIAL_MODELING_PREP"] = "defined, test failed" + elif r.status_code == 200: + key_dict["FINANCIAL_MODELING_PREP"] = "defined, test passed" + else: + key_dict["FINANCIAL_MODELING_PREP"] = "defined, test inconclusive" + + if cfg.API_KEY_QUANDL == "REPLACE_ME": # pragma: allowlist secret + key_dict["QUANDL"] = "Not defined" + else: + try: + quandl.save_key(cfg.API_KEY_QUANDL) + quandl.get_table( + "ZACKS/FC", + paginate=True, + ticker=["AAPL", "MSFT"], + per_end_date={"gte": "2015-01-01"}, + qopts={"columns": ["ticker", "per_end_date"]}, + ) + key_dict["QUANDL"] = "defined, test passed" + except quandl.errors.quandl_error.ForbiddenError: + key_dict["QUANDL"] = "defined, test failed" + + if cfg.API_POLYGON_KEY == "REPLACE_ME": + key_dict["POLYGON"] = "Not defined" + else: + r = requests.get( + f"https://api.polygon.io/v2/aggs/ticker/AAPL/range/1/day/2020-06-01/2020-06-17?apiKey={cfg.API_POLYGON_KEY}" + ) + if r.status_code in [403, 401]: + key_dict["POLYGON"] = "defined, test failed" + elif r.status_code == 200: + key_dict["POLYGON"] = "defined, test passed" + else: + key_dict["POLYGON"] = "defined, test inconclusive" + + if cfg.API_FRED_KEY == "REPLACE_ME": + key_dict["FRED"] = "Not defined" + else: + r = requests.get( + f"https://api.stlouisfed.org/fred/series?series_id=GNPCA&api_key={cfg.API_FRED_KEY}" + ) + if r.status_code in [403, 401, 400]: + key_dict["FRED"] = "defined, test failed" + elif r.status_code == 200: + key_dict["FRED"] = "defined, test passed" + else: + key_dict["FRED"] = "defined, test inconclusive" + + if cfg.API_NEWS_TOKEN == "REPLACE_ME": + key_dict["NEWSAPI"] = "Not defined" + else: + r = requests.get( + f"https://newsapi.org/v2/everything?q=keyword&apiKey={cfg.API_NEWS_TOKEN}" + ) + if r.status_code in [401, 403]: + key_dict["NEWSAPI"] = "defined, test failed" + elif r.status_code == 200: + key_dict["NEWSAPI"] = "defined, test passed" + else: + key_dict["NEWSAPI"] = "defined, test inconclusive" + + if cfg.TRADIER_TOKEN == "REPLACE_ME": + key_dict["TRADIER"] = "Not defined" + else: + r = requests.get( + "https://sandbox.tradier.com/v1/markets/quotes", + params={"symbols": "AAPL"}, + headers={ + "Authorization": f"Bearer {cfg.TRADIER_TOKEN}", + "Accept": "application/json", + }, + ) + if r.status_code in [401, 403]: + key_dict["TRADIER"] = "defined, test failed" + elif r.status_code == 200: + key_dict["TRADIER"] = "defined, test passed" + else: + key_dict["TRADIER"] = "defined, test inconclusive" + + if cfg.API_CMC_KEY == "REPLACE_ME": + key_dict["COINMARKETCAP"] = "Not defined" + else: + cmc = CoinMarketCapAPI(cfg.API_CMC_KEY) + try: + cmc.exchange_info() + key_dict["COINMARKETCAP"] = "defined, test passed" + except CoinMarketCapAPIError: + key_dict["COINMARKETCAP"] = "defined, test failed" + + if cfg.API_FINNHUB_KEY == "REPLACE_ME": + key_dict["FINNHUB"] = "Not defined" + else: + r = r = requests.get( + f"https://finnhub.io/api/v1/quote?symbol=AAPL&token={cfg.API_FINNHUB_KEY}" + ) + if r.status_code in [403, 401, 400]: + key_dict["FINNHUB"] = "defined, test failed" + elif r.status_code == 200: + key_dict["FINNHUB"] = "defined, test passed" + else: + key_dict["FINNHUB"] = "defined, test inconclusive" + + if cfg.API_IEX_TOKEN == "REPLACE_ME": + key_dict["IEXCLOUD"] = "Not defined" + else: + try: + pyEX.Client(api_token=cfg.API_IEX_TOKEN, version="v1") + key_dict["IEXCLOUD"] = "defined, test passed" + except PyEXception: + key_dict["IEXCLOUD"] = "defined, test failed" + + # Reddit + reddit_keys = [ + cfg.API_REDDIT_CLIENT_ID, + cfg.API_REDDIT_CLIENT_SECRET, + cfg.API_REDDIT_USERNAME, + cfg.API_REDDIT_PASSWORD, + cfg.API_REDDIT_USER_AGENT, + ] + if "REPLACE_ME" in reddit_keys: + key_dict["REDDIT"] = "Not defined" + else: + praw_api = praw.Reddit( + client_id=cfg.API_REDDIT_CLIENT_ID, + client_secret=cfg.API_REDDIT_CLIENT_SECRET, + username=cfg.API_REDDIT_USERNAME, + user_agent=cfg.API_REDDIT_USER_AGENT, + password=cfg.API_REDDIT_PASSWORD, + ) + + try: + praw_api.user.me() + key_dict["REDDIT"] = "defined, test passed" + except ResponseException: + key_dict["REDDIT"] = "defined, test failed" + + # Twitter keys + twitter_keys = [ + cfg.API_TWITTER_KEY, + cfg.API_TWITTER_SECRET_KEY, + cfg.API_TWITTER_BEARER_TOKEN, + ] + if "REPLACE_ME" in twitter_keys: + key_dict["TWITTER"] = "Not defined" + else: + params = { + "query": "(\\$AAPL) (lang:en)", + "max_results": "10", + "tweet.fields": "created_at,lang", + } + r = requests.get( + "https://api.twitter.com/2/tweets/search/recent", + params=params, # type: ignore + headers={"authorization": "Bearer " + cfg.API_TWITTER_BEARER_TOKEN}, + ) + if r.status_code == 200: + key_dict["TWITTER"] = "defined, test passed" + elif r.status_code in [401, 403]: + key_dict["TWITTER"] = "defined, test failed" + else: + key_dict["TWITTER"] = "defined, test inconclusive" + + # Robinhood keys + rh_keys = [cfg.RH_USERNAME, cfg.RH_PASSWORD] + if "REPLACE_ME" in rh_keys: + key_dict["ROBINHOOD"] = "Not defined" + else: + key_dict["ROBINHOOD"] = "defined, not tested" + # Degiro keys + dg_keys = [cfg.DG_USERNAME, cfg.DG_PASSWORD, cfg.DG_TOTP_SECRET] + if "REPLACE_ME" in dg_keys: + key_dict["DEGIRO"] = "Not defined" + else: + key_dict["DEGIRO"] = "defined, not tested" + # OANDA keys + oanda_keys = [cfg.OANDA_TOKEN, cfg.OANDA_ACCOUNT] + if "REPLACE_ME" in oanda_keys: + key_dict["OANDA"] = "Not defined" + else: + key_dict["OANDA"] = "defined, not tested" + # Binance keys + bn_keys = [cfg.API_BINANCE_KEY, cfg.API_BINANCE_SECRET] + if "REPLACE_ME" in bn_keys: + key_dict["BINANCE"] = "Not defined" + else: + key_dict["BINANCE"] = "defined, not tested" + + # SentimentInvestor keys + si_keys = [cfg.API_SENTIMENTINVESTOR_KEY, cfg.API_SENTIMENTINVESTOR_TOKEN] + if "REPLACE_ME" in si_keys: + key_dict["SENTIMENT_INVESTOR"] = "Not defined" + else: + account = requests.get( + f"https://api.sentimentinvestor.com/v4/account" + f"?token={cfg.API_SENTIMENTINVESTOR_TOKEN}&key={cfg.API_SENTIMENTINVESTOR_KEY}" + ) + if account.ok and account.json().get("success", False): + key_dict["SENTIMENT_INVESTOR"] = "Defined, test passed" + else: + key_dict["SENTIMENT_INVESTOR"] = "Defined, test unsuccessful" + + print( + tabulate( + pd.DataFrame(key_dict.items()), + showindex=False, + headers=[], + tablefmt="fancy_grid", + ), + "\n", + ) + + +def print_goodbye(): + """Prints a goodbye message when quitting the terminal""" + goodbye_msg = [ + "An informed ape, is a strong ape. ", + "Remember that stonks only go up. ", + "Diamond hands. ", + "Apes together strong. ", + "This is our way. ", + "Keep the spacesuit ape, we haven't reached the moon yet. ", + "I am not a cat. I'm an ape. ", + "We like the terminal. ", + ] + + goodbye_hr = datetime.now().hour + if goodbye_hr < 5: + goodbye_msg_time = "Go get some rest soldier!" + elif goodbye_hr < 11: + goodbye_msg_time = "Rise and shine baby!" + elif goodbye_hr < 17: + goodbye_msg_time = "Enjoy your day!" + elif goodbye_hr < 23: + goodbye_msg_time = "Tomorrow's another day!" + else: + goodbye_msg_time = "Go get some rest soldier!" + + print( + goodbye_msg[random.randint(0, len(goodbye_msg) - 1)] + goodbye_msg_time + "\n" + ) + + +def sha256sum(filename): + h = hashlib.sha256() + b = bytearray(128 * 1024) + mv = memoryview(b) + with open(filename, "rb", buffering=0) as f: + for n in iter(lambda: f.readinto(mv), 0): + h.update(mv[:n]) + return h.hexdigest() + + +def update_terminal(): + """Updates the terminal by running git pull in the directory. Runs poetry install if needed""" + poetry_hash = sha256sum("poetry.lock") + + completed_process = subprocess.run("git pull", shell=True, check=False) + if completed_process.returncode != 0: + return completed_process.returncode + + new_poetry_hash = sha256sum("poetry.lock") + + if poetry_hash == new_poetry_hash: + print("Great, seems like poetry hasn't been updated!") + return completed_process.returncode + print( + "Seems like more modules have been added, grab a coke, this may take a while." + ) + + completed_process = subprocess.run("poetry install", shell=True, check=False) + if completed_process.returncode != 0: + return completed_process.returncode + + return 0 + + +def about_us(): + """Prints an about us section""" + print( + f"\n{Fore.GREEN}Thanks for using Gamestonk Terminal. This is our way!{Style.RESET_ALL}\n" + "\n" + f"{Fore.CYAN}Join our community on discord: {Style.RESET_ALL}https://discord.gg/Up2QGbMKHY\n" + f"{Fore.CYAN}Follow our twitter for updates: {Style.RESET_ALL}https://twitter.com/gamestonkt\n" + f"{Fore.CYAN}Access our landing page: {Style.RESET_ALL}https://gamestonkterminal.vercel.app\n" + "\n" + f"{Fore.YELLOW}Author:{Style.RESET_ALL} DidierRLopes\n" + f"{Fore.YELLOW}Main Devs:{Style.RESET_ALL} jmaslek, aia\n" + "\n" + f"{Fore.YELLOW}Main Contributors:{Style.RESET_ALL}\n" + f"{Fore.MAGENTA}Working towards a GUI using Qt:{Style.RESET_ALL} piiq, hinxx\n" + f"{Fore.MAGENTA}Working on our landing page:{Style.RESET_ALL} jose-donato, crspy, martiaaz\n" + f"{Fore.MAGENTA}Managing Twitter account:{Style.RESET_ALL} Meghan Hone\n" + f"{Fore.MAGENTA}Responsible by developing Forex menu:{Style.RESET_ALL} alokan\n" + f"{Fore.MAGENTA}Degiro's integration:{Style.RESET_ALL} Chavithra, Deel18\n" + f"{Fore.MAGENTA}Preset screeners:{Style.RESET_ALL} Traceabl3\n" + "\n" + f"{Fore.YELLOW}Partnerships:{Style.RESET_ALL}\n" + f"{Fore.CYAN}FinBrain: {Style.RESET_ALL}https://finbrain.tech\n" + f"{Fore.CYAN}Quiver Quantitative: {Style.RESET_ALL}https://www.quiverquant.com\n" + f"{Fore.CYAN}Ops.Syncretism: {Style.RESET_ALL}https://ops.syncretism.io/api.html\n" + f"{Fore.CYAN}SentimentInvestor: {Style.RESET_ALL}https://sentimentinvestor.com\n" + f"\n{Fore.RED}" + "DISCLAIMER: Trading in financial instruments involves high risks including the risk of losing some, " + "or all, of your investment amount, and may not be suitable for all investors. Before deciding to trade in " + "financial instrument you should be fully informed of the risks and costs associated with trading the financial " + "markets, carefully consider your investment objectives, level of experience, and risk appetite, and seek " + "professional advice where needed. The data contained in Gamestonk Terminal (GST) is not necessarily accurate. " + "GST and any provider of the data contained in this website will not accept liability for any loss or damage " + "as a result of your trading, or your reliance on the information displayed." + f"\n{Style.RESET_ALL}" + ) + + +def bootup(): + # Enable VT100 Escape Sequence for WINDOWS 10 Ver. 1607 + if sys.platform == "win32": + os.system("") + + try: + if os.name == "nt": + # pylint: disable=E1101 + sys.stdin.reconfigure(encoding="utf-8") + # pylint: disable=E1101 + sys.stdout.reconfigure(encoding="utf-8") + except Exception as e: + print(e, "\n") + + # Print first welcome message and help + print("\nWelcome to Gamestonk Terminal Beta") + + # The commit has was commented out because the terminal was crashing due to git import for multiple users + # ({str(git.Repo('.').head.commit)[:7]}) + + if gtff.ENABLE_THOUGHTS_DAY: + print("-------------------") + try: + thought.get_thought_of_the_day() + except Exception as e: + print(e) + print("") + + +def reset(): + """Resets the terminal. Allows for checking code or keys without quitting""" + print("resetting...") + plt.close("all") + completed_process = subprocess.run("python terminal.py", shell=True, check=False) + if completed_process.returncode != 0: + completed_process = subprocess.run( + "python3 terminal.py", shell=True, check=False + ) + if completed_process.returncode != 0: + print("Unfortunately, resetting wasn't possible!\n") + + return completed_process.returncode diff --git a/notebooks/templates/crypto_market.ipynb b/notebooks/templates/crypto_market.ipynb index a6fc469534c..3f32abec8bc 100644 --- a/notebooks/templates/crypto_market.ipynb +++ b/notebooks/templates/crypto_market.ipynb @@ -3,8 +3,10 @@ { "cell_type": "code", "execution_count": 47, - "id": "atomic-accessory", - "metadata": {}, + "id": "exempt-thesaurus", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "import importlib\n", @@ -25,8 +27,9 @@ { "cell_type": "code", "execution_count": 48, - "id": "early-oxford", + "id": "latest-waste", "metadata": { + "collapsed": true, "tags": [ "parameters" ] @@ -39,7 +42,7 @@ { "cell_type": "code", "execution_count": 49, - "id": "extra-tennessee", + "id": "tamil-laundry", "metadata": {}, "outputs": [ { @@ -62,8 +65,10 @@ { "cell_type": "code", "execution_count": 50, - "id": "lovely-communications", - "metadata": {}, + "id": "hungry-beverage", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "from gamestonk_terminal.cryptocurrency.coingecko import pycoingecko_view as cg\n", @@ -72,7 +77,7 @@ }, { "cell_type": "markdown", - "id": "ee21a8d8", + "id": "round-connection", "metadata": {}, "source": [ "## Bitcoin Chart" @@ -81,8 +86,10 @@ { "cell_type": "code", "execution_count": null, - "id": "f9872e1e", - "metadata": {}, + "id": "discrete-olive", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "cp.chart(\"btc-bitcoin\", [\"-d\", \"60\"])" @@ -90,7 +97,7 @@ }, { "cell_type": "markdown", - "id": "criminal-connection", + "id": "capable-guidance", "metadata": {}, "source": [ "## Global Market Information" @@ -99,7 +106,7 @@ { "cell_type": "code", "execution_count": 51, - "id": "indonesian-stuff", + "id": "removed-billy", "metadata": {}, "outputs": [ { @@ -145,7 +152,7 @@ }, { "cell_type": "markdown", - "id": "c4af059a", + "id": "dental-productivity", "metadata": {}, "source": [ "## Hot news" @@ -154,7 +161,7 @@ { "cell_type": "code", "execution_count": 64, - "id": "72401875", + "id": "positive-switch", "metadata": {}, "outputs": [ { @@ -247,7 +254,7 @@ }, { "cell_type": "markdown", - "id": "4cb62372", + "id": "organizational-recognition", "metadata": {}, "source": [ "## Top coins market information" @@ -256,7 +263,7 @@ { "cell_type": "code", "execution_count": 65, - "id": "3e0a2546", + "id": "organizational-accuracy", "metadata": {}, "outputs": [ { @@ -308,7 +315,7 @@ }, { "cell_type": "markdown", - "id": "recognized-affair", + "id": "twenty-consideration", "metadata": {}, "source": [ "## Top gainers in last 24h" @@ -317,7 +324,7 @@ { "cell_type": "code", "execution_count": 53, - "id": "special-certification", + "id": "written-insight", "metadata": {}, "outputs": [ { @@ -367,7 +374,7 @@ }, { "cell_type": "markdown", - "id": "473b49ae", + "id": "compliant-orleans", "metadata": {}, "source": [ "## Top losers in last 24h" @@ -376,7 +383,7 @@ { "cell_type": "code", "execution_count": 54, - "id": "38e7f387", + "id": "sound-memorabilia", "metadata": {}, "outputs": [ { @@ -426,7 +433,7 @@ }, { "cell_type": "markdown", - "id": "5285e27d", + "id": "collaborative-chrome", "metadata": {}, "source": [ "## Top coins with most positive sentiment" @@ -435,7 +442,7 @@ { "cell_type": "code", "execution_count": 55, - "id": "0ae215bc", + "id": "featured-creek", "metadata": {}, "outputs": [ { @@ -485,7 +492,7 @@ }, { "cell_type": "markdown", - "id": "indoor-printing", + "id": "champion-repository", "metadata": {}, "source": [ "## Decentralized Finance Global Market Info" @@ -494,7 +501,7 @@ { "cell_type": "code", "execution_count": 56, - "id": "consolidated-childhood", + "id": "governing-navigation", "metadata": {}, "outputs": [ { @@ -528,7 +535,7 @@ }, { "cell_type": "markdown", - "id": "1aab8cf7", + "id": "decreased-twins", "metadata": {}, "source": [ "## Top DeFi Coins" @@ -537,7 +544,7 @@ { "cell_type": "code", "execution_count": 57, - "id": "minus-cross", + "id": "descending-fiber", "metadata": { "scrolled": false }, @@ -589,7 +596,7 @@ }, { "cell_type": "markdown", - "id": "d5431bb2", + "id": "armed-martial", "metadata": {}, "source": [ "## Top Decentralized Exchanges" @@ -598,7 +605,7 @@ { "cell_type": "code", "execution_count": 58, - "id": "0adedc11", + "id": "promotional-pantyhose", "metadata": {}, "outputs": [ { @@ -638,7 +645,7 @@ }, { "cell_type": "markdown", - "id": "8d92faa0", + "id": "north-shelter", "metadata": {}, "source": [ "## Top Yield Farms" @@ -647,7 +654,7 @@ { "cell_type": "code", "execution_count": 59, - "id": "1e386cf8", + "id": "unusual-playback", "metadata": {}, "outputs": [ { @@ -699,7 +706,7 @@ { "cell_type": "code", "execution_count": 60, - "id": "central-jacob", + "id": "turkish-binary", "metadata": {}, "outputs": [ { @@ -936,8 +943,10 @@ { "cell_type": "code", "execution_count": null, - "id": "957a30c6", - "metadata": {}, + "id": "fatal-court", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [] } @@ -959,7 +968,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.10" + "version": "3.6.8" } }, "nbformat": 4, diff --git a/notebooks/templates/dark_pool.ipynb b/notebooks/templates/dark_pool.ipynb index 63a1f48849a..a6b4eb10755 100644 --- a/notebooks/templates/dark_pool.ipynb +++ b/notebooks/templates/dark_pool.ipynb @@ -3,8 +3,10 @@ { "cell_type": "code", "execution_count": null, - "id": "atomic-accessory", - "metadata": {}, + "id": "weighted-pharmacy", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "import importlib\n", @@ -25,8 +27,9 @@ { "cell_type": "code", "execution_count": null, - "id": "early-oxford", + "id": "photographic-wings", "metadata": { + "collapsed": true, "tags": [ "parameters" ] @@ -40,8 +43,10 @@ { "cell_type": "code", "execution_count": null, - "id": "extra-tennessee", - "metadata": {}, + "id": "successful-tradition", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "display(Markdown(f\"# {ticker.upper()} - Dark Pool - {datetime.now().strftime('%Y/%m/%d %H:%M:%S')}\"))" @@ -50,17 +55,19 @@ { "cell_type": "code", "execution_count": null, - "id": "lovely-communications", - "metadata": {}, + "id": "recreational-newsletter", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ - "from gamestonk_terminal.technical_analysis import trendline_api as trend\n", - "from gamestonk_terminal.due_diligence import finviz_view as finviz" + "from gamestonk_terminal.common.technical_analysis import trendline_api as trend\n", + "from gamestonk_terminal.stocks.due_diligence import finviz_view as finviz" ] }, { "cell_type": "markdown", - "id": "criminal-connection", + "id": "nervous-edgar", "metadata": {}, "source": [ "## Top 10 Negative Dark Pool Positions" @@ -69,17 +76,19 @@ { "cell_type": "code", "execution_count": null, - "id": "indonesian-stuff", - "metadata": {}, + "id": "opponent-atlas", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ - "from gamestonk_terminal.discovery import stockgrid_view\n", + "from gamestonk_terminal.stocks.discovery import stockgrid_view\n", "stockgrid_view.darkshort([\"-a\"])" ] }, { "cell_type": "markdown", - "id": "indoor-printing", + "id": "faced-stranger", "metadata": {}, "source": [ "## Previous Ten Days of trading data for the Dark Pool" @@ -88,19 +97,23 @@ { "cell_type": "code", "execution_count": null, - "id": "consolidated-childhood", - "metadata": {}, + "id": "exterior-royal", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ - "from gamestonk_terminal.due_diligence import stockgrid_dd_view\n", + "from gamestonk_terminal.stocks.due_diligence import stockgrid_dd_view\n", "stockgrid_dd_view.darkpos(ticker.upper(), [\"-n\", \"10\", \"-r\"])" ] }, { "cell_type": "code", "execution_count": null, - "id": "minus-cross", - "metadata": {}, + "id": "polar-plain", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "stockgrid_dd_view.shortview(ticker.upper(), [\"-n\", \"10\", \"-r\"])" @@ -108,7 +121,7 @@ }, { "cell_type": "markdown", - "id": "recognized-affair", + "id": "foster-amendment", "metadata": {}, "source": [ "## Options info" @@ -117,8 +130,10 @@ { "cell_type": "code", "execution_count": null, - "id": "special-certification", - "metadata": {}, + "id": "opponent-requirement", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "from gamestonk_terminal.options import barchart_view\n", @@ -127,7 +142,7 @@ }, { "cell_type": "markdown", - "id": "respected-fossil", + "id": "junior-paper", "metadata": {}, "source": [ "## Put and Call Open Interest Expiring" @@ -136,8 +151,10 @@ { "cell_type": "code", "execution_count": null, - "id": "compressed-there", - "metadata": {}, + "id": "general-reserve", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "from gamestonk_terminal.options import yfinance_model, yfinance_view\n", @@ -153,7 +170,7 @@ }, { "cell_type": "markdown", - "id": "combined-integrity", + "id": "decreased-foster", "metadata": {}, "source": [ "## Failure-to-deliver (30 days lag)" @@ -162,22 +179,26 @@ { "cell_type": "code", "execution_count": null, - "id": "exciting-harvard", - "metadata": {}, + "id": "armed-ridge", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ - "from gamestonk_terminal import main_helper\n", - "_, _, _, stock = main_helper.load([\"-t\", ticker], \"\", \"\", 1440, pd.DataFrame())\n", + "from gamestonk_terminal.stocks import stocks_helper\n", + "_, _, _, stock = stocks_helper.load([\"-t\", ticker], \"\", \"\", 1440, pd.DataFrame())\n", "\n", - "from gamestonk_terminal.due_diligence import sec_view\n", + "from gamestonk_terminal.stocks.due_diligence import sec_view\n", "sec_view.fails_to_deliver([], ticker.upper(), stock)" ] }, { "cell_type": "code", "execution_count": null, - "id": "central-jacob", - "metadata": {}, + "id": "noted-mobile", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "!jupyter nbconvert {os.path.join(\"notebooks\", \"reports\", report_name + \".ipynb\")} --to html --no-input" @@ -201,7 +222,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.10" + "version": "3.6.8" } }, "nbformat": 4, diff --git a/notebooks/templates/due_diligence.ipynb b/notebooks/templates/due_diligence.ipynb index f3c53955f77..92cc6acc336 100644 --- a/notebooks/templates/due_diligence.ipynb +++ b/notebooks/templates/due_diligence.ipynb @@ -3,8 +3,10 @@ { "cell_type": "code", "execution_count": null, - "id": "second-school", - "metadata": {}, + "id": "collaborative-pharmacology", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "import importlib\n", @@ -25,8 +27,9 @@ { "cell_type": "code", "execution_count": null, - "id": "amazing-wrapping", + "id": "future-association", "metadata": { + "collapsed": true, "tags": [ "parameters" ] @@ -41,8 +44,10 @@ { "cell_type": "code", "execution_count": null, - "id": "prescription-minister", - "metadata": {}, + "id": "oriental-wells", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "display(Markdown(f\"# {ticker.upper()} - Due Diligence - {datetime.now().strftime('%Y/%m/%d %H:%M:%S')}\"))" @@ -51,8 +56,10 @@ { "cell_type": "code", "execution_count": null, - "id": "conventional-smile", - "metadata": {}, + "id": "fitted-affect", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "report_cache_dir = pathlib.Path(base_path, \"notebooks\", \"reports\", report_name)\n", @@ -68,19 +75,23 @@ { "cell_type": "code", "execution_count": null, - "id": "comfortable-twelve", - "metadata": {}, + "id": "black-latvia", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ - "from gamestonk_terminal.technical_analysis import trendline_api as trend\n", - "from gamestonk_terminal.due_diligence import finviz_view as finviz" + "from gamestonk_terminal.common.technical_analysis import trendline_api as trend\n", + "from gamestonk_terminal.stocks.due_diligence import finviz_view as finviz" ] }, { "cell_type": "code", "execution_count": null, - "id": "african-citation", - "metadata": {}, + "id": "loved-dietary", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "df_stock_cache = pathlib.Path(report_cache_dir, f\"{ticker}_stock_data.pkl\")\n", @@ -98,7 +109,7 @@ }, { "cell_type": "markdown", - "id": "classical-sodium", + "id": "transparent-change", "metadata": {}, "source": [ "## Candle View" @@ -107,8 +118,10 @@ { "cell_type": "code", "execution_count": null, - "id": "instructional-saturday", - "metadata": {}, + "id": "ruled-marks", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "import mplfinance as mpf\n", @@ -135,8 +148,10 @@ { "cell_type": "code", "execution_count": null, - "id": "continuing-defensive", - "metadata": {}, + "id": "ahead-return", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "mpf.plot(df_stock,type='candle',mav=(20,50,200),volume=True, addplot=ap0,\n", @@ -146,7 +161,7 @@ }, { "cell_type": "markdown", - "id": "pursuant-frost", + "id": "amber-hayes", "metadata": {}, "source": [ "## Analyst Targets" @@ -155,8 +170,10 @@ { "cell_type": "code", "execution_count": null, - "id": "stretch-offer", - "metadata": {}, + "id": "conservative-baking", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "df_fa = finviz.analyst_df(ticker)\n", @@ -166,16 +183,18 @@ { "cell_type": "code", "execution_count": null, - "id": "cross-filename", - "metadata": {}, + "id": "moderate-dealer", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ - "from gamestonk_terminal.fundamental_analysis import av_view as av" + "from gamestonk_terminal.stocks.fundamental_analysis import av_view as av" ] }, { "cell_type": "markdown", - "id": "conscious-monkey", + "id": "victorian-classic", "metadata": {}, "source": [ "## Annual Income Statement" @@ -184,8 +203,10 @@ { "cell_type": "code", "execution_count": null, - "id": "completed-likelihood", - "metadata": {}, + "id": "three-vegetation", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "# Annual Income Statement\n", @@ -194,7 +215,7 @@ }, { "cell_type": "markdown", - "id": "rocky-evidence", + "id": "collected-deployment", "metadata": {}, "source": [ "## Quarterly Income Statement" @@ -203,8 +224,10 @@ { "cell_type": "code", "execution_count": null, - "id": "handy-warning", - "metadata": {}, + "id": "grateful-minnesota", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "# Quarterly Income Statement\n", @@ -213,7 +236,7 @@ }, { "cell_type": "markdown", - "id": "south-sphere", + "id": "angry-somerset", "metadata": {}, "source": [ "## Annual Balance Sheet" @@ -222,8 +245,10 @@ { "cell_type": "code", "execution_count": null, - "id": "optimum-sandwich", - "metadata": {}, + "id": "fifty-angola", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "# Annual Balance Sheet\n", @@ -232,7 +257,7 @@ }, { "cell_type": "markdown", - "id": "metric-concentration", + "id": "typical-fundamentals", "metadata": {}, "source": [ "## Annual Cash Flow" @@ -241,8 +266,10 @@ { "cell_type": "code", "execution_count": null, - "id": "plastic-color", - "metadata": {}, + "id": "magnetic-throat", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "# Annual cash flow\n", @@ -252,8 +279,10 @@ { "cell_type": "code", "execution_count": null, - "id": "overall-material", - "metadata": {}, + "id": "instructional-skating", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "!jupyter nbconvert {os.path.join(\"notebooks\", \"reports\", report_name + \".ipynb\")} --to html --no-input" @@ -277,7 +306,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.10" + "version": "3.6.8" } }, "nbformat": 4, diff --git a/notebooks/templates/econ_data.ipynb b/notebooks/templates/econ_data.ipynb index 35359fa9464..f8ee687f598 100644 --- a/notebooks/templates/econ_data.ipynb +++ b/notebooks/templates/econ_data.ipynb @@ -3,8 +3,10 @@ { "cell_type": "code", "execution_count": null, - "id": "blank-couple", - "metadata": {}, + "id": "another-behalf", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "import importlib\n", @@ -24,8 +26,9 @@ { "cell_type": "code", "execution_count": null, - "id": "naked-shower", + "id": "racial-graduation", "metadata": { + "collapsed": true, "tags": [ "parameters" ] @@ -39,8 +42,10 @@ { "cell_type": "code", "execution_count": null, - "id": "5c860cb4", - "metadata": {}, + "id": "commercial-cargo", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "display(Markdown(f\"# Economy Data - {datetime.now().strftime('%Y/%m/%d %H:%M:%S')}\"))" @@ -49,8 +54,10 @@ { "cell_type": "code", "execution_count": null, - "id": "moderate-cheat", - "metadata": {}, + "id": "alive-borough", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "report_cache_dir = pathlib.Path(base_path, \"notebooks\", \"reports\", report_name)\n", @@ -66,16 +73,18 @@ { "cell_type": "code", "execution_count": null, - "id": "southern-gnome", - "metadata": {}, + "id": "orange-merit", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ - "from gamestonk_terminal.papermill import econ_data_helper as edh" + "from gamestonk_terminal.economy.report import econ_data_helper as edh" ] }, { "cell_type": "markdown", - "id": "initial-palace", + "id": "informative-behavior", "metadata": {}, "source": [ "## Dow Jones - 2 year trend with 20, 50 and 200 day SMA" @@ -84,8 +93,10 @@ { "cell_type": "code", "execution_count": null, - "id": "invalid-interstate", - "metadata": {}, + "id": "stylish-elite", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "edh.draw_graph(\"^DJI\", report_cache_dir, line_type=\"line\", draw_mas=(20,50,200), draw_volume=True, time_delta=720, low_trend=False)" @@ -93,7 +104,7 @@ }, { "cell_type": "markdown", - "id": "responsible-poker", + "id": "fifty-happiness", "metadata": {}, "source": [ "## Dow Jones - 1 year trend with 20, 50 and 200 day SMA" @@ -102,8 +113,10 @@ { "cell_type": "code", "execution_count": null, - "id": "departmental-sender", - "metadata": {}, + "id": "identical-classification", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "edh.draw_graph(\"^DJI\", report_cache_dir, line_type=\"line\", draw_mas=(20,50,200), draw_volume=True, time_delta=360, low_trend=True)" @@ -111,7 +124,7 @@ }, { "cell_type": "markdown", - "id": "passing-printing", + "id": "boxed-turning", "metadata": {}, "source": [ "## S&P 500 - 2 year trend with 20, 50 and 200 day SMA" @@ -120,8 +133,10 @@ { "cell_type": "code", "execution_count": null, - "id": "related-quality", - "metadata": {}, + "id": "threaded-language", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "edh.draw_graph(\"^GSPC\", report_cache_dir, line_type=\"line\", draw_mas=(20,50,200), draw_volume=True, time_delta=720, low_trend=False)" @@ -129,7 +144,7 @@ }, { "cell_type": "markdown", - "id": "verified-simulation", + "id": "fleet-transparency", "metadata": {}, "source": [ "## Market Volatility (VIX) - 2 year trend with 20, 50 and 200 day SMA" @@ -138,8 +153,10 @@ { "cell_type": "code", "execution_count": null, - "id": "crude-africa", - "metadata": {}, + "id": "disturbed-workstation", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "edh.draw_graph(\"^VIX\", report_cache_dir, line_type=\"line\", draw_mas=(20,50,200), draw_volume=False, time_delta=720, high_trend=False, low_trend=False)" @@ -147,7 +164,7 @@ }, { "cell_type": "markdown", - "id": "naval-builder", + "id": "civilian-november", "metadata": {}, "source": [ "## Market Volatility (VIX) - 1 year trend with 20, 50 and 200 day SMA" @@ -156,8 +173,10 @@ { "cell_type": "code", "execution_count": null, - "id": "fossil-genealogy", - "metadata": {}, + "id": "several-inventory", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "edh.draw_graph(\"^VIX\", report_cache_dir, line_type=\"line\", draw_mas=(20,50,200), draw_volume=False, time_delta=360, high_trend=False, low_trend=False)" @@ -165,7 +184,7 @@ }, { "cell_type": "markdown", - "id": "annoying-drain", + "id": "bizarre-record", "metadata": {}, "source": [ "## Yield on 5-Year US Treasury Notes - 2 year trend with 20, 50 and 200 day SMA" @@ -174,8 +193,10 @@ { "cell_type": "code", "execution_count": null, - "id": "cathedral-divide", - "metadata": {}, + "id": "military-temperature", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "edh.draw_graph(\"^FVX\", report_cache_dir, line_type=\"line\", draw_mas=(20,50,200), draw_volume=False, time_delta=720, low_trend=False, high_trend=False)" @@ -183,7 +204,7 @@ }, { "cell_type": "markdown", - "id": "selective-macintosh", + "id": "greater-party", "metadata": {}, "source": [ "## Yield on 10-Year US Treasury Notes - 2 year trend with 20, 50 and 200 day SMA" @@ -192,8 +213,10 @@ { "cell_type": "code", "execution_count": null, - "id": "induced-vancouver", - "metadata": {}, + "id": "aboriginal-violin", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "edh.draw_graph(\"^TNX\", report_cache_dir, line_type=\"line\", draw_mas=(20,50,200), draw_volume=False, time_delta=720, low_trend=False, high_trend=False)" @@ -201,7 +224,7 @@ }, { "cell_type": "markdown", - "id": "imported-message", + "id": "continent-sally", "metadata": {}, "source": [ "## Yield on 30-Year US Treasury Notes - 2 year trend with 20, 50 and 200 day SMA" @@ -210,8 +233,10 @@ { "cell_type": "code", "execution_count": null, - "id": "alleged-citizenship", - "metadata": {}, + "id": "formed-heating", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "edh.draw_graph(\"^TYX\", report_cache_dir, line_type=\"line\", draw_mas=(20,50,200), draw_volume=False, time_delta=720, low_trend=False, high_trend=False)" @@ -219,7 +244,7 @@ }, { "cell_type": "markdown", - "id": "complimentary-stomach", + "id": "handled-insurance", "metadata": {}, "source": [ "## Gold - 2 year trend with 20, 50 and 200 day SMA" @@ -228,8 +253,10 @@ { "cell_type": "code", "execution_count": null, - "id": "varying-pasta", - "metadata": {}, + "id": "advisory-johnston", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "edh.draw_graph(\"GLD\", report_cache_dir, line_type=\"line\", draw_mas=(20,50,200), draw_volume=True, time_delta=720)" @@ -237,7 +264,7 @@ }, { "cell_type": "markdown", - "id": "perfect-illness", + "id": "played-writer", "metadata": {}, "source": [ "## Silver - 2 year trend with 20, 50 and 200 day SMA" @@ -246,8 +273,10 @@ { "cell_type": "code", "execution_count": null, - "id": "confirmed-event", - "metadata": {}, + "id": "light-harvest", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "edh.draw_graph(\"SLV\", report_cache_dir, line_type=\"line\", draw_mas=(20,50,200), draw_volume=True, time_delta=720, low_trend=False)" @@ -255,7 +284,7 @@ }, { "cell_type": "markdown", - "id": "illusory-reflection", + "id": "floral-giant", "metadata": {}, "source": [ "## Euro vs US Dollar - 2 year trend with 20, 50 and 200 day SMA" @@ -264,8 +293,10 @@ { "cell_type": "code", "execution_count": null, - "id": "astonishing-star", - "metadata": {}, + "id": "corrected-estimate", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "edh.draw_graph(\"FXE\", report_cache_dir, line_type=\"line\", draw_mas=(20,50,200), draw_volume=True, time_delta=720, low_trend=True)" @@ -273,7 +304,7 @@ }, { "cell_type": "markdown", - "id": "reflective-panda", + "id": "neither-montana", "metadata": {}, "source": [ "## Yen vs US Dollar - 2 year trend with 20, 50 and 200 day SMA" @@ -282,8 +313,10 @@ { "cell_type": "code", "execution_count": null, - "id": "starry-night", - "metadata": {}, + "id": "middle-geneva", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "edh.draw_graph(\"FXY\", report_cache_dir, line_type=\"line\", draw_mas=(20,50,200), draw_volume=True, time_delta=720, low_trend=True)" @@ -291,7 +324,7 @@ }, { "cell_type": "markdown", - "id": "faced-canon", + "id": "theoretical-grammar", "metadata": {}, "source": [ "## Energy - 2 year trend with 20, 50 and 200 day SMA" @@ -300,8 +333,10 @@ { "cell_type": "code", "execution_count": null, - "id": "extended-earthquake", - "metadata": {}, + "id": "swedish-thickness", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "edh.draw_graph(\"XLE\", report_cache_dir, line_type=\"line\", draw_mas=(20,50,200), draw_volume=True, time_delta=720)" @@ -309,7 +344,7 @@ }, { "cell_type": "markdown", - "id": "statewide-explanation", + "id": "gentle-humor", "metadata": {}, "source": [ "## Crude Oil - 2 year trend with 20, 50 and 200 day SMA" @@ -318,8 +353,9 @@ { "cell_type": "code", "execution_count": null, - "id": "classical-coast", + "id": "instructional-serve", "metadata": { + "collapsed": true, "scrolled": false }, "outputs": [], @@ -329,7 +365,7 @@ }, { "cell_type": "markdown", - "id": "spoken-delta", + "id": "classical-listening", "metadata": {}, "source": [ "## Real Estate - 2 year trend with 20, 50 and 200 day SMA" @@ -338,8 +374,10 @@ { "cell_type": "code", "execution_count": null, - "id": "changing-eight", - "metadata": {}, + "id": "enclosed-administration", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "edh.draw_graph(\"XLRE\", report_cache_dir, line_type=\"line\", draw_mas=(20,50,200), draw_volume=True, time_delta=720, low_trend=False)" @@ -347,7 +385,7 @@ }, { "cell_type": "markdown", - "id": "mathematical-support", + "id": "turned-percentage", "metadata": {}, "source": [ "## Real Estate - 1 year trend with 20, 50 and 200 day SMA" @@ -356,8 +394,10 @@ { "cell_type": "code", "execution_count": null, - "id": "exact-jacksonville", - "metadata": {}, + "id": "sharing-removal", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "edh.draw_graph(\"VNQ\", report_cache_dir, line_type=\"line\", draw_mas=(20,50,200), draw_volume=True, time_delta=360, low_trend=True)" @@ -365,7 +405,7 @@ }, { "cell_type": "markdown", - "id": "worse-horror", + "id": "swedish-happiness", "metadata": {}, "source": [ "## Financials - 2 year trend with 20, 50 and 200 day SMA" @@ -374,8 +414,10 @@ { "cell_type": "code", "execution_count": null, - "id": "controlled-portuguese", - "metadata": {}, + "id": "beginning-aspect", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "edh.draw_graph(\"XLF\", report_cache_dir, line_type=\"line\", draw_mas=(20,50,200), draw_volume=True, time_delta=720, low_trend=False)" @@ -383,7 +425,7 @@ }, { "cell_type": "markdown", - "id": "typical-sandwich", + "id": "restricted-glucose", "metadata": {}, "source": [ "## Financials - 1 year trend with 20, 50 and 200 day SMA" @@ -392,8 +434,10 @@ { "cell_type": "code", "execution_count": null, - "id": "headed-bundle", - "metadata": {}, + "id": "personal-whole", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "edh.draw_graph(\"XLF\", report_cache_dir, line_type=\"line\", draw_mas=(20,50,200), draw_volume=True, time_delta=360, low_trend=True)" @@ -401,7 +445,7 @@ }, { "cell_type": "markdown", - "id": "blistering-barnacles", + "id": "detailed-strike", "metadata": {}, "source": [ "## Materials - 2 year trend with 20, 50 and 200 day SMA" @@ -410,8 +454,10 @@ { "cell_type": "code", "execution_count": null, - "id": "italian-portent", - "metadata": {}, + "id": "negative-mitchell", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "edh.draw_graph(\"XLB\", report_cache_dir, line_type=\"line\", draw_mas=(20,50,200), draw_volume=True, time_delta=720, low_trend=False)" @@ -419,7 +465,7 @@ }, { "cell_type": "markdown", - "id": "material-science", + "id": "boolean-rotation", "metadata": {}, "source": [ "## Materials - 1 year trend with 20, 50 and 200 day SMA" @@ -428,8 +474,10 @@ { "cell_type": "code", "execution_count": null, - "id": "bundle-enabler", - "metadata": {}, + "id": "settled-orange", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "edh.draw_graph(\"XLB\", report_cache_dir, line_type=\"line\", draw_mas=(20,50,200), draw_volume=True, time_delta=360, low_trend=True)" @@ -438,8 +486,10 @@ { "cell_type": "code", "execution_count": null, - "id": "german-ecology", - "metadata": {}, + "id": "premium-transportation", + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "!jupyter nbconvert {os.path.join(\"notebooks\", \"reports\", report_name + \".ipynb\")} --to html --no-input" @@ -462,7 +512,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.10" + "version": "3.6.8" } }, "nbformat": 4, diff --git a/terminal.py b/terminal.py index 2998a808580..498436e8ac1 100644 --- a/terminal.py +++ b/terminal.py @@ -5,126 +5,68 @@ __docformat__ = "numpy" import argparse import os import sys -from datetime import datetime -from typing import List -import pandas as pd -import yfinance as yf -from alpha_vantage.timeseries import TimeSeries from prompt_toolkit.completion import NestedCompleter -from gamestonk_terminal.helper_funcs import ( - b_is_stock_market_open, - get_flair, -) -from gamestonk_terminal.main_helper import ( - clear, - load, - view, - candle, +from gamestonk_terminal.terminal_helper import ( print_goodbye, - quote, update_terminal, about_us, bootup, reset, check_api_keys, ) +from gamestonk_terminal.helper_funcs import get_flair from gamestonk_terminal.menu import session -from gamestonk_terminal import config_terminal as cfg from gamestonk_terminal import feature_flags as gtff -from gamestonk_terminal.discovery import disc_controller -from gamestonk_terminal.due_diligence import dd_controller -from gamestonk_terminal.fundamental_analysis import fa_controller -from gamestonk_terminal.papermill import papermill_controller as mill -from gamestonk_terminal.behavioural_analysis import ba_controller -from gamestonk_terminal.technical_analysis import ta_controller -from gamestonk_terminal.comparison_analysis import ca_controller -from gamestonk_terminal.exploratory_data_analysis import eda_controller -from gamestonk_terminal.options import op_controller -from gamestonk_terminal.economy import econ_controller -from gamestonk_terminal.residuals_analysis import ra_controller -from gamestonk_terminal.portfolio_analysis import pa_controller -from gamestonk_terminal.brokers import bro_controller -from gamestonk_terminal.cryptocurrency import crypto_controller -from gamestonk_terminal.screener import screener_controller -from gamestonk_terminal.portfolio_optimization import po_controller -from gamestonk_terminal.forex import fx_controller -from gamestonk_terminal.backtesting import bt_controller -from gamestonk_terminal.resource_collection import rc_controller -from gamestonk_terminal.research import res_controller -from gamestonk_terminal.government import gov_controller +from gamestonk_terminal import config_terminal -# from gamestonk_terminal.etf import etf_controller -from gamestonk_terminal.insider import insider_controller +from gamestonk_terminal.stocks import stocks_controller +from gamestonk_terminal.cryptocurrency import crypto_controller +from gamestonk_terminal.economy import economy_controller +from gamestonk_terminal.options import options_controller +from gamestonk_terminal.etf import etf_controller +from gamestonk_terminal.forex import forex_controller +from gamestonk_terminal.resources import resources_controller +from gamestonk_terminal.portfolio import portfolio_controller # pylint: disable=too-many-public-methods + + class TerminalController: """Terminal Controller class""" - # To hold suffix for Yahoo Finance - suffix = "" - - # Command choices - CHOICES_TICKER_DEPENDENT = [ - "ba", - "res", - "fa", - "ta", - "bt", - "dd", - "eda", - "pred", - "ca", - "ra", - ] - CHOICES = [ "cls", "?", "help", - "quit", "q", + "quit", + ] + + CHOICES_COMMANDS = [ "reset", "update", - "clear", - "load", - "quote", - "candle", - "view", - "disc", - "scr", - "mill", - "econ", - "pa", - "crypto", - "po", - "ins", - "fx", - "rc", - "op", - "gov", - "etf", "about", - "bro", - "ins", "keys", ] - CHOICES += CHOICES_TICKER_DEPENDENT - def __init__( - self, - stock: pd.DataFrame, - ticker: str, - start: datetime, - interval: str, - ): + CHOICES_MENUS = [ + "stocks", + "economy", + "crypto", + "portfolio", + "forex", + "options", + "etf", + "resources", + ] + + CHOICES += CHOICES_COMMANDS + CHOICES += CHOICES_MENUS + + def __init__(self): """Constructor""" - self.stock = stock - self.ticker = ticker - self.start = start - self.interval = interval - self.update_succcess = False self.t_parser = argparse.ArgumentParser(add_help=False, prog="terminal") self.t_parser.add_argument( @@ -147,56 +89,15 @@ What do you want to do? about about us q(uit) to abandon the program -Contexts: -> mill papermill menu, \t\t menu to generate notebook reports -> econ economic data, \t\t\t e.g.: events, FRED data, GDP, VIXCLS -> pa portfolio analysis, \t\t analyses your custom portfolio -> bro brokers holdings, \t\t supports: robinhood, alpaca, ally -> crypto cryptocurrencies, \t\t from: coingecko, coinmarketcap, binance -> po portfolio optimization, \t optimal portfolio weights from pyportfolioopt -> gov government menu, \t\t house trading, contracts, corporate lobbying -> etf TEMPORARILY DISABLED -> fx forex menu, \t\t\t forex support through Oanda -> rc resource collection, \t\t e.g. hf letters, arXiv, EDGAR, FINRA -> op options info, \t e.g.: volume, open interest, chains, volatility -> ins insider trading, \t e.g.: latest penny stock buys, insider sales - """ - - s_intraday = (f"Intraday {self.interval}", "Daily")[self.interval == "1440min"] - if self.ticker and self.start: - help_text += f"\n{s_intraday} Stock: {self.ticker} (from {self.start.strftime('%Y-%m-%d')})\n" - elif self.ticker: - help_text += f"\n{s_intraday} Stock: {self.ticker}\n" - else: - help_text += "\nStock: ?\n" - - help_text += f"Market {('CLOSED', 'OPEN')[b_is_stock_market_open()]}.\n" - - help_text += """ - clear clear a specific stock ticker from analysis - load load a specific stock ticker for analysis +>> stocks +>> crypto +>> economy +>> options +>> portfolio +>> etf +>> forex +>> resources """ - - if self.ticker: - help_text += """quote view the current price for a specific stock ticker - candle view a candle chart for a specific stock ticker - view view and load a specific stock ticker for technical analysis - -> dd in-depth due-diligence, \t e.g.: news, analyst, shorts, insider, sec -> ba behavioural analysis, \t from: reddit, stocktwits, twitter, google -> ta technical analysis, \t e.g.: ema, macd, rsi, adx, bbands, obv -> fa fundamental analysis, \t e.g.: income, balance, cash, earnings -> res research web page, \t e.g.: macroaxis, yahoo finance, fool -> ca comparison analysis, \t e.g.: historical, correlation, financials -> eda exploratory data analysis,\t e.g.: decompose, cusum, residuals analysis -> ra residuals analysis, \t e.g.: model fit, qqplot, hypothesis test -> bt strategy backtester, \t e.g.: simple ema, ema cross, rsi strategies -> pred prediction techniques, \t e.g.: regression, arima, rnn, lstm""" - - help_text += """\n> disc discover trending stocks, \t e.g. map, sectors, high short interest -> scr screener stocks, \t\t e.g. overview/performance, using preset filters - """ - print(help_text) def switch(self, an_input: str): @@ -215,10 +116,6 @@ Contexts: print("") return None - if not self.ticker and an_input in self.CHOICES_TICKER_DEPENDENT: - print("No ticker selected. Use 'load '.\n") - return None - (known_args, other_args) = self.t_parser.parse_known_args(an_input.split()) # Help menu again @@ -247,97 +144,11 @@ Contexts: """Process Quit command - quit the program""" return True + # COMMANDS def call_reset(self, _): """Process reset command""" return True - def call_clear(self, other_args: List[str]): - """Process clear command""" - self.ticker, self.start, self.interval, self.stock = clear( - other_args, self.ticker, self.start, self.interval, self.stock - ) - - def call_load(self, other_args: List[str]): - """Process load command""" - self.ticker, self.start, self.interval, self.stock = load( - other_args, self.ticker, self.start, self.interval, self.stock - ) - if "." in self.ticker: - self.ticker, self.suffix = self.ticker.split(".") - else: - self.suffix = "" - - def call_quote(self, other_args: List[str]): - """Process quote command""" - quote( - other_args, self.ticker + "." + self.suffix if self.suffix else self.ticker - ) - - def call_candle(self, other_args: List[str]): - """Process candle command""" - candle( - self.ticker + "." + self.suffix if self.suffix else self.ticker, - other_args, - ) - - def call_view(self, other_args: List[str]): - """Process view command""" - view(other_args, self.ticker, self.interval, self.stock) - - def call_disc(self, _): - """Process disc command""" - return disc_controller.menu() - - def call_mill(self, _): - """Process mill command""" - return mill.papermill_menu() - - def call_fx(self, _): - """Process fx command""" - return fx_controller.menu() - - def call_econ(self, _): - """Process econ command""" - return econ_controller.menu() - - def call_pa(self, _): - """Process pa command""" - return pa_controller.menu() - - def call_bro(self, _): - """Process bro command""" - return bro_controller.menu() - - def call_crypto(self, _): - """Process crypto command""" - return crypto_controller.menu() - - def call_scr(self, _): - """Process scr command""" - return screener_controller.menu() - - def call_rc(self, _): - """Process rc command""" - return rc_controller.menu() - - def call_etf(self, _): - """Process etf command""" - print("TEMPORARILY DISABLED \n") - - # return etf_controller.menu() - - def call_ins(self, _): - """Process ins command""" - return insider_controller.menu() - - def call_gov(self, _): - """Process gov command""" - return gov_controller.menu(self.ticker) - - def call_po(self, _): - """Process po command""" - return po_controller.menu([self.ticker]) - def call_update(self, _): """Process update command""" self.update_succcess = not update_terminal() @@ -351,143 +162,38 @@ Contexts: """Process about command""" about_us() - def call_ba(self, _): - """Process ba command""" - return ba_controller.menu( - self.ticker, - self.start, - ) + # MENUS + def call_stocks(self, _): + """Process stocks command""" + return stocks_controller.menu() - def call_res(self, _): - """Process res command""" - return res_controller.menu( - self.ticker, - self.start, - self.interval, - ) + def call_crypto(self, _): + """Process crypto command""" + return crypto_controller.menu() - def call_ca(self, _): - """Process ca command""" - return ca_controller.menu(self.ticker, self.start, self.interval, self.stock) + def call_economy(self, _): + """Process econ command""" + return economy_controller.menu() - def call_fa(self, _): - """Process fa command""" - return fa_controller.menu( - self.ticker, - self.start, - self.interval, - ) - - def call_ta(self, _): - """Process ta command""" - return ta_controller.menu( - self.ticker, - self.start, - self.interval, - self.stock, - ) - - def call_dd(self, _): - """Process dd command""" - return dd_controller.menu( - self.ticker, - self.start, - self.interval, - self.stock, - ) - - def call_ra(self, _): - """Process ra command""" - return ra_controller.menu( - self.ticker, - self.start, - self.interval, - self.stock, - ) - - def call_bt(self, _): - """Process bt command""" - return bt_controller.menu( - self.ticker, - self.start, - ) - - def call_eda(self, _): - """Process eda command""" - if self.interval == "1440min": - return eda_controller.menu( - self.ticker, - self.start, - self.interval, - self.stock, - ) - - df_stock = yf.download(self.ticker, start=self.start, progress=False) - df_stock.index.name = "date" - s_interval = "1440min" - - return eda_controller.menu( - self.ticker, - self.start, - s_interval, - df_stock, - ) - - def call_op(self, _): + def call_options(self, _): """Process op command""" - return op_controller.menu(self.ticker) + return options_controller.menu() - def call_pred(self, _): - """Process pred command""" - if not gtff.ENABLE_PREDICT: - print( - "Predict is disabled. Check ENABLE_PREDICT flag on feature_flags.py", - "\n", - ) - return None + def call_etf(self, _): + """Process etf command""" + return etf_controller.menu() - try: - # pylint: disable=import-outside-toplevel - from gamestonk_terminal.prediction_techniques import pred_controller - except ModuleNotFoundError as e: - print("One of the optional packages seems to be missing: ", e, "\n") - return None - except Exception as e: - print(e, "\n") - return None + def call_forex(self, _): + """Process fx command""" + return forex_controller.menu() - if self.interval == "1440min": - return pred_controller.menu( - self.ticker, - self.start, - self.interval, - self.stock, - ) + def call_resources(self, _): + """Process resources command""" + return resources_controller.menu() - # If stock data is intradaily, we need to get data again as prediction - # techniques work on daily adjusted data. By default we load data from - # Alpha Vantage because the historical data loaded gives a larger - # dataset than the one provided by quandl - try: - ts = TimeSeries(key=cfg.API_KEY_ALPHAVANTAGE, output_format="pandas") - # pylint: disable=unbalanced-tuple-unpacking - df_stock_pred, _ = ts.get_daily_adjusted( - symbol=self.ticker, outputsize="full" - ) - - # pylint: disable=no-member - df_stock_pred = df_stock_pred.sort_index(ascending=True) - df_stock_pred = df_stock_pred[self.start :] - return pred_controller.menu( - self.ticker, - self.start, - "1440min", - df_stock_pred, - ) - except Exception as e: - print(e) - print("Either the ticker or the API_KEY are invalids. Try again!") - return None + def call_portfolio(self, _): + """Process portfolio command""" + return portfolio_controller.menu() def terminal(): @@ -495,18 +201,22 @@ def terminal(): bootup() - ticker = "" # "GME" - start = "" # "2021-01-01" - stock = pd.DataFrame() # yf.download(ticker, start, progress=False) - interval = "1440min" + t_controller = TerminalController() + + if config_terminal.DEFAULT_CONTEXT: + if config_terminal.DEFAULT_CONTEXT in t_controller.CHOICES_MENUS: + try: + print("") + t_controller.switch(config_terminal.DEFAULT_CONTEXT.lower()) + except SystemExit: + print("") + else: + print("\nInvalid DEFAULT_CONTEXT config selected!", "\n") - t_controller = TerminalController(stock, ticker, start, interval) t_controller.print_help() - parsed_stdin = False while True: - if gtff.ENABLE_QUICK_EXIT: print("Quick exit enabled") break diff --git a/tests/test_dd_financial_modeling_prep_view.py b/tests/test_dd_financial_modeling_prep_view.py index 0db0c299699..05edc296255 100644 --- a/tests/test_dd_financial_modeling_prep_view.py +++ b/tests/test_dd_financial_modeling_prep_view.py @@ -1,7 +1,7 @@ """ fundamental_analysis/business_insider_api.py tests """ import unittest -from gamestonk_terminal.due_diligence.financial_modeling_prep_view import rating +from gamestonk_terminal.stocks.due_diligence.financial_modeling_prep_view import rating class TestDdFinancialModelingPrepView(unittest.TestCase): diff --git a/tests/test_dd_finviz_view.py b/tests/test_dd_finviz_view.py index 8c062510029..7c980c2f728 100644 --- a/tests/test_dd_finviz_view.py +++ b/tests/test_dd_finviz_view.py @@ -1,7 +1,7 @@ """ due_diligence/finviz_api.py tests """ import unittest -from gamestonk_terminal.due_diligence.finviz_view import analyst +from gamestonk_terminal.stocks.due_diligence.finviz_view import analyst class TestDdFinvizApi(unittest.TestCase): diff --git a/tests/test_discovery_ark_model.py b/tests/test_discovery_ark_model.py index 71fe4f6341e..a9b9993531b 100644 --- a/tests/test_discovery_ark_model.py +++ b/tests/test_discovery_ark_model.py @@ -11,13 +11,16 @@ from gamestonk_terminal.test_helper import ( # noqa: F401 pytest_generate_tests, ) -from gamestonk_terminal.discovery.ark_model import get_ark_orders, add_order_total +from gamestonk_terminal.stocks.discovery.ark_model import ( + get_ark_orders, + add_order_total, +) assertions = unittest.TestCase("__init__") class TestDiscoveryArkModel: - @mock.patch("gamestonk_terminal.discovery.ark_model.requests") + @mock.patch("gamestonk_terminal.stocks.discovery.ark_model.requests") @parameterize_from_file( "test_get_ark_orders", "../tests/data/discovery_ark_model.yaml", @@ -37,7 +40,7 @@ class TestDiscoveryArkModel: ret.to_csv().replace("\r\n", "\n"), expected_orders.replace("\r\n", "\n") ) - @mock.patch("gamestonk_terminal.discovery.ark_model.yf.download") + @mock.patch("gamestonk_terminal.stocks.discovery.ark_model.yf.download") @parameterize_from_file( "test_add_order_total", "../tests/data/discovery_ark_model.yaml", diff --git a/tests/test_discovery_ark_view.py b/tests/test_discovery_ark_view.py index 5b40b6f30a8..c92b0aa3e08 100644 --- a/tests/test_discovery_ark_view.py +++ b/tests/test_discovery_ark_view.py @@ -10,14 +10,16 @@ from gamestonk_terminal.test_helper import ( # noqa: F401 pytest_generate_tests, ) -from gamestonk_terminal.discovery.ark_view import ark_orders_view +from gamestonk_terminal.stocks.discovery.ark_view import ark_orders_view assertions = unittest.TestCase("__init__") class TestDiscoveryArkView: - @mock.patch("gamestonk_terminal.discovery.ark_view.ark_model.get_ark_orders") - @mock.patch("gamestonk_terminal.discovery.ark_view.ark_model.add_order_total") + @mock.patch("gamestonk_terminal.stocks.discovery.ark_view.ark_model.get_ark_orders") + @mock.patch( + "gamestonk_terminal.stocks.discovery.ark_view.ark_model.add_order_total" + ) @parameterize_from_file( "test_ark_orders_view", "../tests/data/discovery_ark_view.yaml", diff --git a/tests/test_discovery_fidelity_api.py b/tests/test_discovery_fidelity_api.py index 7396e54e754..7ff92717cec 100644 --- a/tests/test_discovery_fidelity_api.py +++ b/tests/test_discovery_fidelity_api.py @@ -1,7 +1,7 @@ """ discovery/fidelity_api.py tests """ import unittest -from gamestonk_terminal.discovery.fidelity_view import ( +from gamestonk_terminal.stocks.discovery.fidelity_view import ( buy_sell_ratio_color_red_green, price_change_color_red_green, orders_view, diff --git a/tests/test_discovery_fidelity_model.py b/tests/test_discovery_fidelity_model.py index 34feb5b5ec9..ed8bf8271d2 100644 --- a/tests/test_discovery_fidelity_model.py +++ b/tests/test_discovery_fidelity_model.py @@ -8,13 +8,13 @@ from gamestonk_terminal.test_helper import ( # noqa: F401 pytest_generate_tests, ) -from gamestonk_terminal.discovery.fidelity_model import get_orders +from gamestonk_terminal.stocks.discovery.fidelity_model import get_orders assertions = unittest.TestCase("__init__") class TestDiscoveryFidelityModel: - @mock.patch("gamestonk_terminal.discovery.fidelity_model.requests") + @mock.patch("gamestonk_terminal.stocks.discovery.fidelity_model.requests") @parameterize_from_file( "test_get_orders", "../tests/data/discovery_fidelity_model.yaml", diff --git a/tests/test_discovery_seeing_alpha_model.py b/tests/test_discovery_seeing_alpha_model.py index 3606ca2178d..9cd3c7e677e 100644 --- a/tests/test_discovery_seeing_alpha_model.py +++ b/tests/test_discovery_seeing_alpha_model.py @@ -8,13 +8,15 @@ from gamestonk_terminal.test_helper import ( # noqa: F401 pytest_generate_tests, ) -from gamestonk_terminal.discovery.seeking_alpha_model import get_next_earnings +from gamestonk_terminal.stocks.discovery.seeking_alpha_model import get_next_earnings assertions = unittest.TestCase("__init__") class TestDiscoverySeekingAlphaModel: - @mock.patch("gamestonk_terminal.discovery.seeking_alpha_model.get_earnings_html") + @mock.patch( + "gamestonk_terminal.stocks.discovery.seeking_alpha_model.get_earnings_html" + ) @parameterize_from_file( "test_get_next_earnings", "../tests/data/discovery_seeking_alpha_model.yaml", diff --git a/tests/test_discovery_short_interest_model.py b/tests/test_discovery_short_interest_model.py index 254101054cc..7dd168d1c7d 100644 --- a/tests/test_discovery_short_interest_model.py +++ b/tests/test_discovery_short_interest_model.py @@ -8,7 +8,7 @@ from gamestonk_terminal.test_helper import ( # noqa: F401 pytest_generate_tests, ) -from gamestonk_terminal.discovery.short_interest_model import ( +from gamestonk_terminal.stocks.discovery.short_interest_model import ( get_high_short_interest, get_low_float, ) @@ -17,7 +17,7 @@ assertions = unittest.TestCase("__init__") class TestDiscoveryShortInterestApi: - @mock.patch("gamestonk_terminal.discovery.short_interest_model.requests") + @mock.patch("gamestonk_terminal.stocks.discovery.short_interest_model.requests") @parameterize_from_file( "test_get_high_short_interest", "../tests/data/discovery_short_interest_model.yaml", @@ -36,7 +36,7 @@ class TestDiscoveryShortInterestApi: expected_result.replace("\r\n", "\n"), ) - @mock.patch("gamestonk_terminal.discovery.short_interest_model.requests") + @mock.patch("gamestonk_terminal.stocks.discovery.short_interest_model.requests") @parameterize_from_file( "test_get_low_float", "../tests/data/discovery_short_interest_model.yaml", diff --git a/tests/test_fa_business_insider_view.py b/tests/test_fa_business_insider_view.py index b9d35af0af9..26a8e7e2fc3 100644 --- a/tests/test_fa_business_insider_view.py +++ b/tests/test_fa_business_insider_view.py @@ -1,7 +1,9 @@ """ fundamental_analysis/business_insider_api.py tests """ import unittest -from gamestonk_terminal.fundamental_analysis.business_insider_view import management +from gamestonk_terminal.stocks.fundamental_analysis.business_insider_view import ( + management, +) class TestFaBusinessInsiderApi(unittest.TestCase): diff --git a/tests/test_fa_market_watch_model.py b/tests/test_fa_market_watch_model.py index 4e671236f00..08c51422830 100644 --- a/tests/test_fa_market_watch_model.py +++ b/tests/test_fa_market_watch_model.py @@ -8,7 +8,7 @@ from gamestonk_terminal.test_helper import ( # noqa: F401 pytest_generate_tests, ) -from gamestonk_terminal.fundamental_analysis.market_watch_model import ( +from gamestonk_terminal.stocks.fundamental_analysis.market_watch_model import ( prepare_df_financials, ) @@ -16,7 +16,9 @@ assertions = unittest.TestCase("__init__") class TestFaMarketWatchApiUnit: - @mock.patch("gamestonk_terminal.fundamental_analysis.market_watch_model.requests") + @mock.patch( + "gamestonk_terminal.stocks.fundamental_analysis.market_watch_model.requests" + ) @parameterize_from_file( "test_prepare_df_financials", "../tests/data/fa_market_watch_model.yaml", diff --git a/tests/test_fa_market_watch_view.py b/tests/test_fa_market_watch_view.py index 9ebe411fdb3..ba78cb6a869 100644 --- a/tests/test_fa_market_watch_view.py +++ b/tests/test_fa_market_watch_view.py @@ -1,7 +1,7 @@ """ fundamental_analysis/market_watch_api.py tests """ import unittest -from gamestonk_terminal.fundamental_analysis.market_watch_view import income +from gamestonk_terminal.stocks.fundamental_analysis.market_watch_view import income class TestFaMarketWatchApi(unittest.TestCase): diff --git a/tests/test_fa_yahoo_finance_view.py b/tests/test_fa_yahoo_finance_view.py index fb068647595..7cd9090abae 100644 --- a/tests/test_fa_yahoo_finance_view.py +++ b/tests/test_fa_yahoo_finance_view.py @@ -2,7 +2,7 @@ import unittest # pylint: disable=unused-import -from gamestonk_terminal.fundamental_analysis.yahoo_finance_view import ( # noqa: F401 +from gamestonk_terminal.stocks.fundamental_analysis.yahoo_finance_view import ( # noqa: F401 info, sustainability, calendar_earnings, diff --git a/tests/test_fa_yield_curve_model.py b/tests/test_fa_yield_curve_model.py index 0744e6cad72..35f46aaa555 100644 --- a/tests/test_fa_yield_curve_model.py +++ b/tests/test_fa_yield_curve_model.py @@ -11,7 +11,7 @@ from gamestonk_terminal.test_helper import ( # noqa: F401 pytest_generate_tests, ) -from gamestonk_terminal.fundamental_analysis.yield_curve_model import ( +from gamestonk_terminal.stocks.fundamental_analysis.yield_curve_model import ( get_yield_curve, get_yield_curve_year, ) @@ -21,7 +21,7 @@ assertions = unittest.TestCase("__init__") class TestFaYieldCurveModel: @mock.patch( - "gamestonk_terminal.fundamental_analysis.yield_curve_model.get_yield_curve_year" + "gamestonk_terminal.stocks.fundamental_analysis.yield_curve_model.get_yield_curve_year" ) @parameterize_from_file( "test_get_yield_curve", @@ -53,7 +53,9 @@ class TestFaYieldCurveModel: df.to_csv().replace("\r\n", "\n"), expected_result.replace("\r\n", "\n") ) - @mock.patch("gamestonk_terminal.fundamental_analysis.yield_curve_model.requests") + @mock.patch( + "gamestonk_terminal.stocks.fundamental_analysis.yield_curve_model.requests" + ) @parameterize_from_file( "test_get_yield_curve_year", "../tests/data/fa_yield_curve_model.yaml", diff --git a/tests/test_pred_neural_networks.py b/tests/test_pred_neural_networks.py index d804cc4f129..20d079200c5 100644 --- a/tests/test_pred_neural_networks.py +++ b/tests/test_pred_neural_networks.py @@ -2,7 +2,7 @@ import unittest try: - from gamestonk_terminal.prediction_techniques.neural_networks_view import mlp + from gamestonk_terminal.common.prediction_techniques.neural_networks_view import mlp except ModuleNotFoundError as e_module: print("One of the optional packages seems to be missing") print(e_module)