azapyGUI 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. azapyGUI/AppSettingsPage.py +213 -0
  2. azapyGUI/AppSettingsPageMisc.py +101 -0
  3. azapyGUI/AppSettingsWindow.py +52 -0
  4. azapyGUI/BacktestComputation.py +166 -0
  5. azapyGUI/BacktestEntryWindow.py +307 -0
  6. azapyGUI/BacktestMenuPortfolioWindow.py +20 -0
  7. azapyGUI/CloneMenuPortfolioWindow.py +93 -0
  8. azapyGUI/CrossHairBCursor.py +80 -0
  9. azapyGUI/DF_Window.py +63 -0
  10. azapyGUI/DF_table.py +282 -0
  11. azapyGUI/EditMenuPortfolioWindow.py +16 -0
  12. azapyGUI/EditPortfolioWindow.py +475 -0
  13. azapyGUI/EntryClonePortfolioWindow.py +35 -0
  14. azapyGUI/EntryNameWindow.py +55 -0
  15. azapyGUI/EntryRenamePortfolioWindow.py +33 -0
  16. azapyGUI/GetMktData.py +85 -0
  17. azapyGUI/MenuApp.py +194 -0
  18. azapyGUI/MktDataFrame.py +129 -0
  19. azapyGUI/MktDataNode.py +34 -0
  20. azapyGUI/ModelParamEditWindow.py +143 -0
  21. azapyGUI/NrShares_table.py +54 -0
  22. azapyGUI/PortAnalyseWindow.py +179 -0
  23. azapyGUI/PortDataNode.py +180 -0
  24. azapyGUI/PortfolioFrame.py +197 -0
  25. azapyGUI/RebalanceMenuPortfolioWindow.py +21 -0
  26. azapyGUI/RemoveMenuPortfolioWindow.py +33 -0
  27. azapyGUI/SaveMenuPortfolioWindow.py +36 -0
  28. azapyGUI/Scrollable.py +60 -0
  29. azapyGUI/SelectOneWindow.py +65 -0
  30. azapyGUI/SymbAnalyseWindow.py +21 -0
  31. azapyGUI/SymbExtractWindow.py +129 -0
  32. azapyGUI/SymbTableEntry.py +109 -0
  33. azapyGUI/TimeSeriesViewWindow.py +480 -0
  34. azapyGUI/ViewTip.py +72 -0
  35. azapyGUI/WeightsWindow.py +352 -0
  36. azapyGUI/__init__.py +6 -0
  37. azapyGUI/azHelper.py +27 -0
  38. azapyGUI/azapyApp.py +89 -0
  39. azapyGUI/config.py +35 -0
  40. azapyGUI/configHelps.py +84 -0
  41. azapyGUI/configMSG.py +194 -0
  42. azapyGUI/configModels.py +519 -0
  43. azapyGUI/configPlot.py +70 -0
  44. azapyGUI/configSettings.py +138 -0
  45. azapyGUI/configTips.py +240 -0
  46. azapyGUI/mktDataValidation.py +42 -0
  47. azapyGUI/modelParametersValidation.py +442 -0
  48. azapyGUI/serviceMasterUserConfig.py +28 -0
  49. azapyGUI/tkHelper.py +18 -0
  50. azapyGUI-0.0.1.dist-info/LICENSE +674 -0
  51. azapyGUI-0.0.1.dist-info/METADATA +126 -0
  52. azapyGUI-0.0.1.dist-info/RECORD +54 -0
  53. azapyGUI-0.0.1.dist-info/WHEEL +5 -0
  54. azapyGUI-0.0.1.dist-info/top_level.txt +1 -0
azapyGUI/Scrollable.py ADDED
@@ -0,0 +1,60 @@
1
+ import tkinter as tk
2
+ import platform
3
+
4
+
5
+ class Scrollable(tk.Frame):
6
+ def __init__(self, frame, sbwidth=16, canv_width=200, canv_height=200, **kwargs):
7
+
8
+ scrollbar = tk.Scrollbar(frame, width=sbwidth)
9
+ scrollbar.pack(side=tk.RIGHT, fill=tk.Y, expand=False)
10
+
11
+ self._canvas = tk.Canvas(frame, yscrollcommand=scrollbar.set,
12
+ width=canv_width, height=canv_height)
13
+ self._canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
14
+
15
+ scrollbar.config(command=self._canvas.yview)
16
+ self._canvas.bind('<Configure>', self._fill_canvas)
17
+ super().__init__(frame, **kwargs)
18
+
19
+ self.windows_item = self._canvas.create_window(0, 0, window=self, anchor=tk.NW)
20
+
21
+ self.bind('<Enter>', self._onEnter)
22
+ self.bind('<Leave>', self._onLeave)
23
+
24
+
25
+ def _fill_canvas(self, event):
26
+ canvas_width = event.width
27
+ self._canvas.itemconfig(self.windows_item, width=canvas_width)
28
+
29
+
30
+ def update(self):
31
+ self.update_idletasks()
32
+ self._canvas.config(scrollregion=self._canvas.bbox(self.windows_item))
33
+
34
+
35
+ def _onMouseWheel(self, event):
36
+ if platform.system() == 'Windows':
37
+ self._canvas.yview_scroll(int(-1 * (event.delta / 120)), "units")
38
+ elif platform.system() == 'Darwin':
39
+ self._canvas.yview_scroll(int(-1 * event.delta), "units")
40
+ else:
41
+ if event.num == 4:
42
+ self._canvas.yview_scroll(-1, "units")
43
+ elif event.num == 5:
44
+ self._canvas.yview_scroll(1, "units")
45
+
46
+
47
+ def _onEnter(self, event):
48
+ if platform.system() == 'Linux':
49
+ self._canvas.bind_all("<Button-4>", self._onMouseWheel)
50
+ self._canvas.bind_all("<Button-5>", self._onMouseWheel)
51
+ else:
52
+ self._canvas.bind_all("<MouseWheel>", self._onMouseWheel)
53
+
54
+
55
+ def _onLeave(self, event):
56
+ if platform.system() == 'Linux':
57
+ self._canvas.unbind_all("<Button-4>")
58
+ self._canvas.unbind_all("<Button-5>")
59
+ else:
60
+ self._canvas.unbind_all("<MouseWheel>")
@@ -0,0 +1,65 @@
1
+ import tkinter as tk
2
+ from tkinter import ttk
3
+
4
+ import azapyGUI.config as config
5
+
6
+
7
+ class SelectOneWindow:
8
+ def __init__(self, master=None, title=None, text=None, values=None,
9
+ tip_text=None, btn_text="Save"):
10
+ if (values is None) or (len(values) == 0): return
11
+ self._master = master
12
+
13
+ self._window = tk.Toplevel()
14
+ self._window.geometry("200x130")
15
+ self._window.title(title)
16
+ self._window.protocol("WM_DELETE_WINDOW", self._btn_cancel)
17
+ self._window.focus_set()
18
+
19
+ self.selection = None
20
+
21
+ frm = tk.LabelFrame(master=self._window, text=title, font=("Forte", 10))
22
+ frm.pack(expand=True, fill=tk.BOTH, padx=5, pady=5)
23
+
24
+ row = 0
25
+ lbl = tk.Label(master=frm, text=text)
26
+ lbl.grid(row=row, columnspan=2, pady=5, padx=5, sticky=tk.EW)
27
+ frm.rowconfigure(row, weight=1)
28
+
29
+ row += 1
30
+ self._ent = ttk.Combobox(master=frm, width=15, state='readonly')
31
+ self._ent['values'] = values
32
+ self._ent.current(0)
33
+ self._ent.grid(row=row, columnspan=2, padx=5, pady=5)
34
+ if tip_text is not None:
35
+ config.tiptil.bind(self._ent, tip_text)
36
+ frm.rowconfigure(row, weight=1)
37
+
38
+ row += 1
39
+ btn_calcel = tk.Button(master=frm, text="Cancel",
40
+ command=self._btn_cancel, width=8)
41
+ btn_calcel.grid(row=row, column=0, padx=5, pady=5, sticky=tk.W)
42
+ frm.columnconfigure(0, weight=1)
43
+
44
+ btn_action = tk.Button(master=frm, text=btn_text,
45
+ command=self._btn_action, width=8)
46
+ btn_action.grid(row=row, column=1, padx=5, pady=5, sticky=tk.E)
47
+ frm.columnconfigure(1, weight=1)
48
+ frm.rowconfigure(row, weight=1)
49
+
50
+ self._window.grab_set()
51
+ self._window.update()
52
+ if (self._master is not None) and self._master.winfo_exists():
53
+ self._master.wait_window(self._window)
54
+
55
+
56
+ def _btn_cancel(self):
57
+ self._window.grab_release()
58
+ if (self._master is not None) and self._master.winfo_exists():
59
+ self._master.focus_set()
60
+ self._window.destroy()
61
+
62
+
63
+ def _btn_action(self):
64
+ # to be implemented by the derived class
65
+ pass
@@ -0,0 +1,21 @@
1
+ from copy import deepcopy
2
+
3
+ import azapyGUI.config as config
4
+ from azapyGUI.TimeSeriesViewWindow import TimeSeriesViewWindow
5
+
6
+
7
+ class SymbAnalyseWindow(TimeSeriesViewWindow):
8
+ def __init__(self, master=None, symbols=None):
9
+ mktdata = {}
10
+ ref_name = symbols[0]
11
+ nnrr = config.MktDataDict[ref_name].mktdata.shape[0]
12
+ for symb in symbols:
13
+ mktdata[symb] = deepcopy(config.MktDataDict[symb].mktdata.drop(
14
+ columns=['symbol', 'divd', 'split', 'volume']))
15
+ if mktdata[symb].shape[0] > nnrr:
16
+ nnrr = mktdata[symb].shape[0]
17
+ ref_name = symb
18
+ col_name = 'close'
19
+ title = "Performance"
20
+ super().__init__(master=master, name=title, data=mktdata,
21
+ ref_name=ref_name, col_name=col_name)
@@ -0,0 +1,129 @@
1
+ import tkinter as tk
2
+ from tkinter import ttk
3
+
4
+ import azapyGUI.config as config
5
+ import azapyGUI.configTips as configTips
6
+ import azapyGUI.configSettings as configSettings
7
+ import azapyGUI.modelParametersValidation as mpv
8
+ from azapyGUI.GetMktData import GetMktData
9
+ from azapyGUI.mktDataValidation import sdate_edate_validate
10
+
11
+
12
+ class SymbExtractWindow:
13
+ def __init__(self, master=None, title=None, symbols=None, btn_text="OK", validate=False, entry=False):
14
+ self._master = master
15
+ self._symbols = symbols
16
+ self._validate = validate
17
+ self._entry = entry
18
+
19
+ self.errorSymb = []
20
+
21
+ self._window = tk.Toplevel()
22
+ self._window.title(title)
23
+ self._window.focus_set()
24
+ self._window.grab_set()
25
+ self._window.protocol("WM_DELETE_WINDOW", self._btn_cancel_func)
26
+
27
+ frm = tk.LabelFrame(master=self._window, text=title, font=("Forte", 10))
28
+ frm.pack(fill=tk.BOTH, expand=True)
29
+
30
+ for i in range(4): frm.columnconfigure(i, weight=1)
31
+
32
+ row = 0
33
+ frm.rowconfigure(row, weight=1)
34
+ if self._entry:
35
+ tk.Label(master=frm, text="Symbols").grid(row=row, column=0)
36
+ self._ent_symb = tk.Entry(master=frm)
37
+ self._ent_symb.grid(row=row, column=1, columnspan=3, pady=5, padx=5, sticky=tk.EW)
38
+ self._ent_symb.focus()
39
+ config.tiptil.bind(self._ent_symb, configTips._sew_symb_tip)
40
+ else:
41
+ text = mpv._list2string(self._symbols)
42
+ lbl = tk.Label(master=frm, text=text, justify=tk.LEFT)
43
+ lbl.grid(row=row, columnspan=4, pady=5, padx=5, sticky=tk.NSEW)
44
+
45
+ row += 1
46
+ frm.rowconfigure(row, weight=1)
47
+ lbl = tk.Label(master=frm, text="end date", anchor=tk.W)
48
+ lbl.grid(row=row, column=0, pady=5, padx=5, sticky=tk.EW)
49
+
50
+ self._ent_edate = tk.StringVar(master=frm, value='today')
51
+ ent_edate = tk.Entry(master=frm, width=12, validate='key', textvariable=self._ent_edate)
52
+ ent_edate['validatecommand'] = (ent_edate.register(mpv._validDateMMDDYYYY),'%S','%d','%P')
53
+ ent_edate.grid(row=row, column=1, pady=5, padx=5, sticky=tk.EW)
54
+ config.tiptil.bind(ent_edate, configTips._sew_edate_tip)
55
+
56
+ lbl = tk.Label(master=frm, text="Provider", anchor=tk.W)
57
+ lbl.grid(row=row, column=2, pady=5, sticky=tk.EW)
58
+
59
+ pval = list(configSettings.MasterApplicationSettings["Provider"].keys())
60
+ self._ent_provider = tk.StringVar(master=frm)
61
+ ent_provider = ttk.Combobox(master=frm, width=20, textvariable=self._ent_provider)
62
+ ent_provider["values"] = pval
63
+ ent_provider.current(0)
64
+ ent_provider.grid(row=row, column=3, pady=5, padx=5, sticky=tk.EW)
65
+ config.tiptil.bind(ent_provider, configTips._sew_provider_tip)
66
+
67
+ row += 1
68
+ frm.rowconfigure(row, weight=1)
69
+ lbl = tk.Label(master=frm, text="start date", anchor=tk.W)
70
+ lbl.grid(row=row, column=0, pady=5, padx=5, sticky=tk.EW)
71
+
72
+ self._ent_sdate = tk.StringVar(master=frm, value=None if validate else '1/1/2012')
73
+ ent_sdate = tk.Entry(master=frm, width=12, validate='key', textvariable=self._ent_sdate)
74
+ ent_sdate['validatecommand'] = (ent_sdate.register(mpv._validDateMMDDYYYY),'%S','%d','%P')
75
+ ent_sdate.grid(row=row, column=1, pady=5, padx=5, sticky=tk.EW)
76
+ config.tiptil.bind(ent_sdate, configTips._sew_sdate_tip)
77
+
78
+ frm_chk = tk.Frame(master=frm)
79
+ frm_chk.grid(row=row, column=3, pady=5, padx=5, sticky=tk.EW)
80
+
81
+ lbl = tk.Label(master=frm_chk, text="force", anchor=tk.W)
82
+ lbl.pack(padx=5, pady=5, side=tk.LEFT)
83
+
84
+ self._ent_force = tk.BooleanVar(value=False)
85
+ chk = tk.Checkbutton(master=frm_chk, onvalue=True, offvalue=False, variable=self._ent_force)
86
+ chk.pack(padx=5, pady=5, side=tk.RIGHT)
87
+ config.tiptil.bind(chk, configTips._sew_force_tip)
88
+
89
+ frm_btn = tk.Frame(master=self._window)
90
+ frm_btn.pack(fill=tk.BOTH, expand=True)
91
+
92
+ btn = tk.Button(master=frm_btn, text="Cancel", width=12, command=self._btn_cancel_func)
93
+ btn.pack(pady=5, padx=5, side=tk.LEFT)
94
+
95
+ btn = tk.Button(master=frm_btn, text=btn_text, width=12, command=self._btn_extract_func)
96
+ btn.pack(pady=5, padx=5, side=tk.RIGHT)
97
+
98
+ self._window.update()
99
+ self._master.wait_window(self._window)
100
+
101
+
102
+ def _btn_cancel_func(self):
103
+ self._window.grab_release()
104
+ if (self._master is not None) and self._master.winfo_exists():
105
+ self._master.focus_set()
106
+ self._window.destroy()
107
+
108
+
109
+ def _btn_extract_func(self):
110
+ if self._entry:
111
+ stat, self._symbols = mpv._validate_symbols(self._ent_symb.get().upper().split(','))
112
+ if len(self._symbols) < 1: return
113
+
114
+ source = self._ent_provider.get()
115
+ force = self._ent_force.get()
116
+
117
+ edate = self._ent_edate.get()
118
+ sdate = self._ent_sdate.get()
119
+
120
+ state, sd, ed = sdate_edate_validate(sdate, edate)
121
+ if not state:
122
+ tk.messagebox.showwarning("Warning", sd, parent=self._window)
123
+ return
124
+
125
+ gmd = GetMktData(source, force, validate=self._validate)
126
+ gmd.getMkTDataSymb(self._symbols, sd, ed)
127
+ self.symbols = gmd.symbols
128
+ self.errorSymb = gmd.errorsymb
129
+ self._btn_cancel_func()
@@ -0,0 +1,109 @@
1
+ import tkinter as tk
2
+
3
+ import azapyGUI.config as config
4
+ from azapyGUI.Scrollable import Scrollable
5
+ from azapyGUI.modelParametersValidation import _validate_symbols
6
+
7
+
8
+ class SymbTableEntry:
9
+ def __init__(self, master, nrows=100, ncols=5, name=None, **kwargs):
10
+ self._name = name if name is not None else self._getName()
11
+ self._frm = tk.Frame(master=master)
12
+ self._nrows = nrows
13
+ self._ncols = ncols
14
+
15
+ self._stb = Scrollable(self._frm, **kwargs)
16
+
17
+ self._table = []
18
+ for i in range(self._nrows):
19
+ rw = []
20
+ for j in range(self._ncols):
21
+ self._stb.rowconfigure(i, weight=1)
22
+ self._stb.columnconfigure(j, weight=1)
23
+ ename = "!" + self._name + "_" + str(i) + "_" + str(j)
24
+ tt = tk.Entry(self._stb, width=5, name=ename)
25
+ tt.grid(row=i, column=j, sticky=tk.NSEW)
26
+ rw.append(tt)
27
+ self._table.append(rw)
28
+
29
+ self._table[0][0].focus_set()
30
+
31
+
32
+ def grid(self, *args, **kwargs):
33
+ self._frm.grid(*args, **kwargs)
34
+ self._stb.update()
35
+
36
+
37
+ def pack(self, *args, **kwargs):
38
+ self._frm.pack(*args, **kwargs)
39
+ self._stb.update()
40
+
41
+
42
+ def get(self, row=None, column=None):
43
+ if (row is not None) and (column is not None):
44
+ return self._table[row][column]
45
+
46
+ tx = []
47
+ for i in range(self._nrows):
48
+ for j in range(self._ncols):
49
+ tt = self._table[i][j].get()
50
+ if len(tt) < 1: continue
51
+ tx.append(tt)
52
+ status, sout = _validate_symbols(tx)
53
+ return status, sorted(list(set(sout)))
54
+
55
+
56
+ def _getName(self):
57
+ config.count_SymbTableEntry += 1
58
+ return 'SymbTableEntry' + str(config.count_SymbTableEntry)
59
+
60
+
61
+ def write_order(self, txt):
62
+ self.empty()
63
+ ic = 0
64
+ jc = 0
65
+ for tt in sorted(txt):
66
+ if tt == "": continue
67
+ self._table[ic][jc].insert(0, tt)
68
+ jc += 1
69
+ if jc >= self._ncols:
70
+ jc = 0
71
+ ic += 1
72
+ if ic >= self._nrows:
73
+ self._table[0][0].focus_set()
74
+ return
75
+ self._table[ic][jc].focus_set()
76
+
77
+
78
+ def empty(self):
79
+ for i in range(self._nrows):
80
+ for j in range(self._ncols):
81
+ self._table[i][j].delete(0, tk.END)
82
+
83
+
84
+ def table_focus_get(self):
85
+ tfx = str(self._table[0][0].focus_get())
86
+ fx = tfx.split("!")[-1].split("_")
87
+ if fx[0] == self._name:
88
+ return tuple(int(x) for x in fx[1:])
89
+
90
+ return (None, None)
91
+
92
+
93
+ def key_press(self, event):
94
+ i, j = self.table_focus_get()
95
+
96
+ if i is None: return
97
+ elif event.keysym == 'Up':
98
+ if i == 0: return
99
+ self._table[i-1][j].focus_set()
100
+ elif event.keysym == 'Down':
101
+ if i == self._nrows - 1: return
102
+ self._table[i+1][j].focus_set()
103
+ elif event.keysym == 'Return':
104
+ j += 1
105
+ if j == self._ncols:
106
+ j = 0
107
+ i += 1
108
+ if i == self._nrows: return
109
+ self._table[i][j].focus_set()