Source code for UI.View

import os
import sys
import inspect
import tkinter as tk
from tkinter import ttk
from tkinter import StringVar
from tkinter import filedialog

currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)

from Utils.Utils import Callbacks, Messages, Utils
from .WarningWindow import WarningWindow
from .ConfirmWindow import ConfirmWindow
from .ShareTradingFrame import ShareTradingFrame
from .SettingsWindow import SettingsWindow
from .TradingMateClient import TradingMateClient

APP_NAME = "TradingMate"
assets_dir = os.path.join(Utils.get_install_path(), "data")


[docs]class View: def __init__(self, server): # Local data initialisation self._client = TradingMateClient(self, server) self._portfolio_tabs = {} # Create the user interface self._create_UI() def _create_UI(self): # Create main window self.mainWindow = tk.Tk() self.mainWindow.title(APP_NAME) img = tk.Image("photo", file=assets_dir + "/assets/trading_mate_icon.png") self.mainWindow.tk.call("wm", "iconphoto", self.mainWindow._w, img) self.mainWindow.protocol("WM_DELETE_WINDOW", self._on_close_main_window_event) self.mainWindow.geometry("1024x600") # Create the application main menu self._create_menu() # Create the tab format window self.noteBook = ttk.Notebook(self.mainWindow) self.noteBook.pack(expand=1, fill="both") def _create_menu(self): self.menubar = tk.Menu(self.mainWindow) # Menu File filemenu = tk.Menu(self.menubar, tearoff=0) filemenu.add_command(label="Open...", command=self.on_open_portfolio_event) filemenu.add_command(label="Settings...", command=self.on_show_settings) filemenu.add_command(label="Exit", command=self._on_close_main_window_event) self.menubar.add_cascade(label="File", menu=filemenu) # Menu About helpmenu = tk.Menu(self.menubar, tearoff=0) helpmenu.add_command(label="About", command=self._show_about_popup) self.menubar.add_cascade(label="Help", menu=helpmenu) # Display the menu self.mainWindow.config(menu=self.menubar) def _create_portfolio_tab(self, portfolio): tab = ShareTradingFrame(self.noteBook, portfolio.get_id()) tab.pack(expand=True) tab.set_callback( Callbacks.ON_MANUAL_REFRESH_EVENT, self.on_manual_refresh_event ) tab.set_callback(Callbacks.ON_NEW_TRADE_EVENT, self.on_new_trade_event) tab.set_callback( Callbacks.ON_SET_AUTO_REFRESH_EVENT, self.set_auto_refresh_event ) tab.set_callback(Callbacks.ON_SAVE_LOG_FILE_EVENT, self.on_save_portfolio_event) tab.set_callback(Callbacks.ON_SAVE_AS_EVENT, self.on_save_portfolio_as_event) tab.set_callback( Callbacks.ON_DELETE_LAST_TRADE_EVENT, self.on_delete_last_trade_event ) self.noteBook.add(tab, text=portfolio.get_name()) self._portfolio_tabs[portfolio.get_id()] = tab tab.set_auto_refresh() # ******* MAIN WINDOW *********** def _on_close_main_window_event(self): # Check if there are unsaved chnages before closing the app if self._client.unsaved_changes(): ConfirmWindow( self.mainWindow, "Warning", Messages.UNSAVED_CHANGES.value, self._confirmed_close_window, ) else: self._confirmed_close_window() def _confirmed_close_window(self): self._client.stop() self.mainWindow.destroy() def _show_about_popup(self): WarningWindow(self.mainWindow, "About", Messages.ABOUT_MESSAGE.value)
[docs] def start(self): """Start the User Interface""" # Start thread to fetch data from the server self._client.start() # Start the user interface thread self.mainWindow.mainloop()
# ******* SHARE TRADING FRAMES ************
[docs] def update_portfolio_tab(self, portfolio): """Update the portfolio tab with the recent data""" if portfolio.get_id() not in self._portfolio_tabs.keys(): self._create_portfolio_tab(portfolio) # Update history table self._portfolio_tabs[portfolio.get_id()].update_trades_log( portfolio.get_trade_history()[::-1] ) # Update the current positions validity = True for h in portfolio.get_holding_list(): self._portfolio_tabs[portfolio.get_id()].update_share_trading_holding( h.get_symbol(), h.get_quantity(), h.get_open_price(), h.get_last_price(), h.get_cost(), h.get_value(), h.get_profit_loss(), h.get_profit_loss_perc(), h.get_last_price_valid(), ) validity = validity and h.get_last_price_valid() # Update the balances self._portfolio_tabs[portfolio.get_id()].update_portfolio_balances( portfolio.get_cash_available(), portfolio.get_holdings_value(), portfolio.get_total_value(), portfolio.get_portfolio_pl(), portfolio.get_portfolio_pl_perc(), portfolio.get_open_positions_pl(), portfolio.get_open_positions_pl_perc(), validity, )
def on_new_trade_event(self, new_trade, portfolio_id): try: self._client.new_trade_event(new_trade, portfolio_id) except RuntimeError as e: return {"success": False, "message": e} return {"success": True, "message": "ok"} def on_manual_refresh_event(self, portfolio_id): self._client.manual_refresh_event(portfolio_id) def set_auto_refresh_event(self, value, portfolio_id): self._client.set_auto_refresh_event(value, portfolio_id) def on_open_portfolio_event(self): try: filename = filedialog.askopenfilename( initialdir=Utils.get_install_path(), title="Select file", filetypes=(("json files", "*.json"), ("all files", "*.*")), ) if filename is not None and len(filename) > 0: self._client.open_portfolio_event(filename) except RuntimeError as e: WarningWindow(self.parent, "Warning", e) def on_save_portfolio_event(self, portfolio_id): # None forces to save portfolio in its current filepath self._client.save_portfolio_event(portfolio_id, None) def on_save_portfolio_as_event(self, portfolio_id): try: filename = filedialog.asksaveasfilename( initialdir=Utils.get_install_path(), title="Select file", filetypes=(("json files", "*.json"), ("all files", "*.*")), ) if filename is not None and len(filename) > 0: self._client.save_portfolio_event(portfolio_id, filename) except RuntimeError as e: WarningWindow(self.parent, "Warning", e) def on_delete_last_trade_event(self, portfolio_id): try: self._client.delete_last_trade_event(portfolio_id) except RuntimeError as e: return {"success": False, "message": e} return {"success": True, "message": "ok"} def on_show_settings(self): config = self._client.get_settings_event() SettingsWindow(self.mainWindow, config, self._client.save_settings_event)