I am working on my own UI. For now I have just shaped the main screen. But what I need to do is to run some functions in background while the UI is working and the user is using the UI(i.e. some functions get activated and the user gets redirected to another screen). I have tried the function that uses multiprocessing module:
def runInParallel(self, *fns):
proc = []
for fn in fns:
p = Process(target=fn)
p.start()
proc.append(p)
for p in proc:
p.join()
But unfortunately it does not work, and UI isn't updating.
I have conducted a trial for this method(experimentally) but for some reason when I run this function with arguments self.runInParallel(self.xtb_main_screen, self.getAllSymbols_xtb_api)
inside log_in_xtb_api
function after clicking log in button another instance of the UI just opens up.
Below is the code for the UI class.
What I want to achieve is to get functions like getAllSymbols
or getChartLastRequest
, work always when the UI is running.
For the first time when launching the program it gots to download the data for the first time. But after the startup I need to actualise the data every 1,5,15 or etc [minutes].
So my UI can't be constanly lagged due to the code execution.
How do I make any function I want run in parallel/background so the UI won't lag?
This is code for the UI class:
Note that to use the functions like log_in_xtb_api
or others from xtb broker api
, you need to download the wrapper connector and import it and iside it change ports from 5112 and 5113 to 5124 and 5125 if you have a demo account or leave them as they are if you have real account:
http://developers.xstore.pro/api/wrappers/2.5.0
class UI:
def __init__(self):
self.UI_main = tk.Tk()
self.width_screen, self.height_screen = resolution()
self.canvas_main = tk.Canvas(self.UI_main, height=self.height_screen, width=self.width_screen)
self.canvas_main.pack()
self.login_screen()
self.UI_main.mainloop()
def login_screen(self):
self.frame_login = Frame(self.canvas_main, bg='#131d47')
self.frame_login.pack()
self.frame_login.place(relx=0.5, rely=0.5, anchor=CENTER)
self.login_font = tkFont.Font(family='Calibri', size=30)
self.login_xtb_btn = tk.Button(self.frame_login, text='Log in to XTB', width=25, height=2,
command=self.login_xtb_ui)
self.login_xtb_btn['font'] = self.login_font
self.login_xtb_btn.pack()
self.login_tradingview_btn = tk.Button(self.frame_login, text='Log in to Tradingview', width=25, height=2,
command=self.login_tradingview_choose)
self.login_tradingview_btn['font'] = self.login_font
self.login_tradingview_btn.pack()
def login_xtb_ui(self):
for widgets in self.canvas_main.winfo_children():
widgets.destroy()
self.login_xtb_font = tkFont.Font(family='Calibri', size=25)
self.xtb_login = StringVar()
self.xtb_login.set("Enter user ID")
self.xtb_password = StringVar()
self.xtb_password.set("Enter password here")
self.frame_xtb_login = Frame(self.canvas_main)
self.frame_xtb_login.pack()
self.frame_xtb_login.place(relx=0.5, rely=0.5, anchor=CENTER)
self.xtb_login_entry = Entry(self.frame_xtb_login, textvariable=self.xtb_login, width=25)
self.xtb_login_entry.pack()
self.xtb_login_entry['font'] = self.login_xtb_font
self.xtb_password_entry = Entry(self.frame_xtb_login, textvariable=self.xtb_password, width=25)
self.xtb_password_entry.pack()
self.xtb_password_entry['font'] = self.login_xtb_font
self.xtb_log_in_btn = tk.Button(self.frame_xtb_login, text='Log in', command=self.xtb_log_in)
self.xtb_log_in_btn.pack()
self.xtb_log_in_btn['font'] = self.login_xtb_font
return 'apple'
def xtb_log_in(self):
self.user_id_xtb = self.xtb_login_entry.get()
self.password_xtb = self.xtb_password_entry.get()
'''
self.host = 'xapi.xtb.com'
self.port = 5112
self.host = socket.getaddrinfo(self.host, self.port)[0][4][0]
self.s = socket.socket()
self.s.connect((self.host, self.port))
self.s = ssl.wrap_socket(self.s)
self.END = b'\n\n'
'''
self.log_in_xtb_api(userId=self.user_id_xtb, password=self.password_xtb)
def xtb_main_screen(self):
for widgets in self.canvas_main.winfo_children():
widgets.destroy()
canvas_top_height = math.floor(0.07 * self.height_screen)
canvas_charting_tools_width = math.floor(0.03 * self.width_screen)
canvas_charting_tools_height = self.height_screen - canvas_top_height # takes full screen
paned_window_charting_main_width = self.width_screen - canvas_charting_tools_width
paned_window_charting_main_height = self.height_screen - canvas_top_height
canvas_charting_top_width = self.width_screen - canvas_charting_tools_width
canvas_charting_top_height = self.height_screen - canvas_top_height - math.floor(0.3 * self.height_screen)
canvas_charting_bottom_width = self.width_screen - canvas_charting_tools_width
canvas_charting_bottom_height = self.height_screen - canvas_charting_top_height
canvas_charting_indicators_width = math.floor(0.14 * self.width_screen)
canvas_charting_indicators_height = self.height_screen - canvas_top_height - math.floor(0.3 * self.height_screen)
canvas_charting_chart_width = math.floor(0.65 * self.width_screen)
canvas_charting_chart_height = self.height_screen - canvas_top_height - math.floor(0.3 * self.height_screen)
paned_window_charting_downloads_info_width = self.width_screen - canvas_charting_tools_width - canvas_charting_indicators_width - canvas_charting_chart_width
paned_window_charting_downloads_info_height = canvas_charting_chart_height
canvas_charting_downloads_width = paned_window_charting_downloads_info_width
canvas_charting_downloads_height = math.floor(0.5 * paned_window_charting_downloads_info_height)
canvas_charting_info_width = paned_window_charting_downloads_info_width
canvas_charting_info_height = paned_window_charting_downloads_info_height - canvas_charting_downloads_height
menu_btn_width = 20
menu_btn_height = math.floor(0.7 * canvas_top_height)
menu_xtb_btn_font = tkFont.Font(family='Calibri', size=20)
# Canvas top xtb main aka Menu
# Contains:
# Charting screen
# Symbol search
# Trading Bot
# neural nets
# Machine learning
self.canvas_top_xtb_main = Canvas(self.canvas_main, width=self.width_screen, height=canvas_top_height, bg='#131d47')
self.canvas_top_xtb_main.pack()
# position (0.0, 0.0) top
self.canvas_top_xtb_main.place(relx=0.0, rely=0.0, anchor=NW)
self.frame_menu_xtb_main_top = Frame(self.canvas_top_xtb_main)
self.frame_menu_xtb_main_top.pack(expand=False)
self.frame_menu_xtb_main_top.place(relx=0.0, rely=0.0, anchor=NW)
# Charting screen Button
self.charting_screen_btn = Button(self.frame_menu_xtb_main_top, text='Main Screen')
self.charting_screen_btn.grid(row=0, column=0, padx=5, pady=5)
self.charting_screen_btn['font'] = menu_xtb_btn_font
# Symbol search button
self.symbol_search_btn = Button(self.frame_menu_xtb_main_top, text='Symbol Search', command=self.symbol_search_btn_xtb)
self.symbol_search_btn.grid(row=0, column=1, padx=5, pady=5)
self.symbol_search_btn['font'] = menu_xtb_btn_font
# Trading Bot Button
self.trading_bot_btn = Button(self.frame_menu_xtb_main_top, text='Trading Bot')
self.trading_bot_btn.grid(row=0, column=2, padx=5, pady=5)
self.trading_bot_btn['font'] = menu_xtb_btn_font
# Neural Nets Button
self.neural_nets_btn = Button(self.frame_menu_xtb_main_top, text='Neural Nets')
self.neural_nets_btn.grid(row=0, column=3, padx=5, pady=5)
self.neural_nets_btn['font'] = menu_xtb_btn_font
# Machine Learning Button
self.machine_learning_btn = Button(self.frame_menu_xtb_main_top, text='Machine Learning')
self.machine_learning_btn.grid(row=0, column=4, padx=5, pady=5)
self.machine_learning_btn['font'] = menu_xtb_btn_font
# main charting container
self.canvas_charting_xtb_main = Canvas(self.canvas_main, width=self.width_screen, height=(self.height_screen - canvas_top_height), bg='#ff9100')
self.canvas_charting_xtb_main.pack()
# position (0.0, -100) lowered by the height of frame_top_xtb_main height
self.canvas_charting_xtb_main.place(relx=0.0, y=canvas_top_height, anchor=NW)
# charting tools container
# contains tools to draw on chart
self.canvas_charting_tools = Canvas(self.canvas_charting_xtb_main, width=canvas_charting_tools_width, height=canvas_charting_tools_height, bg='#e80000')
self.canvas_charting_tools.pack()
# position (0.0, 0.0) relative to the frame_charting_xtb_main
self.canvas_charting_tools.place(relx=0.0, rely=0.0, anchor=NW)
# Secondary charting container
self.canvas_charting_xtb_sec = Canvas(self.canvas_charting_xtb_main, width=(self.width_screen - canvas_charting_tools_width), height=(self.height_screen - canvas_top_height), bg='#ff9100')
self.canvas_charting_xtb_sec.pack()
# position (0.0, -100) lowered by the height of frame_top_xtb_main height
self.canvas_charting_xtb_sec.place(x=canvas_charting_tools_width, y=0, anchor=NW)
# Paned Widow main
# Contains:
# Indicator panel
# Chart panel
# dowloades panel
# neural nets panel
self.paned_window_charting_main = PanedWindow(self.canvas_charting_xtb_sec, width=paned_window_charting_main_width, height=paned_window_charting_main_height, bg='#3700ff', orient=VERTICAL)
self.paned_window_charting_main.pack()
self.paned_window_charting_main.place(x=0, y=0)
# Canvas charting Bottom
# Contains:
# Available trained neural nets
self.canvas_charting_bottom = Canvas(width=canvas_charting_bottom_width, height=canvas_charting_bottom_height, bg='#000000')
self.canvas_charting_bottom.pack()
# Paned Window Charting Top
# Contains:
# Indicator panel
# Chart panel
# dowloads panel
self.paned_window_charting_top = PanedWindow(width=canvas_charting_top_width, height=canvas_charting_top_height, bg='#3700ff', orient=HORIZONTAL)
self.paned_window_charting_top.pack()
self.paned_window_charting_top.place(relx=0.0, rely=0.0, anchor=NW)
self.paned_window_charting_main.add(self.paned_window_charting_top)
self.paned_window_charting_main.add(self.canvas_charting_bottom)
# Canvas charting Indicators
# Contains:
# Indicators list available for chosen dataset
self.canvas_charting_indicators = Canvas(width=canvas_charting_indicators_width, height=canvas_charting_indicators_height)
self.canvas_charting_indicators.pack()
# Canvas charting chart
# Contains:
# Chart panel
self.canvas_charting_chart = Canvas(width=canvas_charting_chart_width, height=canvas_charting_chart_height)
self.canvas_charting_chart.pack()
# Paned Window Downloads And Sell/Buy Info
# Contains:
# Downloads Panel
# Symbol BUY/SELL Info
self.paned_window_charting_downloads_info = PanedWindow(width=paned_window_charting_downloads_info_width, height=paned_window_charting_downloads_info_height, orient=VERTICAL, bg='#3700ff')
self.paned_window_charting_downloads_info.pack()
# Canvas charting downloads
# Contains:
# Downloads panel
self.canvas_charting_downloads = Canvas(width=canvas_charting_downloads_width, height=canvas_charting_downloads_height)
self.canvas_charting_downloads.pack()
# Canvas charting info
# Contains:
# Symbol BUY/SELL Info
self.canvas_charting_info = Canvas(width=canvas_charting_info_width, height=canvas_charting_info_height)
self.canvas_charting_info.pack()
self.paned_window_charting_downloads_info.add(self.canvas_charting_downloads)
self.paned_window_charting_downloads_info.add(self.canvas_charting_info)
self.paned_window_charting_top.add(self.canvas_charting_indicators)
self.paned_window_charting_top.add(self.canvas_charting_chart)
self.paned_window_charting_top.add(self.paned_window_charting_downloads_info)
#self.getAllSymbols_xtb_api()
#resp = self.client.commandExecute(commandName='getSymbol', arguments=21)
#print(resp)
#price = self.getChartLastRequest(symbol_name=self.symbols_unique[0], period=5, time=1262944112000)
#print(price)
def login_tradingview_choose(self):
for widgets in self.canvas_main.winfo_children():
widgets.destroy()
self.login_tradingview_font = tkFont.Font(family='Calibri', size=25)
self.frame_tradingview_login = Frame(self.canvas_main)
self.frame_tradingview_login.pack()
self.frame_tradingview_login.place(relx=0.5, rely=0.5, anchor=CENTER)
self.tradingview_login_google_btn = tk.Button(self.frame_tradingview_login, text='Log in with Google', width=25, height=2, command=self.login_tradingview_google)
self.tradingview_login_google_btn.pack()
self.tradingview_login_google_btn['font'] = self.login_tradingview_font
self.tradingview_login_username_btn = tk.Button(self.frame_tradingview_login, text='log in with tradingview', width=25, height=2, command=self.login_tradingview_username)
self.tradingview_login_username_btn.pack()
self.tradingview_login_username_btn['font'] = self.login_tradingview_font
def login_tradingview_google(self):
for widgets in self.canvas_main.winfo_children():
widgets.destroy()
self.login_tradingview_google_font = tkFont.Font(family='Calibri', size=25)
self.tradingview_google_login = StringVar()
self.tradingview_google_login.set("Enter login or email here")
self.tradingview_google_password = StringVar()
self.tradingview_google_password.set("Enter password here")
self.frame_tradingview_google_login = Frame(self.canvas_main)
self.frame_tradingview_google_login.pack()
self.frame_tradingview_google_login.place(relx=0.5, rely=0.5, anchor=CENTER)
self.tradingview_google_login_entry = Entry(self.frame_tradingview_google_login, textvariable=self.tradingview_google_login, width=25)
self.tradingview_google_login_entry.pack()
self.tradingview_google_login_entry['font'] = self.login_tradingview_google_font
self.tradingview_google_password_entry = Entry(self.frame_tradingview_google_login, textvariable=self.tradingview_google_password, width=25)
self.tradingview_google_password_entry.pack()
self.tradingview_google_password_entry['font'] = self.login_tradingview_google_font
self.tradingview_google_log_in_btn = tk.Button(self.frame_tradingview_google_login, text='Log in')
self.tradingview_google_log_in_btn.pack()
self.tradingview_google_log_in_btn['font'] = self.login_tradingview_google_font
def login_tradingview_username(self):
for widgets in self.canvas_main.winfo_children():
widgets.destroy()
self.login_tradingview_username_font = tkFont.Font(family='Calibri', size=25)
self.tradingview_username_login = StringVar()
self.tradingview_username_login.set("Enter login or email here")
self.tradingview_username_password = StringVar()
self.tradingview_username_password.set("Enter password here")
self.frame_tradingview_username_login = Frame(self.canvas_main)
self.frame_tradingview_username_login.pack()
self.frame_tradingview_username_login.place(relx=0.5, rely=0.5, anchor=CENTER)
self.tradingview_username_login_entry = Entry(self.frame_tradingview_username_login, textvariable=self.tradingview_username_login, width=25)
self.tradingview_username_login_entry.pack()
self.tradingview_username_login_entry['font'] = self.login_tradingview_username_font
self.tradingview_username_password_entry = Entry(self.frame_tradingview_username_login, textvariable=self.tradingview_username_password, width=25)
self.tradingview_username_password_entry.pack()
self.tradingview_username_password_entry['font'] = self.login_tradingview_username_font
self.tradingview_username_log_in_btn = tk.Button(self.frame_tradingview_username_login, text='Log in')
self.tradingview_username_log_in_btn.pack()
self.tradingview_username_log_in_btn['font'] = self.login_tradingview_username_font
def log_in_xtb_api(self, userId, password):
# enter your login credentials here
userId = userId
password = "password"
# create & connect to RR socket
self.client = xAPIConnector.APIClient()
# connect to RR socket, login
loginResponse = self.client.execute(xAPIConnector.loginCommand(userId=userId, password=password))
xAPIConnector.logger.info(str(loginResponse))
# check if user logged in correctly
if (loginResponse['status'] == False):
print('Login failed. Error code: {0}'.format(loginResponse['errorCode']))
return
# get ssId from login response
ssid = loginResponse['streamSessionId']
self.runInParallel(self.xtb_main_screen, self.getAllSymbols_xtb_api)
def getAllSymbols_xtb_api(self):
symbols_init = self.client.commandExecute('getAllSymbols')
symbols_list_init = list(symbols_init.items())
symbols_list_final = list()
for i in range(len(symbols_list_init[1][1][:])):
symbols_list_final.append(symbols_list_init[1][1][i])
self.symbols_dataframe = pd.DataFrame(symbols_list_final)
self.unique_category = self.symbols_dataframe['categoryName'].unique()
self.unique_group = self.symbols_dataframe['groupName'].unique()
self.symbols_unique = self.symbols_dataframe['symbol'].unique()
print(self.unique_category)
print(self.unique_group)
def getChartLastRequest(self, symbol_name : str, period : int, time : int):
parameters = {"info" : {
"period": period,
"start": time,
"symbol": symbol_name
}}
price_init = self.client.commandExecute(commandName='getChartLastRequest', arguments=parameters)
print(price_init)
def symbol_search_btn_xtb(self):
for widgets in self.canvas_charting_xtb_sec.winfo_children():
widgets.place_forget()
self.symbol_search_xtb_ui()
def symbol_search_xtb_ui(self):
symbol_search_xtb_btn_font = tkFont.Font(family='Calibri', size=20)
self.frame_search_xtb_btns = Frame(self.canvas_charting_xtb_sec, width=(self.width_screen - math.floor(0.03 * self.width_screen)))
self.frame_search_xtb_btns.pack()
self.frame_search_xtb_btns.place(relx=0.0, rely=0.0, anchor=NW)
pixel = tk.PhotoImage(width=1, height=1)
self.label_search_xtb = Label(self.frame_search_xtb_btns, text='', image=pixel, width=(self.width_screen - math.floor(0.03 * self.width_screen)), anchor=W)
self.label_search_xtb.pack()
self.stocks_xtb_btn = Button(self.frame_search_xtb_btns, text='Stocks', anchor=W)
self.stocks_xtb_btn.pack(fill=X)
self.stocks_xtb_btn['font'] = symbol_search_xtb_btn_font
self.CRT_xtb_btn = Button(self.frame_search_xtb_btns, text='Stocks', anchor=W)
self.CRT_xtb_btn.pack(fill=X)
self.CRT_xtb_btn['font'] = symbol_search_xtb_btn_font
self.ETF_xtb_btn = Button(self.frame_search_xtb_btns, text='Stocks', anchor=W)
self.ETF_xtb_btn.pack(fill=X)
self.ETF_xtb_btn['font'] = symbol_search_xtb_btn_font
self.indexes_xtb_btn = Button(self.frame_search_xtb_btns, text='Indexes', anchor=W)
self.indexes_xtb_btn.pack(fill=X)
self.indexes_xtb_btn['font'] = symbol_search_xtb_btn_font
self.forex_xtb_btn = Button(self.frame_search_xtb_btns, text='Forex', anchor=W)
self.forex_xtb_btn.pack(fill=X)
self.forex_xtb_btn['font'] = symbol_search_xtb_btn_font
self.STK_xtb_btn = Button(self.frame_search_xtb_btns, text='Stocks', anchor=W)
self.STK_xtb_btn.pack(fill=X)
self.STK_xtb_btn['font'] = symbol_search_xtb_btn_font
self.CMD_xtb_btn = Button(self.frame_search_xtb_btns, text='Stocks', anchor=W)
self.CMD_xtb_btn.pack(fill=X)
self.CMD_xtb_btn['font'] = symbol_search_xtb_btn_font
def runInParallel(self, *fns):
proc = []
for fn in fns:
p = Process(target=fn)
p.start()
proc.append(p)
for p in proc:
p.join()
EDIT:
After deleting the last loop in runInParallel
function the code looks like this:
def runInParallel(self, *fns):
proc = []
for fn in fns:
p = Process(target=fn)
p.start()
proc.append(p)
p.join()
And I got an error after this error is raised new instance of the UI class opens up:
Traceback (most recent call last):
File "C:\Users\...\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "C:\Users\...\PycharmProjects\LSTM_multiple_indicators\UI.py", line 92, in xtb_log_in
self.log_in_xtb_api(userId=self.user_id_xtb, password=self.password_xtb)
File "C:\Users\...\PycharmProjects\LSTM_multiple_indicators\UI.py", line 358, in log_in_xtb_api
self.runInParallel(self.xtb_main_screen, self.getAllSymbols_xtb_api)
File "C:\Users\...\PycharmProjects\LSTM_multiple_indicators\UI.py", line 439, in runInParallel
p.start()
File "C:\Users\...\AppData\Local\Programs\Python\Python39\lib\multiprocessing\process.py", line 121, in start
self._popen = self._Popen(self)
File "C:\Users\...\AppData\Local\Programs\Python\Python39\lib\multiprocessing\context.py", line 224, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
File "C:\Users\...\AppData\Local\Programs\Python\Python39\lib\multiprocessing\context.py", line 327, in _Popen
return Popen(process_obj)
File "C:\Users\...\AppData\Local\Programs\Python\Python39\lib\multiprocessing\popen_spawn_win32.py", line 93, in __init__
reduction.dump(process_obj, to_child)
File "C:\Users\...\AppData\Local\Programs\Python\Python39\lib\multiprocessing\reduction.py", line 60, in dump
ForkingPickler(file, protocol).dump(obj)
TypeError: cannot pickle '_tkinter.tkapp' object