lhr
2024-06-25 1d984faf7a3f0bfce557fa03412519fa70928f66
Merge branch 'master' of http://193.112.35.168:10101/r/gp_low_suction
3个文件已修改
1个文件已添加
224 ■■■■■ 已修改文件
gui.py 121 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
local_api/__init__.py 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
local_api/juejin.py 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
local_api/util/gui_util.py 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
gui.py
@@ -6,9 +6,26 @@
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
from local_api.util import tool, gui_util
APP_TITLE = "低吸"
__symbol_name_dict = {}
def get_symbols_names(symbols):
    request_symbols = []
    name_dict = {}
    for symbol in symbols:
        if symbol not in __symbol_name_dict:
            request_symbols.append(symbol)
        else:
            name_dict[symbol] = __symbol_name_dict.get(symbol)
    name_dict_temp = local_api.trade_api.get_symbol_names(request_symbols)
    for symbol in name_dict_temp:
        name_dict[symbol] = name_dict_temp[symbol]
    return name_dict
class MainFrame(wx.Frame):
@@ -19,7 +36,7 @@
        初始化函数
        """
        wx.Frame.__init__(self, None, -1, APP_TITLE, style=wx.DEFAULT_FRAME_STYLE,
                          size=(800, 500))
                          size=(1000, 500))
        self.__init_view()
        self.__init_data()
@@ -67,11 +84,14 @@
        # (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.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.list_ctrl_position.InsertColumn(6, "现价")
        self.list_ctrl_position.InsertColumn(7, "委卖量")
        self.list_ctrl_position.InsertColumn(8, "委卖价格")
        self.main_panel.SetSizer(panel_sizer)
        # 卖出面板
@@ -92,13 +112,22 @@
        sizer1 = wx.BoxSizer(wx.VERTICAL)
        sizer1.Add(wx.StaticText(sell_panel, label="卖出量:"))
        sizer_volume = wx.BoxSizer(wx.HORIZONTAL)
        self.edit_sell_volume = wx.TextCtrl(sell_panel, size=wx.Size(70, -1))
        sizer1.Add(self.edit_sell_volume)
        sizer_volume.Add(self.edit_sell_volume, 0, wx.RIGHT, 10)
        gui_util.GuiViewManager.create_sell_volume_percent(sizer_volume, sell_panel,
                                                           lambda x: self.edit_sell_volume.SetValue(str(int(
                                                               self.label_sell_avaiable_volume.GetLabel()) // x // 100 * 100)))
        sizer1.Add(sizer_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)
        self.btn_cancel_sell = wx.Button(sell_panel, label="撤卖", size=wx.Size(50, 30))
        sizer1.Add(self.btn_cancel_sell, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 10)
        self.btn_sell = wx.Button(sell_panel, label="卖出", size=wx.Size(50, 30))
        sizer1.Add(self.btn_sell, 0, wx.ALIGN_CENTER_VERTICAL, 0)
        sell_pannel_sizer.Add(sizer1, 1, wx.EXPAND)
@@ -113,14 +142,37 @@
        self.list_ctrl_position.Bind(wx.EVT_LIST_ITEM_SELECTED, on_item_selected)
        self.btn_cancel_sell.Bind(wx.EVT_BUTTON, lambda x: self.__cancel_order())
        # 设置快捷键
        entries = [
            # wx.AcceleratorEntry(wx.ACCEL_CTRL, ord('W'), 901),
            wx.AcceleratorEntry(wx.ACCEL_NORMAL, wx.WXK_F4, 901),
            wx.AcceleratorEntry(wx.ACCEL_NORMAL, wx.WXK_F5, 902)
        ]
        # Create an accelerator table
        accel_table = wx.AcceleratorTable(entries)
        self.SetAcceleratorTable(accel_table)
        self.Bind(wx.EVT_MENU, self.quick_sell, id=901)
        self.Bind(wx.EVT_MENU, lambda x: self.__cancel_order(), id=902)
        self.__start_task()
    def quick_sell(self, event):
        self.__sell(event)
    def __cancel_order(self):
        for symbol in self.delegates_dict:
            for d in self.delegates_dict[symbol]:
                local_api.trade_api.cancel_order(d[1], d[2], blocking=False)
    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]))
        sell_percent = gui_util.GuiViewManager.get_sell_volume_percent()
        self.edit_sell_volume.SetValue(str(self.positions[index][3] // sell_percent // 100 * 100))
    def __refresh_blocks(self, event):
        def update_blocks():
@@ -145,13 +197,12 @@
        tick = local_api.latest_tick_dict.get(code)
        # 收盘价,现价
        if tick:
            price, pre_price = tick[2],tick[1]
            price, pre_price = tick[2], tick[1]
            price = tool.get_buy_min_price(price)
            result =  local_api.trade_api.sell(code,int(volume),price)
            result = local_api.trade_api.sell(code, int(volume), price)
            print("卖出结果:", result)
        else:
            wx.MessageBox("没有获取到tick数据")
    def __start_task(self):
        def __show_blocks():
@@ -184,18 +235,28 @@
                self.positions = datas
                # self.list_ctrl_position
                self.list_ctrl_position.DeleteAllItems()
                symbols_names_dict = get_symbols_names([x[0] for x in datas])
                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)))
                    self.list_ctrl_position.SetItem(index, 1, symbols_names_dict.get(data[0]))
                    self.list_ctrl_position.SetItem(index, 2, str(round(data[1], 2)))
                    self.list_ctrl_position.SetItem(index, 3, str(data[2]))
                    self.list_ctrl_position.SetItem(index, 4, str(data[3]))
                    self.list_ctrl_position.SetItem(index, 5, 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]))
                        self.list_ctrl_position.SetItem(index, 6, str(tick[2]))
                    else:
                        self.list_ctrl_position.SetItem(index, 5, str(data[5]))
                        self.list_ctrl_position.SetItem(index, 6, str(data[5]))
                    dvolume = 0
                    if data[0] in self.delegates_dict:
                        delegates_list = self.delegates_dict[data[0]]
                        if delegates_list:
                            dvolume = sum([x[3] for x in delegates_list])
                            self.list_ctrl_position.SetItem(index, 8, f'{delegates_list[-1][4]}')
                    self.list_ctrl_position.SetItem(index, 7, f'{dvolume}')
            while True:
                try:
@@ -211,6 +272,25 @@
                finally:
                    time.sleep(3)
        def __get_delegates():
            # 获取委托
            while True:
                try:
                    delegates = local_api.trade_api.get_unfinish_orders(blocking=True)
                    delegates = [(x["symbol"], x["cl_ord_id"], x["account_id"], x["volume"], x["price"]) for x in
                                 delegates]
                    delegates_dict = {}
                    for x in delegates:
                        if x[0] not in delegates_dict:
                            delegates_dict[x[0]] = []
                        delegates_dict[x[0]].append(x)
                    self.delegates_dict = delegates_dict
                    # wx.CallAfter(lambda: self.label_limit_up_info.SetLabelText(st))
                except:
                    pass
                finally:
                    time.sleep(2)
        """
        开始任务
        :return:
@@ -219,8 +299,11 @@
        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()
        threading.Thread(target=__get_delegates, daemon=True).start()
    def __init_data(self):
        self.delegates_dict = {}
        logs = log_export.load_system_logs()
        self.system_log_ctrl.Clear()
        for l in logs:
local_api/__init__.py
@@ -127,6 +127,42 @@
            return
        return self.__read_result(commands[2], timeout=10)
    def get_unfinish_orders(self, blocking=True):
        """
        获取委托列表
        :param blocking:
        :return:
        """
        commands = ("get_unfinish_orders", {}, self.__create_request_id("get_unfinish_orders"))
        self.command_queue.put_nowait(commands)
        if not blocking:
            return
        return self.__read_result(commands[2], timeout=10)
    def cancel_order(self, local_order_id, account_id, blocking=True):
        """
        撤单
        :param local_order_id:
        :param account_id:
        :param blocking:
        :return:
        """
        commands = ("cancel_order", {"local_order_id": local_order_id, "account_id": account_id},
                    self.__create_request_id("cancel_order"))
        self.command_queue.put_nowait(commands)
        if not blocking:
            return
        return self.__read_result(commands[2], timeout=10)
    def get_symbol_names(self, symbols):
        """
        获取名称
        :param symbols:
        :return:
        """
        results = JueJinApi().get_gp_latest_info(symbols, "symbol,sec_name")
        return {x["symbol"]: x["sec_name"] for x in results}
    def start_read_results(self):
        while True:
            try:
local_api/juejin.py
@@ -54,7 +54,30 @@
        持仓查询
        :return:
        """
        return self.context.account().positions()
        try:
            return self.context.account().positions()
        except:
            return []
    def queryUnfinishOrders(self):
        """
        查询未完成委托
        :return:
        """
        try:
            return get_unfinished_orders()
        except:
            return []
    def cancelOrders(self, local_id, account_id):
        """
        撤单
        :param local_id: 本地订单ID
        :param account_id: 账号ID
        :return:
        """
        async_log_util.info(logger_trade, f"撤单:{local_id}-{account_id}")
        return order_cancel([{"cl_ord_id": local_id, "account_id": account_id}])
__JueJinTradeManager = JueJinTradeManager()
@@ -75,6 +98,7 @@
def on_execution_report(context, execrpt):
    logger_trade.info(f"on_execution_report:{execrpt}")
    logger_print.info(f"on_execution_report:{execrpt}")
def on_error(context, execrpt):
    logger_print.info(f"on_error:{execrpt}")
@@ -98,6 +122,12 @@
            elif type == 'position':
                results = __JueJinTradeManager.queryPosition()
                __send_request_response(request_id, results)
            elif type == 'get_unfinish_orders':
                results = __JueJinTradeManager.queryUnfinishOrders()
                __send_request_response(request_id, results)
            elif type == 'cancel_order':
                __JueJinTradeManager.cancelOrders(data["local_order_id"], data["account_id"])
                __send_request_response(request_id, {})
        except Exception as e:
            logger_print.exception(e)
local_api/util/gui_util.py
New file
@@ -0,0 +1,35 @@
import copy
import wx
class GuiViewManager:
    __selected_index = 1
    @classmethod
    def get_sell_volume_percent(cls):
        return cls.__selected_index
    @classmethod
    def create_sell_volume_percent(cls, sizer, parent, callback):
        def select_percent(event):
            button: wx.Button = event.GetEventObject()
            label = button.GetLabel()
            for btn in btns:
                btn.SetForegroundColour(wx.Colour(0, 0, 0))
            button.SetForegroundColour(wx.Colour(220, 0, 0))
            percent = int(label.split("/")[1])
            cls.__selected_index = percent
            callback(percent)
        btns = [wx.Button(parent, label="1/1", size=wx.Size(30, -1)),
                wx.Button(parent, label="1/2", size=wx.Size(30, -1)),
                wx.Button(parent, label="1/3", size=wx.Size(30, -1)),
                wx.Button(parent, label="1/4", size=wx.Size(30, -1))]
        for btn in btns:
            if int(btn.GetLabel().split("/")[1]) == cls.__selected_index:
                btn.SetForegroundColour(wx.Colour(220, 0, 0))
                callback(cls.__selected_index)
            sizer.Add(btn,0,wx.RIGHT, 5)
            btn.Bind(wx.EVT_BUTTON, select_percent)