""" GUI管理 """ from tkinter import * from tkinter.messagebox import * import numpy import tkintertable import win32gui import constant import data_export_util import multiprocessing import log from db import mysql_data, redis_manager import server import settings from juejin import JueJinManager from l2_code_operate import L2CodeOperate from trade import l2_trade_util from trade.l2_trade_factor import L2TradeFactorUtil from ocr import ocr_server from third_data import data_server, kpl_data_manager, kpl_util from server import * import l2.l2_data_util # 读取server进程的消息 from trade.trade_data_manager import CodeActualPriceProcessor from ui.my_widget import FlatButton def __read_server_pipe(pipe): while True: value = pipe.recv() if value is not None: value = json.loads(value) if value.get("type") == "clear_l2": code = value["data"]["code"] print("清除l2数据", code) if len(code) != 6: continue l2_data_manager.clear_l2_data(code) # 删除level2的数据 if l2.l2_data_util.local_today_datas and code in l2.l2_data_util.local_today_datas: l2.l2_data_util.local_today_datas.pop(code) if l2.l2_data_util.local_latest_datas and code in l2.l2_data_util.local_latest_datas: l2.l2_data_util.local_latest_datas.pop(code) time.sleep(0.1) def createServer(pipe_juejin, pipe_gui): print("create SocketServer") # 初始化参数 global_data_loader.init() t1 = threading.Thread(target=lambda: __read_server_pipe(pipe_gui)) # 后台运行 t1.setDaemon(True) t1.start() t1 = threading.Thread(target=createDataServer) # 后台运行 t1.setDaemon(True) t1.start() laddr = "", 9001 tcpserver = MyThreadingTCPServer(laddr, MyBaseRequestHandle, pipe_juejin=pipe_juejin) # 注意:参数是MyBaseRequestHandle # tcpserver.handle_request() # 只接受一个客户端连接 tcpserver.serve_forever() # 永久循环执行,可以接受多个客户端连接 def createOCRServer(): print("create OCRServer") tcpserver = ocr_server.run("", 9002) tcpserver.serve_forever() def createDataServer(): print("create OCRServer") tcpserver = data_server.run("", 9004) tcpserver.serve_forever() def startJueJin(pipe): juejin.JueJinManager(pipe).start() class GUI: def __init__(self): p1, p2 = multiprocessing.Pipe() gs_gui_pipe, gs_server_pipe = multiprocessing.Pipe() self.serverProcess = multiprocessing.Process(target=createServer, args=(p1, gs_server_pipe,)) self.jueJinProcess = multiprocessing.Process(target=startJueJin, args=(p2,)) self.ocrServerProcess = multiprocessing.Process(target=createOCRServer) self.p1 = p1 self.p2 = p2 self.gs_gui_pipe = gs_gui_pipe self.thsBuy1VolumnManager = THSBuy1VolumnManager() self.codeActualPriceProcessor = CodeActualPriceProcessor() # L2显示 self.l2_codes = {} self.selected_client = {} # 获取l2的客户端列表 clients = authority.get_l2_clients() for client_id in clients: self.l2_codes[client_id] = [] for i in range(0, constant.L2_CODE_COUNT_PER_DEVICE): code = gpcode_manager.get_listen_code_by_pos(client_id, i) self.l2_codes[client_id].append(code) # 读取server进程的消息 def __read_gui_server_pipe(self, pipe): while True: value = pipe.recv() if value is not None: value = json.loads(value) if value.get("type") == "l2_data_notify": code = value["data"]["code"] count = value["data"]["count"] print("l2数据通知:{}-{}", code, count) time.sleep(0.1) def run(self): # TODO self.jueJinProcess.start() self.serverProcess.start() self.ocrServerProcess.start() L2CodeOperate.get_instance() # 客户端队列操作 process = multiprocessing.Process(target=L2CodeOperate.run()) process.start() # 客户端server连接 t1 = threading.Thread(target=lambda: server.test_client_server()) # 后台运行 t1.setDaemon(True) t1.start() t1 = threading.Thread(target=lambda: self.__read_gui_server_pipe(self.gs_gui_pipe)) # 后台运行 t1.setDaemon(True) t1.start() self.create_gui() def _draw_check(self, root): def _set_error_color(text, line, content): for i in range(0, len(content)): text.tag_add('error', "{}.{}".format(line, i)) def click(): text.delete('1.0', END) # 验证redis try: redis = redis_manager.RedisManager().getRedis() redis.set("test", "1") redis.delete("test") text.insert(END, "redis连接成功!\n") except: error = "redis连接失败...\n" text.insert(END, error) _set_error_color(text, 1, error) # 验证mongodb try: counts = mysql_data.Mysqldb().select_one("select count(*) from clients") if counts[0] < 1: raise Exception("") text.insert(END, "mysql连接成功!\n") except: error = "mysql连接失败...\n" text.insert(END, error) _set_error_color(text, 2, error) pass try: trade_gui.THSGuiTrade.checkEnv() text.insert(END, "交易环境检测通过!\n") except Exception as e: error = "交易环境异常-{}...\n".format(str(e)) text.insert(END, error) _set_error_color(text, 3, error) pass jurjin_win = 0 hWndList = [] win32gui.EnumWindows(lambda hWnd, param: param.append(hWnd), hWndList) for hwnd in hWndList: title = win32gui.GetWindowText(hwnd) if title.find("掘金") > -1: print(title) jurjin_win = hwnd break if jurjin_win > 0: text.insert(END, "交易环境-掘金客户端已开启!\n") else: error = "交易环境异常-掘金客户端未开启\n" text.insert(END, error) _set_error_color(text, 4, error) text.tag_config('error', foreground='red') # 设置掘金信息 width = 300 height = 150 frame = Frame(root, {"height": height, "width": width, "bg": "#DDDDDD"}) text = Text(frame, height=100, undo=True) text.place(x=0, y=40) btn = FlatButton(frame, text="运行环境检测", command=click) btn.place(x=5, y=5) frame.grid(row=1, column=2) # 绘制开盘前的数据准备情况 def __draw_pre_data_check(self, frame): def refresh_close_price_data(): redis = redis_manager.RedisManager(0).getRedis() count = len(redis.keys("price-pre-*")) sv_num.set("获取到收盘价数量:{}".format(count)) def re_get_close_price(): juejin.re_set_price_pres(gpcode_manager.get_gp_list()) def get_limit_up_codes_win(): width = 500 height = 800 win = Tk() win.title("今日涨停") win.resizable(height=False, width=False) limit_up_datas = {} limit_up_datas["row{}".format(0)] = {'代码': '', '首次涨停时间': '', '现价': '', '涨幅': '', '涨停封单额': ''} cl = Label(win, text="更新时间:", bg="#DDDDDD", fg="#666666") cl.place(x=10, y=10) limit_up_datas_time = StringVar(value="未知") cl = Label(win, textvariable=limit_up_datas_time, bg="#DDDDDD", fg="#666666") cl.place(x=100, y=10) table_height = height - 100 table_width = width - 20 table_frame = Frame(win, {"height": table_height, "width": table_width, "bg": "#DDDDDD"}) table_frame.place(x=10, y=45) table_limit_up = tkintertable.TableCanvas(table_frame, data=limit_up_datas, read_only=True, width=table_width, height=table_height, thefont=('微软雅黑', 10), cellwidth=90, rowheaderwidth=20) table_limit_up.show() # 获取数据 time_str, datas = gpcode_manager.get_limit_up_list() limit_up_datas_time.set(time_str) # 删除所有的行 # table_limit_up.model.deleteRows() # 增加数据 index = 0 for data in datas: data = json.loads(data) table_limit_up.model.addRow() table_limit_up.model.setValueAt(data["code"], index, 0) table_limit_up.model.setValueAt(data["time"], index, 1) table_limit_up.model.setValueAt(float(data["price"]), index, 2) table_limit_up.model.setValueAt(float(data["limitUpPercent"]), index, 3) table_limit_up.model.setValueAt( "{}{}".format(float(data["limitMoney"]), ("亿" if data["limitMoneyUnit"] == 0 else "万")), index, 4) index += 1 table_limit_up.redraw() win.geometry("{}x{}".format(width, height)) win.mainloop() # 绘制代码交易窗口分配 def refresh_trade_buy_win_data(): code_wins = trade_gui.THSBuyWinManagerNew.get_distributed_code_wins() # 获取代码涨幅 codeActualPriceProcessor = trade_data_manager.CodeActualPriceProcessor() datas = [] for data in code_wins: rate = codeActualPriceProcessor.get_current_rate(data[0]) datas.append((data[0], rate, data[1])) datas.sort(key=lambda tup: tup[1] if tup[1] is not None else 1) datas.reverse() index = 0 table.model.deleteRows() for data in datas: table.model.addRow() table.model.setValueAt(data[0], index, 0) table.model.setValueAt(f"{data[1]}%", index, 1) table.model.setValueAt(data[2], index, 2) # table.model.setValueAt(data["apply_time"], index, 2) index += 1 table.redraw() # 刷新开盘啦数据 def refresh_kpl_data(): kpl_data_manager.KPLDataManager().get_data(kpl_util.KPLDataType.LIMIT_UP) kpl_data_manager.KPLDataManager().get_data(kpl_util.KPLDataType.OPEN_LIMIT_UP) kpl_data_manager.KPLDataManager().get_data(kpl_util.KPLDataType.BEST_FENG_KOU) kpl_data_manager.KPLDataManager().get_data(kpl_util.KPLDataType.FENG_KOU) kpl_data_manager.KPLDataManager().get_data(kpl_util.KPLDataType.FENG_XIANG) start_y = 225 btn = FlatButton(frame, text="刷新收盘价", command=refresh_close_price_data) btn.place(x=5, y=start_y) sv_num = StringVar(value="获取到收盘价数量:未知") cl = Label(frame, textvariable=sv_num, bg="#DDDDDD", fg="#666666") cl.place(x=5, y=start_y + 30) btn = FlatButton(frame, text="重新获取收盘价", command=re_get_close_price) btn.place(x=80, y=start_y) kpl_data = Label(text="涨停:\n炸板:\n最强:\n风向:\n风口:",bg="#DDDDDD",fg="#666666") kpl_data.place(x=190, y=start_y) trade_win_datas = [] # draw_trade_buy_win(360, 140) table_width = 300 table_height = 95 _frame = Frame(frame, {"height": table_height, "width": table_width, "bg": "#DDDDDD"}) table = tkintertable.TableCanvas(_frame, data={"row0": {'代码': '', '涨幅': '', '窗口句柄': ''}}, read_only=True, width=table_width, height=table_height, thefont=('微软雅黑', 9), cellwidth=100, rowheaderwidth=20) table.show() _frame.place(x=450, y=start_y) refresh_trade_buy_win_data() refresh_close_price_data() btn = FlatButton(frame, text="刷新", command=refresh_trade_buy_win_data) btn.place(x=450 - 35, y=start_y) def re_distribute_buy_win(): try: if tool.trade_time_sub(tool.get_now_time_str(), "09:30:00") > 0: raise Exception("只能9:30之前重新分配窗口") datas = JueJinManager.get_codes_limit_rate(gpcode_manager.get_gp_list()) matrix = numpy.array(datas) codes = matrix[:, 0].tolist() trade_gui.re_distribute_buy_win(codes) refresh_trade_buy_win_data() showinfo("提示", "分配完成") except Exception as e: showerror("分配出错", str(e)) btn = FlatButton(frame, text="重新分配窗口", command=re_distribute_buy_win) btn.place(x=450 - 83, y=start_y + 30) # 绘制交易状态 def __draw_trade_state(self, frame): def refresh_data(): normal = True if l2_code_operate.L2CodeOperate.is_read_queue_valid(): cl_queue.configure(text="正常", foreground="#008000") else: cl_queue.configure(text="异常", foreground="#FF7F27") normal = False try: trade_gui.THSGuiTrade.checkEnv() cancel_win_num = trade_gui.THSGuiTrade.getCancelBuyWins() cl_win.configure(text=f"正常({len(cancel_win_num)})", foreground="#008000") except Exception as e: normal = False cl_win.configure(text="异常:{}".format(str(e)), foreground="#FF7F27") try: juejin_length = JueJinManager.get_listen_codes_lenth() codes_length = len(gpcode_manager.get_gp_list()) cl_codes.configure(text="{}/{}".format(juejin_length, codes_length), foreground="#008000") except Exception as e: pass # 获取板块状态 try: ths_dead = client_manager.getTHSState(7) if ths_dead is None: cl_block.configure(text="离线", foreground="#FF7F27") elif ths_dead: normal = False cl_block.configure(text="离线", foreground="#FF7F27") else: cl_block.configure(text="在线", foreground="#008000") except: pass try: codes = self.thsBuy1VolumnManager.get_current_codes() count = 0 if codes: count = len(codes) if count < 1: normal = False cl_buy_1.configure(text="{}".format(count), foreground="#FF7F27") else: cl_buy_1.configure(text="{}".format(count), foreground="#008000") except: pass try: count = self.codeActualPriceProcessor.get_current_price_codes_count() if count is None or int(count) < 1: normal = False cl_price_count.configure( text="{}".format(count), foreground="#FF7F27") else: cl_price_count.configure( text="{}".format(count), foreground="#008000") except: pass # 获取有效的L2客户端数量 l2_client_count = client_manager.getValidL2Clients() if len(l2_client_count) < 6: normal = False # 状态有问题,需要报警 if not normal: alert_util.alarm() def update_data(): while True: # 刷新数据 try: if auo_refresh.get() > 0: refresh_data() except: pass time.sleep(2) start_y = 285 btn = FlatButton(frame, text="刷新状态", command=refresh_data) btn.place(x=10, y=start_y) auo_refresh = IntVar() ch1 = Checkbutton(frame, text='自动刷新', variable=auo_refresh, onvalue=1, offvalue=0, background="#DDDDDD", activebackground="#DDDDDD") # 默认自动刷新 auo_refresh.set(1) ch1.place(x=100, y=start_y) y_ = start_y + 30 cl = Label(frame, text="操作队列状态:", bg="#DDDDDD") cl.place(x=10, y=y_) cl_queue = Label(frame, text="未知", bg="#DDDDDD") cl_queue.place(x=100, y=y_) cl = Label(frame, text="交易窗口状态:", bg="#DDDDDD") cl.place(x=170, y=y_) cl_win = Label(frame, text="未知", bg="#DDDDDD") cl_win.place(x=270, y=y_) cl = Label(frame, text="板块状态:", bg="#DDDDDD") cl.place(x=320, y=y_) cl_block = Label(frame, text="未知", bg="#DDDDDD") cl_block.place(x=380, y=y_) cl = Label(frame, text="掘金代码回调数量:", bg="#DDDDDD") cl.place(x=300, y=y_ + 20) cl_codes = Label(frame, text="未知", bg="#DDDDDD") cl_codes.place(x=410, y=y_ + 20) cl = Label(frame, text="买1代码数量:", bg="#DDDDDD") cl.place(x=10, y=y_ + 20) cl_buy_1 = Label(frame, text="未知", bg="#DDDDDD") cl_buy_1.place(x=10 + 90, y=y_ + 20) cl = Label(frame, text="现价代码数量:", bg="#DDDDDD") cl.place(x=170, y=y_ + 20) cl_price_count = Label(frame, text="未知", bg="#DDDDDD") cl_price_count.place(x=170 + 100, y=y_ + 20) refresh_data() # 添加更新线程 t1 = threading.Thread(target=lambda: update_data()) # 后台运行 t1.setDaemon(True) t1.start() # 绘制l2数据状态 def __draw_l2_state(self, root): def update_data(): while True: # 刷新数据 try: if auo_refresh.get() > 0: refresh_data() except: pass time.sleep(1) def refresh_data(): for client_id in code_sv_map: ip = client_manager.getActiveClientIP(client_id) ths_dead = client_manager.getTHSState(client_id) if ip is not None and len(ip) > 0: if ths_dead: client_state[client_id].configure(text="(在线:{})".format(ip), foreground="#FF7F27") else: client_state[client_id].configure(text="(在线:{})".format(ip), foreground="#008000") else: client_state[client_id].configure(text="(离线:未知IP)", foreground="#999999") for i in range(0, constant.L2_CODE_COUNT_PER_DEVICE): code = gpcode_manager.get_listen_code_by_pos(client_id, i) data_count = l2_data_util.get_l2_latest_data_number(code) if data_count is None: data_count = 0 if code is not None and len(code) > 0: code_sv_map[client_id][i].set(code + "({})".format(data_count)) else: code_sv_map[client_id][i].set("") if data_count > 0: code_labels[client_id][i].configure(foreground="#FF0000") else: code_labels[client_id][i].configure(foreground="#999999") def check(client): msg_list = [] try: result = get_client_env_state(client) if result["ths_l2_win"]: msg_list.append(("同花顺L2屏正常!", 0)) else: msg_list.append(("同花顺L2屏未打开...", 1)) if result["ths_fp_1"]: msg_list.append(("同花顺副屏1正常!", 0)) else: msg_list.append(("同花顺副屏1未打开...", 1)) if result["ths_fp_2"]: msg_list.append(("同花顺副屏2正常!", 0)) else: msg_list.append(("同花顺副屏2未打开...", 1)) if result["ths_trade_success"]: msg_list.append(("交易成功页面正常!", 0)) else: msg_list.append(("交易成功页面未打开...", 1)) if result["l2_channel_invalid_count"] <= 0: msg_list.append(("L2监控线程正常数:{} 异常数:{}...".format(result["l2_channel_valid_count"], result["l2_channel_invalid_count"]), 0)) else: msg_list.append(("L2监控线程正常数:{} 异常数:{}!".format(result["l2_channel_valid_count"], result["l2_channel_invalid_count"]), 1)) if result["limitUp"]: msg_list.append(("涨停监控线程正常!", 0)) else: msg_list.append(("涨停监控线程异常...", 1)) if result["tradeSuccess"]: msg_list.append(("当日成交监控线程正常!", 0)) else: msg_list.append(("当日成交监控线程异常...", 1)) except Exception as e: msg_list.append((str(e), 1)) def repair(): try: server.repair_client_env(client) showinfo("提示", "修复完成") except Exception as e: showerror("修复出错", str(e)) # 创建界面 win = Tk() win.title("检测结果") win.resizable(height=False, width=False) text = Text(win, height=100, undo=True) text.place(x=0, y=30) btn = FlatButton(win, text="一键修复", command=repair) btn.place(x=0, y=0) line = 0 for msg in msg_list: line += 1 if msg[1] == 0: text.insert(END, "{}\n".format(msg[0])) else: text.insert(END, "{}\n".format(msg[0])) for i in range(0, len(msg[0])): text.tag_add('error', "{}.{}".format(line, i)) text.tag_config('error', foreground='red') win.geometry("300x300") win.mainloop() def init(): juejin.everyday_init() def set_accept_l2(): settings.set_accept_l2(accept_l2.get()) def pop_menu(event): self.selected_client = event.widget["command"] menu.post(event.x_root, event.y_root) def ths_test_speed(): if self.selected_client is None: showwarning("警告", "未选中客户端") return try: server.repair_ths_main_site(self.selected_client) showinfo("提示", "同花顺测速完成") except Exception as e: showerror("错误", str(e)) def check_env(): if self.selected_client is None: showwarning("警告", "未选中客户端") return check(self.selected_client) width = 800 height = 360 frame = Frame(root, {"height": height, "width": width, "bg": "#DDDDDD"}) trade_info= "" for_color = "#008000" if constant.TEST: trade_info += "测试环境" for_color = "#FF7F27" else: trade_info += "正式环境" trade_info += " " if constant.TRADE_ENABLE: trade_info += "初始允许交易" else: trade_info += "初始禁止交易" for_color = "#FF7F27" cl = Label(frame, text=f"{trade_info}", bg="#DDDDDD",foreground=f"{for_color}") cl.place(x=5, y=5) accept_l2 = IntVar() ch_accept_l2 = Checkbutton(frame, text='接受l2数据', variable=accept_l2, onvalue=1, offvalue=0, background="#DDDDDD", activebackground="#DDDDDD", command=set_accept_l2) ch_accept_l2.place(x=width - 350, y=5) if settings.is_accept_l2_data(): accept_l2.set(1) else: accept_l2.set(0) btn = FlatButton(frame, text="每日初始化", command=init) btn.place(x=width - 250, y=5) btn = FlatButton(frame, text="刷新数据", command=refresh_data) btn.place(x=width - 150, y=5) auo_refresh = IntVar() ch1 = Checkbutton(frame, text='自动刷新', variable=auo_refresh, onvalue=1, offvalue=0, background="#DDDDDD", activebackground="#DDDDDD") ch1.place(x=width - 80, y=5) auo_refresh.set(1) l2_client_count = 0 code_sv_map = {} code_labels = {} client_state = {} # 右键菜单 menu = Menu(frame, tearoff=False, # bg="black", ) menu.add_command(label="环境检测", command=check_env) menu.add_command(label="同花顺测速", command=ths_test_speed) device_index =0 for key in self.l2_codes: device_index += 1 client_lb = Label(frame, text="设备:{} ID:{}".format(device_index,key), background="#DDDDDD") client_lb.place(x=38, y=40 + l2_client_count * 30) btn = FlatButton(frame, text="检测", command=key) btn.bind('', lambda event: pop_menu(event)) btn.place(x=5, y=35 + l2_client_count * 30) client_state_lb = Label(frame, text="(未知)", padx=0, pady=0, background="#DDDDDD", font=('微软雅黑', 8)) client_state_lb.place(x=112, y=40 + l2_client_count * 30) client_state[key] = client_state_lb code_sv_map[key] = [] code_labels[key] = [] for i in range(0, constant.L2_CODE_COUNT_PER_DEVICE): sv = StringVar(value=self.l2_codes[key][i]) code_sv_map[key].append(sv) cframe = Frame(frame, {"height": 23, "width": 80, "bg": "#FFFFFF"}) code_label = Label(cframe, textvariable=sv, background="#FFFFFF", foreground="#FF0000") code_labels[key].append(code_label) code_label.place(x=0, y=0) cframe.place(x=250 + i * 85, y=40 + l2_client_count * 30) l2_client_count += 1 # 添加更新线程 t1 = threading.Thread(target=lambda: update_data()) # 后台运行 t1.setDaemon(True) t1.start() refresh_data() self.__draw_pre_data_check(frame) frame.grid(row=0, column=1, padx=5, pady=5, rowspan=2) # 绘制交易数据 def __draw_trade_data(self, root): def auto_refresh(): while True: if auo_refresh.get() > 0: refresh_data() time.sleep(1) def refresh_data(): money = trade_manager.get_available_money() if money is not None: sv_trade_money.set(money) else: sv_trade_money.set("未知") # 获取委托数据 datas, time_str = trade_manager.get_trade_delegate_data() # 删除所有的行 table_delegate.model.deleteRows() delegate_datas_time.set(time_str) # 增加数据 index = 0 for data in datas: table_delegate.model.addRow() table_delegate.model.setValueAt(data["time"], index, 0) table_delegate.model.setValueAt(data["code"], index, 1) table_delegate.model.setValueAt(data["apply_time"], index, 2) table_delegate.model.setValueAt(data["num"], index, 3) table_delegate.model.setValueAt(data.get("price"), index, 4) table_delegate.model.setValueAt(data.get("trade_price"), index, 5) table_delegate.model.setValueAt(data.get("trade_num"), index, 6) if int(data["type"]) > 0: table_delegate.model.setValueAt("卖出", index, 7) else: table_delegate.model.setValueAt("买入", index, 7) index += 1 table_delegate.redraw() # 获取所有的数据 datas, time_str = trade_manager.get_trade_success_data() trade_datas_time.set(time_str) # 删除所有的行 table_trade.model.deleteRows() # 增加数据 index = 0 for data in datas: table_trade.model.addRow() table_trade.model.setValueAt(data["code"], index, 0) table_trade.model.setValueAt(data["time"], index, 1) table_trade.model.setValueAt(data["num"], index, 2) table_trade.model.setValueAt(data["price"], index, 3) table_trade.model.setValueAt(data["money"], index, 4) table_trade.model.setValueAt(data["trade_num"], index, 5) if int(data["type"]) > 0: table_trade.model.setValueAt("卖出", index, 6) else: table_trade.model.setValueAt("买入", index, 6) index += 1 table_trade.redraw() pass def create_table(_frame, data, cell_width=75): table = tkintertable.TableCanvas(_frame, data=data, read_only=True, width=table_width, height=table_height, thefont=('微软雅黑', 10), cellwidth=cell_width, rowheaderwidth=20) return table # 设置掘金信息 width = 800 height = 280 frame = Frame(root, {"height": height, "width": width, "bg": "#DDDDDD"}) cl = Label(frame, text="交易数据", bg="#DDDDDD") cl.place(x=5, y=5) # ------表头开始------ # 获取交易账户可用金额 cl = Label(frame, text="交易账户可用资金:", bg="#DDDDDD", fg="#666666") cl.place(x=80, y=5) sv_trade_money = StringVar(value="未知") cl = Label(frame, textvariable=sv_trade_money, bg="#DDDDDD", fg="#666666") cl.place(x=190, y=5) btn = FlatButton(frame, text="刷新数据", command=refresh_data) btn.place(x=width - 150, y=5) auo_refresh = IntVar() ch1 = Checkbutton(frame, text='自动刷新', variable=auo_refresh, onvalue=1, offvalue=0, background="#DDDDDD", activebackground="#DDDDDD") ch1.place(x=width - 80, y=5) auo_refresh.set(1) # ------表头结束------ # 委托表格 cl = Label(frame, text="今日委托:", bg="#DDDDDD", fg="#666666") cl.place(x=5, y=30) delegate_datas = {} delegate_datas["row{}".format(0)] = {'委托时间': '', '代码': '', '申报时间': '', '委托数量': '', '委托价格': '', '成交均价': '', '成交数量': '', '操作': ''} cl = Label(frame, text="更新时间:", bg="#DDDDDD", fg="#666666") cl.place(x=width / 2 - 130, y=30) delegate_datas_time = StringVar(value="未知") cl = Label(frame, textvariable=delegate_datas_time, bg="#DDDDDD", fg="#666666") cl.place(x=width / 2 - 70, y=30) table_height = 180 table_width = width / 2 - 50 table_frame = Frame(frame, {"height": table_height, "width": table_width, "bg": "#DDDDDD"}) table_frame.place(x=5, y=52) table_delegate = create_table(table_frame, data=delegate_datas) table_delegate.show() # 成交表格 cl = Label(frame, text="今日成交:", bg="#DDDDDD", fg="#666666") cl.place(x=width / 2, y=30) cl = Label(frame, text="更新时间:", bg="#DDDDDD", fg="#666666") cl.place(x=width - 130, y=30) trade_datas_time = StringVar(value="10:00:00") cl = Label(frame, textvariable=trade_datas_time, bg="#DDDDDD", fg="#666666") cl.place(x=width - 70, y=30) trade_datas = {} trade_datas["row{}".format(0)] = {'证券代码': '', '成交时间': '', '成交数量': '', '成交均价': '', '成交金额': '', '合同编号': '', '操作': ''} table_frame = Frame(frame, {"height": table_height, "width": table_width, "bg": "#DDDDDD"}) table_frame.place(x=width / 2, y=52) table_trade = create_table(table_frame, trade_datas, 90) table_trade.show() frame.grid(row=2, column=1, padx=5, pady=5, rowspan=2) # 添加更新线程 t1 = threading.Thread(target=lambda: auto_refresh()) # 后台运行 t1.setDaemon(True) t1.start() def __draw_juejin(self, root): def click(): account = account_var.get() sid = sid_var.get() token = token_var.get() if len(account.strip()) < 1 or len(sid.strip()) < 1 or len(token.strip()) < 1: showinfo('提示', "数据不完整") return juejin.setAccountInfo(account, sid, token) showinfo('提示', "设置成功") # 设置掘金信息 frame = Frame(root, {"height": 150, "width": 300, "bg": "#DDDDDD"}) left = 10 top = 10 cl = Label(frame, text="账号ID:", bg="#DDDDDD") cl.place(x=left, y=top) account_var = StringVar(value="1233") entry = Entry(frame, textvariable=account_var, width=30) entry.place(x=left + 60, y=top) cl = Label(frame, text="策略ID:", bg="#DDDDDD") cl.place(x=left, y=top + 30) sid_var = StringVar(value="1233") entry = Entry(frame, textvariable=sid_var, width=30) entry.place(x=left + 60, y=top + 30) token_var = StringVar(value="1233") cl = Label(frame, text="Token:", bg="#DDDDDD") cl.place(x=left, y=top + 60) entry = Entry(frame, textvariable=token_var, width=30) entry.place(x=left + 60, y=top + 60) btn = FlatButton(frame, text="设置掘金参数", command=click) btn.place(x=left + 60, y=top + 90) # frame.place(x=260,y=10) frame.grid(row=0, column=2, pady=5, padx=5) # 设置参数 account, sid, token = juejin.getAccountInfo() account_var.set(account) sid_var.set(sid) token_var.set(token) def __draw_test(self, root): def startJueJinGui(): if self.jueJinProcess.is_alive(): print("已经启动") else: self.jueJinProcess.start() def setGPCode(client, position, gpcode): if client is None or len(client) < 1: return if position is None or len(position) < 1: return if gpcode is None or len(gpcode) < 6: return l2_code_operate.L2CodeOperate.setGPCode(client, position, gpcode) def resub(): self.p1.send("resub") def refresh_hwnds(): try: trade_gui.THSGuiTrade.checkEnv() trade_gui.THSGuiTrade().refresh_hwnds() showinfo('提示', "刷新成功") except Exception as e: print(e) showwarning('警告', e) def export_l2_data(code): if code not in l2.l2_data_util.local_today_datas: l2.l2_data_util.load_l2_data(code) datas = l2.l2_data_util.local_today_datas[code] try: path = data_export_util.export_l2_data(code, datas) showinfo("提示", "导出成功,路径为:" + path) except Exception as e1: showerror("导出失败", str(e1)) def export_l2_data_origin(code): redis = redis_manager.RedisManager(1).getRedis() keys = redis.keys("big_data-{}-*".format(code)) try: for k in keys: datas = redis.get(k) datas = json.loads(datas) _t = k.split("-")[2] k = time.strftime("%Y_%m_%d_%H_%M_%S_", time.localtime(float(_t) / 1000)) k = "{}{}".format(k, _t[-3:]) data_export_util.export_l2_data_origin(code, datas, k) except Exception as e1: showerror("导出失败", str(e1)) showinfo("提示", "导出完成") def compute_m(code): m, msg = L2TradeFactorUtil.compute_m_value(code) showinfo("提示", "{}".format(m)) def clear_l2(code): self.gs_gui_pipe.send(json.dumps({"type": "clear_l2", "data": {"code": code}})) pass # 禁止代码 def cancel_order(code_): try: l2.l2_data_util.load_l2_data(code_, True) l2_data_manager_new.L2TradeDataProcessor.cancel_buy(code_, "手动撤销") showinfo("提示", "撤单成功") except Exception as e: showwarning("提示", "撤单成功异常" + str(e)) frame = Frame(root, {"height": 280, "width": 300, "bg": "#DDDDDD"}) frame.grid(row=2, column=2, rowspan=2, pady=5) btntext = StringVar() el = Label(frame, text="测试区域", bg="#DDDDDD", fg="#A0A000") el.place(x=240, y=10) el = Label(frame, text="客户端ID:", bg="#DDDDDD") el.place(x=10, y=10) ep_client = Entry(frame, width=2) ep_client.place(x=70, y=10) el = Label(frame, text="位置:", bg="#DDDDDD") el.place(x=10, y=40) ep = Entry(frame, width=2) ep.place(x=50, y=40) cl = Label(frame, text="代码:", bg="#DDDDDD") cl.place(x=10, y=70) code = Entry(frame) code.place(x=50, y=70) btn = FlatButton(frame, text="设置代码", command=lambda: setGPCode(ep_client.get(), ep.get(), code.get()), ) btn.place(x=10, y=100) btn = FlatButton(frame, text="修复L2数据", command=lambda: L2CodeOperate.get_instance().repaire_l2_data(code.get())) btn.place(x=70 , y=100) btn = FlatButton(frame, text="导出L2数据", command=lambda: export_l2_data(code.get())) btn.place(x=145, y=100) btn = FlatButton(frame, text="导出L2原始数据", command=lambda: export_l2_data_origin(code.get())) btn.place(x=220, y=100) btn = FlatButton(frame, text="获取m值", command=lambda: compute_m(code.get())) btn.place(x=10, y=130) btn = FlatButton(frame, text="导出交易日志", command=lambda: log.export_l2_log(code.get())) btn.place(x=80, y=130) btn = FlatButton(frame, text="清空l2数据", command=lambda: clear_l2(code.get())) btn.place(x=150, y=130) btn = FlatButton(frame, text="撤销挂单", command=lambda: cancel_order(code.get())) btn.place(x=230, y=130) # 交易按钮 btn = FlatButton(frame, textvariable=btntext, command=startJueJinGui) btn.place(x=10, y=160) btntext.set("启动掘金") btn = FlatButton(frame, text="重新订阅行情", command=resub) btn.place(x=10, y=190) btn = FlatButton(frame, text="刷新窗口句柄", command=refresh_hwnds) btn.place(x=200, y=190) def create_gui(self): root = Tk() root.title("自动化交易系统") root.resizable(height=False, width=False) self.__draw_juejin(root) self._draw_check(root) self.__draw_l2_state(root) self.__draw_trade_state(root) self.__draw_trade_data(root) self.__draw_test(root) root.geometry("1120x660") root.mainloop() if __name__ == '__main__': listen = gpcode_manager.is_listen("000333") print(listen) # 启动掘金任务 GUI().run()