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
@@ -0,0 +1,442 @@
1
+ import string
2
+ from functools import reduce
3
+
4
+ import azapyGUI.configMSG as configMSG
5
+
6
+
7
+ def _validate_nothing(param):
8
+ return True, param
9
+
10
+
11
+ def _validate_hlength(param):
12
+ msg = configMSG._validate_hlength_msg
13
+ field = 'hlength'
14
+ try:
15
+ vv = float(param[field])
16
+ except:
17
+ return False, msg
18
+
19
+ if vv >= 0.5:
20
+ param[field] = vv
21
+ return True, vv
22
+ return False, msg
23
+
24
+
25
+ def _validate_mu0(param):
26
+ msg = configMSG._validate_mu0_msg
27
+ field = 'mu0'
28
+ try:
29
+ vv = float(param[field])
30
+ except:
31
+ return False, msg
32
+
33
+ if vv >= 0:
34
+ param[field] = vv
35
+ return True, vv
36
+ return False, msg
37
+
38
+
39
+ def _validate_mu(param):
40
+ msg = configMSG._validate_mu_msg
41
+ field = 'mu'
42
+ try:
43
+ vv = float(param[field])
44
+ except:
45
+ return False, msg
46
+
47
+ if vv >= 0:
48
+ param[field] = vv
49
+ return True, vv
50
+ return False, msg
51
+
52
+
53
+ def _validate_aversion(param):
54
+ msg = configMSG._validate_aversion_msg
55
+ field = 'aversion'
56
+ try:
57
+ vv = float(param[field])
58
+ except:
59
+ return False, msg
60
+
61
+ if vv > 0:
62
+ param[field] = vv
63
+ return True, vv
64
+ return False, msg
65
+
66
+
67
+ def _validate_ww0(param, ns):
68
+ msg = configMSG._validate_ww0_msg
69
+ field = 'ww0'
70
+ try:
71
+ ww0 = [float(x) for x in param[field].strip(string.whitespace + '[]{}()').split(",")]
72
+ except:
73
+ return False, msg
74
+
75
+ if len(ww0) < ns:
76
+ ww0 += [1.] * (ns - len(ww0))
77
+ ww0 = ww0[:ns]
78
+ if all([(x >= 0) for x in ww0]) & (sum(ww0) > 0):
79
+ param[field] = ww0
80
+ return True, ww0
81
+ return False, msg
82
+
83
+
84
+ def _validate_diver(param):
85
+ msg = configMSG._validate_diver_msg
86
+ field = 'diver'
87
+ try:
88
+ vv = float(param[field])
89
+ except:
90
+ return False, msg
91
+
92
+ if vv > 0:
93
+ param[field] = vv
94
+ return True, vv
95
+ return False, msg
96
+
97
+
98
+ def _validate_alpha_mCVaR(param):
99
+ msg = configMSG._validate_alpha_mCVaR_msg
100
+ field = 'alpha'
101
+ try:
102
+ alpha = [float(x) for x in param[field].strip(string.whitespace + '[]{}()').split(",")]
103
+ except:
104
+ return False, msg
105
+
106
+ if all([(0.99 >= x) & (x >= 0.5) for x in alpha]):
107
+ param[field] = alpha
108
+ return True, alpha
109
+ return False, msg
110
+
111
+
112
+ def _validate_alpha_mSMCR(param):
113
+ msg = configMSG._validate_alpha_mSMCR_msg
114
+ field = 'alpha'
115
+ try:
116
+ alpha = [float(x) for x in param[field].strip(string.whitespace + '[]{}()').split(",")]
117
+ except:
118
+ return False, msg
119
+
120
+ if all([(0.99 >= x) & (x >= 0.5) for x in alpha]):
121
+ param[field] = alpha
122
+ return True, alpha
123
+ return False, msg
124
+
125
+
126
+ def _validate_alpha_mEVaR(param):
127
+ msg = configMSG._validate_alpha_mEVaR_msg
128
+ field = 'alpha'
129
+ try:
130
+ alpha = [float(x) for x in param[field].strip(string.whitespace + '[]{}()').split(",")]
131
+ except:
132
+ return False, msg
133
+
134
+ if all([(0.99 >= x) & (x >= 0.5) for x in alpha]):
135
+ param[field] = alpha
136
+ return True, alpha
137
+ return False, msg
138
+
139
+
140
+ def _validate_alpha_mBTAD(param):
141
+ msg = configMSG._validate_alpha_mBTAD_msg
142
+ field = 'alpha'
143
+ try:
144
+ alpha = [float(x) for x in param[field].strip(string.whitespace + '[]{}()').split(",")]
145
+ param[field] = alpha
146
+ return True, alpha
147
+ except:
148
+ return False, msg
149
+
150
+
151
+ def _validate_alpha_mBTSD(param):
152
+ msg = configMSG._validate_alpha_mBTSD_msg
153
+ field = 'alpha'
154
+ try:
155
+ alpha = [float(x) for x in param[field].strip(string.whitespace + '[]{}()').split(",")]
156
+ param[field] = alpha
157
+ return True, alpha
158
+ except:
159
+ return False, msg
160
+
161
+
162
+ def _validate_coef(param):
163
+ msg = configMSG._validate_coef_msg
164
+ field = 'coef'
165
+ try:
166
+ coef = [float(x) for x in param[field].strip(string.whitespace + '[]{}()').split(",")]
167
+ except:
168
+ return False, msg
169
+
170
+ if all([(x > 0) for x in coef]):
171
+ coef += [1.0] * (len(param['alpha']) - len(coef))
172
+ param[field] = coef[:len(param['alpha'])]
173
+ return True, coef
174
+ return False, msg
175
+
176
+
177
+ def _validate_coef_mMAD(param):
178
+ msg = configMSG._validate_coef_mMAD_msg
179
+ field = 'coef'
180
+ try:
181
+ coef = [float(x) for x in param[field].strip(string.whitespace + '[]{}()').split(",")]
182
+ except:
183
+ return False, msg
184
+
185
+ if bool(reduce(lambda a, b: (b > 0) and (a >= b) and a or False, coef)):
186
+ param[field] = coef
187
+ return True, coef
188
+ return False, msg
189
+
190
+
191
+ def _validate_coef_mLSD(param):
192
+ msg = configMSG._validate_coef_mLSD_msg
193
+ field = 'coef'
194
+ try:
195
+ coef = [float(x) for x in param[field].strip(string.whitespace + '[]{}()').split(",")]
196
+ except:
197
+ return False, msg
198
+
199
+ if bool(reduce(lambda a, b: (b > 0) and (a >= b) and a or False, coef)):
200
+ param[field] = coef
201
+ return True, coef
202
+ return False, msg
203
+
204
+
205
+ def _validate_fw(param):
206
+ msg = configMSG._validate_fw_msg
207
+ field = 'fw'
208
+ try:
209
+ fw = [float(x) for x in param[field].strip(string.whitespace + '[]{}()').split(",")]
210
+ except:
211
+ return False, msg
212
+
213
+ if all([(x >= 0) for x in fw]) & (len(fw) == 4):
214
+ param[field] = fw
215
+ return True, fw
216
+ return False, msg
217
+
218
+
219
+ def _validate_nw(param, ns=1000):
220
+ msg = configMSG._validate_nw_msg
221
+ field = 'nw'
222
+ try:
223
+ vv = int(param[field])
224
+ except:
225
+ return False, msg
226
+
227
+ if (vv > 0) & (vv <= ns):
228
+ param[field] = vv
229
+ return True, vv
230
+ return False, msg
231
+
232
+
233
+ def _validate_threshold(param, ns=1000):
234
+ msg = configMSG._validate_threshold_msg
235
+ field = 'threshold'
236
+ try:
237
+ vv = int(param[field])
238
+ except:
239
+ return False, msg
240
+
241
+ if (vv >= param['nw']) & (vv <= ns):
242
+ param[field] = vv
243
+ return True, vv
244
+ return False, msg
245
+
246
+
247
+ def _validate_corr_threshold(param):
248
+ msg = configMSG._validate_corr_threshold_msg
249
+ field = 'corr_threshold'
250
+ try:
251
+ vv = float(param[field])
252
+ except:
253
+ return False, msg
254
+
255
+ if (vv >= 0) & (vv < 1):
256
+ param[field] = vv
257
+ return True, vv
258
+ return False, msg
259
+
260
+
261
+ def _validate_dirichlet_alpha(param, ns):
262
+ msg = configMSG._validate_dirichlet_alpha_msg
263
+ field = 'dirichlet_alpha'
264
+ if isinstance(param[field], str):
265
+ try:
266
+ da = [float(x) for x in param[field].strip(string.whitespace + '[]{}()').split(",")]
267
+ except:
268
+ return False, msg
269
+ else:
270
+ da = param[field]
271
+
272
+ if len(da) < ns:
273
+ da += [1.] * (ns - len(da))
274
+ da = da[:ns]
275
+ if all([(x > 0) for x in da]):
276
+ param[field] = da
277
+ return True, da
278
+ return False, msg
279
+
280
+
281
+ def _validate_variance_reduction(param):
282
+ field = 'variance_reduction'
283
+ param[field] = True if param[field] == 'True' else False
284
+ return True, param[field]
285
+
286
+
287
+ def _validate_nr_batches(param):
288
+ msg = configMSG._validate_nr_batches_msg
289
+ field = 'nr_batches'
290
+ try:
291
+ mcb = int(param[field])
292
+ if mcb > 0:
293
+ param[field] = mcb
294
+ return True, mcb
295
+ else:
296
+ return False, msg
297
+ except:
298
+ return False, msg
299
+
300
+
301
+ def _validate_mc_paths(param):
302
+ msg = configMSG._validate_mc_paths_msg
303
+ field = 'mc_paths'
304
+ try:
305
+ mcp = int(param[field])
306
+ if mcp > 0:
307
+ param[field] = mcp
308
+ return True, mcp
309
+ else:
310
+ return False, msg
311
+ except:
312
+ return False, msg
313
+
314
+
315
+ def _validate_mc_seed(param):
316
+ msg = configMSG._validate_mc_seed_msg
317
+ field = 'mc_seed'
318
+ try:
319
+ mc_seed = int(param[field].strip(string.whitespace))
320
+ param[field] = mc_seed
321
+ return True, mc_seed
322
+ except:
323
+ return False, msg
324
+
325
+
326
+ def _validate_symbols(symbols):
327
+ sout = []
328
+ if len(symbols) < 1: return True, sout
329
+ allowed_char = set(string.ascii_uppercase + string.digits + '.^-')
330
+ for symb in symbols:
331
+ symb = symb.strip(string.whitespace).upper()
332
+ if (len(symb) > 0) & (set(symb) < allowed_char):
333
+ sout.append(symb)
334
+ return len(symbols) == len(sout), sout
335
+
336
+
337
+ def _validate_portfolio_name(name):
338
+ name = name.strip(string.whitespace)
339
+ allowed_char = set(string.ascii_letters + string.digits + "._-")
340
+ if (len(name) != 0) & (set(name) < allowed_char):
341
+ return True, name
342
+ return False, configMSG._validate_portfolio_name_msg
343
+
344
+
345
+ def _validFloat(inp, acttyp, val):
346
+ # '%S','%d','%P'
347
+ if acttyp != '1': return True
348
+ if (inp.isdigit() and ((len(val) == 1) or (val[0] != '0') or ('.' in val))): return True
349
+ elif (inp == '.') and (val.count('.') <= 1): return True
350
+ elif (inp == '-') and (val.count('-') <= 1) and (val[0] == '-'): return True
351
+ return False
352
+
353
+
354
+ def _validIntPositive(inp, acttyp, val):
355
+ # '%S','%d','%P'
356
+ if acttyp != '1': return True
357
+ if (inp.isdigit() and ((len(val) == 1) or (val[0] != '0'))): return True
358
+ return False
359
+
360
+
361
+ def _validInt(inp, acttyp, val):
362
+ # '%S','%d','%P
363
+ if acttyp != '1': return True
364
+ match len(val):
365
+ case 1:
366
+ return inp.isdigit() or (inp == '-')
367
+ case 2:
368
+ match val[0]:
369
+ case '-': return inp in list('123456789')
370
+ case '0': return False
371
+ case _: return inp.isdigit()
372
+ case _: return (val[0] != '0') and inp.isdigit()
373
+
374
+
375
+ def _validIntNegative(inp, acttyp, val):
376
+ # '%S','%d','%P'
377
+ if acttyp != '1': return True
378
+ match len(val):
379
+ case 1: return (inp in list('0-'))
380
+ case 2: return (val[0] == '-') and (inp in list('123456789'))
381
+ case 3: return (val[0] == '-') and inp.isdigit()
382
+
383
+
384
+ def _validDateMMDDYYYY(inp, acttype, val):
385
+ # '%S','%d','%P'
386
+ if acttype != '1': return True
387
+ match len(val):
388
+ case 1:
389
+ return inp in '0123456789tn'
390
+ case 2:
391
+ match val[0]:
392
+ case '0': return inp in '123456789'
393
+ case '1': return inp in '012/.-'
394
+ case 't': return inp == 'o'
395
+ case 'n': return inp == 'o'
396
+ case _: return inp in '/.-'
397
+ case 3:
398
+ return ((val[1].isdigit() and (inp in '/.-')) or
399
+ ((val[0] == 't') and (inp == 'd')) or
400
+ ((val[0] == 'n') and(inp == 'w')) or
401
+ ((not val[1].isdigit()) and inp.isdigit()))
402
+ case 4:
403
+ return (((val[2] in '/.-') and inp.isdigit()) or
404
+ ((val[2] == '0') and (inp in '123456789')) or
405
+ ((val[2] in '12') and (inp in '0123456789/.-')) or
406
+ ((val[2] == '3') and (inp == '0') and (val[0] != '2')) or
407
+ ((val[2] == '3') and (inp == '1') and (val[0] in '13578')) or
408
+ ((val[2] in '3456789') and (inp in '/.-')) or
409
+ ((val[2] == 'd') and (inp == 'a')))
410
+ case 5:
411
+ return (((val[3] == '0') and (inp in '123456789')) or
412
+ ((val[3] == '0') and (val[1] in '/.-') and (inp in '/.-')) or
413
+ ((val[3] in '12') and (inp in '0123456789/.-')) or
414
+ ((val[3] == '3') and (inp == '0') and (int(val[:2]) != 2)) or
415
+ ((val[3] == '3') and (inp == '1') and (int(val[:2]) in [1, 3, 5, 7, 8, 10, 12])) or
416
+ ((val[3] in '3456789') and (inp in '/.-')) or
417
+ ((val[3] in '/.-') and (inp == '2')) or
418
+ ((val[3] == 'a') and (inp == 'y')))
419
+ case 6:
420
+ return ((val[4].isdigit() and (inp in '/.-')) or
421
+ ((val[4] in '/.-') and (inp == '2')) or
422
+ ((val[4] == '2') and (inp == '0')))
423
+ case 7:
424
+ return (((val[5] in '/.-') and (inp == '2')) or
425
+ ((val[5] == '2') and (inp == '0')) or
426
+ ((val[5] == '0') and inp.isdigit()))
427
+ case 8:
428
+ return (((val[5] in '/.-') and (inp == '0')) or
429
+ ((val[4] in '/._') and inp.isdigit()) or
430
+ ((val[3] in '/._') and inp.isdigit()))
431
+ case 9:
432
+ return (((val[5] in '/.-') and inp.isdigit()) or
433
+ ((val[4] in '/.-') and inp.isdigit()) and
434
+ (((val[7:] != '00') and (int(val[7:]) % 4 == 0)) or (val[0] != '2') or (int(val[2:4]) != 29)))
435
+ case 10:
436
+ return ((val[5] in '/.-') and inp.isdigit() and
437
+ (((val[8:] != '00') and (int(val[8:]) % 4 == 0)) or (int(val[:2]) != 2) or (int(val[3:5]) != 29)))
438
+ case _: return False
439
+
440
+
441
+ def _list2string(lnames, bk=10):
442
+ return '\n'.join([', '.join(lnames[k : (k + bk)]) for k in range(0, len(lnames), bk)])
@@ -0,0 +1,28 @@
1
+ import pathlib
2
+ import json
3
+
4
+ import azapyGUI.configSettings as configSettings
5
+
6
+
7
+ def _fileMasterUserConfig():
8
+ return pathlib.Path.home().joinpath(".azapyGUI/MasterUserConfig.json")
9
+
10
+
11
+ def _readMasterUserConfig():
12
+ out_file = _fileMasterUserConfig()
13
+ try:
14
+ with open(out_file, 'r') as fp:
15
+ data = json.load(fp)
16
+ except FileNotFoundError:
17
+ data = configSettings.get_settings_default_all()
18
+ out_file.parent.mkdir(exist_ok=True, parents=True)
19
+ with open(out_file, 'w') as fp:
20
+ json.dump(data, fp)
21
+ return data
22
+
23
+
24
+ def _saveMasterUserConfig(data):
25
+ out_file = _fileMasterUserConfig()
26
+ out_file.parent.mkdir(exist_ok=True, parents=True)
27
+ with open(out_file, 'w') as fp:
28
+ json.dump(data, fp)
azapyGUI/tkHelper.py ADDED
@@ -0,0 +1,18 @@
1
+ import tkinter as tk
2
+
3
+
4
+ def enable_children(parent, enabled=True):
5
+ for child in parent.winfo_children():
6
+ wtype = child.winfo_class()
7
+ if wtype not in ('Frame', 'Labelframe', 'TFrame', 'TLabelframe'):
8
+ child.configure(state=tk.NORMAL if enabled else tk.DISABLED)
9
+ else:
10
+ enable_children(child, enabled)
11
+
12
+
13
+ def enable_widget(widget, enabled=True):
14
+ wtype = widget.winfo_class()
15
+ if wtype not in ('Frame', 'Labelframe', 'TFrame', 'TLabelframe'):
16
+ widget.configure(state=tk.NORMAL if enabled else tk.DISABLED)
17
+ else:
18
+ enable_children(widget, enabled)