QuantAll 1.0.0__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 (128) hide show
  1. QuantAll/Arg.pyd +0 -0
  2. QuantAll/LICENSE.txt +79 -0
  3. QuantAll/L_Dbase.pyd +0 -0
  4. QuantAll/L_Deasy.pyd +0 -0
  5. QuantAll/L_SelManage.pyd +0 -0
  6. QuantAll/L_UiBase.pyd +0 -0
  7. QuantAll/L_UiCross.pyd +0 -0
  8. QuantAll/L_UiManage.pyd +0 -0
  9. QuantAll/L_UiRule.pyd +0 -0
  10. QuantAll/L_UiSelect.pyd +0 -0
  11. QuantAll/M_Ser.pyd +0 -0
  12. QuantAll/MainWindow.pyd +0 -0
  13. QuantAll/Nowheel_widget.pyd +0 -0
  14. QuantAll/O_cur.pyd +0 -0
  15. QuantAll/README.md +237 -0
  16. QuantAll/RunExec.pyd +0 -0
  17. QuantAll/SD.pyd +0 -0
  18. QuantAll/Test.duckdb +0 -0
  19. QuantAll/W_A.pyd +0 -0
  20. QuantAll/W_CtrlLay.pyd +0 -0
  21. QuantAll/W_Cur.pyd +0 -0
  22. QuantAll/W_RW_Cur.pyd +0 -0
  23. QuantAll/W_S.pyd +0 -0
  24. QuantAll/__init__.py +30 -0
  25. QuantAll/ai_prompts.toml +488 -0
  26. quantall-1.0.0.dist-info/METADATA +277 -0
  27. quantall-1.0.0.dist-info/RECORD +128 -0
  28. quantall-1.0.0.dist-info/WHEEL +5 -0
  29. quantall-1.0.0.dist-info/licenses/LICENSE.txt +79 -0
  30. quantall-1.0.0.dist-info/top_level.txt +4 -0
  31. src/Arg.py +334 -0
  32. src/L_Dbase.py +272 -0
  33. src/L_Deasy.py +2390 -0
  34. src/L_SelManage.py +299 -0
  35. src/L_UiBase.py +168 -0
  36. src/L_UiCross.py +119 -0
  37. src/L_UiManage.py +357 -0
  38. src/L_UiRule.py +198 -0
  39. src/L_UiSelect.py +147 -0
  40. src/M_Ser.py +469 -0
  41. src/MainWindow.py +1030 -0
  42. src/Nowheel_widget.py +831 -0
  43. src/O_cur.py +221 -0
  44. src/RunExec.py +955 -0
  45. src/SD.py +926 -0
  46. src/Test.duckdb +0 -0
  47. src/W_A.py +134 -0
  48. src/W_CtrlLay.py +97 -0
  49. src/W_Cur.py +471 -0
  50. src/W_RW_Cur.py +330 -0
  51. src/W_S.py +18 -0
  52. src/__init__.py +30 -0
  53. src/ai_prompts.toml +488 -0
  54. src_aid/API_tushare.txt +1 -0
  55. src_aid/Add_db_lab.py +52 -0
  56. src_aid/P_ai.py +774 -0
  57. src_aid/RunAtStarup.py +558 -0
  58. src_aid/Test.duckdb +0 -0
  59. src_aid/UpdateStock_skill.py +1408 -0
  60. src_aid/__init__.py +0 -0
  61. src_aid/add_note.py +359 -0
  62. src_aid/bg.py +123 -0
  63. src_aid/ceshi.py +267 -0
  64. src_aid/ceshi2.py +34 -0
  65. src_aid/ceshi3.py +0 -0
  66. src_aid/code.py +23 -0
  67. src_aid/creat_dialog.py +413 -0
  68. src_aid/db_clear.py +187 -0
  69. src_aid/db_data_move.py +47 -0
  70. src_aid/db_move_data.py +98 -0
  71. src_aid/db_update.py +586 -0
  72. src_aid/dialog_option.py +217 -0
  73. src_aid/ex.py +73 -0
  74. src_aid/exec_add_fun.py +774 -0
  75. src_aid/get_dfcf.py +302 -0
  76. src_aid/icon_4_preview.py +155 -0
  77. src_aid/icon_build.py +149 -0
  78. src_aid/icon_glod.py +10649 -0
  79. src_aid/min1_k.py +246 -0
  80. src_aid/my_logger.py +32 -0
  81. src_aid/normal_bbq.py +91 -0
  82. src_aid/note.py +80 -0
  83. src_aid/re_cumsum.py +178 -0
  84. src_aid/table_stract.py +50 -0
  85. src_aid/test_script.py +13 -0
  86. src_aid/up_ex.py +358 -0
  87. src_aid/up_image.py +78 -0
  88. src_aid/up_k.py +834 -0
  89. src_build/ARG.py +154 -0
  90. src_build/Actions.py +1541 -0
  91. src_build/DCS.py +71 -0
  92. src_build/MainWindow.py +20 -0
  93. src_build/Mcp_ser.py +582 -0
  94. src_build/Mcp_tools.py +1906 -0
  95. src_build/Nowheel_widget.py +828 -0
  96. src_build/Opt_arg.py +788 -0
  97. src_build/P_color.py +879 -0
  98. src_build/P_cre_layer.py +613 -0
  99. src_build/P_layer.py +1519 -0
  100. src_build/P_note_sel.py +1282 -0
  101. src_build/P_order.py +1250 -0
  102. src_build/P_player.py +1264 -0
  103. src_build/P_read_table.py +1260 -0
  104. src_build/P_set.py +2153 -0
  105. src_build/P_update_db.py +1518 -0
  106. src_build/__init__.py +5 -0
  107. src_build/browser.py +1069 -0
  108. src_build/creat_dialog.py +345 -0
  109. src_build/db_set.py +576 -0
  110. src_build/dock_title.py +176 -0
  111. src_build/icon_black.py +10626 -0
  112. src_build/icon_blue.py +10626 -0
  113. src_build/icon_cyan.py +10626 -0
  114. src_build/icon_glod.py +10626 -0
  115. src_build/icon_gray.py +10626 -0
  116. src_build/icon_green.py +10626 -0
  117. src_build/icon_pink.py +10626 -0
  118. src_build/icon_purple.py +10626 -0
  119. src_build/icon_red.py +10626 -0
  120. src_build/icon_white.py +10626 -0
  121. src_build/load_hc.py +3417 -0
  122. src_build/mw.py +2666 -0
  123. src_build/net_icloud.py +209 -0
  124. src_build/wid_cur_2.py +5174 -0
  125. src_build/wid_history.py +175 -0
  126. src_build/wid_tab.py +706 -0
  127. src_build/wid_txt.py +209 -0
  128. src_build/wid_win_title.py +272 -0
@@ -0,0 +1,613 @@
1
+ import os, time
2
+ import json
3
+ import numpy as np
4
+ import pandas as pd
5
+ from PySide6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout,
6
+ QLabel,QSizePolicy, QToolButton,QLineEdit,
7
+ QMessageBox, QMenu)
8
+ from PySide6.QtCore import Qt, Signal, QObject, Slot, QTimer
9
+ from PySide6.QtGui import QAction, QIcon
10
+ from .Nowheel_widget import NoWheelComboBox, SRC_TextEdit, cur_Worker
11
+ from .wid_cur_2 import wid_cur
12
+
13
+
14
+ # 时间范围20260205-20270115
15
+ if time.time() < 1.77e9 or time.time() > 1.8e9:
16
+ os._exit(1)
17
+
18
+
19
+ class P_cre_layer_wid(QWidget):
20
+ sig_up_names = Signal()
21
+ sig_able = Signal(bool)
22
+ def __init__(self,parent=None, mode=None, option={}):
23
+ super().__init__(parent, objectName="P_cre_layer_wid")
24
+ self.title = "P_cre_layer_wid"
25
+ self.plugin = "P_cre_layer"
26
+ self.parent = parent
27
+ # if self.parent:
28
+ self.option = self.parent.option['main']
29
+ self.path = self.parent.path
30
+ # else:
31
+ # self.option = {
32
+ # "fm_size":12,
33
+ # "fm_var":[0,120,215,255],
34
+ # "fm_d":[0,242,255,255],
35
+ # "fm_d_not":[160,0,0,255],
36
+ # "fm_out":[140,255,0,255],
37
+ # "fm_key":[195,0,255,255],
38
+ # "fm_str":[255,145,0,255],
39
+ # "fm_number":[255,213,0,255],
40
+ # "fm_comment":[128,128,128,255]
41
+ # }
42
+ # self.path = os.path.dirname(os.path.dirname(__file__)) # 设置程序路径
43
+ self.setMinimumHeight(30)
44
+ self.setMinimumWidth(30)
45
+ # if self.parent:
46
+ self.hc = self.parent.hc
47
+ self.thread_pool = self.parent.thread_pool
48
+ self.logger = self.parent.logger
49
+ # else:
50
+ # from PySide6.QtCore import QThreadPool
51
+ # from .Nowheel_widget import logger_model
52
+ # from .load_hc import load_hc
53
+ # from . import icon_glod
54
+ # self.thread_pool = QThreadPool() # 线程池
55
+ # self.logger = logger_model()
56
+ # self.hc = load_hc()
57
+ # self.hc.read_hc_npz()
58
+
59
+ self.lg = {'left':'左','right':'右',"name":"名称","start_work":"执行代码",
60
+ "mold: ":"模板","compute":"计算(添加)","Current_Axis:":"现有数据:",
61
+ "remove":"移除","contrl_tip":"提示","save_or_save_as":"保存或另存",
62
+ "remove_data":"移除数据",
63
+ "wid_cre_layer":"新建图层","wid_cre_layer_":"新建图层",
64
+ "P_cre_layer_wid":"创建图层",
65
+ "default":"默认","mode":"模式",
66
+ "dock_title_bar":"部件标题栏",
67
+ "minsize":"最小化",
68
+ "maxsize":"最大化","close":"关闭",
69
+ "show_or_hide_title":"显示/隐藏_标题栏",
70
+ "Will delete":"将删除:",
71
+ "delete":"删除",
72
+ 'select':"执行选择",
73
+ "A":"A(重选)",
74
+ "AB":"AB(交集)",
75
+ "A+B":"A+B(并集)",
76
+ "A-B":"A-B(差集)",
77
+ "B-A":"B-A(差集)",
78
+ "A+B-AB":"A+B-AB",
79
+ "eval_hold":"评估持仓",
80
+ "draw_hold":"绘制持仓"
81
+ }
82
+
83
+ self.mode = mode if mode else ['default',['default'],'str']
84
+ self.thread_do = True
85
+ self.data = {}
86
+ self.menus = {'main':None, 'select':None, 'mode':None,'dock':None}
87
+ self.initui()
88
+ # 创建线程来读本地数据,目前提升不大,后续大文本可能会有提升,保留
89
+ self.sig_up_names.connect(self.act_up_names)
90
+ self.sig_able.connect(self.act_wid_able)
91
+ self.task_pool(self.load_data)
92
+ # 启用自定义上下文菜单
93
+ self.setContextMenuPolicy(Qt.CustomContextMenu)
94
+ self.customContextMenuRequested.connect(self.show_context_menu)
95
+ # 写一个延迟更新
96
+ QTimer.singleShot(100, self._delay_init) # 界面先行
97
+
98
+
99
+
100
+ def load_data(self):
101
+ self.thread_do = False
102
+ try:
103
+ path = os.path.join(self.path,"data","creat_layer.json")
104
+ with open(path, 'r', encoding='utf-8') as file:
105
+ self.data = json.load(file)
106
+ except:
107
+ self.data={}
108
+ finally:
109
+ self.thread_do = True
110
+ self.sig_up_names.emit()
111
+ # 多线程触发更新self.name_com选项
112
+
113
+ def initui(self):
114
+ mainlayout = QVBoxLayout(self)
115
+ mainlayout.setContentsMargins(0,2,0,2)
116
+ mainlayout.setSpacing(2)
117
+
118
+ row1_layout = QHBoxLayout()
119
+ row1_layout.setContentsMargins(5,0,5,0)
120
+ row1_layout.setSpacing(2)
121
+ mainlayout.addLayout(row1_layout)
122
+
123
+ name_lab = QLabel(self.lg.get("name","name"),self)
124
+ name_lab.adjustSize() # 自动调整大小以匹配内容
125
+ name_lab.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) # 关键设置
126
+
127
+ row1_layout.addWidget(name_lab)
128
+
129
+ self.name_com = NoWheelComboBox(self)
130
+ self.name_com.setEditable(True)
131
+ self.name_com.addItems(list(self.data.keys()))
132
+ self.name_com.currentIndexChanged.connect(self.change_name_com)
133
+ row1_layout.addWidget(self.name_com)
134
+
135
+ self.save_btn = QToolButton(self)
136
+ self.save_btn.setIcon(QIcon(":/icons/f_save"))
137
+ self.save_btn.setToolTip(self.lg.get("save_or_save_as","save_or_save_as"))
138
+ self.save_btn.clicked.connect(self.act_save)
139
+ row1_layout.addWidget(self.save_btn)
140
+
141
+ self.remove_btn = QToolButton(self)
142
+ self.remove_btn.setIcon(QIcon(":/icons/remove"))
143
+ self.remove_btn.setToolTip(self.lg.get("remove_data","remove_data"))
144
+ self.remove_btn.clicked.connect(self.act_remove)
145
+ row1_layout.addWidget(self.remove_btn)
146
+
147
+ self.ok_btn = QToolButton(self,icon=QIcon(":/icons/check_ok"))
148
+ self.ok_btn.setToolTip(self.lg.get("start_work","start_work"))
149
+ self.ok_btn.clicked.connect(self.act_ok)
150
+ row1_layout.addWidget(self.ok_btn)
151
+
152
+ # 第二行,用来显示关键字
153
+ src_lay_row2 = QHBoxLayout()
154
+ src_lay_row2.setContentsMargins(0,0,0,0)
155
+ src_lay_row2.setSpacing(2)
156
+ mainlayout.addLayout(src_lay_row2)
157
+ self.key_led = QLineEdit(self.lg.get("Current_Axis:","Current_Axis:"),self)
158
+ self.key_led.setReadOnly(True)
159
+ src_lay_row2.addWidget(self.key_led)
160
+ up_key_tb = QToolButton(self,icon=QIcon(":/icons/refresh"))
161
+ up_key_tb.clicked.connect(self.act_up_current_axis)
162
+ src_lay_row2.addWidget(up_key_tb)
163
+
164
+ self.src_ted = SRC_TextEdit(self)
165
+ # self.src_ted.setLineWrapMode(QTextEdit.NoWrap)
166
+ self.src_ted.textChanged.connect(self.act_src_no_save)
167
+ mainlayout.addWidget(self.src_ted)
168
+
169
+ self.change_name_com(0)
170
+
171
+ def _delay_init(self):
172
+ res,err = self.hc.get_available_data()
173
+ if res:
174
+ self.src_ted.highlighter.up_keys(res)
175
+ else:
176
+ self.src_ted.highlighter.up_keys({"d":[],"col_attrs":[]})
177
+
178
+ def act_up_names(self):
179
+ self.name_com.blockSignals(True)
180
+ self.name_com.clear()
181
+ self.name_com.blockSignals(False)
182
+ self.name_com.addItems(list(self.data.keys()))
183
+
184
+ def act_src_no_save(self):
185
+ self.save_btn.setIcon(QIcon(":/icons/no_save"))
186
+ self.src_ted.blockSignals(True)
187
+
188
+ def act_save(self):
189
+ name = self.name_com.currentText()
190
+ if not name:
191
+ return
192
+ if name not in self.data:
193
+ self.name_com.addItem(name)
194
+ self.data[name] = self.src_ted.toPlainText()
195
+ try:
196
+ path = os.path.join(self.path,"data","creat_layer.json")
197
+ with open(path, "w", encoding="utf-8") as file:
198
+ json.dump(self.data, file, ensure_ascii=False)
199
+ except:
200
+ pass
201
+ finally:
202
+ self.save_btn.setIcon(QIcon(":/icons/f_save"))
203
+ self.src_ted.blockSignals(False)
204
+
205
+ def act_remove(self):
206
+ name = self.name_com.currentText()
207
+ # 弹出删除确认对话框
208
+ reply = QMessageBox.question(
209
+ self, # 父窗口,None 表示顶级窗口
210
+ self.lg.get("delete","delete"), # 标题
211
+ "{} '{}'".format(self.lg.get("Will delete","Will delete"),name), # 内容
212
+ QMessageBox.Yes | QMessageBox.No, # 按钮
213
+ QMessageBox.No # 默认按钮
214
+ )
215
+
216
+ # 判断用户点击了哪个按钮
217
+ if reply != QMessageBox.Yes:
218
+ return
219
+ if name not in self.data:
220
+ self.name_com.currentIndexChanged.disconnect(self.change_name_com)
221
+ self.name_com.setCurrentText('')
222
+ self.name_com.currentIndexChanged.connect(self.change_name_com)
223
+ self.src_ted.setText('')
224
+ index = self.name_com.findText(name)
225
+ if index != -1:
226
+ self.name_com.removeItem(index)
227
+ else:
228
+ del self.data[name]
229
+ index = self.name_com.findText(name)
230
+ if index != -1:
231
+ self.name_com.removeItem(index)
232
+ try:
233
+ path = os.path.join(self.path,"data","creat_layer.json")
234
+ with open(path, "w", encoding="utf-8") as file:
235
+ json.dump(self.data, file, ensure_ascii=False)
236
+ except:
237
+ pass
238
+
239
+ @Slot() # 执行创建图层
240
+ def act_ok(self):
241
+ name = self.name_com.currentText()
242
+ e_txt = self.src_ted.toPlainText()
243
+ if not name or not e_txt:
244
+ return
245
+ if self.thread_do:
246
+ self.sig_able.emit(False)
247
+ self.task_pool(self.thread_ok, name, e_txt)
248
+
249
+ def thread_ok(self, name, e_txt):
250
+ self.thread_do = False
251
+ try:
252
+ wid = self.parent.opt['current_wid']
253
+ if not isinstance(wid,wid_cur):
254
+ return
255
+ if wid.mode[0] != "default":
256
+ return
257
+ # 不自动重命名,因为如果多次误点到大图层,大量的多余数据,内存可能溢出
258
+ if name in wid.dc:
259
+ return
260
+ gps, rq1s = self.hc.map_exec_layer(e_txt)
261
+ if gps is None:
262
+ return
263
+ if len(gps)<=0 or len(gps) != len(rq1s):
264
+ return
265
+ dc = wid.dc_m.copy()
266
+ dc['rq1'] = rq1s
267
+ dc['clist'] = gps
268
+ # 不自动映射
269
+ shape = dc['rq1'].shape
270
+ dc['gx'] = np.full(shape,0.0,dtype=np.float32)
271
+ dc['mx'] = np.full(shape,0.0,dtype=np.float32)
272
+ dc['gy'] = np.full(shape,0.0,dtype=np.float32)
273
+ dc['my'] = np.full(shape,0.0,dtype=np.float32)
274
+ dc['ox'] = np.full(shape,0.0,dtype=np.float32)
275
+ dc['oy'] = np.full(shape,0.0,dtype=np.float32)
276
+ re = self.hc.get_layer_data(gps=dc['clist'],rq1s=dc['rq1'],
277
+ L=dc['left'],R=dc['right'],
278
+ lay_type=dc['type'])
279
+ for k,v in re.items():
280
+ dc[k] = v
281
+ dc['len'] = dc['y'].shape[0] * dc['y'].shape[1]
282
+ # 创建vao
283
+ dc['ay'] = dc['y'] # +0,初始不给偏移量
284
+ dc['ax'] = dc['x'] # +0,初始不够偏移量
285
+ wid.sigs.vao.emit({'name':name,'dc':dc})
286
+ except Exception as e:
287
+ self.logger.warning("P_cre_layer_218_{}".format(e))
288
+ finally:
289
+ self.thread_do = True
290
+ self.sig_able.emit(True)
291
+
292
+ @Slot() # 执行选中
293
+ def act_select(self, mod):
294
+ # name = self.name_com.currentText()
295
+ e_txt = self.src_ted.toPlainText()
296
+ if not e_txt:
297
+ return
298
+ if self.thread_do:
299
+ self.sig_able.emit(False)
300
+ self.task_pool(self.thread_select, e_txt, mod)
301
+
302
+ def thread_select(self, e_txt, mod):
303
+ self.thread_do = False
304
+ try:
305
+ wid = self.parent.opt['current_wid']
306
+ if not isinstance(wid,wid_cur):
307
+ return
308
+ if wid.mode[0] != "default":
309
+ return
310
+ gps, rq1s = self.hc.map_exec_layer(e_txt)
311
+ if gps is None:
312
+ return
313
+ wid.sel_compute('', gps, rq1s, mod)
314
+ except Exception as e:
315
+ self.logger.warning("P_cre_layer_218_{}".format(e))
316
+ finally:
317
+ self.sig_able.emit(True)
318
+ self.thread_do = True
319
+
320
+ def change_name_com(self,i):
321
+ """恢复保存按钮的图标颜色"""
322
+ self.src_ted.blockSignals(True)
323
+ txt = self.name_com.currentText()
324
+ if txt in self.data:
325
+ self.src_ted.setText(self.data.get(txt,''))
326
+ self.save_btn.setIcon(QIcon(":/icons/f_save"))
327
+ self.src_ted.blockSignals(False)
328
+
329
+ def show_axis_tip(self):
330
+ if self.axis_tip_ted.isHidden():
331
+ self.axis_tip_ted.show()
332
+ else:
333
+ self.axis_tip_ted.hide()
334
+
335
+ def reload_data(self,data):
336
+ pass
337
+
338
+ @Slot(bool) # 运行中屏蔽功能
339
+ def act_wid_able(self,tf:bool=True):
340
+ self.ok_btn.setEnabled(tf)
341
+ if self.menus['select']: # 右键菜单可能还没被创建
342
+ self.menus['select'].setEnabled(tf)
343
+
344
+ def _right_menu(self): # 右键菜单
345
+ # 右键菜单的设计,多级设计
346
+ if self.menus['main'] is None:
347
+ self.menus['main'] = QMenu('main',self)
348
+ self.menus['main'].setWindowFlags(self.menus['main'].windowFlags()
349
+ | Qt.FramelessWindowHint
350
+ | Qt.NoDropShadowWindowHint)
351
+ self.menus['main'].setAttribute(Qt.WA_TranslucentBackground)
352
+ else:
353
+ self.menus['main'].clear()
354
+ menu = self.menus['main']
355
+
356
+ # region 筛选
357
+ sub = menu.addMenu(self.lg.get('select','select'))
358
+ sub.setWindowFlags(sub.windowFlags() | Qt.FramelessWindowHint
359
+ | Qt.NoDropShadowWindowHint)
360
+ sub.setAttribute(Qt.WA_TranslucentBackground)
361
+ self.menus['select'] = sub
362
+ # 一套颜色查询逻辑,对但是
363
+ act = sub.addAction(self.lg.get("A","A"))
364
+ act.triggered.connect(lambda: self.act_select("A"))
365
+ act = sub.addAction(self.lg.get("AB","AB"))
366
+ act.triggered.connect(lambda: self.act_select("AB"))
367
+ act = sub.addAction(self.lg.get("A+B","A+B"))
368
+ act.triggered.connect(lambda: self.act_select("A+B"))
369
+ act = sub.addAction(self.lg.get("A-B","A-B"))
370
+ act.triggered.connect(lambda: self.act_select("A-B"))
371
+ act = sub.addAction(self.lg.get("B-A","B-A"))
372
+ act.triggered.connect(lambda: self.act_select("B-A"))
373
+ act = sub.addAction(self.lg.get("A+B-AB","A+B-AB"))
374
+ act.triggered.connect(lambda: self.act_select("A+B-AB"))
375
+ # endregion 筛选
376
+
377
+ # 添加两个action,1.评估持仓;2.绘制持仓
378
+ act = menu.addAction(self.lg.get("eval_hold","eval_hold"))
379
+ act.triggered.connect(self.act_eval_hold)
380
+
381
+ act = menu.addAction(self.lg.get("draw_hold","draw_hold"))
382
+ act.triggered.connect(self.act_draw_hold)
383
+
384
+
385
+
386
+
387
+ # region 模式菜单
388
+ if self.menus['mode'] is None:
389
+ self.menus['mode'] = menu.addMenu("mode")
390
+ self.menus['mode'].setWindowFlags(self.menus['mode'].windowFlags()
391
+ | Qt.FramelessWindowHint
392
+ | Qt.NoDropShadowWindowHint)
393
+ self.menus['mode'].setAttribute(Qt.WA_TranslucentBackground)
394
+ self.menus['mode'].triggered.connect(self.act_change_mode)
395
+ else:
396
+ self.menus['mode'].clear()
397
+
398
+ for m in self.mode[1]:
399
+ self.menus['mode'].addAction(self.lg.get(m,m))
400
+ # endregion
401
+
402
+ # region 一级子菜单 dock_title_bar
403
+ if self.menus['dock'] is None:
404
+ self.menus['dock'] = menu.addMenu(self.lg.get("dock_title_bar","dock_title_bar"))
405
+ self.menus['dock'].setWindowFlags(self.menus['dock'].windowFlags()
406
+ | Qt.FramelessWindowHint
407
+ | Qt.NoDropShadowWindowHint)
408
+ self.menus['dock'].setAttribute(Qt.WA_TranslucentBackground)
409
+ else:
410
+ self.menus['dock'].clear()
411
+ sub = self.menus['dock']
412
+ act = sub.addAction(self.lg.get("minsize","minsize"))
413
+ act.triggered.connect(self.dock_min)
414
+ act = sub.addAction(self.lg.get("maxsize","maxsize"))
415
+ act.triggered.connect(self.dock_max)
416
+ act = sub.addAction(self.lg.get("close","close"))
417
+ act.triggered.connect(self.dock_close)
418
+ act = sub.addAction(self.lg.get("show_or_hide_title","show_or_hide_title"))
419
+ act.triggered.connect(self.dock_hide_title)
420
+ # endregion
421
+
422
+ def show_context_menu(self, pos):
423
+ """显示右键菜单"""
424
+ if not self.menus['main']:
425
+ self._right_menu()
426
+ self.menus['main'].exec(self.mapToGlobal(pos))
427
+
428
+ def act_change_mode(self, a:QAction):
429
+ self.dock_mode(a.text())
430
+ # 检测父级对象是不是有要更新的
431
+ # if self.parent:
432
+ # p_dock = self.parent.wids['plugin'][self.plugin].get('dock')
433
+ # if p_dock:
434
+ # p_title = p_dock.titleBarWidget()
435
+ # if isinstance(p_title,dock_title):
436
+ # p_title.dock_mode(a.text())
437
+
438
+ def act_up_current_axis(self):
439
+ res,err = self.hc.get_available_data()
440
+ if err:
441
+ txt = "d:[] col_attrs:[]"
442
+ else:
443
+ txt = "d:" + str(res['d']) + " col_attrs:" + str(res['col_attrs'])
444
+ self.key_led.setText(txt)
445
+ # self.src_ted.highlighter.up_d_keys(keys)
446
+
447
+ def act_eval_hold(self):
448
+ name = self.name_com.currentText()
449
+ e_txt = self.src_ted.toPlainText()
450
+ if not name or not e_txt:
451
+ return
452
+ if self.thread_do:
453
+ self.sig_able.emit(False)
454
+ self.task_pool(self.thread_eval_hold, name, e_txt)
455
+ # print("评估持仓")
456
+ # pass
457
+
458
+ def thread_eval_hold(self,name,code):
459
+ self.thread_do = False
460
+ try:
461
+ if not code:
462
+ self.parent.sig_log.emit(f"代码文本为空")
463
+ return
464
+ df = self.hc.run_exec(code,False) # 没恢复显示结构,直接pd.DataFrame输出
465
+ if isinstance(df,pd.DataFrame):
466
+ res = self.hc.eval_hold(df,0.00025,0.00075,
467
+ 'close',0,False,name)
468
+ if isinstance(res,dict):
469
+ self.parent.sig_log.emit(f"{res}")
470
+ else:
471
+ self.parent.sig_log.emit(res)
472
+ else:
473
+ self.parent.sig_log.emit("结果异常,返回的不是pd.DataFrame")
474
+ return
475
+ except Exception as e:
476
+ self.logger.warning("P_cre_layer_463_{}".format(e))
477
+ finally:
478
+ self.thread_do = True
479
+ self.sig_able.emit(True)
480
+
481
+ def act_draw_hold(self):
482
+ name = self.name_com.currentText()
483
+ e_txt = self.src_ted.toPlainText()
484
+ if not name or not e_txt:
485
+ return
486
+ if self.thread_do:
487
+ self.sig_able.emit(False)
488
+ self.task_pool(self.thread_draw_hold, name, e_txt)
489
+
490
+ def thread_draw_hold(self, name:str, code:str):
491
+ self.thread_do = False
492
+ try:
493
+ wid = self.parent.opt['current_wid']
494
+ if not isinstance(wid,wid_cur):
495
+ self.parent.sig_log.emit("没有活动的绘图部件")
496
+ return
497
+ elif wid.mode[0] != "default":
498
+ self.parent.sig_log.emit("活动的绘图部件不是默认模式")
499
+ return
500
+ elif name in wid.dc: # 不自动重命名,
501
+ self.parent.sig_log.emit(f"名称[{name}]已存在,放弃执行")
502
+ return
503
+ elif not code:
504
+ self.parent.sig_log.emit(f"代码文本为空")
505
+ return
506
+ df = self.hc.run_exec(code,False) # 没恢复显示结构,直接pd.DataFrame输出
507
+ if not isinstance(df,pd.DataFrame):
508
+ self.parent.sig_log.emit("结果异常,返回的不是pd.DataFrame")
509
+ return
510
+ gps, rq1s, rq2s = self.hc.draw_hold(df)
511
+ if gps is None:
512
+ self.parent.sig_log.emit("计算异常,列匹配出错")
513
+ return
514
+ if len(gps)<=0 or len(gps) != len(rq1s) or len(gps) != len(rq2s):
515
+ self.parent.sig_log.emit("结果为空,或者出错")
516
+ return
517
+
518
+ dc = wid.dc_m.copy()
519
+ dc['rq1'] = rq1s
520
+ dc['clist'] = gps
521
+ dc['rq2'] = rq2s
522
+ dc['type'] = "double_time"
523
+ dc['left'] = 0
524
+ dc['right'] = 1
525
+ # 不自动映射
526
+ shape = dc['rq1'].shape
527
+ dc['gx'] = np.full(shape,0.0,dtype=np.float32)
528
+ dc['mx'] = np.full(shape,0.0,dtype=np.float32)
529
+ dc['gy'] = np.full(shape,0.0,dtype=np.float32)
530
+ dc['my'] = np.full(shape,0.0,dtype=np.float32)
531
+ dc['ox'] = np.full(shape,0.0,dtype=np.float32)
532
+ dc['oy'] = np.full(shape,0.0,dtype=np.float32)
533
+ res = self.hc.get_layer_data(gps=dc['clist'],rq1s=dc['rq1'],
534
+ rq2s=dc['rq2'],
535
+ L=dc['left'],R=dc['right'],
536
+ lay_type=dc['type'])
537
+ for k,v in res.items():
538
+ dc[k] = v
539
+ # 设置w
540
+ ay = dc['y']
541
+ bool_arr:np.ndarray = ~np.isnan(ay)
542
+ cumsum_arr = bool_arr.cumsum(axis=0)
543
+ last_id = np.argmax(cumsum_arr, axis=0)
544
+ range_id = np.arange(ay.shape[1], dtype=np.int64)
545
+ dc['w'] = ay[last_id,range_id]
546
+ dc['w_name'] = "卖价/买价"
547
+ dc['len'] = dc['y'].shape[0] * dc['y'].shape[1]
548
+ # # 创建vao
549
+ dc['ay'] = dc['y'] # +0,初始不给偏移量
550
+ dc['ax'] = dc['x'] # +0,初始不够偏移量
551
+ wid.sigs.vao.emit({'name':name,'dc':dc})
552
+ except Exception as e:
553
+ self.logger.warning("P_cre_layer_551_{}".format(e))
554
+ finally:
555
+ self.thread_do = True
556
+ self.sig_able.emit(True)
557
+
558
+ # region 与dock_title相关
559
+ def dock_mode(self,mod=None):
560
+ return
561
+
562
+ def dock_min(self):
563
+ self.parent.dock_min(self.plugin,'plugin')
564
+
565
+ def dock_close(self):
566
+ self.parent.dock_close(self.plugin,'plugin')
567
+
568
+ def dock_max(self):
569
+ self.parent.dock_max(self.plugin,'plugin')
570
+
571
+ def dock_hide_title(self):
572
+ self.parent.dock_title_hide(self.plugin,'plugin')
573
+ # endregion
574
+
575
+ # region 多线程相关管理及可调用函
576
+ def task_pool(self, task, *args): # 线程调用,查询空闲线程,转载任务并启动
577
+ worker = cur_Worker(task,*args)
578
+ self.thread_pool.start(worker)
579
+ # endregion 多线程相关管理及可调用函
580
+
581
+
582
+ class P_cre_layer(QObject):
583
+ def __init__(self, parent=None):
584
+ super().__init__(parent, objectName="P_cre_layer")
585
+ self.title = 'P_cre_layer'
586
+ self.wid = 'P_cre_layer_wid'
587
+ self.parent = parent
588
+ # if not self.parent:
589
+ # from . import icon_glod
590
+ # self.lg = {"creat_layer":"创建图层"} #2
591
+
592
+
593
+ def install(self):
594
+ # 在侧栏添加一个按钮
595
+ act_side = QAction(QIcon(":/icons/s_new_layer"),
596
+ "创建图层",
597
+ self.parent,
598
+ toolTip= "创建图层")
599
+ act_side.triggered.connect(lambda: self.parent.plugin_creat_dock(
600
+ wid_type=self.wid, plugin=self.title))
601
+ self.parent.acts.tool_plugins.addAction(act_side)
602
+
603
+ def uninstall(self):
604
+ pass
605
+
606
+
607
+
608
+
609
+ # if __name__ == "__main__":
610
+ # app = QApplication([])
611
+ # window = P_cre_layer_wid()
612
+ # window.show()
613
+ # app.exec()