import threading import time import wx import local_api from local_api.limit_up_manager import KPLLimitUpDataManager from local_api.log_module import log_export from local_api.util import tool APP_TITLE = "低吸" class MainFrame(wx.Frame): mark_lines = {} def __init__(self): """ 初始化函数 """ wx.Frame.__init__(self, None, -1, APP_TITLE, style=wx.DEFAULT_FRAME_STYLE, size=(800, 500)) self.__init_view() self.__init_data() def __init_view(self): root_sizer = wx.BoxSizer(wx.HORIZONTAL) left_sizer = wx.BoxSizer(wx.VERTICAL) right_sizer = wx.BoxSizer(wx.VERTICAL) root_sizer.Add(left_sizer, 1, wx.EXPAND | wx.TOP | wx.LEFT | wx.BOTTOM, 5) root_sizer.Add(right_sizer, 0, wx.EXPAND | wx.ALL, 5) self.SetSizer(root_sizer) self.system_log_ctrl = wx.TextCtrl(self, size=wx.Size(250, -1), style=wx.TE_MULTILINE | wx.TE_READONLY) self.system_log_ctrl.AppendText("---系统日志区域---") right_sizer.Add(self.system_log_ctrl, 1) self.trade_log_ctrl = wx.TextCtrl(self, size=wx.Size(250, -1), style=wx.TE_MULTILINE | wx.TE_READONLY) self.trade_log_ctrl.AppendText("---交易日志区域---") right_sizer.Add(self.trade_log_ctrl, 1) self.main_panel = wx.Panel(self, size=wx.Size(-1, -1)) self.main_panel.SetBackgroundColour(wx.Colour(255, 255, 255)) left_sizer.Add(self.main_panel, 1, wx.EXPAND | wx.TOP | wx.LEFT | wx.BOTTOM, 5) self.SetBackgroundColour(wx.Colour(225, 225, 225)) # -------添加操作按钮-------- panel_sizer = wx.BoxSizer(wx.VERTICAL) # 板块与涨停代码数量 sizer = wx.BoxSizer(wx.HORIZONTAL) self.btn_request_blocks = wx.Button(self.main_panel, 101, "刷新板块") sizer.Add(self.btn_request_blocks, 0, wx.TOP | wx.LEFT, 5) self.label_block_info = wx.StaticText(self.main_panel) sizer.Add(self.label_block_info, 0, wx.TOP | wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5) panel_sizer.Add(sizer) sizer = wx.BoxSizer(wx.HORIZONTAL) self.btn_repaire_limit_up_task = wx.Button(self.main_panel, 102, "修复涨停") sizer.Add(self.btn_repaire_limit_up_task, 0, wx.TOP | wx.LEFT, 5) self.label_limit_up_info = wx.StaticText(self.main_panel, size=wx.Size(100, -1)) sizer.Add(self.label_limit_up_info, 0, wx.TOP | wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 5) self.label_limit_up_info.SetLabelText("涨停列表更新:") panel_sizer.Add(sizer) self.list_ctrl_position = wx.ListCtrl(self.main_panel, style=wx.LC_REPORT, size=wx.Size(-1, 300)) panel_sizer.Add(wx.StaticText(self.main_panel, label="持仓:"), 0, wx.LEFT | wx.TOP, 5) panel_sizer.Add(self.list_ctrl_position, 0, wx.EXPAND | wx.ALL, 5) # (p["symbol"], p["amount"], p["volume"], p["available"], p["cost"], p["price"],) self.list_ctrl_position.InsertColumn(0, "代码") self.list_ctrl_position.InsertColumn(1, "持仓金额") self.list_ctrl_position.InsertColumn(2, "持仓数量") self.list_ctrl_position.InsertColumn(3, "可用数量") self.list_ctrl_position.InsertColumn(4, "持仓成本") self.list_ctrl_position.InsertColumn(5, "现价") self.main_panel.SetSizer(panel_sizer) # 卖出面板 sell_panel = wx.Panel(self.main_panel, size=wx.Size(-1, 50)) sell_pannel_sizer = wx.BoxSizer(wx.HORIZONTAL) sell_panel.SetSizer(sell_pannel_sizer) sizer1 = wx.BoxSizer(wx.VERTICAL) sizer1.Add(wx.StaticText(sell_panel, label="代码:")) self.label_sell_code = wx.StaticText(sell_panel, label="000000", size=wx.Size(100, -1)) sizer1.Add(self.label_sell_code) sell_pannel_sizer.Add(sizer1) sizer1 = wx.BoxSizer(wx.VERTICAL) sizer1.Add(wx.StaticText(sell_panel, label="可用持仓:")) self.label_sell_avaiable_volume = wx.StaticText(sell_panel, label="0", size=wx.Size(70, -1)) sizer1.Add(self.label_sell_avaiable_volume) sell_pannel_sizer.Add(sizer1) sizer1 = wx.BoxSizer(wx.VERTICAL) sizer1.Add(wx.StaticText(sell_panel, label="卖出量:")) self.edit_sell_volume = wx.TextCtrl(sell_panel, size=wx.Size(70, -1)) sizer1.Add(self.edit_sell_volume) sell_pannel_sizer.Add(sizer1) sizer1 = wx.BoxSizer(wx.HORIZONTAL) self.btn_sell = wx.Button(sell_panel, label="卖出", size=wx.Size(50, 30)) sizer1.Add(wx.StaticText(sell_panel), 1) sizer1.Add(self.btn_sell, 0, wx.ALIGN_CENTER_VERTICAL, 0) sell_pannel_sizer.Add(sizer1, 1, wx.EXPAND) panel_sizer.Add(sell_panel, 0, wx.ALL | wx.EXPAND, 5) self.btn_request_blocks.Bind(wx.EVT_BUTTON, self.__refresh_blocks) self.btn_repaire_limit_up_task.Bind(wx.EVT_BUTTON, self.__repaire_limit_up_task) self.btn_sell.Bind(wx.EVT_BUTTON, self.__sell) on_item_selected = lambda event: self.__show_sell_data(event.GetIndex()) self.list_ctrl_position.Bind(wx.EVT_LIST_ITEM_SELECTED, on_item_selected) self.__start_task() def __show_sell_data(self, index): if index < 0: return self.label_sell_code.SetLabel(self.positions[index][0]) self.label_sell_avaiable_volume.SetLabel(str(self.positions[index][3])) self.edit_sell_volume.SetValue(str(self.positions[index][3])) def __refresh_blocks(self, event): def update_blocks(): local_api.update_blocks() wx.CallAfter(lambda: self.btn_request_blocks.SetLabel("刷新板块")) self.btn_request_blocks.SetLabel("刷新板块...") threading.Thread(target=update_blocks, daemon=True).start() def __repaire_limit_up_task(self, event): KPLLimitUpDataManager().repaire_task() wx.MessageBox("修复成功") def __sell(self, event): volume = self.edit_sell_volume.GetValue() if not volume.isdigit(): wx.MessageBox("量输入错误") return print("卖出量:", volume) symbol = self.label_sell_code.GetLabel() code = symbol.split(".")[1] tick = local_api.latest_tick_dict.get(code) # 收盘价,现价 if tick: price, pre_price = tick[2],tick[1] price = tool.get_buy_min_price(price) result = local_api.trade_api.sell(code,int(volume),price) print("卖出结果:", result) else: wx.MessageBox("没有获取到tick数据") def __start_task(self): def __show_blocks(): while True: try: today_count, before_count = local_api.get_blocks_count_info() st = f"有板块代码数: 今日-{today_count} 昨日-{before_count}" wx.CallAfter(lambda: self.label_block_info.SetLabelText(st)) except: pass finally: time.sleep(1) def __show_limit_up_list_info(): while True: try: info = KPLLimitUpDataManager().get_current_limitup_info() if info is None: st = f"涨停列表:尚未更新" else: st = f"涨停列表:{info[0]}-{len(info[1])}个" wx.CallAfter(lambda: self.label_limit_up_info.SetLabelText(st)) except: pass finally: time.sleep(1) def __get_positions(): def __show_positions(datas): self.positions = datas # self.list_ctrl_position self.list_ctrl_position.DeleteAllItems() for data in datas: code = data[0].split(".")[1] index = self.list_ctrl_position.InsertItem(self.list_ctrl_position.GetItemCount(), data[0]) self.list_ctrl_position.SetItem(index, 1, str(round(data[1], 2))) self.list_ctrl_position.SetItem(index, 2, str(data[2])) self.list_ctrl_position.SetItem(index, 3, str(data[3])) self.list_ctrl_position.SetItem(index, 4, str(round(data[4], 2))) tick = local_api.latest_tick_dict.get(code) if tick: self.list_ctrl_position.SetItem(index, 5, str(tick[2])) else: self.list_ctrl_position.SetItem(index, 5, str(data[5])) while True: try: positions = local_api.trade_api.positions(blocking=True) print("持仓:", positions) wx.CallAfter(lambda: __show_positions( [(p["symbol"], p["amount"], p["volume"], p["available_now"], p["cost"], p["price"],) for p in positions])) # wx.CallAfter(lambda: self.label_limit_up_info.SetLabelText(st)) except: pass finally: time.sleep(3) """ 开始任务 :return: """ threading.Thread(target=__show_blocks, daemon=True).start() threading.Thread(target=__show_limit_up_list_info, daemon=True).start() threading.Thread(target=__get_positions, daemon=True).start() def __init_data(self): logs = log_export.load_system_logs() self.system_log_ctrl.Clear() for l in logs: self.system_log_ctrl.AppendText(f"{l[0]} - {l[1]}\n") logs = log_export.load_trade_logs() self.trade_log_ctrl.Clear() for l in logs: self.trade_log_ctrl.AppendText(f"{l[0]} - {l[1]}\n") class MainApp(wx.App): def __init_data(self): pass def OnInit(self): self.SetAppName("低吸") self.__init_data() self.frame = MainFrame() self.frame.Show() return True