Files
OpenBB/stock_market_cli.py
2021-01-16 15:54:15 +00:00

321 lines
12 KiB
Python

""" Example or something
Is this not informative enough?
Load a specific stock
Then apply a specific TA on it
Do this because AlphaVantage only allows 5 API calls per minutes.
This way we only need 1 call, and can apply TA to the result without
using an API request.
Multiple TA with kind stock
Do my own personal Fundamental Analysis Dataframe
Do option to explain important key metrics
Do own personal Technical Analysis with multiple indicators perhaps?
Split Menu into fa, ta and pred. Fundamental Analysis, Technical Analysis and Prediction, respectively.
Do Reddit popularity study!
- By using defined ticker
- By looking for mentioned tickers
- By giving your own subreddit, using used ones.
At the end, provide save tool where we save all data into an excel with:
NIO_datetimesaved.xlsx
- Sheet1 - Profile/Overview (FMP or AV)
- Sheet2 - Finance (Market watch)
- Sheet3 - Earnings (Market watch)
- Sheet4 - SEC filings
- Sheet5 - Insiders
- Sheet6 - Analyst prices
- Sheet7 - News
- Sheet8 - Warnings & Key metrics
- Sheet9 - Reddit popularity
"""
import argparse
import pandas as pd
from stock_market_helper_funcs import *
from fundamental_analysis import fa_menu as fam
from technical_analysis import ta_menu as tam
from discovery import disc_menu as dam
# delete this important when automatic loading tesla
#i.e. when program is done
import config_bot as cfg
from alpha_vantage.timeseries import TimeSeries
# ----------------------------------------------------- LOAD -----------------------------------------------------
def load(l_args, s_ticker, s_start, s_interval, df_stock):
parser = argparse.ArgumentParser(prog='load', description=""" Load a stock in order to perform analysis""")
parser.add_argument('-t', "--ticker", action="store", dest="s_ticker", required=True, help="Stock ticker")
parser.add_argument('-s', "--start", type=valid_date, dest="s_start_date", help="The starting date (format YYYY-MM-DD) of the stock")
parser.add_argument('-i', "--interval", action="store", dest="n_interval", type=int, default=1440, choices=[1,5,15,30,60], help="Intraday stock minutes")
try:
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
except SystemExit:
print("")
return [s_ticker, s_start, s_interval, df_stock]
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}")
# Update values:
s_ticker = ns_parser.s_ticker
s_start = ns_parser.s_start_date
s_interval = str(ns_parser.n_interval)+'min'
try:
ts = TimeSeries(key=cfg.API_KEY_ALPHAVANTAGE, output_format='pandas')
# Daily
if s_interval == "1440min":
df_stock, d_stock_metadata = ts.get_daily_adjusted(symbol=ns_parser.s_ticker, outputsize='full')
# Intraday
else:
df_stock, d_stock_metadata = ts.get_intraday(symbol=ns_parser.s_ticker, outputsize='full', interval=s_interval)
except:
print("Either the ticker or the API_KEY are invalids. Try again!")
return [s_ticker, s_start, s_interval, df_stock]
s_intraday = (f'Intraday {s_interval}', 'Daily')[s_interval == "1440min"]
if s_start:
# Slice dataframe from the starting date YYYY-MM-DD selected
df_stock = df_stock[ns_parser.s_start_date:]
print(f"Loading {s_intraday} {s_ticker} stock with starting period {s_start.strftime('%Y-%m-%d')} for analysis.\n")
else:
print(f"Loading {s_intraday} {s_ticker} stock for analysis.\n")
return [s_ticker, s_start, s_interval, df_stock]
# ----------------------------------------------------- VIEW -----------------------------------------------------
def view(l_args, s_ticker, s_start, s_interval, df_stock):
parser = argparse.ArgumentParser(prog='view', description='Visualise historical data of a stock. An alpha_vantage key is necessary.')
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')
parser.add_argument('-s', "--start", type=valid_date, dest="s_start_date", help="The starting date (format YYYY-MM-DD) of the stock")
parser.add_argument('-i', "--interval", action="store", dest="n_interval", type=int, default=0, choices=[1,5,15,30,60], help="Intraday stock minutes")
parser.add_argument("--type", action="store", dest="n_type", type=check_positive, default=5, # in case it's daily
help='1234 corresponds to types: 1. open; 2. high; 3.low; 4. close; while 14 corresponds to types: 1.open; 4. close')
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}")
# Update values:
s_ticker = ns_parser.s_ticker
if ns_parser.s_start_date:
s_start = ns_parser.s_start_date
# A new interval intraday period was given
if ns_parser.n_interval != 0:
s_interval = str(ns_parser.n_interval)+'min'
try:
ts = TimeSeries(key=cfg.API_KEY_ALPHAVANTAGE, output_format='pandas')
# Daily
if s_interval == "1440min":
df_stock, d_stock_metadata = ts.get_daily_adjusted(symbol=s_ticker, outputsize='full')
# Intraday
else:
df_stock, d_stock_metadata = ts.get_intraday(symbol=s_ticker, outputsize='full', interval=s_interval)
except:
print("Either the ticker or the API_KEY are invalids. Try again!")
return
# Slice dataframe from the starting date YYYY-MM-DD selected
df_stock = df_stock[s_start:]
# Daily
if s_interval == "1440min":
# The default doesn't exist for intradaily data
ln_col_idx = [int(x)-1 for x in list(str(ns_parser.n_type))]
if 4 not in ln_col_idx:
ln_col_idx.append(4)
# Check that the types given are not bigger than 4, as there are only 5 types (0-4)
if len([i for i in ln_col_idx if i > 4]) > 0:
print("An index bigger than 4 was given, which is wrong. Try again")
return
# Append last column of df to be filtered which corresponds to: 6. Volume
ln_col_idx.append(5)
# Intraday
else:
# The default doesn't exist for intradaily data
if ns_parser.n_type == 5:
ln_col_idx = [3]
else:
ln_col_idx = [int(x)-1 for x in list(str(ns_parser.n_type))]
# Check that the types given are not bigger than 3, as there are only 4 types (0-3)
if len([i for i in ln_col_idx if i > 3]) > 0:
print("An index bigger than 3 was given, which is wrong. Try again")
return
# Append last column of df to be filtered which corresponds to: 5. Volume
ln_col_idx.append(4)
# Plot view of the stock
plot_view_stock(df_stock.iloc[:, ln_col_idx], ns_parser.s_ticker)
# ----------------------------------------------------- HELP ------------------------------------------------------------------
def print_help(s_ticker, s_start, s_interval, b_is_market_open):
""" Print help
"""
print("What do you want to do?")
print(" help help to see this menu again")
print(" quit to abandon the program")
print("")
print(" clear clear a specific stock ticker from analysis")
print(" load load a specific stock ticker for analysis")
print(" view view and load a specific stock ticker for technical analysis")
s_intraday = (f'Intraday {s_interval}', 'Daily')[s_interval == "1440min"]
if s_ticker and s_start:
print(f"\n{s_intraday} Stock: {s_ticker} (from {s_start.strftime('%Y-%m-%d')})")
elif s_ticker:
print(f"\n{s_intraday} Stock: {s_ticker}")
else:
print("\nStock: ?")
print(f"Market {('CLOSED', 'OPEN')[b_is_market_open]}.")
if s_ticker:
print("\nMenus:")
print(" disc discovery mode")
print(" fa fundamental analysis")
print(" ta technical analysis")
print(" pred prediction techniques")
'''
print("\nPrediction:")
print(" ma")
print(" ema")
print(" lr")
print(" knn")
print(" arima")
print(" rnn")
print(" lstm")
print(" prophet")
'''
# -----------------------------------------------------------------------------------------------------------------------
def main():
""" Main function of the program
"""
s_ticker = ""
s_start = ""
df_stock = pd.DataFrame()
b_intraday = False
s_interval = "1440min"
# Set stock by default to speed up testing
s_ticker = "NIO"
s_start = datetime.strptime("2020-06-04", "%Y-%m-%d")
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 = df_stock[s_start:]
# Delete above in the future
# Add list of arguments that the main parser accepts
menu_parser = argparse.ArgumentParser(prog='stock_market_bot', add_help=False)
menu_parser.add_argument('opt', choices=['help', 'quit',
'clear', 'load', 'view',
'disc', 'fa', 'ta'])
# Print first welcome message and help
print("\nWelcome to Didier's Stock Market Bot\n")
print_help(s_ticker, s_start, s_interval, b_is_stock_market_open())
print("\n")
# Loop forever and ever
while True:
# Get input command from user
as_input = input('> ')
# Is command empty
if not len(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
if ns_known_args.opt == 'help':
print_help(s_ticker, s_start, s_interval, b_is_stock_market_open())
elif ns_known_args.opt == 'quit':
print("Hope you made money today. Good bye my lover, good bye my friend.\n")
return
elif ns_known_args.opt == 'clear':
print("Clearing stock ticker to be used for analysis")
s_ticker = ""
s_start = ""
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)
elif ns_known_args.opt == 'view':
view(l_args, s_ticker, s_start, s_interval, df_stock)
# DISCOVERY MENU
elif ns_known_args.opt == 'disc':
b_quit = dam.disc_menu()
if b_quit:
print("Hope you made money today. Good bye my lover, good bye my friend.\n")
return
else:
print_help(s_ticker, s_start, s_interval, b_is_stock_market_open())
# FUNDAMENTAL ANALYSIS MENU
elif ns_known_args.opt == 'fa':
b_quit = fam.fa_menu(s_ticker, s_start, s_interval)
if b_quit:
print("Hope you made money today. Good bye my lover, good bye my friend.\n")
return
else:
print_help(s_ticker, s_start, s_interval, b_is_stock_market_open())
# TECHNICAL ANALYSIS MENU
elif ns_known_args.opt == 'ta':
b_quit = tam.ta_menu(df_stock, s_ticker, s_start, s_interval)
if b_quit:
print("Hope you made money today. Good bye my lover, good bye my friend.\n")
return
else:
print_help(s_ticker, s_start, s_interval, b_is_stock_market_open())
else:
print('Shouldnt see this command!')
print("")
if __name__ == "__main__":
main()