#!/usr/bin/env python import argparse import sys import os import subprocess from datetime import datetime, timedelta import pandas as pd import yfinance as yf from matplotlib import pyplot as plt from alpha_vantage.timeseries import TimeSeries from prompt_toolkit.completion import NestedCompleter 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.discovery import disc_controller from gamestonk_terminal.due_diligence import dd_controller from gamestonk_terminal.fundamental_analysis import fa_controller from gamestonk_terminal.helper_funcs import b_is_stock_market_open, get_flair from gamestonk_terminal.main_helper import ( clear, export, load, print_help, view, candle, print_goodbye, update_terminal, ) from gamestonk_terminal.menu import session 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.econ import econ_controller from gamestonk_terminal.residuals_analysis import ra_controller from gamestonk_terminal.portfolio import port_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.etf import etf_controller # pylint: disable=too-many-statements,too-many-branches def main(): """ Gamestonk Terminal is an awesome stock market terminal that has been developed for fun, while I saw my GME shares tanking. But hey, I like the stock. """ # Enable VT100 Escape Sequence for WINDOWS 10 Ver. 1607 if sys.platform == "win32": os.system("") s_ticker = "" s_start = "2015-01-01" df_stock = pd.DataFrame() s_interval = "1440min" update_succcess = False # Set stock by default to speed up testing # s_ticker = "BB" # ts = TimeSeries(key=cfg.API_KEY_ALPHAVANTAGE, output_format='pandas') # df_stock, d_stock_metadata = ts.get_daily_adjusted(symbol=s_ticker, outputsize='full') # df_stock.sort_index(ascending=True, inplace=True) # s_start = datetime.strptime("2020-06-04", "%Y-%m-%d") # df_stock = df_stock[s_start:] # Add list of arguments that the main parser accepts menu_parser = argparse.ArgumentParser(add_help=False, prog="gamestonk_terminal") choices = [ "help", "quit", "q", "reset", "update", "clear", "load", "candle", "view", "export", "disc", "scr", "mill", "ba", "res", "fa", "ta", "bt", "dd", "eda", "pred", "ca", "op", "econ", "pa", "crypto", "ra", "po", "fx", "rc", "gov", "etf", ] menu_parser.add_argument("opt", choices=choices) completer = NestedCompleter.from_nested_dict({c: None for c in choices}) 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 Ape.\n") should_print_help = True parsed_stdin = False if gtff.ENABLE_THOUGHTS_DAY: print("-------------------") try: thought.get_thought_of_the_day() except Exception as e: print(e) print("") # Loop forever and ever while True: main_cmd = False if should_print_help: print_help(s_ticker, s_start, s_interval, b_is_stock_market_open()) should_print_help = False if gtff.ENABLE_QUICK_EXIT: print("Quick exit enabled") break # Get input command from stdin or user if not parsed_stdin and len(sys.argv) > 1: as_input = " ".join(sys.argv[1:]) parsed_stdin = True print(f"{get_flair()}> {as_input}") elif session and gtff.USE_PROMPT_TOOLKIT: as_input = session.prompt(f"{get_flair()}> ", completer=completer) else: as_input = input(f"{get_flair()}> ") plt.close("all") # Is command empty if not as_input: print("") continue # Parse main command of the list of possible commands try: (ns_known_args, l_args) = menu_parser.parse_known_args(as_input.split()) except SystemExit: print("The command selected doesn't exist\n") continue b_quit = False if ns_known_args.opt == "help": should_print_help = True elif ( (ns_known_args.opt == "quit") or (ns_known_args.opt == "q") or (ns_known_args.opt == "reset") ): break elif ns_known_args.opt == "clear": s_ticker, s_start, s_interval, df_stock = clear( l_args, s_ticker, s_start, s_interval, df_stock ) main_cmd = True elif ns_known_args.opt == "load": s_ticker, s_start, s_interval, df_stock = load( l_args, s_ticker, s_start, s_interval, df_stock ) main_cmd = True elif ns_known_args.opt == "candle": if s_ticker: candle( s_ticker, (datetime.now() - timedelta(days=180)).strftime("%Y-%m-%d"), ) else: print( "No ticker selected. Use 'load ticker' to load the ticker you want to look at.", "\n", ) main_cmd = True elif ns_known_args.opt == "view": view(l_args, s_ticker, s_start, s_interval, df_stock) main_cmd = True elif ns_known_args.opt == "export": export(l_args, df_stock) main_cmd = True elif ns_known_args.opt == "disc": b_quit = disc_controller.menu() elif ns_known_args.opt == "mill": b_quit = mill.papermill_menu() elif ns_known_args.opt == "ba": if s_ticker: b_quit = ba_controller.menu( s_ticker.split(".")[0] if "." in s_ticker else s_ticker, s_start ) else: print("Please load a ticker using ") print("") continue elif ns_known_args.opt == "res": if s_ticker: b_quit = res_controller.menu( s_ticker.split(".")[0] if "." in s_ticker else s_ticker, s_start, s_interval, ) else: print("Please load a ticker using ") print("") continue elif ns_known_args.opt == "ca": if s_ticker: b_quit = ca_controller.menu(df_stock, s_ticker, s_start, s_interval) else: print("Please load a ticker using ") print("") continue elif ns_known_args.opt == "fa": if s_ticker: b_quit = fa_controller.menu( s_ticker.split(".")[0] if "." in s_ticker else s_ticker, s_start, s_interval, ) else: print("Please load a ticker using ") print("") continue elif ns_known_args.opt == "fx": b_quit = fx_controller.menu() elif ns_known_args.opt == "ta": if s_ticker: b_quit = ta_controller.menu( df_stock, s_ticker.split(".")[0] if "." in s_ticker else s_ticker, s_start, s_interval, ) else: print("Please load a ticker using ") print("") continue elif ns_known_args.opt == "dd": if s_ticker: b_quit = dd_controller.menu( df_stock, s_ticker.split(".")[0] if "." in s_ticker else s_ticker, s_start, s_interval, ) else: print("Please load a ticker using ") print("") continue elif ns_known_args.opt == "eda": if s_ticker: if s_interval == "1440min": b_quit = eda_controller.menu( df_stock, s_ticker.split(".")[0] if "." in s_ticker else s_ticker, s_start, s_interval, ) else: df_stock = yf.download(s_ticker, start=s_start, progress=False) df_stock = df_stock.rename( columns={ "Open": "1. open", "High": "2. high", "Low": "3. low", "Close": "4. close", "Adj Close": "5. adjusted close", "Volume": "6. volume", } ) df_stock.index.name = "date" s_interval = "1440min" b_quit = eda_controller.menu( df_stock, s_ticker.split(".")[0] if "." in s_ticker else s_ticker, s_start, s_interval, ) else: print("Please load a ticker using ") print("") continue elif ns_known_args.opt == "op": if s_ticker: b_quit = op_controller.menu( s_ticker, df_stock["5. adjusted close"].values[-1] ) else: print("Please load a ticker using ") print("") continue elif ns_known_args.opt == "econ": b_quit = econ_controller.menu() elif ns_known_args.opt == "pa": b_quit = port_controller.menu() elif ns_known_args.opt == "crypto": b_quit = crypto_controller.menu() elif ns_known_args.opt == "po": b_quit = po_controller.menu([s_ticker]) elif ns_known_args.opt == "pred": if not s_ticker: print("Please load a ticker using ") print("") continue if not gtff.ENABLE_PREDICT: print("Predict is not enabled in feature_flags.py") print("Prediction menu is disabled") print("") continue 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") print("Optional packages need to be installed") print(e) print("") continue except Exception as e: print(e) print("") continue if s_interval == "1440min": b_quit = pred_controller.menu( df_stock, s_ticker.split(".")[0] if "." in s_ticker else s_ticker, s_start, s_interval, ) # 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 else: try: ts = TimeSeries( key=cfg.API_KEY_ALPHAVANTAGE, output_format="pandas" ) # pylint: disable=unbalanced-tuple-unpacking df_stock_pred, _ = ts.get_daily_adjusted( symbol=s_ticker, outputsize="full" ) # pylint: disable=no-member df_stock_pred = df_stock_pred.sort_index(ascending=True) df_stock_pred = df_stock_pred[s_start:] b_quit = pred_controller.menu( df_stock_pred, s_ticker.split(".")[0] if "." in s_ticker else s_ticker, s_start, interval="1440min", ) except Exception as e: print(e) print("Either the ticker or the API_KEY are invalids. Try again!") return elif ns_known_args.opt == "ra": b_quit = ra_controller.menu( df_stock, s_ticker.split(".")[0] if "." in s_ticker else s_ticker, s_start, s_interval, ) elif ns_known_args.opt == "scr": b_quit = screener_controller.menu() elif ns_known_args.opt == "bt": b_quit = bt_controller.menu( s_ticker.split(".")[0] if "." in s_ticker else s_ticker, s_start ) elif ns_known_args.opt == "rc": b_quit = rc_controller.menu() elif ns_known_args.opt == "gov": b_quit = gov_controller.menu(s_ticker) elif ns_known_args.opt == "etf": b_quit = etf_controller.menu() elif ns_known_args.opt == "update": update_succcess = not update_terminal() break else: print("Shouldn't see this command!") continue if b_quit: break if not main_cmd: should_print_help = True if not gtff.ENABLE_QUICK_EXIT: if ns_known_args.opt == "reset" or update_succcess: print("resetting...") 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") print_goodbye() else: print_goodbye() if __name__ == "__main__": main()