From 70da6a57bc20f1e9a59dcff5d25c34735e230cc8 Mon Sep 17 00:00:00 2001 From: xingmingxu <65040750+xingmingxu@users.noreply.github.com> Date: Sun, 17 Jan 2021 00:05:40 -0500 Subject: [PATCH 1/2] Updated UI Doesn't look cosmetically good yet, still need the statistics portions --- main.py | 124 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 108 insertions(+), 16 deletions(-) diff --git a/main.py b/main.py index 5bdc044..79cd6ce 100644 --- a/main.py +++ b/main.py @@ -1,43 +1,135 @@ """ Different teams for the project (see discord for the rest of the information) - 1. GUI (tkinter) 2. Graphs, stats and data-analysis (statitstics and matplotlib for graphs) 3. AI and predictive analysis (tensorflow and scikit) - """ import numpy as np import pandas as pd import tkinter as tk +from tkinter import * from tkinter import messagebox +from matplotlib import pyplot as pp from datetime import datetime import statistics +#from matplotlib import pyplot - +# Windows settings root = tk.Tk() -root.iconbitmap(r'icon.ico') -root.geometry("500x500") +#root.iconbitmap(r'icon.ico') +root.geometry("600x500") root.resizable(True, True) -root.title("Stock tracker") -root.configure(bg = "#a2a2a2") +root.title("Stock Tracker Portal") +root.configure(bg = "#282C2F") -data = "" -def acceptFile(): - fileName = fileInput.get() +class date: + def __init__(self, colData): + date, self.open, self.high, self.low, self.close, self.adjClose, self.volume = colData + self.year, self.month, self.day = date.split('-') + + +# Reading the data files (format Datasets\File.csv) +def acceptFile(fileName): try: data = pd.read_csv(fileName) - except Exception as e: + return data + except Exception: messagebox.showerror(title = "Invalid file", message = "Please ensure file is in current working directory and the correct name was entered!") - print(e) -fileInput = tk.Entry(root, width = 55, bd = 2, justify = "left", font = "TkDefault 10") -fileInput.grid(row = 0, column = 0) -fileAccept = tk.Button(root, text = "Submit", font = "TkDefault 10", command = acceptFile) -fileAccept.grid(row = 0, column = 1) +# Finding the corresponding data file for the current ticker + time period +def searchTicker(): + ticker = fileInput.get() + data = acceptFile('SPY_max.csv').transpose() # change to ticker at the end. Changed to for testing + dateObj = [] + for colNum, colData in data.iteritems(): + obj = date(colData) + dateObj.append(obj) + + + +# Frames for organization +instructionFrame = tk.Frame(master = root) +topFrame = tk.Frame(master = root) +bodyFrame = tk.Frame(master = root) +resultFrame = tk.Frame(master = root) + +instructions = tk.Label( + master = instructionFrame, + text = "1. Select timeframe of prices.\n2. Click Submit.\n3. Produce results!", + font = 'TkDefault 16', + foreground = 'white', + background = '#303030' + ) +instructions.grid(row=0, column = 0) + + +# Text box for stock ticker +# TODO implement smart search of ticker to generate file +fileInput = tk.Entry(master = topFrame, width = 55, bd = 2, justify = "left", font = "TkDefault 10") +fileInput.grid(row = 1, column = 0) + +# Drop down box to add time frame +timeOptions = ["1D", "1W", "1M", "3M", "6M", "1Y", "5Y", "max"] +optionList = StringVar(topFrame) +optionList.set(timeOptions[0]) +timePeriod = tk.OptionMenu(topFrame, optionList, *timeOptions) +timePeriod.config(width = 3, font = "TKDefault 10") +timePeriod.grid(row = 1, column = 1) + + +# Button to commence search for data +fileAccept = tk.Button(master = topFrame, text = "Submit", font = "TkDefault 10", command = searchTicker) +fileAccept.grid(row = 1, column = 2) + +results = tk.Label( + master = resultFrame, + text = "Price is going: [UP/DOWN]", + font = 'TkDefault 16', + foreground = 'white', + background = '#303030' + ) +results.grid(row=3, column = 0) + + +instructionFrame.pack() +topFrame.pack() +bodyFrame.pack() +resultFrame.pack() root.mainloop() + + +# Temporary definition of Day class +class Day: + def __init__(self, day, month, year, open, high, low, close, volume): + self.day = day + self.month = month + self.year = year + self.open = open + self.high = high + self.low = low + self.close = close + self.volume = volume + self.date = "" + day + "/" + month + "/" + year + + +# Temporary place for graphing utility +# scope is a listof Day +def graphData(scope): + x_values = [] + y_values = [] + + for i in scope: + x_values.append(i.date) # open price + y_values.append(i.open) + + x_values.append(i.date) # close price + y_values.append(i.close) + + pp.plot(x_values, y_values) + pp.show() From 8b6c5f425082f6c33ee52d1a67234365697984f0 Mon Sep 17 00:00:00 2001 From: xingmingxu <65040750+xingmingxu@users.noreply.github.com> Date: Sun, 17 Jan 2021 00:27:43 -0500 Subject: [PATCH 2/2] Updated UI Still need to connect the statistics/graphs properly --- main.py | 202 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 162 insertions(+), 40 deletions(-) diff --git a/main.py b/main.py index 79cd6ce..07c7925 100644 --- a/main.py +++ b/main.py @@ -4,17 +4,24 @@ 2. Graphs, stats and data-analysis (statitstics and matplotlib for graphs) 3. AI and predictive analysis (tensorflow and scikit) """ - - import numpy as np import pandas as pd import tkinter as tk -from tkinter import * from tkinter import messagebox from matplotlib import pyplot as pp -from datetime import datetime +from datetime import datetime, date, timedelta import statistics -#from matplotlib import pyplot +from dateutil.relativedelta import relativedelta +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg +import tensorflow as tf +from tensorflow import keras +from sklearn import preprocessing +from sklearn.preprocessing import MinMaxScaler +from tensorflow.keras import layers +from tensorflow.keras import callbacks +from sklearn.model_selection import train_test_split +from sklearn.linear_model import LinearRegression + # Windows settings root = tk.Tk() @@ -24,12 +31,12 @@ root.title("Stock Tracker Portal") root.configure(bg = "#282C2F") -class date: +class point: def __init__(self, colData): - date, self.open, self.high, self.low, self.close, self.adjClose, self.volume = colData - self.year, self.month, self.day = date.split('-') + dates, self.open, self.high, self.low, self.close, self.adjClose, self.volume = colData + year, month, day = dates.split('-') + self.date = date(int(year), int(month), int(day)) - # Reading the data files (format Datasets\File.csv) def acceptFile(fileName): try: @@ -39,23 +46,50 @@ def acceptFile(fileName): messagebox.showerror(title = "Invalid file", message = "Please ensure file is in current working directory and the correct name was entered!") -# Finding the corresponding data file for the current ticker + time period +def subtractDay(dateObj, num): + return dateObj - timedelta(num) + +def subtractMonth(dateObj, num): + return dateObj - relativedelta(months=num) + +def subtractYear(dateObj, num): + return dateObj - relativedelta(years=num) + + def searchTicker(): ticker = fileInput.get() data = acceptFile('SPY_max.csv').transpose() # change to ticker at the end. Changed to for testing dateObj = [] for colNum, colData in data.iteritems(): - obj = date(colData) + obj = point(colData) dateObj.append(obj) + dataDates = date.today() + + dateSelection = optionList.get() + if dateSelection[1] == 'D': + dataDates = subtractDay(dataDates, int(dateSelection[0])) + elif dateSelection[1] == 'W': + dataDates = subtractDay(dataDates, int(dateSelection[0])*7) + elif dateSelection[1] == 'M': + dataDates = subtractMonth(dataDates, int(dateSelection[0])) + elif dateSelection[1] == 'Y': + dataDates = subtractYear(dataDates, int(dateSelection[0])) + else: + dataDates = date(1, 1, 1) + + filteredData = set() + for obj in dateObj: + if obj.date >= dataDates: + filteredData.add(obj) # Frames for organization instructionFrame = tk.Frame(master = root) topFrame = tk.Frame(master = root) bodyFrame = tk.Frame(master = root) -resultFrame = tk.Frame(master = root) +# User instructions instructions = tk.Label( master = instructionFrame, text = "1. Select timeframe of prices.\n2. Click Submit.\n3. Produce results!", @@ -64,72 +98,160 @@ def searchTicker(): background = '#303030' ) instructions.grid(row=0, column = 0) - +instructionFrame.pack() # Text box for stock ticker -# TODO implement smart search of ticker to generate file fileInput = tk.Entry(master = topFrame, width = 55, bd = 2, justify = "left", font = "TkDefault 10") fileInput.grid(row = 1, column = 0) # Drop down box to add time frame timeOptions = ["1D", "1W", "1M", "3M", "6M", "1Y", "5Y", "max"] -optionList = StringVar(topFrame) +optionList = tk.StringVar(topFrame) optionList.set(timeOptions[0]) timePeriod = tk.OptionMenu(topFrame, optionList, *timeOptions) timePeriod.config(width = 3, font = "TKDefault 10") timePeriod.grid(row = 1, column = 1) - # Button to commence search for data fileAccept = tk.Button(master = topFrame, text = "Submit", font = "TkDefault 10", command = searchTicker) fileAccept.grid(row = 1, column = 2) +topFrame.pack() -results = tk.Label( - master = resultFrame, - text = "Price is going: [UP/DOWN]", +# Immediate Predictions +result1 = tk.Label( + master = bodyFrame, + text = "Price is going: [UP/DOWN]\n", font = 'TkDefault 16', foreground = 'white', background = '#303030' ) -results.grid(row=3, column = 0) +result1.grid(row = 2, column = 0) +result2 = tk.Label( + master = bodyFrame, + text = "Predicted Price: ", + font = 'TkDefault 12', + foreground = 'white', + background = '#303030' + ) +result2.grid(row = 3, column = 0) +result3 = tk.Label( + master = bodyFrame, + text = "Percent change from yesterday: ", + font = 'TkDefault 12', + foreground = 'white', + background = '#303030' + ) +result3.grid(row = 4, column = 0) +bodyFrame.pack() +#random data to add to the GUI +data1 = {'Year': [1993,1994,1995,1996,1997,1998,1999,2000], + 'Opening_Price': [41,42,43,44,45,46,47,48.] + } +df1 = pd.DataFrame(data1,columns=['Year','Opening_Price']) + +#adds the graph to the GUI (under the topFrame and bodyFrame) +figure1 = pp.Figure(figsize=(4,4), dpi=100) +ax1 = figure1.add_subplot(111) # 111 represents how much of the whitespace that the graph fills +line1 = FigureCanvasTkAgg(figure1, root) +line1.get_tk_widget().pack(fill=tk.BOTH) +df1 = df1[['Year','Opening_Price']].groupby('Year').sum() +df1.plot(kind='line', legend=True, ax=ax1, color='r',marker='o', fontsize=10) +ax1.set_title('Year Vs. Opening_Price') -instructionFrame.pack() -topFrame.pack() -bodyFrame.pack() -resultFrame.pack() root.mainloop() -# Temporary definition of Day class -class Day: - def __init__(self, day, month, year, open, high, low, close, volume): - self.day = day - self.month = month - self.year = year - self.open = open - self.high = high - self.low = low - self.close = close - self.volume = volume - self.date = "" + day + "/" + month + "/" + year + +def some_prep(data): + new_data = data[["Date", "Adj Close"]].shift(-1) + new_data[['Open', 'High', 'Low', 'Close', 'Volume']] = data[ + ['Open', 'High', 'Low', 'Close', 'Volume']] + to_predict = new_data.iloc[-1:] + return new_data, to_predict + + +def get_data(data): + val_size = data.shape[0] + val_size = 2112 + train_size = 4931 + data = data.drop("Date", axis = 1) + cols = data.columns + scaler = MinMaxScaler(feature_range=(0, 1)) + data = pd.DataFrame(scaler.fit_transform(data), columns = cols) + data_x = (data.copy()).drop("Adj Close", axis = 1) + data_y = data["Adj Close"] + X_train = data_x.iloc[:train_size] + X_val = data_x.iloc[val_size:] + Y_train = data_y.iloc[:train_size] + Y_val = data_y.iloc[val_size:] + return X_train, X_val, Y_train, Y_val + +def model_deep(data): + # normalize the dataset + X_train, X_valid, y_train, y_valid = get_data(data) + input_shape = [data.shape[1] - 1] + model = keras.Sequential([ + layers.BatchNormalization(input_shape=input_shape), + layers.Dense(512, activation='relu'), + layers.BatchNormalization(), + layers.Dense(512, activation='relu'), + layers.BatchNormalization(), + layers.Dense(512, activation='relu'), + layers.BatchNormalization(), + layers.Dense(1), + ]) + model.compile( + optimizer='sgd', + loss='mae', + metrics=['mae'], + ) + EPOCHS = 100 + history = model.fit( + X_train, y_train, + validation_data=(X_valid, y_valid), + batch_size=64, + epochs=EPOCHS, + verbose=0, + ) + + history_df = pd.DataFrame(history.history) + return history_df + + +def linear_reg(data): + input_shape = [data.shape[1] - 1] + data_x = data["Date"] + data_y = data["Adj Close"] + model = keras.Sequential([layers.Dense(units=1, input_shape = [6])]) + model(data_x) + weights = model.get_weights() + return weights + +#df['Date'] = pd.to_datetime(df.Date,format='%Y-%m-%d') + + + + + + + +""" # Temporary place for graphing utility -# scope is a listof Day +# scope is a list of Day def graphData(scope): x_values = [] y_values = [] - for i in scope: x_values.append(i.date) # open price y_values.append(i.open) - x_values.append(i.date) # close price y_values.append(i.close) - pp.plot(x_values, y_values) pp.show() +"""