-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStockVisualizerY.py
More file actions
337 lines (280 loc) · 10.9 KB
/
Copy pathStockVisualizerY.py
File metadata and controls
337 lines (280 loc) · 10.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
# import packages
from pandas import DataFrame
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from tkinter import *
import datetime
import yfinance as yf
from yahoo_fin import stock_info as si
from time import sleep
import time
import threading
import pandas as pd
import numpy as np
# define the plot style and initialize the tkinter GUI
plt.style.use('seaborn-darkgrid')
root = Tk()
# define the tickers and arrays to hold the data
symbollist = ["MSFT", "AAPL", "TSLA"]
symbol2 = "MSFT"
gainerdata = []
loserdata = []
activedata = []
# initialize the stocks
stockOne = yf.Ticker(symbollist[0])
stockTwo = yf.Ticker(symbol2)
# define the string variables for the labels
currPrice1 = StringVar()
currPrice2 = StringVar()
gainers = StringVar()
losers = StringVar()
activity = StringVar()
symbol = StringVar()
symbol.set(symbollist[0])
symbol1 = StringVar()
symbol1.set(symbol2)
# labels for stock data
Label(root, textvariable=currPrice1, font=("Times", 16)).grid(row=0, column=2, sticky='WENS')
Label(root, textvariable=symbol, font=("Times", 16)).grid(row=0, column=1, sticky='WENS')
Label(root, textvariable=currPrice2, font=("Times", 16)).grid(row=2, column=2, sticky='WENS')
Label(root, textvariable=symbol1, font=("Times", 16)).grid(row=2, column=1, sticky='WENS')
count = 0
# these three functions define what to do when an index is selected on one of the list boxes
def onselectGainer(evt):
global symbol2, gainerdata, stockTwo, canvas3
# Note here that Tkinter passes an event object to onselect()
w = evt.widget
index = int(w.curselection()[0])
symbol2 = gainerdata['Symbol'][index]
symbol1.set(symbol2)
stockTwo = yf.Ticker(symbol2)
updateDailies()
plotgraph4()
def onselectLoser(evt):
global symbol2, loserdata, stockTwo
# Note here that Tkinter passes an event object to onselect()
w = evt.widget
index = int(w.curselection()[0])
symbol2 = loserdata['Symbol'][index]
symbol1.set(symbol2)
stockTwo = yf.Ticker(symbol2)
updateDailies()
plotgraph4()
def onselectActive(evt):
global symbol2, activedata, stockTwo
# Note here that Tkinter passes an event object to onselect()
w = evt.widget
index = int(w.curselection()[0])
symbol2 = activedata['Symbol'][index]
symbol1.set(symbol2)
stockTwo = yf.Ticker(symbol2)
updateDailies()
plotgraph4()
# labels for gainers and losers
Label(root, text="Top Gainers", font=("Times", 16), fg="green").grid(row=0, column=3, sticky='WENS')
gainerbox = Listbox(root, listvariable=gainers, font=("Times", 12), fg="green", width=30, selectmode=SINGLE)
gainerbox.grid(row=1, column=3, sticky='WENS')
Label(root, text="Top Active", font=("Times", 16), fg="blue").grid(row=2, column=3, sticky='WENS')
activitybox = Listbox(root, listvariable=activity, font=("Times", 12), fg="blue", width=30, selectmode=SINGLE)
activitybox.grid(row=3, column=3, sticky='WENS')
Label(root, text="Top Losers", font=("Times", 16), fg="red").grid(row=0, column=4, sticky='WENS')
loserbox = Listbox(root, listvariable=losers, font=("Times", 12), fg="red", width=30, selectmode=SINGLE)
loserbox.grid(row=1, column=4, sticky='WENS')
# defines what function to call when something is double clicked
gainerbox.bind("<Double-Button-1>", onselectGainer)
loserbox.bind("<Double-Button-1>", onselectLoser)
activitybox.bind("<Double-Button-1>", onselectActive)
# initialize the current time
current_time = 0
# figure one data
df1 = None
figure1 = plt.Figure(figsize=(4, 3), dpi=100)
ax1 = figure1.add_subplot(111)
canvas1 = FigureCanvasTkAgg(figure1, root)
canvas1.get_tk_widget().grid(row=1, column=1, sticky='WENS')
# figure two data
df2 = None
figure2 = plt.Figure(figsize=(4, 3), dpi=100)
ax2 = figure2.add_subplot(111)
canvas2 = FigureCanvasTkAgg(figure2, root)
canvas2.get_tk_widget().grid(row=1, column=2, sticky='WENS')
# figure three data
df3 = None
figure3 = plt.Figure(figsize=(4, 3), dpi=100)
ax3 = figure3.add_subplot(111)
canvas3 = FigureCanvasTkAgg(figure3, root)
canvas3.get_tk_widget().grid(row=3, column=1, sticky='WENS')
# figure four data
df4 = None
figure4 = plt.Figure(figsize=(4, 3), dpi=100)
ax4 = figure4.add_subplot(111)
canvas4 = FigureCanvasTkAgg(figure4, root)
canvas4.get_tk_widget().grid(row=3, column=2, sticky='WENS')
# stop event for threading
stopEvent = threading.Event()
# defines what to do on startup to initialize everything
def startup():
# plot the historical graphs and set up the top movers lists
plotgraph1()
plotgraph3()
getDayMovers()
plotgraph2()
plotgraph4()
# updates the daily graphs and label
def updateDailies():
global stockOne, stockTwo, loserbox, gainerbox, activitybox
# set the current price label to the current price
currPrice1.set("Current Price: $" + (str(round(float(si.get_live_price(symbol1)), 2))))
currPrice2.set("Current Price: $" + (str(round(float(si.get_live_price(symbol2)), 2))))
# plot the graphs
plotgraph1()
plotgraph3()
# main loop to handle updating the graph once program starts
def stonkLoop():
try:
# define the timings of stock market hours (EST)
start = '09:30:00'
end = '16:00:00'
# confirm threading stopEvent
while not stopEvent.is_set():
# get current time and date
t = time.localtime()
d = datetime.datetime.now()
currtime = time.strftime("%H:%M:%S", t)
# check if stock market is open
if (start < currtime < end) and (d.isoweekday() in range(1, 6)):
# get the current data and update the graphs
updateDailies()
getDayMovers()
# amount between graph and price updates - in seconds
sleep(30)
except RuntimeError:
print("[INFO] caught a RuntimeError")
# rotate through list of tickers every 15 seconds
def rotateTickers():
global symbol1, symbollist, stockOne, count
try:
# define the timings of stock market hours (EST)
start = '08:30:00'
end = '16:00:00'
# confirm threading stopEvent
while not stopEvent.is_set():
# get current time and date
t = time.localtime()
d = datetime.datetime.now()
currtime = time.strftime("%H:%M:%S", t)
# check if stock market is open
if (start < currtime < end) and (d.isoweekday() in range(1, 6)):
# get the current data and update the graphs
symbol1 = symbollist[count]
symbol.set(symbol1)
stockOne = yf.Ticker(symbol1)
updateDailies()
plotgraph2()
count = count + 1
if count > (len(symbollist) - 1):
count = 0
# amount between graph and price updates - in seconds
sleep(15)
except RuntimeError:
print("[INFO] caught a RuntimeError")
# get the daily gainers, losers, and active stocks
def getDayMovers():
global gainers, losers, activity, gainerdata, loserdata, activedata
gainerdata = pd.DataFrame(si.get_day_gainers())[['Symbol', 'Price (Intraday)', '% Change']]
gainerdata['Price (Intraday)'] = "$" + gainerdata['Price (Intraday)'].astype(str)
gainerdata['% Change'] = "+" + gainerdata['% Change'].astype(str) + "%"
gainerdata['Combined'] = gainerdata[gainerdata.columns[0:]].apply(
lambda x: ':'.join(x.dropna().astype(str)),
axis=1
)
loserdata = pd.DataFrame(si.get_day_losers())[['Symbol', 'Price (Intraday)', '% Change']]
loserdata['Price (Intraday)'] = "$" + loserdata['Price (Intraday)'].astype(str)
loserdata['% Change'] = loserdata['% Change'].astype(str) + "%"
loserdata['Combined'] = loserdata[loserdata.columns[0:]].apply(
lambda x: ':'.join(x.dropna().astype(str)),
axis=1
)
activedata = pd.DataFrame(si.get_day_most_active())[['Symbol', 'Price (Intraday)', '% Change']]
activedata['Price (Intraday)'] = "$" + activedata['Price (Intraday)'].astype(str)
activedata['% Change'] = activedata['% Change'].astype(str) + "%"
activedata['Combined'] = activedata[activedata.columns[0:]].apply(
lambda x: ':'.join(x.dropna().astype(str)),
axis=1
)
# sets the list box data
gainers.set('\n'.join(gainerdata['Combined']))
losers.set('\n'.join(loserdata['Combined']))
activity.set('\n'.join(activedata['Combined']))
# stonk one - current price
def plotgraph1():
global df1, figure1, ax1, root, canvas1
# define the daily data
dailyData = pd.DataFrame(stockOne.history(period="1d", interval="1m"))['Open']
dailyData.index = dailyData.index.strftime("%H:%M:%S")
# clear the axis and dataframe so there's no overwriting
ax1.clear()
df1 = None
# data for the plot
df1 = dailyData
df1.plot(kind='line', legend=False, ax=ax1, grid=True, x=df1.index, y=df1, title="Current Trend")
figure1.autofmt_xdate()
# draw the plot
canvas1.draw_idle()
# stonk one - one month price graph
def plotgraph2():
global df2, figure2, ax2, root, canvas2
# define the daily data
monthlyData = pd.DataFrame(stockOne.history(period="1mo", interval="1d"))['Open']
monthlyData.index = monthlyData.index.strftime("%m/%d")
# clear the axis and dataframe so there's no overwriting
ax2.clear()
df2 = None
# data for the plot
df2 = monthlyData
df2.plot(kind='line', legend=False, ax=ax2, grid=True, x=df2.index, y=df2, title="One Month Trend")
figure2.autofmt_xdate()
# draw the plot
canvas2.draw_idle()
# stonk two - current price
def plotgraph3():
global df3, figure3, ax3, root, canvas3
# define the daily data
dailyData = pd.DataFrame(stockTwo.history(period="1d", interval="1m"))['Open']
dailyData.index = dailyData.index.strftime("%H:%M:%S")
# clear the axis and dataframe so there's no overwriting
ax3.clear()
df3 = None
# data for the plot
df3 = dailyData
df3.plot(kind='line', legend=False, ax=ax3, grid=True, x=df3.index, y=df3, title="Current Trend")
figure3.autofmt_xdate()
# draw the plot
canvas3.draw_idle()
# stonk two - one month price graph
def plotgraph4():
global df4, figure4, ax4, root, canvas4
# define the daily data
monthlyData = pd.DataFrame(stockTwo.history(period="1mo", interval="1d"))['Open']
monthlyData.index = monthlyData.index.strftime("%m/%d")
# clear the axis and dataframe so there's no overwriting
ax4.clear()
df4 = None
# data for the plot
df4 = monthlyData
df4.plot(kind='line', legend=False, ax=ax4, grid=True, x=df4.index, y=df4, title="One Month Trend")
figure4.autofmt_xdate()
# draw the plot
canvas4.draw_idle()
# show the plots
plt.show()
# set GUI title
root.wm_title("StonksTracker")
startup()
# start the threading
thread = threading.Thread(target=stonkLoop, args=())
thread.start()
thread1 = threading.Thread(target=rotateTickers, args=())
thread1.start()
# start GUI mainloop
root.mainloop()