From cdbd62113dffba870c044f607d99047b00c490f5 Mon Sep 17 00:00:00 2001 From: didier Date: Thu, 24 Dec 2020 23:35:53 +0000 Subject: [PATCH] Add ratings, and improve CLI interface --- stock_market_cli.py | 67 ++++++++++++----------- stock_market_fundamental_analysis.py | 27 +++++++++ stock_market_helper_funcs.py | 3 +- stock_market_technical_analysis.py | 82 +++++----------------------- 4 files changed, 79 insertions(+), 100 deletions(-) create mode 100644 stock_market_fundamental_analysis.py diff --git a/stock_market_cli.py b/stock_market_cli.py index f8e9e3b7f90..19309142f3d 100644 --- a/stock_market_cli.py +++ b/stock_market_cli.py @@ -24,8 +24,7 @@ register_matplotlib_converters() from stock_market_helper_funcs import * import stock_market_menu as smm import stock_market_technical_analysis as smta - - +import stock_market_fundamental_analysis as smfa # ----------------------------------------------------------------------------------------------------------------------- def print_help(s_ticker, s_start, b_is_market_open): @@ -36,37 +35,38 @@ def print_help(s_ticker, s_start, b_is_market_open): print("\nMenu:") print(" gainers show latest top gainers") print(" view view and load a specific stock ticker for technical analysis") - print(" clear clear a specific stock ticker from technical analysis") - print(" load load a specific stock ticker for technical analysis") + print(" clear clear a specific stock ticker from analysis") + print(" load load a specific stock ticker for analysis") print(" help help to see this menu again") print(" quit to abandon the program") if s_ticker and s_start: - print(f"\n-----> {s_ticker} starting at {s_start.strftime('%Y-%m-%d')} <-----") + print(f"\nStock: {s_ticker} (from {s_start.strftime('%Y-%m-%d')})") elif s_ticker: - print(f"\n-----> {s_ticker} <-----") + print(f"\nStock: {s_ticker}") else: - print("\n-----> ? <-----") + print("\nStock: ?") - print("\nFundamental Analysis:") - print(" example not yet covered") + if s_ticker: + print("\nFundamental Analysis:") + print(" ratings company ratings from strong sell to strong buy") - print("\nTechnical Analysis:") - print(" sma simple moving average") - print(" ema exponential moving average") + print("\nTechnical Analysis:") + print(" sma simple moving average") + print(" ema exponential moving average") - print("\nPrediction:") - print(" ma") - print(" ema") - print(" lr") - print(" knn") - print(" arima") - print(" rnn") - print(" lstm") - print(" prophet") + print("\nPrediction:") + print(" ma") + print(" ema") + print(" lr") + print(" knn") + print(" arima") + print(" rnn") + print(" lstm") + print(" prophet") - print(f"\nMarket {('Closed', 'Open')[b_is_market_open]}. Play stocks:") - print("Stock name, and how much money to bet?") + print(f"\nMarket {('CLOSED', 'OPEN')[b_is_market_open]}.") + print("Stonks and things") # ----------------------------------------------------------------------------------------------------------------------- @@ -86,7 +86,7 @@ def main(): main_parser = argparse.ArgumentParser(prog='stock_market_bot', add_help=False) # Add list of arguments that the main parser accepts - main_parser.add_argument('cmd', choices=['quit', 'help', 'gainers' ,'view', 'load', 'clear', 'sma', 'ema']) + main_parser.add_argument('cmd', choices=['quit', 'help', 'gainers' ,'view', 'load', 'clear', 'sma', 'ema', 'ratings']) # Print first welcome message and help print("\nWelcome to Didier's Stock Market Bot\n") @@ -143,26 +143,29 @@ def main(): # ------------------------------------------- FUNDAMENTAL ANALYSIS --------------------------------------------- # -------------------------------------------------------------------------------------------------------------- + # --------------------------------------------------- RATINGS -------------------------------------------------- + elif ns_known_args.cmd == 'ratings': + smfa.ratings(l_args, s_ticker) + continue + # -------------------------------------------------------------------------------------------------------------- # -------------------------------------------- TECHNICAL ANALYSIS ---------------------------------------------- # -------------------------------------------------------------------------------------------------------------- - # -------------------------------------------------------------------------------------------------------------- - # ------------------------------------------------ PREDICTION -------------------------------------------------- - # -------------------------------------------------------------------------------------------------------------- - # ---------------------------------------------------- SMA ---------------------------------------------------- elif ns_known_args.cmd == 'sma': - [s_ticker, s_start] = smta.sma(l_args, s_ticker, s_start) + smta.sma(l_args, s_ticker, df_stock) continue # ---------------------------------------------------- EMA ---------------------------------------------------- elif ns_known_args.cmd == 'ema': - [s_ticker, s_start] = smta.ema(l_args, s_ticker, s_start) + smta.ema(l_args, s_ticker, df_stock) continue - - + # -------------------------------------------------------------------------------------------------------------- + # ------------------------------------------------ PREDICTION -------------------------------------------------- + # -------------------------------------------------------------------------------------------------------------- + else: print('Shouldnt see this command!') diff --git a/stock_market_fundamental_analysis.py b/stock_market_fundamental_analysis.py new file mode 100644 index 00000000000..3ef55097c8f --- /dev/null +++ b/stock_market_fundamental_analysis.py @@ -0,0 +1,27 @@ +import FundamentalAnalysis as fa +import config_bot as cfg +import argparse +from stock_market_helper_funcs import * + +# ---------------------------------------------------- RATINGS ---------------------------------------------------- +def ratings(l_args, s_ticker): + parser = argparse.ArgumentParser(prog='ratings', + description=""" Gives information about the rating of a company which includes + i.a. the company rating and recommendation as well as ratings based + on a variety of ratios.""") + + try: + (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) + except SystemExit: + print("") + return + + if l_unknown_args: + print(f"The following args couldn't be interpreted: {l_unknown_args}") + + try: + df_ratings = fa.rating(s_ticker, cfg.API_KEY_FINANCIALMODELINGPREP) + print(df_ratings) + print("") + except: + print("") diff --git a/stock_market_helper_funcs.py b/stock_market_helper_funcs.py index 9af941f9f4d..b73e838871a 100644 --- a/stock_market_helper_funcs.py +++ b/stock_market_helper_funcs.py @@ -41,7 +41,7 @@ def plot_view_stock(df, symbol): # ----------------------------------------------------------------------------------------------------------------------- def plot_stock_ta(df_stock, s_stock, df_ta, s_ta): - plt.plot(df_stock.index, df_stock['4. close'].values) + plt.plot(df_stock.index, df_stock.values) plt.plot(df_ta.index, df_ta.values) plt.title(f"{s_ta} on {s_stock}") plt.xlim(df_stock.index[0], df_stock.index[-1]) @@ -52,6 +52,7 @@ def plot_stock_ta(df_stock, s_stock, df_ta, s_ta): plt.minorticks_on() plt.grid(b=True, which='minor', color='#999999', linestyle='-', alpha=0.2) plt.show() + print("") # ----------------------------------------------------------------------------------------------------------------------- diff --git a/stock_market_technical_analysis.py b/stock_market_technical_analysis.py index 37a6079d5f9..2589c5279e9 100644 --- a/stock_market_technical_analysis.py +++ b/stock_market_technical_analysis.py @@ -5,7 +5,7 @@ import config_bot as cfg from stock_market_helper_funcs import * # ----------------------------------------------------- SMA ----------------------------------------------------- -def sma(l_args, s_ticker, s_start): +def sma(l_args, s_ticker, df_stock): parser = argparse.ArgumentParser(prog='sma', description=""" Moving Averages are used to smooth the data in an array to help eliminate noise and identify trends. The Simple Moving Average is literally @@ -16,52 +16,26 @@ def sma(l_args, s_ticker, s_start): filtering out those changes. """) parser.add_argument('-p', "--period", action="store", dest="n_time_period", type=check_positive, default=20, help='Number of data points used to calculate each moving average value.') - parser.add_argument("-s", "--start", type=valid_date, dest="s_start_date", - help="The starting date (format YYYY-MM-DD) of the stock") - if s_ticker: - parser.add_argument('-t', "--ticker", action="store", dest="s_ticker", default=s_ticker, help='Stock ticker') - else: - parser.add_argument('-t', "--ticker", action="store", dest="s_ticker", required=True, help='Stock ticker') - + try: (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) except SystemExit: print("") - return [s_ticker, s_start] + return if l_unknown_args: print(f"The following args couldn't be interpreted: {l_unknown_args}") - try: # Get stock data - ts = TimeSeries(key=cfg.API_KEY_ALPHAVANTAGE, output_format='pandas') - df_stock, d_stock_metadata = ts.get_daily(symbol=ns_parser.s_ticker, outputsize='full') + try: + df_ta = ta.sma(df_stock, timeperiod=ns_parser.n_time_period).dropna() + plot_stock_ta(df_stock, s_ticker, df_ta, f"{ns_parser.n_time_period} SMA") except: - print("ERROR! Try again!") - print("Check that: 1. The ticker symbol exists and is valid") - print(" 2. Less than 5 AlphaVantage requests have been made in 1 minute") - print(" 3. The API_KEY is (still) valid") - return [s_ticker, s_start] - - # Update TA ticker - s_ticker = ns_parser.s_ticker - - # Update TA starting point if needed - if ns_parser.s_start_date: - s_start = ns_parser.s_start_date - - # Slice dataframe from the starting date YYYY-MM-DD selected - if s_start: - df_stock = df_stock[ns_parser.s_start_date:] - - df_ta = ta.sma(df_stock['4. close'], timeperiod=ns_parser.n_time_period).dropna() - - plot_stock_ta(df_stock, d_stock_metadata['2. Symbol'], df_ta, f"{ns_parser.n_time_period} SMA") - - return [s_ticker, s_start] + print("") + return # ----------------------------------------------------- EMA ----------------------------------------------------- -def ema(l_args, s_ticker, s_start): +def ema(l_args, s_ticker, df_stock): parser = argparse.ArgumentParser(prog='ema', description=""" The Exponential Moving Average is a staple of technical analysis and is used in countless technical indicators. In a Simple Moving @@ -73,45 +47,19 @@ def ema(l_args, s_ticker, s_start): in the data. """) parser.add_argument('-p', "--period", action="store", dest="n_time_period", type=check_positive, default=20, help='Number of data points used to calculate each moving average value.') - parser.add_argument("-s", "--start", type=valid_date, dest="s_start_date", - help="The starting date (format YYYY-MM-DD) of the stock") - if s_ticker: - parser.add_argument('-t', "--ticker", action="store", dest="s_ticker", default=s_ticker, help='Stock ticker') - else: - parser.add_argument('-t', "--ticker", action="store", dest="s_ticker", required=True, help='Stock ticker') try: (ns_parser, l_unknown_args) = parser.parse_known_args(l_args) except SystemExit: print("") - return [s_ticker, s_start] + return if l_unknown_args: print(f"The following args couldn't be interpreted: {l_unknown_args}") - try: # Get stock data - ts = TimeSeries(key=cfg.API_KEY_ALPHAVANTAGE, output_format='pandas') - df_stock, d_stock_metadata = ts.get_daily(symbol=ns_parser.s_ticker, outputsize='full') + try: + df_ta = ta.ema(df_stock, timeperiod=ns_parser.n_time_period).dropna() + plot_stock_ta(df_stock, s_ticker, df_ta, f"{ns_parser.n_time_period} EMA") except: - print("ERROR! Try again!") - print("Check that: 1. The ticker symbol exists and is valid") - print(" 2. Less than 5 AlphaVantage requests have been made in 1 minute") - print(" 3. The API_KEY is (still) valid") - return [s_ticker, s_start] - - # Update TA ticker - s_ticker = ns_parser.s_ticker - - # Update TA starting point if needed - if ns_parser.s_start_date: - s_start = ns_parser.s_start_date - - # Slice dataframe from the starting date YYYY-MM-DD selected - if s_start: - df_stock = df_stock[ns_parser.s_start_date:] - - df_ta = ta.ema(df_stock['4. close'], timeperiod=ns_parser.n_time_period).dropna() - - plot_stock_ta(df_stock, d_stock_metadata['2. Symbol'], df_ta, f"{ns_parser.n_time_period} EMA") - - return [s_ticker, s_start] \ No newline at end of file + print("") + return