Beispiel #1
0
 def subscribe(self, instrument_id_list=None):
     """订阅合约"""
     super().subscribe(instrument_id_list)
     if instrument_id_list is None:
         instrument_id_list = self.instrument_id_list
     # channel_head = Config.REDIS_CHANNEL[self.md_period]
     # channel_list = [channel_head + instrument_id for instrument_id in instrument_id_list]
     channel_list = [get_channel(config.MARKET_NAME, self.md_period, instrument_id)
                     for instrument_id in instrument_id_list]
     self.pub_sub.psubscribe(*channel_list)
Beispiel #2
0
    def unsubscribe(self, instrument_id_list):
        """退订合约"""
        if instrument_id_list is None:
            instrument_id_list = self.instrument_id_list

        super().unsubscribe(instrument_id_list)

        # channel_head = config.REDIS_CHANNEL[self.md_period]
        # channel_list = [channel_head + instrument_id for instrument_id in instrument_id_list]
        channel_list = [get_channel(config.MARKET_NAME, self.md_period, instrument_id)
                        for instrument_id in instrument_id_list]
        if self.pub_sub is not None:  # 在回测模式下有可能不进行 connect 调用以及 subscribe 订阅,因此,没有 pub_sub 实例
            self.pub_sub.punsubscribe(*channel_list)
Beispiel #3
0
def check_redis():
    """
    检测redis是否可以正常工作
    """
    global _signal
    instrument_id = 'rb1805'
    channel = get_channel(market=config.MARKET_NAME,
                          period=PeriodType.Year1,
                          symbol=instrument_id)
    logger.info('测试 Channel:%s', channel)
    _signal['redis'] = False

    timer_t = threading.Thread(target=_timer, args=(channel, ))
    timer_t.start()

    def _receiver(_channel):
        # 接收订阅的行情,成功接收后退出
        global _signal
        redis_client = get_redis(config.REDIS_INFO_DIC['REDIS_HOST'],
                                 config.REDIS_INFO_DIC['REDIS_PORT'])
        try:
            pub_sub = redis_client.pubsub()
            pub_sub.psubscribe(_channel)
            for item in pub_sub.listen():
                logger.debug("接收成功 %s", item)
                if item['type'] == 'pmessage':
                    md_dic_str = bytes_2_str(item['data'])
                    md_dic = json.loads(md_dic_str)
                    if "message" in md_dic and "count" in md_dic:
                        _signal['redis'] = True
                        logger.debug("接收到消息")
                        break
        except:
            logger.exception('Redis 检测时发现异常,可能是由于redis没有启动')
            pass

    receiver_t = threading.Thread(target=_receiver, args=(channel, ))
    receiver_t.start()

    for n in range(20):
        if _signal['redis']:
            logging.debug("检测redis %d %s", n, _signal['redis'])
            timer_t.join(1)
            break
        time.sleep(1)
    else:
        logger.error("redis 检测未通过")

    return _signal['redis']
Beispiel #4
0
def check_redis():
    global _signal
    # channel_header = Config.REDIS_CHANNEL[PeriodType.Tick]
    instrument_id = 'rb1805'
    # channel = channel_header + 'test.' + instrument_id
    channel = get_channel(ExchangeName.BitMex.name, PeriodType.Year1,
                          instrument_id)
    _signal['redis'] = False

    timer_t = threading.Thread(target=_timer, args=(channel, ))
    timer_t.start()

    def _receiver(channel):
        # 接收订阅的行情,成功接收后退出
        global _signal
        redis_client = get_redis()
        pub_sub = redis_client.pubsub()
        pub_sub.psubscribe(channel)
        for item in pub_sub.listen():
            logger.debug("接收成功 %s", item)
            if item['type'] == 'pmessage':
                md_dic_str = bytes_2_str(item['data'])
                md_dic = json.loads(md_dic_str)
                if "message" in md_dic and "count" in md_dic:
                    _signal['redis'] = True
                    logger.debug("接收到消息")
                    break

    receiver_t = threading.Thread(target=_receiver, args=(channel, ))
    receiver_t.start()

    for n in range(20):
        if _signal['redis']:
            logging.debug("检测redis %d %s", n, _signal['redis'])
            timer_t.join(1)
            break
        time.sleep(1)
    else:
        logger.error("redis 检测未通过")

    return _signal['redis']
Beispiel #5
0
    def handle(self, msg):
        """
        收到数据后,tick数据直接发送,
        channel:md.market.tick.pair
        channel:md.market.min1.pair 每个分钟时点切换时,发送一次分钟线数据
        例如:
        md.huobi.tick.ethusdt
        md.huobi.1min.ethusdt
        通过 redis-cli 可以 PUBSUB CHANNELS 查阅活跃的频道
        PSUBSCRIBE pattern [pattern ...]  查看频道内容
        SUBSCRIBE channel [channel ...]  查看频道内容
        :param msg:
        :return:
        """
        # TODO: 设定一个定期检查机制,只发送订阅的品种,降低网络负载
        if 'ch' in msg:
            topic = msg.get('ch')
            _, symbol, _, period_str = topic.split('.')
            data = msg.get('tick')
            # 调整相关属性
            ts_start = datetime.fromtimestamp(data.pop('id'))
            data['ts_start'] = datetime_2_str(ts_start, format=STR_FORMAT_DATETIME2)
            data['market'] = config.MARKET_NAME  # 'huobi'
            data['ts_curr'] = datetime_2_str(datetime.fromtimestamp(msg['ts'] / 1000), format=STR_FORMAT_DATETIME2)
            data['symbol'] = symbol
            # Json
            md_str = json.dumps(data)

            # 先发送Tick数据
            if period_str == '1min':
                # channel = f'md.{self.market}.tick.{symbol}'
                channel = get_channel(self.market, PeriodType.Tick, symbol)
                self.r.publish(channel, md_str)

            # period_str 1min, 5min, 15min, 30min, 60min, 1day, 1mon, 1week, 1year
            if period_str == '1min':
                period = PeriodType.Min1
            elif period_str == '5min':
                period = PeriodType.Min5
            elif period_str == '15min':
                period = PeriodType.Min15
            elif period_str == '30min':
                period = PeriodType.Min30
            elif period_str == '60min':
                period = PeriodType.Hour1
            elif period_str == '1day':
                period = PeriodType.Day1
            elif period_str == '1mon':
                period = PeriodType.Mon1
            elif period_str == '1week':
                period = PeriodType.Week1
            elif period_str == '1year':
                period = PeriodType.Year1
            else:
                raise ValueError('period_str=%s 为无效参数' % period_str)

            # 分钟线切换时发送分钟线数据
            ts_start_last = self.last_ts_start_pair_tick.setdefault((period_str, symbol), None)
            if ts_start_last is not None and ts_start_last != ts_start:
                md_str_last = self.last_tick_pair_tick[(period_str, symbol)]
                # channel_min1 = f'md.{self.market}.{period}.{pair}'
                channel_min1 = get_channel(self.market, period, symbol)
                self.r.publish(channel_min1, md_str_last)

            self.last_ts_start_pair_tick[(period_str, symbol)] = ts_start
            self.last_tick_pair_tick[(period_str, symbol)] = md_str

        elif 'rep' in msg:
            # topic = msg.get('rep')
            # data = msg.get('data')
            self.logger.info(msg)
        else:
            self.logger.warning(msg)