Split code across different files

This commit is contained in:
didier
2020-12-24 14:55:07 +00:00
parent 6e747de5c3
commit 0436dbf14a
5 changed files with 487 additions and 430 deletions

View File

@@ -1,430 +0,0 @@
""" 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.
Finviz for data
"""
from alpha_vantage.timeseries import TimeSeries
import argparse
import config_bot as cfg
import pandas as pd
import pandas_ta as ta
from datetime import datetime
import matplotlib
import matplotlib.pyplot as plt
from pandas.plotting import register_matplotlib_converters
from pytz import timezone
from holidays import US as holidaysUS
from datetime import datetime, time as Time
register_matplotlib_converters()
# -----------------------------------------------------------------------------------------------------------------------
def print_help(s_ta_ticker, s_ta_start, b_is_market_open):
""" Print help
"""
print("What do you want to do?")
print("\n--- Screeners:")
print("view view and load a specific stock ticker for technical analysis")
print("gainers show latest top gainers")
print("load load a specific stock ticker for technical analysis")
print("clear clear a specific stock ticker from technical analysis")
if s_ta_ticker and s_ta_start:
print(f"\n--- Technical Analysis on {s_ta_ticker} starting at {s_ta_start.strftime('%Y-%m-%d')}:")
elif s_ta_ticker:
print(f"\n--- Technical Analysis on {s_ta_ticker}:")
else:
print("\n--- Technical Analysis:")
print("sma simple moving average")
print("ema exponential moving average")
print("\n--- Prediction:")
print("RNN")
print("ARIMA")
print("LSTM")
print("Facebook prophet")
print(f"\n--- Market {('Closed', 'Open')[b_is_market_open]}. Play stocks:")
print("Stock name, and how much money to bet?")
print("\n--- Others:")
print("help help to see this menu again")
print("quit to abandon the program")
# -----------------------------------------------------------------------------------------------------------------------
def check_positive(value):
ivalue = int(value)
if ivalue <= 0:
raise argparse.ArgumentTypeError(f"{value} is an invalid positive int value")
return ivalue
# -----------------------------------------------------------------------------------------------------------------------
def valid_date(s):
try:
return datetime.strptime(s, "%Y-%m-%d")
except ValueError:
raise argparse.ArgumentTypeError("Not a valid date: {s}")
# -----------------------------------------------------------------------------------------------------------------------
def plot_view_stock(df, symbol):
pfig, axVolume = plt.subplots()
plt.bar(df.index, df['5. volume'].values, color='k', alpha=0.8)
plt.ylabel('Volume')
axPrice = axVolume.twinx()
plt.plot(df.index, df.iloc[:, :-1])
plt.title(symbol + ' (Time Series)')
plt.xlim(df.index[0], df.index[-1])
plt.xlabel('Time')
plt.ylabel('Share Price ($)')
plt.legend(df.columns)
plt.grid(b=True, which='major', color='#666666', linestyle='-')
plt.minorticks_on()
plt.grid(b=True, which='minor', color='#999999', linestyle='-', alpha=0.2)
plt.show()
# -----------------------------------------------------------------------------------------------------------------------
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_ta.index, df_ta.values)
plt.title(f"{s_ta} on {s_stock}")
plt.xlim(df_stock.index[0], df_stock.index[-1])
plt.xlabel('Time')
plt.ylabel('Share Price ($)')
plt.legend([s_stock, s_ta])
plt.grid(b=True, which='major', color='#666666', linestyle='-')
plt.minorticks_on()
plt.grid(b=True, which='minor', color='#999999', linestyle='-', alpha=0.2)
plt.show()
# -----------------------------------------------------------------------------------------------------------------------
def b_is_stock_market_open():
''' checks if the stock market is open '''
# Get current US time
now = datetime.now(timezone('US/Eastern'))
# Check if it is a weekend
if now.date().weekday() > 4:
return False
# Check if it is a holiday
if now.strftime('%Y-%m-%d') in holidaysUS():
return False
# Check if it hasn't open already
if now.time() < Time(hour=9, minute=30, second=0):
return False
# Check if it has already closed
if now.time() > Time(hour=16, minute=0, second=0):
return False
# Otherwise, Stock Market is open!
return True
# -----------------------------------------------------------------------------------------------------------------------
def main():
""" Main function of the program
"""
# temporary
#parser.add_argument('-a', action="store_true", default=False, help='example of flag')
#parser.add_argument('-b', action="store", dest="b", help='example of string')
#parser.add_argument('-c', action="store", dest="c", type=int, help='example of int')
s_ta_ticker = ""
s_ta_start = ""
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'])
# Print first welcome message and help
print("\nWelcome to Didier's Stock Market Bot\n")
print_help(s_ta_ticker, s_ta_start, b_is_stock_market_open())
print("\n")
# Loop forever and ever
while True:
# Get input command from user
as_input = input('> ')
# Parse main command of the list of possible commands
try:
(ns_known_args, l_args) = main_parser.parse_known_args(as_input.split())
except SystemExit:
print("The command selected doesn't exist\n")
continue
# ---------------------------------------------------- GAINERS ----------------------------------------------------
if ns_known_args.cmd == 'gainers':
parser = argparse.ArgumentParser(prog='gainers',
description='Show top ticker gainers from Yahoo Finance')
parser.add_argument('-n', "--num", action="store", dest="n_gainers", type=int, default=5, choices=range(1, 25),
help='Number of the top gainers stocks to retrieve (default 5)')
try:
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
except SystemExit:
print("")
continue
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}")
df_gainers = pd.read_html('https://finance.yahoo.com/screener/predefined/day_gainers')[0]
print(df_gainers.head(ns_parser.n_gainers).to_string(index=False))
# ---------------------------------------------------- VIEW ----------------------------------------------------
elif ns_known_args.cmd == 'view':
parser = argparse.ArgumentParser(prog='view',
description='Given a stock market ticker, allows to see historical data of \
the corresponding stock. Note that the alpha_vantage key is necessary \
for this to work!')
parser.add_argument('-t', "--ticker" ,action="store", dest="s_ticker", required=True, help='Stock ticker')
parser.add_argument("--type", action="store", dest="n_type", type=check_positive, default=4,
help='1234 corresponds to types: 1. open; 2. high; 3.low; 4. close \
while 14 corresponds to types: 1.open; 4. close')
parser.add_argument('-s', "--start", type=valid_date, dest="s_start_date",
help="The starting date (format YYYY-MM-DD) of the stock")
try:
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
except SystemExit:
print("")
continue
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}")
# Currently only supports daily stocks
# TODO: Intra-daily perhaps
ts = TimeSeries(key=cfg.API_KEY, output_format='pandas')
try:
df_stock, d_stock_metadata = ts.get_daily(symbol=ns_parser.s_ticker, outputsize='full')
except:
print("Either the ticker or the API_KEY are invalids. Try again!")
continue
s_ta_ticker = ns_parser.s_ticker
# Add function to plot data
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")
continue
# Slice dataframe from the starting date YYYY-MM-DD selected
if ns_parser.s_start_date:
df_stock = df_stock[ns_parser.s_start_date:]
s_ta_start = ns_parser.s_start_date
ln_col_idx.append(4) # Append last column of df to be filtered which corresponds to: 5. Volume
plot_view_stock(df_stock.iloc[:, ln_col_idx], ns_parser.s_ticker)
# ---------------------------------------------------- LOAD ----------------------------------------------------
elif ns_known_args.cmd == 'load':
parser = argparse.ArgumentParser(prog='load',
description=""" Given a stock market ticker, and an optional starting time,
load a stock in order to perform technical analysis""")
parser.add_argument('-t', "--ticker", action="store", dest="s_ticker", required=True, help='Stock ticker')
parser.add_argument("--type", action="store", dest="n_type", type=check_positive, default=4,
help='1234 corresponds to types: 1. open; 2. high; 3.low; 4. close \
while 14 corresponds to types: 1.open; 4. close')
parser.add_argument('-s', "--start", type=valid_date, dest="s_start_date",
help="The starting date (format YYYY-MM-DD) of the stock")
try:
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
except SystemExit:
print("")
continue
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}")
# Currently only supports daily stocks
# TODO: Intra-daily perhaps
ts = TimeSeries(key=cfg.API_KEY, output_format='pandas')
try:
df_stock, d_stock_metadata = ts.get_daily(symbol=ns_parser.s_ticker, outputsize='full')
except:
print("Either the ticker or the API_KEY are invalids. Try again!")
continue
s_ta_ticker = ns_parser.s_ticker
# Add function to plot data
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")
continue
# Slice dataframe from the starting date YYYY-MM-DD selected
if ns_parser.s_start_date:
df_stock = df_stock[ns_parser.s_start_date:]
s_ta_start = ns_parser.s_start_date
else:
s_ta_start = ""
if s_ta_start:
print(f"Loading {s_ta_ticker} stock with starting period {s_ta_start.strftime('%Y-%m-%d')} for technical analysis.")
else:
print(f"Loading {s_ta_ticker} stock for technical analysis.")
# ---------------------------------------------------- CLEAR ----------------------------------------------------
elif ns_known_args.cmd == 'clear':
print("Clearing stock ticker to be used for technical analysis")
s_ta_ticker = ""
s_ta_start = ""
# --------------------------------------------------------------------------------------------------------------
# -------------------------------------------- TECHNICAL ANALYSIS ----------------------------------------------
# --------------------------------------------------------------------------------------------------------------
# ---------------------------------------------------- SMA ----------------------------------------------------
elif ns_known_args.cmd == 'sma':
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
the simplest form of a moving average. Each output value is the average of the
previous n values. In a Simple Moving Average, each value in the time period carries
equal weight, and values outside of the time period are not included in the average.
This makes it less responsive to recent changes in the data, which can be useful for
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_ta_ticker:
parser.add_argument('-t', "--ticker", action="store", dest="s_ticker", default=s_ta_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("")
continue
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, output_format='pandas')
df_stock, d_stock_metadata = ts.get_daily(symbol=ns_parser.s_ticker, outputsize='full')
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")
continue
# Update TA ticker
s_ta_ticker = ns_parser.s_ticker
# Update TA starting point if needed
if ns_parser.s_start_date:
s_ta_start = ns_parser.s_start_date
# Slice dataframe from the starting date YYYY-MM-DD selected
if s_ta_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")
continue
# ---------------------------------------------------- EMA ----------------------------------------------------
elif ns_known_args.cmd == 'ema':
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
Average, each value in the time period carries equal weight, and values outside
of the time period are not included in the average. However, the Exponential
Moving Average is a cumulative calculation, including all data. Past values have
a diminishing contribution to the average, while more recent values have a greater
contribution. This method allows the moving average to be more responsive to changes
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_ta_ticker:
parser.add_argument('-t', "--ticker", action="store", dest="s_ticker", default=s_ta_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("")
continue
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, output_format='pandas')
df_stock, d_stock_metadata = ts.get_daily(symbol=ns_parser.s_ticker, outputsize='full')
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")
continue
# Update TA ticker
s_ta_ticker = ns_parser.s_ticker
# Update TA starting point if needed
if ns_parser.s_start_date:
s_ta_start = ns_parser.s_start_date
# Slice dataframe from the starting date YYYY-MM-DD selected
if s_ta_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")
continue
# ---------------------------------------------------- HELP ----------------------------------------------------
elif ns_known_args.cmd == 'help':
print_help(s_ta_ticker, s_ta_start, b_is_stock_market_open())
# ---------------------------------------------------- QUIT ----------------------------------------------------
elif ns_known_args.cmd == 'quit':
print("Hope you made money today. Good bye my lover, good bye my friend.\n")
break
else:
print('Shouldnt see this command!')
print("\n")
if __name__ == "__main__":
main()

172
stock_market_cli.py Normal file
View File

@@ -0,0 +1,172 @@
""" 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.
Finviz for data
"""
from alpha_vantage.timeseries import TimeSeries
import argparse
import config_bot as cfg
import pandas as pd
import pandas_ta as ta
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
from stock_market_helper_funcs import *
import stock_market_menu as smm
import stock_market_technical_analysis as smta
# -----------------------------------------------------------------------------------------------------------------------
def print_help(s_ticker, s_start, b_is_market_open):
""" Print help
"""
print("What do you want to do?")
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(" 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')} <-----")
elif s_ticker:
print(f"\n-----> {s_ticker} <-----")
else:
print("\n-----> ? <-----")
print("\nFundamental Analysis:")
print(" example not yet covered")
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(f"\nMarket {('Closed', 'Open')[b_is_market_open]}. Play stocks:")
print("Stock name, and how much money to bet?")
# -----------------------------------------------------------------------------------------------------------------------
def main():
""" Main function of the program
"""
# temporary
#parser.add_argument('-a', action="store_true", default=False, help='example of flag')
#parser.add_argument('-b', action="store", dest="b", help='example of string')
#parser.add_argument('-c', action="store", dest="c", type=int, help='example of int')
s_ticker = ""
s_start = ""
df_stock = pd.DataFrame()
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'])
# Print first welcome message and help
print("\nWelcome to Didier's Stock Market Bot\n")
print_help(s_ticker, s_start, b_is_stock_market_open())
print("\n")
# Loop forever and ever
while True:
# Get input command from user
as_input = input('> ')
# Parse main command of the list of possible commands
try:
(ns_known_args, l_args) = main_parser.parse_known_args(as_input.split())
except SystemExit:
print("The command selected doesn't exist\n")
continue
# --------------------------------------------------------------------------------------------------------------
# --------------------------------------------------- MENU -----------------------------------------------------
# --------------------------------------------------------------------------------------------------------------
# --------------------------------------------------- GAINERS --------------------------------------------------
if ns_known_args.cmd == 'gainers':
smm.gainers(l_args)
continue
# --------------------------------------------------- CLEAR ----------------------------------------------------
elif ns_known_args.cmd == 'clear':
print("Clearing stock ticker to be used for analysis")
s_ticker = ""
s_start = ""
# ---------------------------------------------------- LOAD ----------------------------------------------------
elif ns_known_args.cmd == 'load':
[s_ticker, s_start, df_stock] = smm.load(l_args, s_ticker, s_start, df_stock)
continue
# ---------------------------------------------------- VIEW ----------------------------------------------------
elif ns_known_args.cmd == 'view':
smm.view(l_args, s_ticker, s_start)
continue
# ---------------------------------------------------- HELP ----------------------------------------------------
elif ns_known_args.cmd == 'help':
print_help(s_ticker, s_start, b_is_stock_market_open())
# ----------------------------------------------------- QUIT ----------------------------------------------------
elif ns_known_args.cmd == 'quit':
print("Hope you made money today. Good bye my lover, good bye my friend.\n")
break
# --------------------------------------------------------------------------------------------------------------
# ------------------------------------------- FUNDAMENTAL ANALYSIS ---------------------------------------------
# --------------------------------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------------------------------
# -------------------------------------------- TECHNICAL ANALYSIS ----------------------------------------------
# --------------------------------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------------------------------
# ------------------------------------------------ PREDICTION --------------------------------------------------
# --------------------------------------------------------------------------------------------------------------
# ---------------------------------------------------- SMA ----------------------------------------------------
elif ns_known_args.cmd == 'sma':
[s_ticker, s_start] = smta.sma(l_args, s_ticker, s_start)
continue
# ---------------------------------------------------- EMA ----------------------------------------------------
elif ns_known_args.cmd == 'ema':
[s_ticker, s_start] = smta.ema(l_args, s_ticker, s_start)
continue
else:
print('Shouldnt see this command!')
print("\n")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,76 @@
from pytz import timezone
from holidays import US as holidaysUS
from datetime import datetime, time as Time
import matplotlib
import matplotlib.pyplot as plt
# -----------------------------------------------------------------------------------------------------------------------
def check_positive(value):
ivalue = int(value)
if ivalue <= 0:
raise argparse.ArgumentTypeError(f"{value} is an invalid positive int value")
return ivalue
# -----------------------------------------------------------------------------------------------------------------------
def valid_date(s):
try:
return datetime.strptime(s, "%Y-%m-%d")
except ValueError:
raise argparse.ArgumentTypeError("Not a valid date: {s}")
# -----------------------------------------------------------------------------------------------------------------------
def plot_view_stock(df, symbol):
pfig, axVolume = plt.subplots()
plt.bar(df.index, df['5. volume'].values, color='k', alpha=0.8)
plt.ylabel('Volume')
axPrice = axVolume.twinx()
plt.plot(df.index, df.iloc[:, :-1])
plt.title(symbol + ' (Time Series)')
plt.xlim(df.index[0], df.index[-1])
plt.xlabel('Time')
plt.ylabel('Share Price ($)')
plt.legend(df.columns)
plt.grid(b=True, which='major', color='#666666', linestyle='-')
plt.minorticks_on()
plt.grid(b=True, which='minor', color='#999999', linestyle='-', alpha=0.2)
plt.show()
# -----------------------------------------------------------------------------------------------------------------------
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_ta.index, df_ta.values)
plt.title(f"{s_ta} on {s_stock}")
plt.xlim(df_stock.index[0], df_stock.index[-1])
plt.xlabel('Time')
plt.ylabel('Share Price ($)')
plt.legend([s_stock, s_ta])
plt.grid(b=True, which='major', color='#666666', linestyle='-')
plt.minorticks_on()
plt.grid(b=True, which='minor', color='#999999', linestyle='-', alpha=0.2)
plt.show()
# -----------------------------------------------------------------------------------------------------------------------
def b_is_stock_market_open():
''' checks if the stock market is open '''
# Get current US time
now = datetime.now(timezone('US/Eastern'))
# Check if it is a weekend
if now.date().weekday() > 4:
return False
# Check if it is a holiday
if now.strftime('%Y-%m-%d') in holidaysUS():
return False
# Check if it hasn't open already
if now.time() < Time(hour=9, minute=30, second=0):
return False
# Check if it has already closed
if now.time() > Time(hour=16, minute=0, second=0):
return False
# Otherwise, Stock Market is open!
return True

122
stock_market_menu.py Normal file
View File

@@ -0,0 +1,122 @@
import argparse
from alpha_vantage.timeseries import TimeSeries
import config_bot as cfg
import pandas as pd
from stock_market_helper_funcs import *
# ---------------------------------------------------- GAINERS ----------------------------------------------------
def gainers(l_args):
parser = argparse.ArgumentParser(prog='gainers',
description='Show top ticker gainers from Yahoo Finance')
parser.add_argument('-n', "--num", action="store", dest="n_gainers", type=int, default=5, choices=range(1, 25),
help='Number of the top gainers stocks to retrieve (default 5)')
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}")
df_gainers = pd.read_html('https://finance.yahoo.com/screener/predefined/day_gainers')[0]
print(df_gainers.head(ns_parser.n_gainers).to_string(index=False))
print("")
# ----------------------------------------------------- LOAD -----------------------------------------------------
def load(l_args, s_ticker, s_start, df_stock):
parser = argparse.ArgumentParser(prog='load',
description=""" Given a stock market ticker, and an optional starting time,
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")
try:
(ns_parser, l_unknown_args) = parser.parse_known_args(l_args)
except SystemExit:
print("")
return [s_ticker, s_start, df_stock]
if l_unknown_args:
print(f"The following args couldn't be interpreted: {l_unknown_args}")
# Currently only supports daily stocks
ts = TimeSeries(key=cfg.API_KEY_ALPHAVANTAGE, output_format='pandas')
try:
df_stock, d_stock_metadata = ts.get_daily(symbol=ns_parser.s_ticker, outputsize='full')
except:
print("Either the ticker or the API_KEY are invalids. Try again!")
return [s_ticker, s_start, df_stock]
s_ticker = ns_parser.s_ticker
if ns_parser.s_start_date:
s_start = ns_parser.s_start_date
# Slice dataframe from the starting date YYYY-MM-DD selected
if ns_parser.s_start_date:
df_stock = df_stock[ns_parser.s_start_date:]
# Get stock close price
df_stock = df_stock.iloc[:, 3]
if s_start:
print(f"Loading {s_ticker} stock with starting period {s_start.strftime('%Y-%m-%d')} for analysis.\n")
else:
print(f"Loading {s_ticker} stock for analysis.\n")
return [s_ticker, s_start, df_stock]
# ----------------------------------------------------- VIEW -----------------------------------------------------
def view(l_args, s_ticker, s_start):
parser = argparse.ArgumentParser(prog='view',
description='Given a stock market ticker, allows to see historical data of \
the corresponding stock. Note that the alpha_vantage key is necessary \
for this to work!')
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("--type", action="store", dest="n_type", type=check_positive, default=4,
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}")
# Currently only supports daily stocks
ts = TimeSeries(key=cfg.API_KEY_ALPHAVANTAGE, output_format='pandas')
try:
df_stock, d_stock_metadata = ts.get_daily(symbol=ns_parser.s_ticker, outputsize='full')
except:
print("Either the ticker or the API_KEY are invalids. Try again!")
return
# Slice dataframe from the starting date YYYY-MM-DD selected
if ns_parser.s_start_date:
df_stock = df_stock[ns_parser.s_start_date:]
# Add function to plot data
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
ln_col_idx.append(4) # Append last column of df to be filtered which corresponds to: 5. Volume
plot_view_stock(df_stock.iloc[:, ln_col_idx], ns_parser.s_ticker)

View File

@@ -0,0 +1,117 @@
import argparse
from alpha_vantage.timeseries import TimeSeries
import pandas_ta as ta
import config_bot as cfg
from stock_market_helper_funcs import *
# ----------------------------------------------------- SMA -----------------------------------------------------
def sma(l_args, s_ticker, s_start):
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
the simplest form of a moving average. Each output value is the average of the
previous n values. In a Simple Moving Average, each value in the time period carries
equal weight, and values outside of the time period are not included in the average.
This makes it less responsive to recent changes in the data, which can be useful for
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]
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')
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]
# ----------------------------------------------------- EMA -----------------------------------------------------
def ema(l_args, s_ticker, s_start):
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
Average, each value in the time period carries equal weight, and values outside
of the time period are not included in the average. However, the Exponential
Moving Average is a cumulative calculation, including all data. Past values have
a diminishing contribution to the average, while more recent values have a greater
contribution. This method allows the moving average to be more responsive to changes
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]
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')
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]