示例#1
0
文件: proxy.py 项目: majinke/DTGear
    def on_default_handler(self, header: ResponseHeader, body: Buffer):
        """
        如果没有匹配处理器则由此处理
        :param header:
        :param body:
        :return:
        """
        if header.event_id == 0x0B:
            print("注册模拟设备成功的信息: %s." % str(binascii.b2a_hex(body.bytes())))
        elif header.event_id == 0x0FDB:
            notice = struct.unpack("<116s", body.bytes()[0xb2:0x126])
            print("收到代理服务器的公告信息:%s ..." % notice[0].decode('gbk'))

            callback_proc = self.get_handler(EVENT_READY)
            if callback_proc is not None:
                callback_proc()

        elif header.event_id == 0x000D:
            self.market = ResponseMarketInfo.parse(body)
            print("市场最新交易信息: 券商名称:%s, 最后交易时间:%d" %
                  (self.market.server_name, self.market.date_sz))
        elif header.event_id == 0x044E:
            count = body.read_format("<H")[0]
            if header.cmd_id == 0x6B:
                print("收到sz市场股票数量为: %d." % count)
                self.stock_sz_count = count
            elif header.cmd_id == 0x6C:
                print("收到sh市场股票数量为: %d." % count)
                self.stock_sh_count = count
        else:
            # 收到未知封包
            print("收到未知封包, event_id = %d, content: %s." %
                  (header.event_id, str(binascii.b2a_hex(body.bytes()))))
示例#2
0
    def handle_read(self):
        super(TdxReportClient, self).handle_read()

        while True:
            try:
                if self.in_buffer.length() <= 0:
                    break

                header_size = ResponseHeader.length()
                header = self.in_buffer.peek_bytes(header_size)
                if len(header) < header_size:
                    self.get_handler(0)(header=Buffer(header))
                    break
                """
                L: 封包标识
                B: 是否压缩的标识
                H: 索引(股票索引)
                B: 判断封包类型(此字段与发送的字段相同,靠这个字段可以确定封包的功能)
                H: 未知标识
                H: 事件标识,靠此字段可以确定封包的类别
                2H: 分别是封包长度, 解压所需要的空间大小
                """
                obj_header = ResponseHeader.parse(Buffer(header))

                if self.in_buffer.length(
                ) < obj_header.body_length + header_size:
                    # 如果封包不足则等待下一次接收后继续再判断,直至封包完整再继续解析
                    break

                self.in_buffer.read_bytes(header_size)
                compress_data = self.in_buffer.read_bytes(
                    obj_header.body_length)

                if obj_header.is_compress:
                    decompiler = zlib.decompressobj()
                    content = decompiler.decompress(compress_data)
                else:
                    content = compress_data

                # print("收到 content: %s." % str(binascii.b2a_hex(content)))

                handle_proc = self.get_handler(obj_header.event_id)

                if handle_proc is None:
                    self.get_handler(0)(header=obj_header,
                                        body=Buffer(content))
                else:
                    handle_proc(header=obj_header, body=Buffer(content))

            except StopIteration:
                sys.exit()
            except Exception as ex:
                print("发生未知错误: %s" % str(ex))
示例#3
0
    def on_download(self, header: ResponseHeader, body: Buffer):
        length = body.read_format("<I")[0]  # 移除body大小字段, 只保留文件内容
        content = body.bytes()

        if self.current_report_offset is 0:
            fp = open(self.current_save_report, 'wb+')
        else:
            fp = open(self.current_save_report, 'ab+')

        self.current_report_offset += length

        with fp as outfile:
            outfile.write(content)

        fp.close()
        self.send(next(self.data_gen))
示例#4
0
    def parse(cls, data: Buffer, _fund: bool = False):
        """
        解析
        :param data:
        :param bool _fund: 是否是基金
        :return:
        """
        data_stock = data.read_format(cls.__identity)

        stock_day = ResponseStockDays()

        stock_day.date = "%d%02d%02d" % (data_stock[0] / 10000, data_stock[0] %
                                         10000 / 100, data_stock[0] % 100)

        precision = 100.00
        if _fund:
            precision = 1000.00

        stock_day.open = data_stock[1] / precision
        stock_day.high = data_stock[2] / precision
        stock_day.low = data_stock[3] / precision
        stock_day.close = data_stock[4] / precision
        stock_day.amount = data_stock[5]
        stock_day.volume = data_stock[6]

        return stock_day
示例#5
0
    def on_stock_bonus(self, header: ResponseHeader, body: Buffer):
        """处理权息封包"""
        idx = 0
        current_df_list = []
        stocks_count = body.read_format("<H")[0]
        self.bonus_idx += stocks_count

        while idx < stocks_count:
            idx += 1
            bonus_idx = 0
            body.read_bytes(7)  # 跳过股票代码和市场的字节
            bonus_count = body.read_format("<H")[0]
            while bonus_idx < bonus_count:
                stock_bonus = ResponseStockBonus.parse(body)

                bonus_item = [
                    stock_bonus.code, stock_bonus.date, stock_bonus.market,
                    stock_bonus.type, stock_bonus.money, stock_bonus.price,
                    stock_bonus.count, stock_bonus.rate
                ]
                current_df_list.append(bonus_item)
                bonus_idx += 1

        data_bonus = pd.DataFrame(current_df_list,
                                  columns=[
                                      "code", "date", "market", "type",
                                      "money", "price", "count", "rate"
                                  ])
        self.data_bonus = pd.concat([self.data_bonus, data_bonus],
                                    ignore_index=True)

        print("收到 %d 只股票的高送转信息." % stocks_count)
        if header.idx == 0x1100:
            print("保存权息数据")
            self.data_bonus.to_csv(config.get("files").get("bonus"),
                                   index=False,
                                   mode="w",
                                   encoding='utf8',
                                   float_format="%.6f")
            # 数据更新完毕, 解除事件绑定
            self.bonus_idx = 0
            self.proxy.del_handler(header.event_id)
            print("权息数据更新完毕")
            self.proxy.close()
        else:
            self.update_bonus()
示例#6
0
 def on_default_handler(header: ResponseHeader, body: Buffer):
     """
     如果没有匹配处理器则由此处理
     :param header:
     :param body:
     :return:
     """
     print("收到未知封包, event_id = %d, content: %s." %
           (header.event_id, str(binascii.b2a_hex(body.bytes()))))
示例#7
0
    def on_base(self, header: ResponseHeader, body: Buffer):
        """更新市场股票基础信息列表"""
        idx = 0
        current_df_list = []

        market_type = 0 if header.cmd_id == 0x6D else 1  # 0表示深市,1表示沪市
        stocks_count = body.read_format("<H")[0]
        while idx < stocks_count:
            obj_stock_base = ResponseStockBase.parse(body)

            stock_item = [
                obj_stock_base.code, obj_stock_base.name, market_type,
                obj_stock_base.unknown1, obj_stock_base.unknown2,
                obj_stock_base.unknown3, obj_stock_base.price,
                obj_stock_base.bonus1, obj_stock_base.bonus2
            ]

            current_df_list.append(stock_item)
            idx += 1

        data_stocks = pd.DataFrame(current_df_list,
                                   columns=[
                                       'code', 'name', 'market', 'unknown1',
                                       'unknown2', 'unknown3', 'price',
                                       'bonus1', 'bonus2'
                                   ])
        self.data_stocks = pd.concat([self.data_stocks, data_stocks],
                                     ignore_index=True)

        if len(self.data_stocks) >= (self.proxy.stock_sz_count +
                                     self.proxy.stock_sh_count):
            # 保存数据信息
            print("保存基础数据...")
            self.data_stocks.to_csv(config.get("files").get("stock_list"),
                                    index=False,
                                    mode="w",
                                    encoding='utf8',
                                    float_format="%.3f")

            # 解绑事件处理器
            self.proxy.del_handler(header.event_id)

            # 开始更新股票权息数据
            self.update_bonus()
            return

        self.proxy.send(next(self.data_gen))
示例#8
0
    def on_history(self, header: ResponseHeader, body: Buffer):
        """处理日线封包"""
        current_df_list = []
        is_st = 0
        stock_code = self.data_stocks.ix[header.idx]['code']
        stock_name = self.data_stocks.ix[header.idx]['name']
        market = int(self.data_stocks.ix[header.idx]['market'])

        if header.cmd_id != 0x87:
            # 只处理日线数据
            return

        if stock_name.startswith("ST") or stock_name.startswith("SST") or \
                stock_name.startswith("*ST") or stock_name.startswith("S*ST"):
            is_st = 1

        # 日线数据
        item_count = body.read_format("<HL")[1] / ResponseStockDays.length()

        idx = 0
        while idx < item_count:
            if stocks.type_with_code(stock_code) == 2:
                item = ResponseStockDays.parse(body, _fund=True)
            else:
                item = ResponseStockDays.parse(body)

            current_df_list.append([
                item.date,
                int(market), stock_code, stock_name, item.open, item.low,
                item.high, item.close, item.volume, item.amount, is_st
            ])
            idx += 1

        print("获取 %d-%s 的日线数据" % (market, stock_code))

        hs_df = pd.DataFrame(current_df_list,
                             columns=[
                                 'date', 'market', 'code', 'name', 'open',
                                 'low', 'high', 'close', 'volume', 'amount',
                                 'st'
                             ])

        self.__db_client.insert_json(hs_df)

        self.proxy.send(next(self.data_gen))
示例#9
0
    def parse(cls, data: Buffer):
        """
        解析
        :param data:
        :return:
        """
        market_info = ResponseMarketInfo()

        server_info = data.read_format(cls.__identity)

        market_info.date_sz = server_info[11]
        market_info.last_flag_sz = server_info[12]
        market_info.data_sh = server_info[13]
        market_info.last_flag_sh = server_info[14]
        market_info.server_name = str(server_info[18].decode('gbk'))
        market_info.domain_url = str(server_info[19].decode('ascii'))

        return market_info
示例#10
0
    def parse(cls, data: Buffer):
        """
        解析应答封包
        :param data:
        :return:
        """
        header = ResponseHeader()
        data_header = data.read_format(cls.__identity)

        header.pkg_flag = data_header[0]
        header.is_compress = data_header[1] & 0x10 != 0
        header.idx = data_header[2]
        header.cmd_id = data_header[3]
        header.unknown = data_header[4]
        header.event_id = data_header[5]
        header.body_length = data_header[6]
        header.body_max_length = data_header[7]

        return header
示例#11
0
    def parse(cls, data: Buffer):
        """
        解析
        :param data:
        :return:
        """
        data_stock = data.read_format(cls.__identity)

        stock_base = ResponseStockBase()

        stock_base.code = "%s" % data_stock[0].decode('gbk')
        stock_base.unknown1 = data_stock[1]
        stock_base.name = "%s" % data_stock[2].decode('gbk').replace("\00", "")
        stock_base.unknown2 = data_stock[3]
        stock_base.unknown3 = data_stock[4]
        stock_base.price = data_stock[5]
        stock_base.bonus1 = data_stock[6]
        stock_base.bonus2 = data_stock[7]

        return stock_base
示例#12
0
    def parse(cls, data: Buffer):
        """
        解析
        :param data:
        :return:
        """
        data_stock = data.read_format(cls.__identity)

        stock_bonus = ResponseStockBonus()

        stock_bonus.market = data_stock[0]
        stock_bonus.code = "%s" % data_stock[1].decode('ascii')
        stock_bonus.date = "%d%02d%02d" % (data_stock[3] / 10000, data_stock[3]
                                           % 10000 / 100, data_stock[3] % 100)

        stock_bonus.type = data_stock[4]

        stock_bonus.money = data_stock[5]
        stock_bonus.price = data_stock[6]
        stock_bonus.count = data_stock[7]
        stock_bonus.rate = data_stock[8]

        return stock_bonus
示例#13
0
    def on_report_list(self, header: ResponseHeader, body: Buffer):
        body.read_format("<I")
        content = body.bytes().decode("utf-8")

        self.cw_list = content.split('\n')
        self.__callback_proc()