admin
2023-06-08 9cacd9bb9931802d0857363e36f6f1f521801d25
华鑫日志接入
12个文件已修改
2个文件已添加
11656 ■■■■■ 已修改文件
gui_wx.py 147 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
huaxin/document.html 11031 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
huaxin/log.py 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
huaxin/test.py 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
huaxin/trade_server.py 222 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/codes_list.html 64 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/index23-05-04.html 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/js/code_list.js 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/js/http.js 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/js/page.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kpl/gui.py 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kpl/gui.spec 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
main.py 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
res/setting.conf 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
gui_wx.py
@@ -327,7 +327,7 @@
class FloatFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "悬浮盯盘", style=wx.CAPTION ^ wx.MINIMIZE_BOX ^ wx.CLOSE_BOX ^ wx.STAY_ON_TOP,
                          size=(320, 195))
                          size=(435, 200))
        self.SetBackgroundColour(wx.Colour(224, 224, 224))
        self.SetTransparent(230)
        self.Bind(wx.EVT_CLOSE, self.OnExit)
@@ -335,23 +335,33 @@
        window_info = setting.get_float_watch_window_info()
        if window_info:
            self.SetPosition(wx.Point(window_info[0], window_info[1]))
            self.Size = wx.Size(window_info[2], window_info[3])
        boxsier = wx.FlexGridSizer(5, 2, 2, 5)
            # self.Size = wx.Size(window_info[2], window_info[3])
        boxsier = wx.FlexGridSizer(5, 3, 4, 5)
        bs1 = wx.BoxSizer(wx.HORIZONTAL)
        self.btn_remove_black = wx.Button(self, label="移除黑名单", size=(70, 30))
        self.btn_close_buy = wx.Button(self, label="关闭交易", size=(70, 30))
        self.btn_remove_black = wx.Button(self, label="移除黑名单", size=(65, 30))
        self.btn_close_buy = wx.Button(self, label="关闭交易", size=(65, 30))
        self.btn_close_buy.SetForegroundColour("#FF3232")
        bs1.Add(self.btn_remove_black)
        bs1.Add(self.btn_close_buy)
        boxsier.Add(bs1, 0, wx.TOP, 5)
        bs1 = wx.BoxSizer(wx.HORIZONTAL)
        self.btn_remove_white = wx.Button(self, label="移除白名单", size=(70, 30))
        self.btn_open_buy = wx.Button(self, label="开启交易", size=(70, 30), )
        self.btn_remove_white = wx.Button(self, label="移除白名单", size=(65, 30))
        self.btn_open_buy = wx.Button(self, label="开启交易", size=(65, 30), )
        self.btn_open_buy.SetForegroundColour("#00e600")
        bs1.Add(self.btn_open_buy, 0, wx.TOP, 5)
        bs1.Add(self.btn_remove_white, 0, wx.TOP, 5)
        boxsier.Add(bs1, 0, wx.LEFT, 0)
        # 买想买
        bs1 = wx.BoxSizer(wx.HORIZONTAL)
        self.btn_buy_mode_want = wx.Button(self, label="仅买想买", size=(65, 30))
        self.btn_buy_mode_all = wx.Button(self, label="全部都买", size=(65, 30), )
        # self.btn_buy_mode_all.SetForegroundColour("#00e600")
        bs1.Add(self.btn_buy_mode_want, 0, wx.TOP, 5)
        bs1.Add(self.btn_buy_mode_all, 0, wx.TOP, 5)
        boxsier.Add(bs1, 0, wx.LEFT, 0)
@@ -361,14 +371,15 @@
        self.check_auto_refresh = wx.CheckBox(self, size=(-1, -1))
        bs1.Add(self.check_auto_refresh, 0, wx.LEFT, 10)
        boxsier.Add(bs1, 0, wx.TOP, 5)
        # 加空白
        boxsier.Add(wx.BoxSizer(wx.HORIZONTAL), 0, wx.TOP, 5)
        bs1 = wx.BoxSizer(wx.HORIZONTAL)
        self.want_list = wx.Button(self, label="想买单", size=(45, 20))
        bs1.Add(self.want_list, 0, wx.TOP, 2)
        self.btn_want_buy = wx.Button(self, label="加入想买单", size=(70, 25))
        self.btn_want_buy = wx.Button(self, label="加入想买单", size=(65, 25))
        bs1.Add(self.btn_want_buy)
        boxsier.Add(bs1, 0, wx.LEFT, 25)
        boxsier.Add(bs1, 0, wx.LEFT, 20)
        label = wx.StaticText(self, label="分组刷新:")
        bs1 = wx.BoxSizer(wx.HORIZONTAL)
@@ -377,8 +388,11 @@
        bs1.Add(self.check_auto_click, 0, wx.LEFT, 10)
        boxsier.Add(bs1)
        self.btn_want_buy_remove = wx.Button(self, label="移除想买单", size=(70, 25))
        boxsier.Add(self.btn_want_buy_remove, 0, wx.LEFT, 70)
        # 加空白
        boxsier.Add(wx.BoxSizer(wx.HORIZONTAL), 0, wx.TOP, 5)
        self.btn_want_buy_remove = wx.Button(self, label="移除想买单", size=(65, 25))
        boxsier.Add(self.btn_want_buy_remove, 0, wx.LEFT, 65)
        self.edit_code = wx.TextCtrl(self, size=(80, -1))
        boxsier.Add(self.edit_code)
@@ -386,9 +400,17 @@
        self.notify_text = wx.StaticText(self, label="", size=(80, -1))
        boxsier.Add(self.notify_text, 0, wx.LEFT, -45)
        #
        bs1 = wx.BoxSizer(wx.HORIZONTAL)
        self.pause_buy_list = wx.Button(self, label="暂不买单", size=(55, 20))
        bs1.Add(self.pause_buy_list, 0, wx.TOP, 2)
        self.btn_pause_buy = wx.Button(self, label="加入暂不买", size=(65, 25))
        bs1.Add(self.btn_pause_buy)
        boxsier.Add(bs1, 0, wx.LEFT, 10)
        # 代码
        bs1 = wx.BoxSizer(wx.HORIZONTAL)
        self.btn_black = wx.Button(self, label="加入黑名单", size=(70, 30))
        self.btn_black = wx.Button(self, label="加入黑名单", size=(65, 30))
        bs1.Add(self.btn_black)
        self.black_list = wx.Button(self, label="黑名单", size=(45, 20))
        self.black_list.SetForegroundColour("#00e600")
@@ -396,13 +418,16 @@
        boxsier.Add(bs1, 0, wx.LEFT, 0)
        bs1 = wx.BoxSizer(wx.HORIZONTAL)
        self.btn_white = wx.Button(self, label="加入白名单", size=(70, 30))
        self.btn_white = wx.Button(self, label="加入白名单", size=(65, 30))
        self.white_list = wx.Button(self, label="白名单", size=(45, 20))
        self.white_list.SetForegroundColour("#FF3232")
        bs1.Add(self.white_list, 0, wx.CENTER | wx.ALL, 0)
        bs1.Add(self.btn_white, 0, wx.LEFT, 2)
        boxsier.Add(bs1, 0, wx.LEFT, 22)
        boxsier.Add(bs1, 0, wx.LEFT, 17)
        self.btn_pause_buy_remove = wx.Button(self, label="移除暂不买", size=(65, 25))
        boxsier.Add(self.btn_pause_buy_remove, 0, wx.LEFT, 65)
        # 绑定
        self.btn_open_buy.Bind(wx.EVT_BUTTON, self.__open_buy)
@@ -416,11 +441,18 @@
        self.btn_want_buy.Bind(wx.EVT_BUTTON, self.add_want)
        self.btn_want_buy_remove.Bind(wx.EVT_BUTTON, self.remove_from_want)
        self.btn_pause_buy.Bind(wx.EVT_BUTTON, self.add_pause_buy)
        self.btn_pause_buy_remove.Bind(wx.EVT_BUTTON, self.remove_from_pause_buy)
        self.btn_buy_mode_want.Bind(wx.EVT_BUTTON, lambda e: self.__set_trade_mode(e, 1))
        self.btn_buy_mode_all.Bind(wx.EVT_BUTTON, lambda e: self.__set_trade_mode(e, 0))
        self.check_auto_click.Bind(wx.EVT_CHECKBOX, self.__auto_click_check)
        self.check_auto_refresh.Bind(wx.EVT_CHECKBOX, self.__auto_refresh_check)
        self.white_list.Bind(wx.EVT_BUTTON, lambda e: self.show_list(e, "白名单列表", 302))
        self.black_list.Bind(wx.EVT_BUTTON, lambda e: self.show_list(e, "黑名单列表", 301))
        self.want_list.Bind(wx.EVT_BUTTON, lambda e: self.show_list(e, "想要买列表", 403))
        self.pause_buy_list.Bind(wx.EVT_BUTTON, lambda e: self.show_list(e, "暂不买列表", 413))
        root_boxsier = wx.BoxSizer(wx.HORIZONTAL)
        root_boxsier.Add(boxsier, 1, wx.LEFT, 10)
@@ -497,6 +529,17 @@
            self.show_warning(str(e))
            return
    def add_pause_buy(self, event):
        try:
            code = self.__get_code()
            print("加入暂不买", code)
            self.__request([code], 411)
            self.show_info(f"{code}加入暂不买名单成功")
            self.edit_code.SetValue("")
        except Exception as e:
            self.show_warning(str(e))
            return
    def add_want(self, event):
        try:
            code = self.__get_code()
@@ -514,6 +557,17 @@
            print("移除黑名单", code)
            self.__request([code], 203)
            self.show_info(f"{code}移除黑名单成功")
            self.edit_code.SetValue("")
        except Exception as e:
            self.show_warning(str(e))
            return
    def remove_from_pause_buy(self, event):
        try:
            code = self.__get_code()
            print("移除暂不买名单", code)
            self.__request([code], 412)
            self.show_info(f"{code}移除暂不买成功")
            self.edit_code.SetValue("")
        except Exception as e:
            self.show_warning(str(e))
@@ -588,6 +642,7 @@
        else:
            self.check_auto_refresh.SetValue(False)
        self.__init_trade_state()
        self.__init_trade_mode()
    def __init_trade_state(self):
        # 获取交易状态
@@ -601,6 +656,21 @@
                else:
                    self.btn_open_buy.SetLabelText("开启交易")
                    self.btn_close_buy.SetLabelText("关闭交易*")
        except:
            pass
    def __init_trade_mode(self):
        # 获取交易模式
        try:
            result = self.__request_buy_mode()
            result = json.loads(result)
            if result["code"] == 0:
                if result["data"]["mode"] == 0:
                    self.btn_buy_mode_want.SetLabelText("仅买想买")
                    self.btn_buy_mode_all.SetLabelText("全部都买*")
                else:
                    self.btn_buy_mode_want.SetLabelText("仅买想买*")
                    self.btn_buy_mode_all.SetLabelText("全部都买")
        except:
            pass
@@ -659,6 +729,40 @@
        result = client.recv(1024)
        client.close()
        return result.decode("gbk")
        # 获取买入模式
    def __request_buy_mode(self):
        client = socket.socket()  # 生成socket,连接server
        ip_port = (SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
        client.connect(ip_port)
        data = {"type": 504, "data": {}}
        client.send(json.dumps(data).encode("utf-8"))
        # 读取内容
        result = client.recv(1024)
        client.close()
        return result.decode("gbk")
    def __request_set_buy_mode(self, mode):
        client = socket.socket()  # 生成socket,连接server
        ip_port = (SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
        client.connect(ip_port)
        data = {"type": 503, "data": {"mode": mode}}
        client.send(json.dumps(data).encode("utf-8"))
        # 读取内容
        result = client.recv(1024)
        client.close()
        return result.decode("gbk")
    def __set_trade_mode(self, event, mode):
        try:
            result = self.__request_set_buy_mode(mode)
            result = json.loads(result)
            if result["code"] != 0:
                raise Exception(result["msg"])
            self.__init_trade_mode()
        except Exception as e:
            show_warning(str(e), None)
    def __open_buy(self, event):
        def open_buy(sure):
@@ -1224,6 +1328,9 @@
        self.floatFrame = FloatFrame()
        global_datas["tickFrame"] = self.frame
        global_datas["floatFrame"] = self.floatFrame
        # # 测试
        # self.__show_float_frame()
        # return True
        t1 = threading.Thread(target=lambda: self.__refresh())
        # 后台运行
@@ -1336,9 +1443,9 @@
                wx.CallAfter(lambda: global_datas["tickFrame"].Show())
            elif type_ == "exit":
                try:
                   jueJinProcess.terminate()
                    jueJinProcess.terminate()
                except:
                   pass
                    pass
                wx.CallAfter(lambda: sys.exit())
@@ -1379,8 +1486,6 @@
    app.MainLoop()
if __name__ == "__main__":
    ths_auto_refresh()
    app = mainApp()
    app.MainLoop()
huaxin/document.html
New file
Diff too large
huaxin/log.py
New file
@@ -0,0 +1,42 @@
import logging
import sys
import time
log_records = []
class MyLogHandler(logging.Handler, object):
    """
    自定义日志handler
    """
    def __init__(self, name, other_attr=None, **kwargs):
        logging.Handler.__init__(self)
    def emit(self, record):
        """
        emit函数为自定义handler类时必重写的函数,这里可以根据需要对日志消息做一些处理,比如发送日志到服务器
        发出记录(Emit a record)
        """
        try:
            msg = self.format(record)
            log_records.append((round(time.time() * 1000), msg))
        except Exception:
            self.handleError(record)
logger = logging.getLogger('logger')
logger.setLevel(logging.DEBUG)
# 创建一个流处理器handler并设置其日志级别为DEBUG
stdout_handler = logging.StreamHandler(sys.stdout)
stdout_handler.setLevel(logging.DEBUG)
# 创建一个格式器formatter并将其添加到处理器handler
formatter = logging.Formatter("%(asctime)s - %(message)s")
stdout_handler.setFormatter(formatter)
logger.addHandler(stdout_handler)
# 内存日志handler
my_log_handler = MyLogHandler('LoggerHandler')
logger.addHandler(my_log_handler)
huaxin/test.py
@@ -101,7 +101,7 @@
            # 终端信息采集
            # UserProductInfo填写终端名称
            login_req.UserProductInfo = 'pyapidemo'
            login_req.UserProductInfo = 'jiabei'
            # 按照监管要求填写终端信息
            login_req.TerminalInfo = 'PC;IIP=000.000.000.000;IPORT=00000;LIP=x.xx.xxx.xxx;MAC=123ABC456DEF;HD=XXXXXXXXXX'
            # 以下内外网IP地址若不填则柜台系统自动采集,若填写则以终端填值为准报送
@@ -219,7 +219,7 @@
                if ret != 0:
                    print('ReqQryPosition fail, ret[%d]' % ret)
            if 1:
            if 0:
                req_field = traderapi.CTORATstpQryTradeField()
                self.__req_id += 1
                ret = api.ReqQryTrade(req_field, self.__req_id)
@@ -232,9 +232,9 @@
                req_field.ExchangeID = traderapi.TORA_TSTP_EXD_SSE
                req_field.ShareholderID = SSE_ShareHolderID
                req_field.SecurityID = '603099'
                req_field.SecurityID = '601985'
                req_field.Direction = traderapi.TORA_TSTP_D_Sell
                req_field.VolumeTotalOriginal = 100
                req_field.VolumeTotalOriginal = 700
                '''
                上交所支持限价指令和最优五档剩撤、最优五档剩转限两种市价指令,对于科创板额外支持本方最优和对手方最优两种市价指令和盘后固定价格申报指令
@@ -242,7 +242,7 @@
                限价指令和上交所科创板盘后固定价格申报指令需填写报单价格,其它市价指令无需填写报单价格
                以下以上交所限价指令为例,其它指令参考开发指南相关说明填写OrderPriceType、TimeCondition和VolumeCondition三个字段:
                '''
                req_field.LimitPrice = 11.74
                req_field.LimitPrice = 6.69
                req_field.OrderPriceType = traderapi.TORA_TSTP_OPT_LimitPrice
                req_field.TimeCondition = traderapi.TORA_TSTP_TC_GFD
                req_field.VolumeCondition = traderapi.TORA_TSTP_VC_AV
@@ -304,7 +304,7 @@
                if ret != 0:
                    print('ReqOrderAction fail, ret[%d]' % ret)
            if 1:
            if 0:
                # 查询集中交易资金
                req_field = traderapi.CTORATstpReqInquiryJZFundField()
@@ -535,14 +535,14 @@
def __buy():
    data = {"type": 0, "req_id": f"test-{random.randint(0, 10000)}",
            "data": json.dumps({"code": "601985", "count": 1000, "price": 6.85})}
            "data": json.dumps({"code": "600706", "count": 1500, "price": 17.42})}
    result = __send_msg(data)
    print("下单结果", json.loads(result))
def __cancel_buy():
    data = {"type": 1, "req_id": f"test-{random.randint(0, 10000)}",
            "data": json.dumps({"code": "601985", "order_sys_id": "110018100000015"})}
            "data": json.dumps({"code": "601611", "order_sys_id": "110018100025424"})}
    result = __send_msg(data)
    print("取消订单", json.loads(result))
@@ -570,7 +570,7 @@
if __name__ == '__main__':
    # __buy()
    __cancel_buy()
    # # __cancel_buy()
    __list_delegate()
    __list_traded()
    # if 1>0:
@@ -591,8 +591,8 @@
    #
    # if 1:  # 模拟环境,TCP 直连Front方式
    #     # 注册单个交易前置服务地址
    #     # TD_TCP_FrontAddress = "tcp://210.14.72.21:4400"  # 仿真交易环境
    #     TD_TCP_FrontAddress = "tcp://210.14.72.15:4400"  # 24小时环境A套
    #     TD_TCP_FrontAddress = "tcp://210.14.72.21:4400"  # 仿真交易环境
    #     # TD_TCP_FrontAddress = "tcp://210.14.72.15:4400"  # 24小时环境A套
    #     # TD_TCP_FrontAddress="tcp://210.14.72.16:9500" #24小时环境B套
    #     api.RegisterFront(TD_TCP_FrontAddress)
    #     # 注册多个交易前置服务地址,用逗号隔开 形如: api.RegisterFront("tcp://10.0.1.101:6500,tcp://10.0.1.101:26500")
huaxin/trade_server.py
@@ -3,9 +3,11 @@
import logging
import socket
import socketserver
import sys
import time
from huaxin import traderapi
from huaxin import traderapi, log
from huaxin.log import logger
UserID = '00043201'
# 登陆密码
@@ -84,8 +86,6 @@
        req_field.OrderPriceType = traderapi.TORA_TSTP_OPT_LimitPrice
        req_field.TimeCondition = traderapi.TORA_TSTP_TC_GFD
        req_field.VolumeCondition = traderapi.TORA_TSTP_VC_AV
        print(req_field)
        '''
        OrderRef为报单引用,类型为整型,该字段报单时为选填
@@ -176,38 +176,81 @@
            raise Exception('ReqQryTrade fail, ret[%d]' % ret)
        return req_id
    def login(self):
        # 请求登录
        login_req = traderapi.CTORATstpReqUserLoginField()
        # 支持以用户代码、资金账号和股东账号方式登录
        # (1)以用户代码方式登录
        login_req.LogInAccount = UserID
        login_req.LogInAccountType = traderapi.TORA_TSTP_LACT_UserID
        # (2)以资金账号方式登录
        # login_req.DepartmentID = DepartmentID
        # login_req.LogInAccount = AccountID
        # login_req.LogInAccountType = traderapi.TORA_TSTP_LACT_AccountID
        # (3)以上海股东账号方式登录
        # login_req.LogInAccount = SSE_ShareHolderID
        # login_req.LogInAccountType = traderapi.TORA_TSTP_LACT_SHAStock
        # (4)以深圳股东账号方式登录
        # login_req.LogInAccount = SZSE_ShareHolderID
        # login_req.LogInAccountType = traderapi.TORA_TSTP_LACT_SZAStock
        # 支持以密码和指纹(移动设备)方式认证
        # (1)密码认证
        # 密码认证时AuthMode可不填
        # login_req.AuthMode = traderapi.TORA_TSTP_AM_Password
        login_req.Password = Password
        # (2)指纹认证
        # 非密码认证时AuthMode必填
        # login_req.AuthMode = traderapi.TORA_TSTP_AM_FingerPrint
        # login_req.DeviceID = '03873902'
        # login_req.CertSerial = '9FAC09383D3920CAEFF039'
        # 终端信息采集
        # UserProductInfo填写终端名称
        login_req.UserProductInfo = 'jiabei'
        # 按照监管要求填写终端信息
        login_req.TerminalInfo = 'PC;IIP=123.112.154.118;IPORT=50361;LIP=192.168.118.107;MAC=54EE750B1713FCF8AE5CBD58;HD=TF655AY91GHRVL'
        # 以下内外网IP地址若不填则柜台系统自动采集,若填写则以终端填值为准报送
        # login_req.MacAddress = '5C-87-9C-96-F3-E3'
        # login_req.InnerIPAddress = '10.0.1.102'
        # login_req.OuterIPAddress = '58.246.43.50'
        TradeSimpleApi.req_id += 1
        ret = api.ReqUserLogin(login_req, TradeSimpleApi.req_id)
        if ret != 0:
            raise Exception('ReqUserLogin fail, ret[%d]' % ret)
class TraderSpi(traderapi.CTORATstpTraderSpi):
    def __init__(self, api, callback):
    def __init__(self, callback):
        traderapi.CTORATstpTraderSpi.__init__(self)
        self.__api = api
        self.__front_id = 0
        self.__session_id = 0
        self.__data_callback = callback
        self.__temp_order_list_dict = {}
    def OnFrontConnected(self) -> "void":
        print('OnFrontConnected')
        logger.info('OnFrontConnected')
        # 获取终端信息
        TradeSimpleApi.req_id += 1
        ret = self.__api.ReqGetConnectionInfo(TradeSimpleApi.req_id)
        ret = api.ReqGetConnectionInfo(TradeSimpleApi.req_id)
        if ret != 0:
            print('ReqGetConnectionInfo fail, ret[%d]' % ret)
        print(ret)
            logger.info('ReqGetConnectionInfo fail, ret[%d]' % ret)
    def OnFrontDisconnected(self, nReason: "int") -> "void":
        print('OnFrontDisconnected: [%d]' % nReason)
        logger.info('OnFrontDisconnected: [%d]' % nReason)
    def OnRspGetConnectionInfo(self, pConnectionInfoField: "CTORATstpConnectionInfoField",
                               pRspInfoField: "CTORATstpRspInfoField", nRequestID: "int") -> "void":
        if pRspInfoField.ErrorID == 0:
            print('inner_ip_address[%s]' % pConnectionInfoField.InnerIPAddress)
            print('inner_port[%d]' % pConnectionInfoField.InnerPort)
            print('outer_ip_address[%s]' % pConnectionInfoField.OuterIPAddress)
            print('outer_port[%d]' % pConnectionInfoField.OuterPort)
            print('mac_address[%s]' % pConnectionInfoField.MacAddress)
            logger.info('inner_ip_address[%s]' % pConnectionInfoField.InnerIPAddress)
            logger.info('inner_port[%d]' % pConnectionInfoField.InnerPort)
            logger.info('outer_ip_address[%s]' % pConnectionInfoField.OuterIPAddress)
            logger.info('outer_port[%d]' % pConnectionInfoField.OuterPort)
            logger.info('mac_address[%s]' % pConnectionInfoField.MacAddress)
            # 请求登录
            login_req = traderapi.CTORATstpReqUserLoginField()
@@ -249,18 +292,18 @@
            # login_req.OuterIPAddress = '58.246.43.50'
            TradeSimpleApi.req_id += 1
            ret = self.__api.ReqUserLogin(login_req, TradeSimpleApi.req_id)
            ret = api.ReqUserLogin(login_req, TradeSimpleApi.req_id)
            if ret != 0:
                print('ReqUserLogin fail, ret[%d]' % ret)
                logger.info('ReqUserLogin fail, ret[%d]' % ret)
            print(log.log_records)
        else:
            print('GetConnectionInfo fail, [%d] [%d] [%s]!!!' % (
            logger.info('GetConnectionInfo fail, [%d] [%d] [%s]!!!' % (
                nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
    def OnRspUserLogin(self, pRspUserLoginField: "CTORATstpRspUserLoginField", pRspInfoField: "CTORATstpRspInfoField",
                       nRequestID: "int") -> "void":
        if pRspInfoField.ErrorID == 0:
            print('Login success! [%d]' % nRequestID)
            logger.info('Login success! [%d]' % nRequestID)
            self.__front_id = pRspUserLoginField.FrontID
            self.__session_id = pRspUserLoginField.SessionID
@@ -272,43 +315,43 @@
                # req_field.ExchangeID = traderapi.TORA_TSTP_EXD_SSE
                TradeSimpleApi.req_id += 1
                ret = self.__api.ReqQryShareholderAccount(req_field, TradeSimpleApi.req_id)
                ret = api.ReqQryShareholderAccount(req_field, TradeSimpleApi.req_id)
                if ret != 0:
                    print('ReqQryShareholderAccount fail, ret[%d]' % ret)
                    logger.info('ReqQryShareholderAccount fail, ret[%d]' % ret)
        else:
            print('Login fail!!! [%d] [%d] [%s]'
                  % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
            logger.info('Login fail!!! [%d] [%d] [%s]'
                        % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
    def OnRspUserPasswordUpdate(self, pUserPasswordUpdateField: "CTORATstpUserPasswordUpdateField",
                                pRspInfoField: "CTORATstpRspInfoField", nRequestID: "int") -> "void":
        if pRspInfoField.ErrorID == 0:
            print('OnRspUserPasswordUpdate: OK! [%d]' % nRequestID)
            logger.info('OnRspUserPasswordUpdate: OK! [%d]' % nRequestID)
        else:
            print('OnRspUserPasswordUpdate: Error! [%d] [%d] [%s]'
                  % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
            logger.info('OnRspUserPasswordUpdate: Error! [%d] [%d] [%s]'
                        % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
    def OnRspOrderInsert(self, pInputOrderField: "CTORATstpInputOrderField", pRspInfoField: "CTORATstpRspInfoField",
                         nRequestID: "int") -> "void":
        if pRspInfoField.ErrorID == 0:
            print('[%d] OnRspOrderInsert: OK! [%d]' % (round(time.time() * 1000), nRequestID))
            logger.info('[%d] OnRspOrderInsert: OK! [%d]' % (round(time.time() * 1000), nRequestID))
        else:
            print('OnRspOrderInsert: Error! [%d] [%d] [%s]'
                  % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
            logger.info('OnRspOrderInsert: Error! [%d] [%d] [%s]'
                        % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
            self.__data_callback(TYPE_BUY, nRequestID, {"sinfo": pInputOrderField.SInfo, "orderStatus": -1,
                                                        "orderStatusMsg": pRspInfoField.ErrorMsg})
    def OnRspOrderAction(self, pInputOrderActionField: "CTORATstpInputOrderActionField",
                         pRspInfoField: "CTORATstpRspInfoField", nRequestID: "int") -> "void":
        if pRspInfoField.ErrorID == 0:
            print('OnRspOrderAction: OK! [%d]' % nRequestID)
            logger.info('OnRspOrderAction: OK! [%d]' % nRequestID)
            self.__data_callback(TYPE_CANCEL_BUY, nRequestID, {"sinfo": pInputOrderActionField.SInfo,
                                                               "orderSysID": pInputOrderActionField.OrderSysID,
                                                               "cancel": 1})
        else:
            print('OnRspOrderAction: Error! [%d] [%d] [%s]'
                  % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
            logger.info('OnRspOrderAction: Error! [%d] [%d] [%s]'
                        % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
            self.__data_callback(TYPE_CANCEL_BUY, nRequestID, {"sinfo": pInputOrderActionField.SInfo,
                                                               "orderSysID": pInputOrderActionField.OrderSysID,
                                                               "cancel": 0, "errorID": pRspInfoField.ErrorID,
@@ -317,22 +360,22 @@
    def OnRspInquiryJZFund(self, pRspInquiryJZFundField: "CTORATstpRspInquiryJZFundField",
                           pRspInfoField: "CTORATstpRspInfoField", nRequestID: "int") -> "void":
        if pRspInfoField.ErrorID == 0:
            print('OnRspInquiryJZFund: OK! [%d] [%.2f] [%.2f]'
                  % (nRequestID, pRspInquiryJZFundField.UsefulMoney, pRspInquiryJZFundField.FetchLimit))
            logger.info('OnRspInquiryJZFund: OK! [%d] [%.2f] [%.2f]'
                        % (nRequestID, pRspInquiryJZFundField.UsefulMoney, pRspInquiryJZFundField.FetchLimit))
        else:
            print('OnRspInquiryJZFund: Error! [%d] [%d] [%s]'
                  % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
            logger.info('OnRspInquiryJZFund: Error! [%d] [%d] [%s]'
                        % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
    def OnRspTransferFund(self, pInputTransferFundField: "CTORATstpInputTransferFundField",
                          pRspInfoField: "CTORATstpRspInfoField", nRequestID: "int") -> "void":
        if pRspInfoField.ErrorID == 0:
            print('OnRspTransferFund: OK! [%d]' % nRequestID)
            logger.info('OnRspTransferFund: OK! [%d]' % nRequestID)
        else:
            print('OnRspTransferFund: Error! [%d] [%d] [%s]'
                  % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
            logger.info('OnRspTransferFund: Error! [%d] [%d] [%s]'
                        % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
    def OnRtnOrder(self, pOrderField: "CTORATstpOrderField") -> "void":
        print(
        logger.info(
            '[%d] OnRtnOrder: SInfo[%s] InvestorID[%s] SecurityID[%s] OrderRef[%d] OrderLocalID[%s] LimitPrice[%.2f] VolumeTotalOriginal[%d] OrderSysID[%s] OrderStatus[%s]'
            % (round(time.time() * 1000), pOrderField.SInfo, pOrderField.InvestorID, pOrderField.SecurityID,
               pOrderField.OrderRef, pOrderField.OrderLocalID,
@@ -347,59 +390,68 @@
                                               "accountId": pOrderField.AccountID})
    def OnRtnTrade(self, pTradeField: "CTORATstpTradeField") -> "void":
        print(
        logger.info(
            'OnRtnTrade: TradeID[%s] InvestorID[%s] SecurityID[%s] OrderRef[%d] OrderLocalID[%s] Price[%.2f] Volume[%d]'
            % (pTradeField.TradeID, pTradeField.InvestorID, pTradeField.SecurityID,
               pTradeField.OrderRef, pTradeField.OrderLocalID, pTradeField.Price, pTradeField.Volume))
    def OnRtnMarketStatus(self, pMarketStatusField: "CTORATstpMarketStatusField") -> "void":
        print('OnRtnMarketStatus: MarketID[%s] MarketStatus[%s]'
              % (pMarketStatusField.MarketID, pMarketStatusField.MarketStatus))
        # TORA_TSTP_MKD_SHA(1): 上海A股
        # TORA_TSTP_MKD_SZA(2): 深圳A股
        # TORA_TSTP_MKD_BJMain(a):北京主板
        # TORA_TSTP_MST_UnKnown(  # ):未知
        # TORA_TSTP_MST_BeforeTrading(0): 开盘前
        # TORA_TSTP_MST_Continous(1): 连续交易
        # TORA_TSTP_MST_Closed(2): 收盘
        # TORA_TSTP_MST_OpenCallAuction(3): 开盘集合竞价
        logger.info('OnRtnMarketStatus: MarketID[%s] MarketStatus[%s]'
                    % (pMarketStatusField.MarketID, pMarketStatusField.MarketStatus))
    def OnRspQrySecurity(self, pSecurityField: "CTORATstpSecurityField", pRspInfoField: "CTORATstpRspInfoField",
                         nRequestID: "int", bIsLast: "bool") -> "void":
        if bIsLast != 1:
            print(
            logger.info(
                'OnRspQrySecurity[%d]: SecurityID[%s] SecurityName[%s] MarketID[%s] OrderUnit[%s] OpenDate[%s] UpperLimitPrice[%.2f] LowerLimitPrice[%.2f]'
                % (nRequestID, pSecurityField.SecurityID, pSecurityField.SecurityName, pSecurityField.MarketID,
                   pSecurityField.OrderUnit, pSecurityField.OpenDate, pSecurityField.UpperLimitPrice,
                   pSecurityField.LowerLimitPrice))
        else:
            print('查询合约结束[%d] ErrorID[%d] ErrorMsg[%s]'
                  % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
            logger.info('查询合约结束[%d] ErrorID[%d] ErrorMsg[%s]'
                        % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
    def OnRspQryInvestor(self, pInvestorField: "CTORATstpInvestorField", pRspInfoField: "CTORATstpRspInfoField",
                         nRequestID: "int", bIsLast: "bool") -> "void":
        if bIsLast != 1:
            print('OnRspQryInvestor[%d]: InvestorID[%s] InvestorName[%s] Operways[%s]'
                  % (nRequestID, pInvestorField.InvestorID, pInvestorField.InvestorName,
                     pInvestorField.Operways))
            logger.info('OnRspQryInvestor[%d]: InvestorID[%s] InvestorName[%s] Operways[%s]'
                        % (nRequestID, pInvestorField.InvestorID, pInvestorField.InvestorName,
                           pInvestorField.Operways))
        else:
            print('查询投资者结束[%d] ErrorID[%d] ErrorMsg[%s]'
                  % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
            logger.info('查询投资者结束[%d] ErrorID[%d] ErrorMsg[%s]'
                        % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
    def OnRspQryShareholderAccount(self, pShareholderAccountField: "CTORATstpShareholderAccountField",
                                   pRspInfoField: "CTORATstpRspInfoField", nRequestID: "int",
                                   bIsLast: "bool") -> "void":
        if bIsLast != 1:
            print('OnRspQryShareholderAccount[%d]: InvestorID[%s] ExchangeID[%s] ShareholderID[%s]'
                  % (nRequestID, pShareholderAccountField.InvestorID, pShareholderAccountField.ExchangeID,
                     pShareholderAccountField.ShareholderID))
            logger.info('OnRspQryShareholderAccount[%d]: InvestorID[%s] ExchangeID[%s] ShareholderID[%s]'
                        % (nRequestID, pShareholderAccountField.InvestorID, pShareholderAccountField.ExchangeID,
                           pShareholderAccountField.ShareholderID))
        else:
            print('查询股东账户结束[%d] ErrorID[%d] ErrorMsg[%s]'
                  % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
            logger.info('查询股东账户结束[%d] ErrorID[%d] ErrorMsg[%s]'
                        % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
    def OnRspQryTradingAccount(self, pTradingAccountField: "CTORATstpTradingAccountField",
                               pRspInfoField: "CTORATstpRspInfoField", nRequestID: "int", bIsLast: "bool") -> "void":
        if bIsLast != 1:
            print(
            logger.info(
                'OnRspQryTradingAccount[%d]: DepartmentID[%s] InvestorID[%s] AccountID[%s] CurrencyID[%s] UsefulMoney[%.2f] FetchLimit[%.2f]'
                % (nRequestID, pTradingAccountField.DepartmentID, pTradingAccountField.InvestorID,
                   pTradingAccountField.AccountID, pTradingAccountField.CurrencyID,
                   pTradingAccountField.UsefulMoney, pTradingAccountField.FetchLimit))
        else:
            print('查询资金账号结束[%d] ErrorID[%d] ErrorMsg[%s]'
                  % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
            logger.info('查询资金账号结束[%d] ErrorID[%d] ErrorMsg[%s]'
                        % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
    def OnRspQryOrder(self, pOrderField: "CTORATstpOrderField", pRspInfoField: "CTORATstpRspInfoField",
                      nRequestID: "int", bIsLast: "bool") -> "void":
@@ -407,7 +459,7 @@
        if nRequestID not in self.__temp_order_list_dict:
            self.__temp_order_list_dict[nRequestID] = []
        if not bIsLast:
            print(
            logger.info(
                'OnRspQryOrder[%d]: SecurityID[%s] OrderLocalID[%s] Direction[%s] OrderRef[%d] OrderSysID[%s] VolumeTraded[%d] OrderStatus[%s] OrderSubmitStatus[%s], StatusMsg[%s]'
                % (nRequestID, pOrderField.SecurityID, pOrderField.OrderLocalID, pOrderField.Direction,
                   pOrderField.OrderRef, pOrderField.OrderSysID,
@@ -425,29 +477,30 @@
                 "orderSubmitStatus": pOrderField.OrderSubmitStatus, "statusMsg": pOrderField.StatusMsg})
        else:
            print('查询报单结束[%d] ErrorID[%d] ErrorMsg[%s]'
                  % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
            logger.info('查询报单结束[%d] ErrorID[%d] ErrorMsg[%s]'
                        % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
            self.__data_callback(TYPE_LIST_DELEGATE, nRequestID, self.__temp_order_list_dict[nRequestID])
            self.__temp_order_list_dict.pop(nRequestID)
    def OnRspQryPosition(self, pPositionField: "CTORATstpPositionField", pRspInfoField: "CTORATstpRspInfoField",
                         nRequestID: "int", bIsLast: "bool") -> "void":
        if bIsLast != 1:
            print('OnRspQryPosition[%d]: InvestorID[%s] SecurityID[%s] HistoryPos[%d] TodayBSPos[%d] TodayPRPos[%d]'
                  % (nRequestID, pPositionField.InvestorID, pPositionField.SecurityID, pPositionField.HistoryPos,
                     pPositionField.TodayBSPos, pPositionField.TodayPRPos))
            logger.info(
                'OnRspQryPosition[%d]: InvestorID[%s] SecurityID[%s] HistoryPos[%d] TodayBSPos[%d] TodayPRPos[%d]'
                % (nRequestID, pPositionField.InvestorID, pPositionField.SecurityID, pPositionField.HistoryPos,
                   pPositionField.TodayBSPos, pPositionField.TodayPRPos))
        else:
            print('查询持仓结束[%d] ErrorID[%d] ErrorMsg[%s]'
                  % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
            logger.info('查询持仓结束[%d] ErrorID[%d] ErrorMsg[%s]'
                        % (nRequestID, pRspInfoField.ErrorID, pRspInfoField.ErrorMsg))
    # 成交回报,参数pTradeField是一个CTORATstpTradeField类对象
    def OnRtnTrade(self, pTradeField: "CTORATstpTradeField") -> "void":
        print("OnRtnTrade")
        logger.info("OnRtnTrade")
    # 查询成交响应,参数pTradeField是一个CTORATstpTradeField类对象
    def OnRspQryTrade(self, pTradeField: "CTORATstpTradeField", pRspInfoField: "CTORATstpRspInfoField",
                      nRequestID: "int", bIsLast: "bool") -> "void":
        print("查询成交响应")
        logger.info("查询成交响应")
        if nRequestID not in self.__temp_order_list_dict:
            self.__temp_order_list_dict[nRequestID] = []
        if not bIsLast:
@@ -489,7 +542,7 @@
            logging.exception(e)
    def setup(self):
        print("----setup方法被执行-----", self.__inited)
        logger.info("----setup方法被执行-----")
        self.__init()
    @classmethod
@@ -522,7 +575,7 @@
                data_str = str(data, encoding="utf-8")
                if not data_str:
                    continue
                print("接收到数据:", data_str)
                logger.info(f"接收到数据:{data_str}")
                return_str = ''
                try:
                    data_json = json.loads(data_str)
@@ -537,7 +590,7 @@
                        code = _data["code"]
                        count = _data["count"]
                        price = round(float(_data["price"]), 2)
                        print("下单参数:", code, count, price)
                        logger.info(f"下单参数:{code} {count} {price}")
                        self.__tradeSimpleApi.buy(code, count, price, _req_id)
                        # 下单成功
                        self.__req_socket_dict[_req_id] = sk
@@ -548,7 +601,7 @@
                        _data = json.loads(_data)
                        code = _data["code"]
                        order_sys_id = _data["order_sys_id"]
                        print("撤单参数:", code, order_sys_id)
                        logger.info("撤单参数:{code} {order_sys_id}")
                        self.__tradeSimpleApi.cancel_buy(code, order_sys_id, _req_id)
                        # 撤单成功
                        self.__req_socket_dict[_req_id] = sk
@@ -565,7 +618,18 @@
                        time.sleep(3)
                    elif _type == 100:
                        # 活动日志
                        pass
                        _data = json.loads(_data)
                        start = _data["start"]
                        count = _data["count"]
                        total_count = len(log.log_records)
                        records = log.log_records[start:start + count]
                        return_str = json.dumps({"code": 0, "data": {"count": total_count, "data": records}})
                        sk.send(return_str.encode())
                    elif _type == 101:
                        # 清除日志
                        log.log_records.clear()
                        return_str = json.dumps({"code": 0, "msg": "清除成功"})
                        sk.send(return_str.encode())
                    else:
                        sk.send(return_str.encode())
@@ -581,12 +645,12 @@
def __init_trade_data_server():
    print("初始化交易服务器")
    logger.info("初始化交易服务器")
    global api
    api = traderapi.CTORATstpTraderApi.CreateTstpTraderApi('./flow', False)
    # 创建回调对象
    global spi
    spi = TraderSpi(api, MyBaseRequestHandle.traderapi_callback)
    spi = TraderSpi(MyBaseRequestHandle.traderapi_callback)
    # 注册回调接口
    api.RegisterSpi(spi)
@@ -598,8 +662,8 @@
    if 1:  # 模拟环境,TCP 直连Front方式
        # 注册单个交易前置服务地址
        # TD_TCP_FrontAddress = "tcp://210.14.72.21:4400"  # 仿真交易环境
        TD_TCP_FrontAddress = "tcp://210.14.72.15:4400"  # 24小时环境A套
        TD_TCP_FrontAddress = "tcp://210.14.72.21:4400"  # 仿真交易环境
        # TD_TCP_FrontAddress = "tcp://210.14.72.15:4400"  # 24小时环境A套
        # TD_TCP_FrontAddress="tcp://210.14.72.16:9500" #24小时环境B套
        api.RegisterFront(TD_TCP_FrontAddress)
        # 注册多个交易前置服务地址,用逗号隔开 形如: api.RegisterFront("tcp://10.0.1.101:6500,tcp://10.0.1.101:26500")
kp_html/kp/codes_list.html
@@ -8,7 +8,9 @@
        <script src="http://cdn.yeshitv.com/js/vue.min.js"></script>
        <script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
        <script src="js/code_list.js"></script>
        <script src="js/qwebchannel.js"></script>
        <script src="js/kpl.js"></script>
        <script src="js/http.js"></script>
        <style>
        </style>
@@ -24,6 +26,37 @@
            </div>
            <div>
                <!-- H撤单 -->
                <table v-if="trade_data&&trade_data.h_cancel">
                    <caption class="table-name">H撤 <span v-if="trade_data.h_cancel.computed_info">(已撤{{parseFloat(trade_data.h_cancel.computed_info[1])*100}}%/目标{{parseFloat(trade_data.h_cancel.computed_info[0])*100}}%)</span></caption>
                    <tbody>
                        <tr><td style="padding: 0;">
                        <div >
                            <table>
                                <thead>
                                    <tr><td>时间</td><td>手数</td><td>金额</td><td>是否撤单</td></tr>
                                </thead>
                                <tbody>
                                <tr v-for="(item,i) in trade_data.h_cancel.datas" >
                                    <td><span class="red"> {{item[0]}}</span></td>
                                    <td><span class="red"> {{item[1]}}</span></td>
                                    <td><span class="red"> {{item[2]}}</span></td>
                                    <td><span class="red" v-if="item[3]"> 已撤</span></td>
                                </tr>
                                </tbody>
                            </table>
                        </div>
                        </td></tr>
                    </tbody>
                </table>
                <!-- 买前评分 -->
@@ -91,36 +124,7 @@
                    </span>
                </div>
                
                <!-- H撤单 -->
                <table v-if="trade_data&&trade_data.h_cancel">
                    <caption class="table-name">H撤 <span v-if="trade_data.h_cancel.computed_info">(已撤{{trade_data.h_cancel.computed_info[1]}}/目标{{trade_data.h_cancel.computed_info[0]}})</span></caption>
                    <tbody>
                        <tr><td style="padding: 0;">
                        <div class="scroll-y" style="max-height: 350px;">
                            <table>
                                <thead>
                                    <tr><td>时间</td><td>手数</td><td>金额</td><td>是否撤单</td></tr>
                                </thead>
                                <tbody>
                                <tr v-for="(item,i) in trade_data.h_cancel.datas" >
                                    <td><span class="red"> {{item[0]}}</span></td>
                                    <td><span class="red"> {{item[1]}}</span></td>
                                    <td><span class="red"> {{item[2]}}</span></td>
                                    <td><span class="red" v-if="item[3]"> 已撤</span></td>
                                </tr>
                                </tbody>
                            </table>
                        </div>
                        </td></tr>
                    </tbody>
                </table>
                
                
                <!-- 交易参数 -->
kp_html/kp/index23-05-04.html
@@ -590,6 +590,12 @@
                    <span id="" class="button-normal" style="display: inline-block;float: right;"
                        @click="do_action_for_code(5)">移出想买单
                    </span>
                    <span id="" class="button-normal" style="display: inline-block;"
                        @click="do_action_for_code(6)">加入暂不买
                    </span>
                    <span id="" class="button-normal" style="display: inline-block;float: right;"
                        @click="do_action_for_code(7)">移出暂不买
                    </span>
                </div>
            </div>
kp_html/kp/js/code_list.js
@@ -1,5 +1,43 @@
document.addEventListener("DOMContentLoaded", function() {
    //把对象赋值到JS中
    try {
        new QWebChannel(qt.webChannelTransport, function(channel) {
            window.pyjs = channel.objects.Bridge;
            console.log("回调成功");
        });
    } catch (e) {
    }
});
var app;
$(function() {
    function is_trade_time() {
        var nowdate = new Date();
        h = nowdate.getHours();
        m = nowdate.getMinutes();
        total_m = h * 60 + m;
        if ((total_m >= (9 * 60 + 25) && total_m <= (11 * 60 + 30)) || (total_m >= 13 * 60 && total_m <= 15 *
                60)) {
            return true;
        } else {
            return false;
        }
    }
    // 定时拉取H撤数据
    setInterval(function() {
        if (app.code != '000000' && app.trade_data) {
            if (is_trade_time()) {
                http_util.get_h_cancel_data(app.code, function(res) {
                    res = JSON.parse(res);
                    console.log("结果:", res)
                    if (res.code == 0) {
                        app.$set(app.trade_data, 'h_cancel', res.data)
                    }
                });
            }
        }
    }, 3000)
    new VConsole();
    app = new Vue({
        el: "#app",
@@ -62,14 +100,14 @@
                } else {
                    app.initiative_buy_codes = null;
                }
                if(passive_buy_codes){
                if (passive_buy_codes) {
                    app.passive_buy_codes = JSON.parse(passive_buy_codes);
                }else{
                } else {
                    app.passive_buy_codes = null;
                }
            }
        }
    })
kp_html/kp/js/http.js
@@ -101,6 +101,17 @@
                type_desc = "移除想买"
                //移除想买
                break;
            case 6:
                data.type = 411;
                data.data.plates = [plate]
                type_desc = "加暂不买"
                //加想买
                break;
            case 7:
                data.type = 412;
                type_desc = "移除暂不买"
                //移除想买
                break;
        }
        console.log("socket请求", data)
@@ -151,5 +162,10 @@
        http_util.http_request("/kpl/get_plate_codes", {
            plate: plate
        }, callback);
    },
    get_h_cancel_data:function(code,callback){
        http_util.http_request("/get_h_cancel_data", {
            code: code
        }, callback);
    }
};
kp_html/kp/js/page.js
@@ -13,10 +13,11 @@
var app;
$(function() {
    function _resize() {
        var code_info_height = 480
        console.log("总高", $(window).height())
        var bottom_height = $(window).height() - 465 - 110;
        var bottom_height = $(window).height() - code_info_height - 110;
        console.log("底部高", bottom_height)
        $("#body>div:nth-child(2)>div").css("height", 465).css("max-height", 465);
        $("#body>div:nth-child(2)>div").css("height", code_info_height).css("max-height", code_info_height);
        $("#body>div:nth-child(3)").css("height", bottom_height)
        $("#body>div:nth-child(3)>div:nth-child(2)").css("height", bottom_height - 10)
        $("#body>div:nth-child(3)>div:nth-child(3)").css("height", bottom_height - 60)
kpl/gui.py
@@ -7,6 +7,7 @@
import time
import requests
import schedule
import wx
import tool
@@ -158,6 +159,21 @@
        self.__init_capture_threads()
        # 开启定时器,在9点26时读取竞价数据
        # schedule.every().day.at("17:54:30").do(test) #lambda: self.__capture_bidding(None)
        def schedule_fun():
            self.__capture_bidding(None)
        schedule.every().day.at("18:02:30").do(schedule_fun) #lambda: self.__capture_bidding(None)
        t1 = threading.Thread(target=self.run_schedule)
        t1.setDaemon(True)
        t1.start()
    def run_schedule(self):
        while True:
            schedule.run_pending()
    def __init_data(self):
        self.capture_status = {}
        self.keys = ["limit_up", "open_limit_up", "limit_down", "ever_limit_down", "feng_kou", "best_feng_kou",
kpl/gui.spec
@@ -46,5 +46,5 @@
    strip=False,
    upx=True,
    upx_exclude=[],
    name='开盘啦1',
    name='开盘啦2',
)
main.py
@@ -20,16 +20,15 @@
freeze_support()
class JSBridgeClass(QObject):
class BaseBridgeClass(QObject):
    signal_request = pyqtSignal(str, str, str)
    def __request_result_callback(self, method, key, result):
        self.webview.page().runJavaScript(f"{method}('{key}','{result}')")
        self.__webview.page().runJavaScript(f"{method}('{key}','{result}')")
    def __init__(self, window, webview):
    def __init__(self, webview):
        super().__init__()
        self.window = window
        self.webview = webview
        self.__webview = webview
        self.signal_request.connect(self.__request_result_callback)
    def __http_request(self, url, callback_info):
@@ -57,6 +56,14 @@
    def socket_request(self, text):
        print("socket_request", text)
        return network_util.socket_request(json.loads(text))
class JSBridgeClass(BaseBridgeClass):
    def __init__(self, window, webview):
        super().__init__(webview)
        self.window = window
        self.webview = webview
    @pyqtSlot(str)
    def show_info(self, msg):
@@ -104,11 +111,17 @@
        self.webview.page().setZoomFactor(1)
        self.setCentralWidget(self.webview)
        self.signal_update_kpl.connect(self.set_kpl_data)
        # JS桥设置
        channel = QWebChannel(self.webview.page())
        self.webview.page().setWebChannel(channel)
        self.python_bridge = BaseBridgeClass(self.webview)
        channel.registerObject("Bridge", self.python_bridge)
        t1 = threading.Thread(target=self.update_kpl_func)
        t1.setDaemon(True)
        t1.start()
        # self.signal_update_kpl.connect(self.set_kpl_data)
        # t1 = threading.Thread(target=self.update_kpl_func)
        # t1.setDaemon(True)
        # t1.start()
    def loadUrl(self, url):
        self.webview.load(QUrl(url))
res/setting.conf
@@ -2,9 +2,9 @@
stay_on_top = 1
window_info = [[-1711, 194, 1280, 800], [1473, 621, 320, 195]]
xgb_window_info = [-1921, -8, 1920, 1017]
window_watch_float_info = [1178, 372, 320, 195]
window_watch_float_info = [294, 497, 435, 200]
window_tick_info = [-1919, 1, 1918, 1038]
kp_second_window_info = [363, 160, 738, 890]
kp_second_window_info = [627, 93, 738, 890]
[juejin]
strategy_id = 95a982ce-fc2d-11ec-8ff3-0a0027000010