def __init__(self, parent, window, *args, **kvargs): tkinter.Frame.__init__(self, parent, *args, **kvargs) # Backend try: openInstruments = core.open_instruments(accounts.get_all()[0]["name"]) openInstruments.sort() except Exception as e: print(e) openInstruments = [] # Frontend self.symbolVar = tkinter.StringVar(self) symbolLabel = tkinter.Label(self, text="Symbol:") symbolCombo = tkinter.ttk.Combobox(self, textvariable=self.symbolVar, **self.COMBO_PARAMS) symbolCombo["values"] = openInstruments self.qtyLabel = tkinter.Label(self, text="Quantity:") self.qtySpin = tkinter.Spinbox(self, from_=1, to=SPINBOX_LIMIT, **self.SPINBOX_PARAMS) buyButton = tkinter.Button(self, text="Buy/Long", command=lambda: window._send(sell=False), **self.BUTTON_PARAMS) sellButton = tkinter.Button(self, text="Sell/Short", command=lambda: window._send(sell=True), **self.BUTTON_PARAMS) symbolLabel.grid(column=0, row=0) symbolCombo.grid(column=1, row=0) self.qtyLabel.grid(column=0, row=1) self.qtySpin.grid(column=1, row=1) buyButton.grid(column=0, row=2) sellButton.grid(column=1, row=2)
def _get_delay(self): """ Compute, how many seconds should this object wait before submitting more requests with respect for how many accounts are requests sent. Internal method. Overriding. """ delay = int(60 / self.REQUESTS_PER_MINUTE * len(accounts.get_all())) return delay
def update_values(self): """ Query backend for loaded accounts and place them into treeview. Usually called by settings window when opened. """ self.tree.delete(*self.tree.get_children()) for account in accounts.get_all(): self.tree.insert("", "end", text=account["name"], values=(account["host"], account["key"]))
def update_accounts(self): """ Query backend for logged in accounts and adjust ui adequately. """ names = [account["name"] for account in accounts.get_all()] self.accountsCombo["values"] = names if self.accountVar.get() in names: backend.botsettings.set_account(self.accountVar.get()) elif backend.botsettings.get_account() in names: self.accountVar.set(backend.botsettings.get_account()) else: self.accountVar.set(names[0]) backend.botsettings.set_account(names[0])
def __init__(self, *args, **kwargs): tkinter.Frame.__init__(self, *args, **kwargs) label = tkinter.Label(self, text="Select Accounts:") label.pack(anchor=tkinter.W) self.names = [] self.vars = [] for account in accounts.get_all(): name = account["name"] var = tkinter.IntVar(self) check = tkinter.Checkbutton(self, text=name, var=var) check.pack(anchor=tkinter.W) self.names.append(name) self.vars.append(var)
def _do_iteration(self): """ Query backend for all accounts margin stats and save them in this object. Internal method. Overriding. """ # Get all acount names names = [x["name"] for x in accounts.get_all()] # Get info try: accs = core.account_margin_stats(names) except Exception as e: print(str(e)) return False accs.sort(key=lambda x: x["name"], reverse=False) # Sort self.accounts = accs return True
def update_accounts(self): """ Query backend for account list and place them into treeview. Completely clears tree beforehand. """ # Clear tree self.tree.delete(*self.tree.get_children()) # Get all acount names names = [x["name"] for x in accounts.get_all()] # Fill tree for name in names: item = self.tree.insert("", "end", text=name, open=False, values=["" for x in self.VAR]) self._resize_tree()
def _do_iteration(self): """ Query backend for all accounts position stats and save them in this object. Internal method. Overriding. """ # Get all acount names names = [x["name"] for x in accounts.get_all()] # Get info try: positions = core.position_info(names) except Exception as e: print(str(e)) return False for account in positions: account["positions"].sort(key=lambda x: x["symbol"], reverse=False) self.positions = positions return True
def __init__(self, *args, **kwargs): tkinter.Frame.__init__(self, *args, **kwargs) leftFrame = tkinter.Frame(self) rightFrame = tkinter.Frame(self) label = tkinter.Label(leftFrame, text="Select Accounts:") label.pack() self.names = [] self.vars = [] for i, account in enumerate(accounts.get_all()): name = account["name"] var = tkinter.IntVar(self) check = tkinter.Checkbutton(rightFrame, text=name, var=var) check.grid(column=i, row=0) self.names.append(name) self.vars.append(var) leftFrame.grid(column=0, row=0) rightFrame.grid(column=1, row=0)
def _fetch_instruments(self): """ Request list of open instruments from api. Then populate this frame's symbol comboboxes with it. Will schedule itself to repeat if fetch fails. Internal method """ try: openInstruments = core.open_instruments(accounts.get_all()[0]["name"]) openInstruments.sort() except IndexError: print("Warning: No accounts were created yet.") openInstruments = [] except Exception as e: print(e) openInstruments = [] # Schedule repeat if no openInstrumets if not openInstruments: self.after(RETRY_DELAY, self._fetch_instruments) print("Warning: Failed to fetch open instruments. Retrying...") return # Priority symbols at top of list if they exist for symbol in self.PRIORITY_SYMBOLS[::-1]: if symbol in openInstruments: openInstruments.remove(symbol) openInstruments.insert(0, symbol) # Set first instrument as selected self.firstVar.set(openInstruments[0]) self.secondVar.set(openInstruments[0]) # Populate comboboxes self.firstCombo["values"] = openInstruments self.secondCombo["values"] = openInstruments
def update_margin(self): """ Query backend for all accounts margin stats, place them into treeview. Sets this function to repeat after UPDATE_SECONDS seconds. """ # Clear tree self.tree.delete(*self.tree.get_children()) # Get all acount names names = [x["name"] for x in accounts.get_all()] # Get info success = False try: accs = core.account_margin_stats(names) success = True self.delay_multiplier = 1 # Reset to normal value except Exception as e: print(str(e)) self.delay_multiplier += 1 if success: # Fill tree accs.sort(key=lambda x: x["name"], reverse=False) # Sort for account in accs: name = account["name"] stats = account["stats"] values = [] for v in self.VAR: values.append(str(stats[v])) self.tree.insert("", "end", text=name, values=values) # Resize tree new_height = len(self.tree.get_children()) if new_height < self.MIN_TREE_HEIGHT: new_height = self.MIN_TREE_HEIGHT if new_height > self.MAX_TREE_HEIGHT: new_height = self.MAX_TREE_HEIGHT self.tree.configure(height=new_height) self.tree.grid(column=0, row=0) # Update dots self.dots += 1 if self.dots > self.MAX_DOTS: self.dots = self.MIN_DOTS self.label.configure(text="." * self.dots) else: # On error self.label.configure( text="Error: Wasn't able to retrieve accounts" + " info. Retrying...") # Set repeat if not self._job is None: self.after_cancel(self._job) if self.fastVar.get(): delay = int(1000 * (60 * len(names) / self.REQUESTS_FASTER)) else: delay = int(1000 * (60 * len(names) / self.REQUESTS_PER_MINUTE)) delay *= self.delay_multiplier self._job = self.after(delay, self.update_margin)
def __init__(self, *args, **kvargs): tkinter.Frame.__init__(self, *args, **kvargs) # Backend try: openInstruments = core.open_instruments( accounts.get_all()[0]["name"]) except Exception as e: print(e) openInstruments = [] openInstruments.sort() # Priority symbols at top of list if they exist for symbol in self.PRIORITY_SYMBOLS[::-1]: if symbol in openInstruments: openInstruments.remove(symbol) openInstruments.insert(0, symbol) # Frontend self.symbolVar = tkinter.StringVar(self) self.limitVar = tkinter.IntVar(self) self.stopVar = tkinter.IntVar(self) self.symbolVar.set(openInstruments[0]) self.limitVar.set(1) self.stopVar.set(1) symbolLabel = tkinter.Label(self, text="Symbol", **self.LABEL_PARAMS) qtyLabel = tkinter.Label(self, text="Quantity", **self.LABEL_PARAMS) levLabel = tkinter.Label(self, text="Leverage", **self.LABEL_PARAMS) pxLabel = tkinter.Checkbutton(self, text="Limit Price", var=self.limitVar, # dirty hack ahead command=lambda: self.pxSpin.configure( state=\ tkinter.NORMAL if self.limitVar.get() else tkinter.DISABLED ), # end of dirty hack **self.LABEL_PARAMS) pctLabel = tkinter.Label(self, text="%", **self.LABEL_PARAMS) entryLabel = tkinter.Label(self, text="Entry Price", **self.LABEL_PARAMS) exitLabel = tkinter.Label(self, text="Exit Price", **self.LABEL_PARAMS) stopLabel = tkinter.Checkbutton(self, text="Stop Price", var=self.stopVar, # dirty hack ahead command=lambda: self.stopSpin.configure( state=\ tkinter.NORMAL if self.stopVar.get() else tkinter.DISABLED ), # end of dirty hack **self.LABEL_PARAMS) symbolCombo = tkinter.ttk.Combobox(self, textvariable=self.symbolVar, **self.COMBO_PARAMS) symbolCombo["values"] = openInstruments self.qtySpin = tkinter.Spinbox(self, from_=1, to=SPINBOX_LIMIT, **self.SPINBOX_PARAMS) self.levSpin = tkinter.Spinbox(self, from_=0, to=1000, state=tkinter.DISABLED, **self.SPINBOX_PARAMS) self.pxSpin = tkinter.Spinbox(self, from_=1, to=SPINBOX_LIMIT, value=self.DEFAULT_PX, **self.SPINBOX_PARAMS) self.entryLabel = tkinter.Label(self, text="0", state=tkinter.DISABLED) self.exitLabel = tkinter.Label(self, text="0", state=tkinter.DISABLED) self.stopSpin = tkinter.Spinbox(self, from_=1, to=SPINBOX_LIMIT, value=self.DEFAULT_PX, **self.SPINBOX_PARAMS) symbolLabel.grid(column=0, row=0) qtyLabel.grid(column=1, row=0) levLabel.grid(column=2, row=0) pxLabel.grid(column=3, row=0) entryLabel.grid(column=4, row=0) exitLabel.grid(column=5, row=0) stopLabel.grid(column=6, row=0) symbolCombo.grid(column=0, row=1) self.qtySpin.grid(column=1, row=1) self.levSpin.grid(column=2, row=1) self.pxSpin.grid(column=3, row=1) self.entryLabel.grid(column=4, row=1) self.exitLabel.grid(column=5, row=1) self.stopSpin.grid(column=6, row=1)