예제 #1
0
파일: conns.py 프로젝트: TalesYuan/tushare
def api(retry_count=3):
    for _ in range(retry_count):
        try:
            api = TdxHq_API(heartbeat=True)
            api.connect(ct._get_server(), ct.T_PORT)
        except Exception as e:
            print(e)
        else:
            return api
    raise IOError(ct.NETWORK_URL_ERROR_MSG)
예제 #2
0
def QA_fetch_get_stock_transaction_realtime(code, ip=None, port=None):
    '实时分笔成交 包含集合竞价 buyorsell 1--sell 0--buy 2--盘前'
    global best_ip
    if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None:
        best_ip = select_best_ip()
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None:
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    else:
        pass
    api = TdxHq_API()
    try:
        with api.connect(ip, port):
            data = pd.DataFrame()
            data = pd.concat([api.to_df(api.get_transaction_data(
                _select_market_code(str(code)), code, (2 - i) * 2000, 2000)) for i in range(3)], axis=0)
            if 'value' in data.columns:
                data = data.drop(['value'], axis=1)
            data = data.dropna()
            day = datetime.date.today()
            return data.assign(date=str(day)).assign(datetime=pd.to_datetime(data['time'].apply(lambda x: str(day) + ' ' + str(x))))\
                .assign(code=str(code)).assign(order=range(len(data.index))).set_index('datetime', drop=False, inplace=False)
    except:
        return None
예제 #3
0
def QA_fetch_get_index_min(code, start, end, level='1min', ip=best_ip, port=7709):
    api = TdxHq_API()
    type_ = ''
    if str(level) in ['5', '5m', '5min', 'five']:
        level, type_ = 0, '5min'
    elif str(level) in ['1', '1m', '1min', 'one']:
        level, type_ = 8, '1min'
    elif str(level) in ['15', '15m', '15min', 'fifteen']:
        level, type_ = 1, '15min'
    elif str(level) in ['30', '30m', '30min', 'half']:
        level, type_ = 2, '30min'
    elif str(level) in ['60', '60m', '60min', '1h']:
        level, type_ = 3, '60min'
    with api.connect(ip, port):
        if str(code)[0] in ['5', '1']:  # ETF
            data = pd.concat([api.to_df(api.get_security_bars(
                level, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (25 - i) * 800, 800)) for i in range(26)], axis=0)
        else:
            data = pd.concat([api.to_df(api.get_index_bars(
                level, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (25 - i) * 800, 800)) for i in range(26)], axis=0)
        data = data\
            .assign(datetime=pd.to_datetime(data['datetime']), code=str(code))\
            .drop(['year', 'month', 'day', 'hour', 'minute'], axis=1, inplace=False)\
            .assign(date=data['datetime'].apply(lambda x: str(x)[0:10]))\
            .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(x)))\
            .assign(time_stamp=data['datetime'].apply(lambda x: QA_util_time_stamp(x)))\
            .assign(type=type_).set_index('datetime', drop=False, inplace=False)[start:end]
        # data
        return data.assign(datetime=data['datetime'].apply(lambda x: str(x)))
예제 #4
0
def QA_fetch_get_index_day(code, start_date, end_date, level='day', ip=best_ip, port=7709):
    '指数日线'
    api = TdxHq_API()
    if level in ['day', 'd', 'D', 'DAY', 'Day']:
        level = 9
    elif level in ['w', 'W', 'Week', 'week']:
        level = 5
    elif level in ['month', 'M', 'm', 'Month']:
        level = 6
    elif level in ['Q', 'Quarter', 'q']:
        level = 10
    elif level in ['y', 'Y', 'year', 'Year']:
        level = 11

    with api.connect(ip, port):
        if str(code)[0] in ['5', '1']:  # ETF
            data = pd.concat([api.to_df(api.get_security_bars(
                level, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (25 - i) * 800, 800)) for i in range(26)], axis=0)
        else:
            data = pd.concat([api.to_df(api.get_index_bars(
                level, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (25 - i) * 800, 800)) for i in range(26)], axis=0)
        data = data.assign(date=data['datetime'].apply(lambda x: str(x[0:10]))).assign(code=str(code))\
            .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\
            .set_index('date', drop=False, inplace=False)\
            .drop(['year', 'month', 'day', 'hour',
                   'minute', 'datetime'], axis=1)[start_date:end_date]
        return data.assign(date=data['date'].apply(lambda x: str(x)[0:10]))
예제 #5
0
def QA_fetch_get_stock_xdxr(code, ip=None, port=None):
    '除权除息'
    global best_ip
    if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None:
        best_ip = select_best_ip()
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None:
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    else:
        pass
    api = TdxHq_API()
    market_code = _select_market_code(code)
    with api.connect(ip, port):
        category = {
            '1': '除权除息', '2': '送配股上市', '3': '非流通股上市', '4': '未知股本变动', '5': '股本变化',
            '6': '增发新股', '7': '股份回购', '8': '增发新股上市', '9': '转配股上市', '10': '可转债上市',
            '11': '扩缩股', '12': '非流通股缩股', '13':  '送认购权证', '14': '送认沽权证'}
        data = api.to_df(api.get_xdxr_info(market_code, code))
        if len(data) >= 1:
            data = data\
                .assign(date=pd.to_datetime(data[['year', 'month', 'day']]))\
                .drop(['year', 'month', 'day'], axis=1)\
                .assign(category_meaning=data['category'].apply(lambda x: category[str(x)]))\
                .assign(code=str(code))\
                .rename(index=str, columns={'panhouliutong': 'liquidity_after',
                                            'panqianliutong': 'liquidity_before', 'houzongguben': 'shares_after',
                                            'qianzongguben': 'shares_before'})\
                .set_index('date', drop=False, inplace=False)
            return data.assign(date=data['date'].apply(lambda x: str(x)[0:10]))
        else:
            return None
예제 #6
0
def QA_fetch_get_stock_block(ip=None, port=None):
    '板块数据'
    global best_ip
    if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None:
        best_ip = select_best_ip()
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None:
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    else:
        pass
    api = TdxHq_API()
    with api.connect(ip, port):

        data = pd.concat([api.to_df(api.get_and_parse_block_info("block_gn.dat")).assign(type='gn'),
                          api.to_df(api.get_and_parse_block_info(
                              "block.dat")).assign(type='yb'),
                          api.to_df(api.get_and_parse_block_info(
                              "block_zs.dat")).assign(type='zs'),
                          api.to_df(api.get_and_parse_block_info("block_fg.dat")).assign(type='fg')])

        if len(data) > 10:
            return data.assign(source='tdx').drop(['block_type', 'code_index'], axis=1).set_index('code', drop=False, inplace=False).drop_duplicates()
        else:
            QA_util_log_info('Wrong with fetch block ')
예제 #7
0
 def _get_bars(self, market, code, ktype):
     data = []
     tdx_market = self._trans_market(market)
     if tdx_market is None:
         print("tdx_market == None")
         return data
     
     tdx_ktype = self._trans_ktype(ktype)
     if tdx_ktype is None:
         print("tdx_ktype == None")
         return data
     
     try:
         ip = self.getParam('ip')
         port = self.getParam('port')
     except:
         ip = '119.147.212.81'
         port = 7709
         
     api = TdxHq_API(raise_exception=True)
     
     with api.connect(ip, port):
         if (market == 'SH' and code[:3] == '000') \
               or (market == 'SZ'  and code[:2] == '39'):
             for i in range(self._max[ktype]):
                 data += api.get_index_bars(tdx_ktype, tdx_market, code,
                                        (self._max[ktype]-1-i)*800,800)
         else:
             for i in range(self._max[ktype]):
                 data += api.get_security_bars(tdx_ktype, tdx_market, code,
                                             (self._max[ktype]-1-i)*800,800)
             
     return data
예제 #8
0
    def __call__(self):
        count = 0
        connect = sqlite3.connect(self.sqlitefile)
        try:
            progress = ProgressBar(self)
            api = TdxHq_API()
            api.connect(self.ip, self.port)
            count = import_time(connect, self.market, self.quotations, api,
                                 self.dest_dir, max_days=self.max_days, progress=progress)
        except Exception as e:
            print(e)
        finally:
            connect.commit()
            connect.close()

        self.queue.put([self.task_name, self.market, 'TIME', None, count])
예제 #9
0
def QA_fetch_get_stock_realtime(code=['000001', '000002'], ip=best_ip, port=7709):
    api = TdxHq_API()
    __data = pd.DataFrame()
    code = [code] if type(code) is str else code






    async def _get_security_quotes(__code):
        """
        """
        assert isinstance(__code, str)

        data=await api.get_security_quotes([(__select_market_code(__code), __code)])
        data=api.to_df(data)
        data['datetime'] = datetime.datetime.now()

        return data[['datetime', 'code', 'open', 'high', 'low', 'price']]

    with api.connect(ip, port):
        coroutines = [asyncio.ensure_future(
            _get_security_quotes(code_)) for code_ in code]

        print(coroutines)
        try:
            loop = asyncio.get_event_loop()
        except RuntimeError:
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)

        res = loop.run_until_complete(asyncio.gather(*coroutines))
        print(res)
        return res
예제 #10
0
def ping(ip):
    __time1 = datetime.datetime.now()
    api = TdxHq_API()
    try:
        with api.connect(ip, 7709):
            if len(api.get_security_list(0, 1)) > 800:
                return datetime.datetime.now() - __time1
    except:
        return datetime.timedelta(9, 9, 0)
예제 #11
0
def ping(ip):
    api = TdxHq_API()
    __time1 = datetime.datetime.now()
    try:
        with api.connect(ip, 7709):
            if len(api.get_security_list(0, 1)) > 800:
                return datetime.datetime.now() - __time1
    except:
        print('Bad REPSONSE %s' % ip)
        return datetime.timedelta(9, 9, 0)
예제 #12
0
def QA_fetch_get_index_min(code, start, end, frequence='1min', ip=None, port=None):
    '指数分钟线'
    global best_ip
    if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None:
        best_ip = select_best_ip()
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None:
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    else:
        pass
    api = TdxHq_API()
    type_ = ''

    start_date = str(start)[0:10]
    today_ = datetime.date.today()
    lens = QA_util_get_trade_gap(start_date, today_)
    if str(frequence) in ['5', '5m', '5min', 'five']:
        frequence, type_ = 0, '5min'
        lens = 48 * lens
    elif str(frequence) in ['1', '1m', '1min', 'one']:
        frequence, type_ = 8, '1min'
        lens = 240 * lens
    elif str(frequence) in ['15', '15m', '15min', 'fifteen']:
        frequence, type_ = 1, '15min'
        lens = 16 * lens
    elif str(frequence) in ['30', '30m', '30min', 'half']:
        frequence, type_ = 2, '30min'
        lens = 8 * lens
    elif str(frequence) in ['60', '60m', '60min', '1h']:
        frequence, type_ = 3, '60min'
        lens = 4 * lens

    if lens > 20800:
        lens = 20800
    with api.connect(ip, port):

        if str(code)[0] in ['5', '1']:  # ETF
            data = pd.concat([api.to_df(api.get_security_bars(
                frequence, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (int(lens / 800) - i) * 800, 800)) for i in range(int(lens / 800) + 1)], axis=0)
        else:
            data = pd.concat([api.to_df(api.get_index_bars(
                frequence, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (int(lens / 800) - i) * 800, 800)) for i in range(int(lens / 800) + 1)], axis=0)
        data = data\
            .assign(datetime=pd.to_datetime(data['datetime']), code=str(code))\
            .drop(['year', 'month', 'day', 'hour', 'minute'], axis=1, inplace=False)\
            .assign(code=code)\
            .assign(date=data['datetime'].apply(lambda x: str(x)[0:10]))\
            .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(x)))\
            .assign(time_stamp=data['datetime'].apply(lambda x: QA_util_time_stamp(x)))\
            .assign(type=type_).set_index('datetime', drop=False, inplace=False)[start:end]
        # data
        return data.assign(datetime=data['datetime'].apply(lambda x: str(x)))
예제 #13
0
def QA_fetch_get_stock_realtime(code=['000001', '000002'], ip=best_ip, port=7709):
    api = TdxHq_API()
    __data = pd.DataFrame()
    with api.connect(ip, port):
        code = [code] if type(code) is str else code
        for id_ in range(int(len(code) / 80) + 1):
            __data = __data.append(api.to_df(api.get_security_quotes(
                [(__select_market_code(x), x) for x in code[80 * id_:80 * (id_ + 1)]])))
            __data['datetime'] = datetime.datetime.now()
        data = __data[['datetime', 'code', 'open', 'high', 'low', 'price']]
        return data.set_index('code', drop=False, inplace=False)
예제 #14
0
def QA_fetch_get_stock_latest(code, ip=best_ip, port=7709):
    code = [code] if isinstance(code, str) else code
    api = TdxHq_API(multithread=True)
    with api.connect(ip, port):
        data = pd.concat([api.to_df(api.get_security_bars(
            9, __select_market_code(item), item, 0, 1)).assign(code=item) for item in code], axis=0)
        return data\
            .assign(date=pd.to_datetime(data['datetime']
                                        .apply(lambda x: x[0:10])), date_stamp=data['datetime']
                    .apply(lambda x: QA_util_date_stamp(str(x[0:10]))))\
            .set_index('date', drop=False)\
            .drop(['year', 'month', 'day', 'hour', 'minute', 'datetime'], axis=1)
예제 #15
0
파일: tdx.py 프로젝트: intrad/fooltrader
def get_tdx_kdata(security_item, start, end):
    api = TdxHq_API()
    with api.connect():
        # open close high low vol amount date code
        # KDATA_COLUMN = ['timestamp', 'code', 'low', 'open', 'close', 'high', 'volume', 'turnover', 'securityId']

        df = api.get_k_data(security_item['code'], start, end)
        df = df[['date', 'code', 'low', 'open', 'close', 'high', 'vol', 'amount']]
        df['securityId'] = df['code'].apply(lambda x: 'stock_{}_{}'.format(get_exchange(x), x))
        df['vol'] = df['vol'].apply(lambda x: x * 100)
        df.columns = KDATA_COLUMN
    return df
예제 #16
0
    def _test_speed(self, ip, port=7709):

        api = TdxHq_API(raise_exception=True, auto_retry=False)
        _time = datetime.datetime.now()
        try:
            with api.connect(ip, port, time_out=0.05):
                if len(api.get_security_list(0, 1)) > 800:
                    return (datetime.datetime.now() - _time).total_seconds()
                else:
                    return datetime.timedelta(9, 9, 0).total_seconds()
        except Exception as e:
            return datetime.timedelta(9, 9, 0).total_seconds()
예제 #17
0
def QA_fetch_get_stock_info(code, ip=None, port=None):
    '股票基本信息'
    global best_ip
    if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None:
        best_ip = select_best_ip()
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None:
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    else:
        pass
    api = TdxHq_API()
    market_code = _select_market_code(code)
    with api.connect(ip, port):
        return api.to_df(api.get_finance_info(market_code, code))
예제 #18
0
def ping(ip, port=7709, multithread=False):
    api = TdxHq_API(multithread=multithread)
    success = False
    starttime = time.time()
    try:
        with api.connect(ip, port, time_out=1):
            #x = api.get_security_count(0)
            #x = api.get_index_bars(7, 1, '000001', 800, 100)
            x = api.get_security_bars(7, 0, '000001', 800, 100)
            if x:
                success = True

    except Exception as e:
        success = False

    endtime = time.time()
    return (success, endtime - starttime, ip, port)
예제 #19
0
def QA_fetch_get_index_day(code, start_date, end_date, frequence='day', ip=None, port=None):
    '指数日线'
    global best_ip
    if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None:
        best_ip = select_best_ip()
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None:
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    else:
        pass
    api = TdxHq_API()
    if frequence in ['day', 'd', 'D', 'DAY', 'Day']:
        frequence = 9
    elif frequence in ['w', 'W', 'Week', 'week']:
        frequence = 5
    elif frequence in ['month', 'M', 'm', 'Month']:
        frequence = 6
    elif frequence in ['Q', 'Quarter', 'q']:
        frequence = 10
    elif frequence in ['y', 'Y', 'year', 'Year']:
        frequence = 11

    with api.connect(ip, port):

        start_date = str(start_date)[0:10]
        today_ = datetime.date.today()
        lens = QA_util_get_trade_gap(start_date, today_)

        if str(code)[0] in ['5', '1']:  # ETF
            data = pd.concat([api.to_df(api.get_security_bars(
                frequence, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (int(lens / 800) - i) * 800, 800)) for i in range(int(lens / 800) + 1)], axis=0)
        else:
            data = pd.concat([api.to_df(api.get_index_bars(
                frequence, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (int(lens / 800) - i) * 800, 800)) for i in range(int(lens / 800) + 1)], axis=0)
        data = data.assign(date=data['datetime'].apply(lambda x: str(x[0:10]))).assign(code=str(code))\
            .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\
            .set_index('date', drop=False, inplace=False)\
            .assign(code=code)\
            .drop(['year', 'month', 'day', 'hour',
                   'minute', 'datetime'], axis=1)[start_date:end_date]
        return data.assign(date=data['date'].apply(lambda x: str(x)[0:10]))
예제 #20
0
def QA_fetch_get_stock_list(type_='stock', ip=best_ip, port=7709):

    api = TdxHq_API()
    with api.connect(ip, port):
        data = pd.concat([pd.concat([api.to_df(api.get_security_list(j, i * 1000)).assign(sse='sz' if j == 0 else 'sh').set_index(
            ['code', 'sse'], drop=False) for i in range(int(api.get_security_count(j) / 1000) + 1)], axis=0) for j in range(2)], axis=0)
        if type_ in ['stock', 'gp']:
            return pd.concat([data[data['sse'] == 'sz'][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 10000 <= 30][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 100000 != 2],
                              data[data['sse'] == 'sh'][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 100000 == 6]]).assign(code=data['code'].apply(lambda x: str(x)))
        elif type_ in ['index', 'zs']:

            return pd.concat([data[data['sse'] == 'sz'][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 1000 >= 399],
                              data[data['sse'] == 'sh'][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 1000 == 0]]).sort_index().assign(code=data['code'].apply(lambda x: str(x)))

        elif type_ in ['etf', 'ETF']:
            return pd.concat([data[data['sse'] == 'sz'][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 10000 == 15],
                              data[data['sse'] == 'sh'][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 10000 == 51]]).sort_index().assign(code=data['code'].apply(lambda x: str(x)))

        else:
            return data.assign(code=data['code'].apply(lambda x: str(x)))
예제 #21
0
def QA_fetch_get_security_bars(code, _type, lens, ip=None, port=None):
    """按bar长度推算数据

    Arguments:
        code {[type]} -- [description]
        _type {[type]} -- [description]
        lens {[type]} -- [description]

    Keyword Arguments:
        ip {[type]} -- [description] (default: {best_ip})
        port {[type]} -- [description] (default: {7709})

    Returns:
        [type] -- [description]
    """
    global best_ip
    if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None:
        best_ip = select_best_ip()
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None:
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    else:
        pass
    api = TdxHq_API()
    with api.connect(ip, port):
        data = pd.concat([api.to_df(api.get_security_bars(_select_type(_type), _select_market_code(
            code), code, (i - 1) * 800, 800)) for i in range(1, int(lens / 800) + 2)], axis=0)
        data = data\
            .assign(datetime=pd.to_datetime(data['datetime']), code=str(code))\
            .drop(['year', 'month', 'day', 'hour', 'minute'], axis=1, inplace=False)\
            .assign(date=data['datetime'].apply(lambda x: str(x)[0:10]))\
            .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(x)))\
            .assign(time_stamp=data['datetime'].apply(lambda x: QA_util_time_stamp(x)))\
            .assign(type=_type).set_index('datetime', drop=False, inplace=False).tail(lens)
        if data is not None:
            return data
        else:
            return None
예제 #22
0
def ping(ip, port=7709, type_='stock'):
    api = TdxHq_API()
    apix = TdxExHq_API()
    __time1 = datetime.datetime.now()
    try:
        if type_ in ['stock']:
            with api.connect(ip, port, time_out=0.7):
                if len(api.get_security_list(0, 1)) > 800:
                    return datetime.datetime.now() - __time1
                else:
                    print('BAD RESPONSE {}'.format(ip))
                    return datetime.timedelta(9, 9, 0)
        elif type_ in ['future']:
            with apix.connect(ip, port, time_out=0.7):
                if apix.get_instrument_count() > 10000:
                    return datetime.datetime.now() - __time1
                else:
                    print('️Bad FUTUREIP REPSONSE {}'.format(ip))
                    return datetime.timedelta(9, 9, 0)
    except:
        print('BAD RESPONSE {}'.format(ip))
        return datetime.timedelta(9, 9, 0)
예제 #23
0
def QA_fetch_get_stock_latest(code, ip=None, port=None):
    global best_ip
    if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None:
        best_ip = select_best_ip()
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None:
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    else:
        pass
    code = [code] if isinstance(code, str) else code
    api = TdxHq_API(multithread=True)
    with api.connect(ip, port):
        data = pd.concat([api.to_df(api.get_security_bars(
            9, _select_market_code(item), item, 0, 1)).assign(code=item) for item in code], axis=0)
        return data\
            .assign(date=pd.to_datetime(data['datetime']
                                        .apply(lambda x: x[0:10])), date_stamp=data['datetime']
                    .apply(lambda x: QA_util_date_stamp(str(x[0:10]))))\
            .set_index('date', drop=False)\
            .drop(['year', 'month', 'day', 'hour', 'minute', 'datetime'], axis=1)
예제 #24
0
def QA_fetch_get_stock_transaction(code, start, end, retry=2, ip=None, port=None):
    '历史分笔成交 buyorsell 1--sell 0--buy 2--盘前'
    global best_ip
    if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None:
        best_ip = select_best_ip()
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None:
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    else:
        pass
    api = TdxHq_API()

    real_start, real_end = QA_util_get_real_datelist(start, end)
    if real_start is None:
        return None
    real_id_range = []
    with api.connect(ip, port):
        data = pd.DataFrame()
        for index_ in range(trade_date_sse.index(real_start), trade_date_sse.index(real_end) + 1):

            try:
                data_ = __QA_fetch_get_stock_transaction(
                    code, trade_date_sse[index_], retry, api)
                if len(data_) < 1:
                    return None
            except:
                QA_util_log_info('Wrong in Getting {} history transaction data in day {}'.format(
                    code, trade_date_sse[index_]))
            else:
                QA_util_log_info('Successfully Getting {} history transaction data in day {}'.format(
                    code, trade_date_sse[index_]))
                data = data.append(data_)
        if len(data) > 0:

            return data.assign(datetime=data['datetime'].apply(lambda x: str(x)[0:19]))
        else:
            return None
예제 #25
0
def QA_fetch_get_stock_transaction(code, start, end, retry=2, ip=best_ip, port=7709):
    api = TdxHq_API()

    real_start, real_end = QA_util_get_real_datelist(start, end)
    real_id_range = []
    with api.connect(ip, port):
        data = pd.DataFrame()
        for index_ in range(trade_date_sse.index(real_start), trade_date_sse.index(real_end) + 1):

            try:
                data_ = __QA_fetch_get_stock_transaction(
                    code, trade_date_sse[index_], retry, api)
                if len(data_) < 1:
                    return None
            except:
                QA_util_log_info('Wrong in Getting %s history transaction data in day %s' % (
                    code, trade_date_sse[index_]))
            else:
                QA_util_log_info('Successfully Getting %s history transaction data in day %s' % (
                    code, trade_date_sse[index_]))
                data = data.append(data_)

        return data.assign(datetime=data['datetime'].apply(lambda x: str(x)[0:19]))
예제 #26
0
파일: QATdx.py 프로젝트: musicx/QUANTAXIS
def QA_fetch_get_stock_xdxr(code,
                            ip=best_ip['stock']['ip'],
                            port=best_ip['stock']['port']):
    '除权除息'
    api = TdxHq_API()
    market_code = _select_market_code(code)
    with api.connect(ip, port):
        category = {
            '1': '除权除息',
            '2': '送配股上市',
            '3': '非流通股上市',
            '4': '未知股本变动',
            '5': '股本变化',
            '6': '增发新股',
            '7': '股份回购',
            '8': '增发新股上市',
            '9': '转配股上市',
            '10': '可转债上市',
            '11': '扩缩股',
            '12': '非流通股缩股',
            '13': '送认购权证',
            '14': '送认沽权证'
        }
        data = api.to_df(api.get_xdxr_info(market_code, code))
        if len(data) >= 1:
            data = data\
                .assign(date=pd.to_datetime(data[['year', 'month', 'day']]))\
                .drop(['year', 'month', 'day'], axis=1)\
                .assign(category_meaning=data['category'].apply(lambda x: category[str(x)]))\
                .assign(code=str(code))\
                .rename(index=str, columns={'panhouliutong': 'liquidity_after',
                                            'panqianliutong': 'liquidity_before', 'houzongguben': 'shares_after',
                                            'qianzongguben': 'shares_before'})\
                .set_index('date', drop=False, inplace=False)
            return data.assign(date=data['date'].apply(lambda x: str(x)[0:10]))
        else:
            return None
예제 #27
0
def QA_fetch_depth_market_data(code=['000001', '000002'],
                               ip=best_ip['stock'],
                               port=7709):
    api = TdxHq_API()
    __data = pd.DataFrame()
    with api.connect(ip, port):
        code = [code] if type(code) is str else code
        for id_ in range(int(len(code) / 80) + 1):
            __data = __data.append(
                api.to_df(
                    api.get_security_quotes([
                        (_select_market_code(x), x)
                        for x in code[80 * id_:80 * (id_ + 1)]
                    ])))
            __data['datetime'] = datetime.datetime.now()
        data = __data[[
            'datetime', 'active1', 'active2', 'last_close', 'code', 'open',
            'high', 'low', 'price', 'cur_vol', 's_vol', 'b_vol', 'vol', 'ask1',
            'ask_vol1', 'bid1', 'bid_vol1', 'ask2', 'ask_vol2', 'bid2',
            'bid_vol2', 'ask3', 'ask_vol3', 'bid3', 'bid_vol3', 'ask4',
            'ask_vol4', 'bid4', 'bid_vol4', 'ask5', 'ask_vol5', 'bid5',
            'bid_vol5'
        ]]
        return data.set_index(['datetime', 'code'], drop=False, inplace=False)
예제 #28
0
파일: QATdx.py 프로젝트: ZhianLin/QUANTAXIS
def QA_fetch_get_stock_min(code, start, end, frequence='1min', ip=None, port=None):
    ip, port = get_mainmarket_ip(ip, port)
    api = TdxHq_API()
    type_ = ''
    start_date = str(start)[0:10]
    today_ = datetime.date.today()
    lens = QA_util_get_trade_gap(start_date, today_)
    if str(frequence) in ['5', '5m', '5min', 'five']:
        frequence, type_ = 0, '5min'
        lens = 48 * lens
    elif str(frequence) in ['1', '1m', '1min', 'one']:
        frequence, type_ = 8, '1min'
        lens = 240 * lens
    elif str(frequence) in ['15', '15m', '15min', 'fifteen']:
        frequence, type_ = 1, '15min'
        lens = 16 * lens
    elif str(frequence) in ['30', '30m', '30min', 'half']:
        frequence, type_ = 2, '30min'
        lens = 8 * lens
    elif str(frequence) in ['60', '60m', '60min', '1h']:
        frequence, type_ = 3, '60min'
        lens = 4 * lens
    if lens > 20800:
        lens = 20800
    with api.connect(ip, port):

        data = pd.concat([api.to_df(api.get_security_bars(frequence, _select_market_code(
            str(code)), str(code), (int(lens / 800) - i) * 800, 800)) for i in range(int(lens / 800) + 1)], axis=0)
        data = data\
            .assign(datetime=pd.to_datetime(data['datetime']), code=str(code))\
            .drop(['year', 'month', 'day', 'hour', 'minute'], axis=1, inplace=False)\
            .assign(date=data['datetime'].apply(lambda x: str(x)[0:10]))\
            .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(x)))\
            .assign(time_stamp=data['datetime'].apply(lambda x: QA_util_time_stamp(x)))\
            .assign(type=type_).set_index('datetime', drop=False, inplace=False)[start:end]
        return data.assign(datetime=data['datetime'].apply(lambda x: str(x)))
예제 #29
0
def QA_fetch_get_stock_list(type_='stock', ip=best_ip, port=7709):

    api = TdxHq_API()
    with api.connect(ip, port):
        data = pd.concat([
            pd.concat([
                api.to_df(api.get_security_list(j, i * 1000)).assign(
                    sse='sz' if j == 0 else 'sh').set_index(['code', 'sse'],
                                                            drop=False)
                for i in range(int(api.get_security_count(j) / 1000) + 1)
            ],
                      axis=0) for j in range(2)
        ],
                         axis=0)
        if type_ in ['stock', 'gp']:
            return pd.concat([
                data[data['sse'] == 'sz'][data.assign(code=data['code'].apply(
                    lambda x: int(x)))['code'] // 10000 <= 30][data.assign(
                        code=data['code'].apply(lambda x: int(x)))['code'] //
                                                               100000 != 2],
                data[data['sse'] == 'sh'][data.assign(
                    code=data['code'].apply(lambda x: int(x)))['code'] //
                                          100000 == 6]
            ]).assign(code=data['code'].apply(lambda x: str(x)))
        elif type_ in ['index', 'zs']:

            return pd.concat([
                data[data['sse'] == 'sz'][data.assign(
                    code=data['code'].apply(lambda x: int(x)))['code'] //
                                          1000 >= 399],
                data[data['sse'] == 'sh'][data.assign(
                    code=data['code'].apply(lambda x: int(x)))['code'] //
                                          1000 == 0]
            ]).sort_index().assign(code=data['code'].apply(lambda x: str(x)))
        else:
            return data.assign(code=data['code'].apply(lambda x: str(x)))
def download_index_bars(index_code, freq='day', market=None):
    """获取指数
    market -> 市场代码 0:深圳,1:上海
    """
    if not market:
        if stock_code[0] == '3':
            market = 0
        else:
            market = 1
    category = FREQUENT[freq]

    api = TdxHq_API()
    with api.connect('119.147.212.81', 7709):
        index = 0
        stock_data = []
        while True:
            older_data = api.get_index_bars(category, market, index_code, index * 800, 800)
            if older_data:
                stock_data = older_data + stock_data
                index += 1
            else:
                break
        stock_df = api.to_df(stock_data) # 返回DataFrame
    return stock_df[ct.STOCK_COLS]
예제 #31
0
def QA_fetch_get_stock_realtime(code=['000001', '000002'], ip=None, port=None):
    global best_ip
    if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None:
        best_ip = select_best_ip()
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None:
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    else:
        pass
    api = TdxHq_API()
    __data = pd.DataFrame()
    with api.connect(ip, port):
        code = [code] if type(code) is str else code
        for id_ in range(int(len(code) / 80) + 1):
            __data = __data.append(api.to_df(api.get_security_quotes(
                [(_select_market_code(x), x) for x in code[80 * id_:80 * (id_ + 1)]])))
            __data['datetime'] = datetime.datetime.now()
        data = __data[['datetime', 'active1', 'active2', 'last_close', 'code', 'open', 'high', 'low', 'price', 'cur_vol',
                       's_vol', 'b_vol', 'vol', 'ask1', 'ask_vol1', 'bid1', 'bid_vol1', 'ask2', 'ask_vol2',
                       'bid2', 'bid_vol2', 'ask3', 'ask_vol3', 'bid3', 'bid_vol3', 'ask4',
                       'ask_vol4', 'bid4', 'bid_vol4', 'ask5', 'ask_vol5', 'bid5', 'bid_vol5']]
        return data.set_index('code', drop=False, inplace=False)
예제 #32
0
def QA_fetch_depth_market_data(code=['000001', '000002'], ip=None, port=None):
    global best_ip
    if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None:
        best_ip = select_best_ip()
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None:
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    else:
        pass
    api = TdxHq_API()
    __data = pd.DataFrame()
    with api.connect(ip, port):
        code = [code] if type(code) is str else code
        for id_ in range(int(len(code) / 80) + 1):
            __data = __data.append(api.to_df(api.get_security_quotes(
                [(_select_market_code(x), x) for x in code[80 * id_:80 * (id_ + 1)]])))
            __data['datetime'] = datetime.datetime.now()
        data = __data[['datetime', 'active1', 'active2', 'last_close', 'code', 'open', 'high', 'low', 'price', 'cur_vol',
                       's_vol', 'b_vol', 'vol', 'ask1', 'ask_vol1', 'bid1', 'bid_vol1', 'ask2', 'ask_vol2',
                       'bid2', 'bid_vol2', 'ask3', 'ask_vol3', 'bid3', 'bid_vol3', 'ask4',
                       'ask_vol4', 'bid4', 'bid_vol4', 'ask5', 'ask_vol5', 'bid5', 'bid_vol5']]
        return data.set_index(['datetime', 'code'], drop=False, inplace=False)
예제 #33
0
def QA_fetch_get_stock_list(type_='stock', ip=None, port=None):
    global best_ip
    if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None:
        best_ip = select_best_ip()
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None:
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    else:
        pass
    api = TdxHq_API()
    with api.connect(ip, port):
        data = pd.concat([pd.concat([api.to_df(api.get_security_list(j, i * 1000)).assign(sse='sz' if j == 0 else 'sh').set_index(
            ['code', 'sse'], drop=False) for i in range(int(api.get_security_count(j) / 1000) + 1)], axis=0) for j in range(2)], axis=0)
        #data.code = data.code.apply(int)
        sz = data.query('sse=="sz"')
        sh = data.query('sse=="sh"')

        sz = sz.assign(sec=sz.code.apply(for_sz))
        sh = sh.assign(sec=sh.code.apply(for_sh))

        if type_ in ['stock', 'gp']:

            return pd.concat([sz, sh]).query('sec=="stock_cn"').sort_index().assign(name=data['name'].apply(lambda x: str(x)[0:6]))

        elif type_ in ['index', 'zs']:

            return pd.concat([sz, sh]).query('sec=="index_cn"').sort_index().assign(name=data['name'].apply(lambda x: str(x)[0:6]))
            #.assign(szm=data['name'].apply(lambda x: ''.join([y[0] for y in lazy_pinyin(x)])))\
            #.assign(quanpin=data['name'].apply(lambda x: ''.join(lazy_pinyin(x))))
        elif type_ in ['etf', 'ETF']:
            return pd.concat([sz, sh]).query('sec=="etf_cn"').sort_index().assign(name=data['name'].apply(lambda x: str(x)[0:6]))

        else:
            return data.assign(code=data['code'].apply(lambda x: str(x))).assign(name=data['name'].apply(lambda x: str(x)[0:6]))
예제 #34
0
파일: Tdx.py 프로젝트: Rgveda/TradingLib
 def __hq_bars(self, code, offset, frequency=9, index=False):
     assert self.__hq.qsize() > 0
     api = TdxHq_API()
     if index is True:
         market_func = get_index_market
         bars_func = api.get_index_bars
     else:
         market_func = get_code_market
         bars_func = api.get_security_bars
     ip, port = self.__hq.get()
     with api.connect(ip, port):
         df = list()
         for _code in code:
             market = market_func(_code)
             for _start, _count in offset:
                 df.append(
                     api.to_df(
                         bars_func(frequency, market, _code, _start,
                                   _count)).assign(code=_code))
         api.disconnect()
         self.__hq.put((ip, port))
         if len(df) < 1:
             return None
         return pandas.concat(df, sort=False)
예제 #35
0
파일: QATdx.py 프로젝트: musicx/QUANTAXIS
def QA_fetch_get_stock_block(ip=best_ip['stock']['ip'],
                             port=best_ip['stock']['port']):
    '板块数据'
    api = TdxHq_API()
    with api.connect(ip, port):

        data = pd.concat([
            api.to_df(api.get_and_parse_block_info("block_gn.dat")).assign(
                type='gn'),
            api.to_df(
                api.get_and_parse_block_info("block.dat")).assign(type='yb'),
            api.to_df(api.get_and_parse_block_info("block_zs.dat")).assign(
                type='zs'),
            api.to_df(
                api.get_and_parse_block_info("block_fg.dat")).assign(type='fg')
        ])

        if len(data) > 10:
            return data.assign(source='tdx').drop(
                ['block_type', 'code_index'],
                axis=1).set_index('code', drop=False,
                                  inplace=False).drop_duplicates()
        else:
            QA_util_log_info('Wrong with fetch block ')
예제 #36
0
def QA_fetch_get_stock_transaction(code, start, end, retry=2, ip=best_ip, port=7709):
    '逐笔成交'
    api = TdxHq_API()

    real_start, real_end = QA_util_get_real_datelist(start, end)
    real_id_range = []
    with api.connect(ip, port):
        data = pd.DataFrame()
        for index_ in range(trade_date_sse.index(real_start), trade_date_sse.index(real_end) + 1):

            try:
                data_ = __QA_fetch_get_stock_transaction(
                    code, trade_date_sse[index_], retry, api)
                if len(data_) < 1:
                    return None
            except:
                QA_util_log_info('Wrong in Getting %s history transaction data in day %s' % (
                    code, trade_date_sse[index_]))
            else:
                QA_util_log_info('Successfully Getting %s history transaction data in day %s' % (
                    code, trade_date_sse[index_]))
                data = data.append(data_)

        return data.assign(datetime=data['datetime'].apply(lambda x: str(x)[0:19]))
예제 #37
0
def QA_fetch_get_stock_day(code,
                           start_date,
                           end_date,
                           ip='119.147.212.81',
                           port=7709):
    api = TdxHq_API()
    market_code = __select_market_code(code)
    start_date = QA_util_get_real_date(start_date, trade_date_sse, 1)
    end_date = QA_util_get_real_date(end_date, trade_date_sse, -1)
    with api.connect(ip, port):
        data = []
        for i in range(10):
            data += api.get_security_bars(9, market_code, code, (9 - i) * 800,
                                          800)
        data = api.to_df(data)
        data['date'] = data['datetime'].apply(lambda x: x[0:10])
        data['date_stamp'] = data['date'].apply(
            lambda x: QA_util_date_stamp(x))
        data['date'] = pd.to_datetime(data['date'])
        data = data.set_index('date', drop=False)
        data['date'] = data['date'].apply(lambda x: str(x)[0:10])
        data = data.drop(
            ['year', 'month', 'day', 'hour', 'minute', 'datetime'], axis=1)
        return data[start_date:end_date]
예제 #38
0
파일: QATdx.py 프로젝트: hengthu/QUANTAXIS
def QA_fetch_get_stock_min(code,
                           start,
                           end,
                           level='1min',
                           ip=best_ip,
                           port=7709):
    api = TdxHq_API()
    type_ = ''
    if str(level) in ['5', '5m', '5min', 'five']:
        level, type_ = 0, '5min'
    elif str(level) in ['1', '1m', '1min', 'one']:
        level, type_ = 8, '1min'
    elif str(level) in ['15', '15m', '15min', 'fifteen']:
        level, type_ = 1, '15min'
    elif str(level) in ['30', '30m', '30min', 'half']:
        level, type_ = 2, '30min'
    elif str(level) in ['60', '60m', '60min', '1h']:
        level, type_ = 3, '60min'
    with api.connect(ip, port):

        data = pd.concat([
            api.to_df(
                api.get_security_bars(level, __select_market_code(str(code)),
                                      str(code), (25 - i) * 800, 800))
            for i in range(26)
        ],
                         axis=0)

        data = data\
            .assign(datetime=pd.to_datetime(data['datetime']), code=str(code))\
            .drop(['year', 'month', 'day', 'hour', 'minute'], axis=1, inplace=False)\
            .assign(date=data['datetime'].apply(lambda x: str(x)[0:10]))\
            .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(x)))\
            .assign(time_stamp=data['datetime'].apply(lambda x: QA_util_time_stamp(x)))\
            .assign(type=type_).set_index('datetime', drop=False, inplace=False)[start:end]
        return data.assign(datetime=data['datetime'].apply(lambda x: str(x)))
예제 #39
0
from pytdx.hq import TdxHq_API

api = TdxHq_API()

with api.connect('119.147.212.81', 7709):
    df = api.to_df(api.get_security_quotes([(0, '000001'), (1, '600300')]))
    print(df.to_json())

    data = api.get_minute_time_data(1, '600300')
    print(data)

    list_df = api.to_df(api.get_security_list(0, 300))
    print(list_df.to_json())
예제 #40
0
class MongoDB(object):
    def __init__(
            self,
            ip="stock_mongo",  #mongo db 数据库docker 容器名
            port=27017,
            user_name=None,
            pwd=None,
            authdb=None):
        self.__server_ip = ip
        self.__server_port = port
        self.__user_name = user_name
        self.__pwd = pwd
        self.__authdb = authdb
        self.client = None
        self.trade_day = True
        self.TDX_IP_SETS = STOCK_IP_SETS
        self.api = TdxHq_API(heartbeat=True)
        self.today = None
        self.accounts = []
        self.db = "stock_mock"  #数据库
        self.account_collection = "account"  #保存各个账户的当前资金信息
        self.account_his_collection = "account_history"  #保存每个账户的历史净值信息
        self.prefix = "holdlist_"
        self.accounts = []
        self.stocks = []

    def connect(self):
        '''建立数据库的连接
        '''
        _db_session = MongoClient(self.__server_ip, self.__server_port)
        if self.__user_name:
            eval("_db_session.{}".format(self.__authdb)).authenticate(
                self.__user_name, self.__pwd)

        self.client = _db_session

    def connect_market(self):
        for ip in self.TDX_IP_SETS:
            try:
                if self.api.connect(ip, 7709):
                    return
            except:
                pass

    def disconnect(self):
        '''断开数据库连接        
        '''
        self.client.close()
        return True

    def _dbclient(self, db):
        '''返回某个特定数据库的对象
        '''
        return eval("self.client.{}".format(db))

    def handle_ex_right(self):
        '''处理持仓股票除权价格和数量
        '''
        func = lambda x: 0 if not x else x
        today = datetime.datetime.today().date().day
        year = datetime.datetime.today().date().year
        month = datetime.datetime.today().date().month

        for stock in self.stocks:
            mk = self._select_market_code(stock)
            cqcx = self.api.get_xdxr_info(mk, stock)[::-1]
            dct = {"fenhong": 0, 'peigu': 0, 'peigujia': 0, "songzhuangu": 0}
            iscq = False
            for i in cqcx:
                if i["day"] != today or i["month"] != month or i[
                        "year"] != year:
                    break
                else:
                    iscq = True
                    dct["fenhong"] += func(i["fenhong"])
                    dct["peigu"] += func(i["peigu"])
                    dct["peigujia"] += func(i["peigujia"])
                    dct["songzhuangu"] += func(i["songzhuangu"])

            if iscq:  #发生除权除息
                rst = self.api.get_security_bars(4, mk, stock, 0, 2)
                if rst[0]["day"] != today or i["month"] != month or i[
                        "year"] != year:
                    close = rst[0]["close"]
                else:
                    close = rst[1]["close"]
                preclose = (close * 10 - dct["fenhong"] +
                            dct["peigu"] * dct['peigujia']) / (
                                10 + dct['peigu'] + dct['songzhuangu'])
                rate = close / preclose
                logger.info("除权除息:{},rate:{}".format(stock, rate))
                for account in self.accounts:
                    filt = {"code": stock, "cx_date": {"$ne": self.today}}
                    dt = {
                        "$mul": {
                            "cost": 1 / rate,
                            "number": rate
                        },
                        "$set": {
                            "cx_date": self.today
                        }
                    }
                    self._dbclient(self.db)[self.prefix + account].update_one(
                        filt, dt)

    def set_accounts(self):

        self.accounts = [
            i["account"]
            for i in self._dbclient(self.db)[self.account_collection].find()
        ]

    def set_stocks(self):
        rst = []
        for account in self.accounts:
            rst.extend([
                i["code"]
                for i in self._dbclient(self.db)[self.prefix + account].find(
                    {"number": {
                        "$gt": 0
                    }}, {
                        "_id": 0,
                        "code": 1
                    })
            ])
        self.stocks = set(rst)

    def initial(self):
        '''每天初始化状态,连接行情数据源,更新除权信息
        '''
        self.today = datetime.datetime.today().date().strftime('%Y-%m-%d')
        df = ts.trade_cal()
        self.trade_day = df[(
            df["calendarDate"] == self.today)].isOpen.values[0]
        if self.trade_day:  #交易日,连接数据库,连接行情源,处理除权除息
            self.connect()
            self.connect_market()
            self.set_accounts()
            self.set_stocks()
            self.handle_ex_right()
        logger.info("initial finished")

    def _select_market_code(self, code):
        code = str(code)
        if code[0] in ['5', '6', '9'] or code[:3] in [
                "009", "126", "110", "201", "202", "203", "204"
        ]:
            return 1
        return 0

    def updateaccount(self, account="test"):
        '''更新账户净值,添加一条净值记录
        '''
        hold_collection = self.prefix + account
        tm = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        plimit = 80
        filt = {'number': {'$gt': 0}}
        stocks = [(self._select_market_code(i["code"]), i["code"])
                  for i in self._dbclient(self.db)[hold_collection].find(filt)]
        rst = {}
        for i in range(math.ceil(len(stocks) / plimit)):
            ss = stocks[i * plimit:(i + 1) * plimit]
            for item in self.api.get_security_quotes(ss):
                rst[item["code"]] = item["price"]

        if len(rst) > 0:
            bulk = self._dbclient(
                self.db)[hold_collection].initialize_ordered_bulk_op()
            for code, price in rst.items():
                d = {"price": price, "update_datetime": tm}
                bulk.find({"code": code}).upsert().update({"$set": d})
            bulk.execute()
        holdvalue = self._dbclient(self.db)[hold_collection].aggregate([{
            "$group": {
                "_id": None,
                "total": {
                    "$sum": {
                        "$multiply": ["$price", "$number"]
                    }
                }
            }
        }])
        try:
            holdvalue = [i for i in holdvalue][0]["total"]
        except:
            holdvalue = 0
        rst = self._dbclient(self.db)[self.account_collection].find(
            {"account": account}, {"_id": 0})[0]
        rst["total"] = rst["rest"] + holdvalue
        rst["hold"] = holdvalue
        #更新账户当前值
        self._dbclient(self.db)[self.account_collection].update_one(
            {"account": account}, {"$set": rst})
        #更新账户历史记录值
        dtm = datetime.datetime.now()
        minute = dtm.minute
        if minute >= 50:
            dtm = dtm.replace(hour=dtm.hour + 1, minute=0)
        else:
            minute = int(minute / 10) * 10 + 10
            dtm = dtm.replace(minute=minute)
        self._dbclient(self.db)[self.account_his_collection].update_one(
            {
                "account": account,
                "date": dtm.strftime("%Y-%m-%d %H:%M")
            }, {"$set": rst},
            upsert=True)

    def run(self):
        if not self.trade_day:  #交易日,更新账户信息
            return
        for account in self.accounts:
            self.updateaccount(account)
예제 #41
0
    def _run(self):
        src_dir = self.config['tdx']['dir']
        dest_dir = self.config['hdf5']['dir']
        hdf5_import_progress = {
            'SH': {
                'DAY': 0,
                '1MIN': 0,
                '5MIN': 0
            },
            'SZ': {
                'DAY': 0,
                '1MIN': 0,
                '5MIN': 0
            }
        }
        trans_progress = {'SH': 0, 'SZ': 0}
        time_progress = {'SH': 0, 'SZ': 0}

        #正在导入代码表
        self.send_message(['INFO', '导入股票代码表'])

        connect = sqlite3.connect(dest_dir + "/stock.db")
        create_database(connect)

        pytdx_api = TdxHq_API()
        pytdx_api.connect(self.hosts[0][2], self.hosts[0][3])

        count = import_stock_name(connect, pytdx_api, 'SH', self.quotations)
        if count > 0:
            self.send_message(['INFO', '上证新增股票数:%s' % count])
        count = import_stock_name(connect, pytdx_api, 'SZ', self.quotations)
        if count > 0:
            self.send_message(['INFO', '深证新增股票数:%s' % count])

        self.process_list.clear()
        for task in self.tasks:
            p = Process(target=task)
            self.process_list.append(p)
            p.start()

        finished_count = len(self.tasks)
        while finished_count > 0:
            message = self.queue.get()
            taskname, market, ktype, progress, total = message
            if progress is None:
                finished_count -= 1
                if taskname in ('IMPORT_KDATA', 'IMPORT_TRANS', 'IMPORT_TIME'):
                    self.send_message(
                        [taskname, 'FINISHED', market, ktype, total])
                else:
                    self.send_message([taskname, 'FINISHED'])
                continue

            if taskname == 'IMPORT_WEIGHT':
                if market == 'INFO':
                    self.send_message(['INFO', ktype])
                self.send_message([taskname, market, total])
            elif taskname == 'IMPORT_FINANCE':
                self.send_message([taskname, progress])
            elif taskname == 'IMPORT_KDATA':
                hdf5_import_progress[market][ktype] = progress
                current_progress = (hdf5_import_progress['SH'][ktype] +
                                    hdf5_import_progress['SZ'][ktype]) // 2
                self.send_message([taskname, ktype, current_progress])
            elif taskname == 'IMPORT_TRANS':
                trans_progress[market] = progress
                current_progress = (trans_progress['SH'] +
                                    trans_progress['SZ']) // 2
                self.send_message([taskname, ktype, current_progress])
            elif taskname == 'IMPORT_TIME':
                time_progress[market] = progress
                current_progress = (time_progress['SH'] +
                                    time_progress['SZ']) // 2
                self.send_message([taskname, ktype, current_progress])
            else:
                print("Unknow task: ", taskname)
예제 #42
0
def test_raise_excepiton():
    api = TdxHq_API(raise_exception=True)
    with pytest.raises(TdxConnectionError):
        with api.connect('8.8.8.8'):
            pass
예제 #43
0
파일: tdx.py 프로젝트: piaoxue85/wakuang
class TDX(object):
    '''
    This class is tong da xin data source.
    We can use it to get down the stock datas.
    Tushare can't get minter line and or year line.
    TDX can search index of stock and funds.
    '''
    def __init__(self):
        self.tdx_api = TdxHq_API()
        self.__ip = '119.147.212.81'  #输入IP
        self.__port = 7709  #端口
        self.__code = '600200'
        self.__market = 1  #市场代码 0:深圳,1:上海
        self._startdate = "2017-01-01"
        self.today = datetime.date.today()
        self._enddate = datetime.datetime.strftime(self.today, '%Y-%m-%d')

        self.__mkt_segment = {
            'sh': '60',
            "sz": '00',
            "cyb": "30",
        }  #segment  当前板块开始字符串

    def __str__(self):
        return 'TDX object (code : %s)' % self.code

    @property
    def IP(self):  # self.IP
        return self.__ip

    @property
    def PORT(self):
        return self.__port

    @property
    def code(self):  #定义stock code 属性
        return self.__code

    @code.setter  #设定code
    def code(self, code_input):
        """
        The setter of the code property
        """
        if not isinstance(code_input, str):  #确定是否是字符串
            raise ValueError('the code must string!')
        if not len(code_input) == 6:  #确定长度
            raise ValueError('the code value error,the len must SIX !')
        if code_input.startswith('60'):  #确定表头
            self.__market = 1
        elif code_input.startswith('00'):
            self.__market = 0
        elif code_input.startswith('30'):
            self.__market = 0
        else:
            raise ValueError('this code is not stock code')
        self.__code = code_input

    @property
    def startdate(self):  #开始日期
        return self._startdate

    @startdate.setter  #设置日期
    def startdate(self, date_input):
        """
        The setter of the start date property
        """
        if not isinstance(date_input, str):
            raise ValueError('the date must string!')
        if not len(date_input) == 8:
            raise ValueError(
                'the date value error,the date formet must xxxx-xx-xx !')
        self._startdate = date_input

    @property  #结束日期
    def enddate(self):
        return self._enddate

    @enddate.setter
    def enddate(self, date_input):
        """
        The setter of the start date property
        """
        if not isinstance(date_input, str):
            raise ValueError('the date must string!')
        if not len(date_input) == 8:
            raise ValueError(
                'the date value error,the date formet must xxxx-xx-xx !')
        self._enddate = date_input

    def get_day_data_tdx(self):  #获取K line
        with self.tdx_api.connect(self.IP, self.PORT):
            data = self.tdx_api.get_k_data(self.code, self.startdate,
                                           self.enddate)
            data = pandas.DataFrame(data)
            data.date = data.date.apply(
                lambda x: datetime.datetime.strptime(x, "%Y-%m-%d"))
        return data

    #TODO: 现在是用800点进行计数,以后会细化功能
    def get_k_data_tdx(self, k_mode=9):
        """
        获取k 线图,总计800 点

        Parameters
        ----------
        k_mode= 0-11 
                    0 5分钟K线 
                    1 15分钟K线 
                    2 30分钟K线 
                    3 1小时K线 
                    4 日K线
                    5 周K线
                    6 月K线
                    7 1分钟
                    8 1分钟K线 9 日K线
                    10 季K线
                    11 年K线

        Returns
        -------

        """
        with self.tdx_api.connect(self.self.IP, self.self.PORT):
            data = self.tdx_api.get_security_bars(k_mode, self.__market,
                                                  self.code, 0, 800)

            data = pandas.DataFrame(data)
            #data.date = data.date.apply(
            #    lambda x: datetime.datetime.strptime(x, "%Y-%m-%d"))
        return data

    def len_market(self):  #市场有多少只股票
        with self.tdx_api.connect(self.IP, self.PORT):
            _len = self.tdx_api.get_security_count(self.__market)
        return _len

    def get_page_tdx(self, block=None):

        if block is None:
            market = 1
            page = [0]
        elif block in ['sh', 'SH']:
            market = 1
            page = [13, 14]
        elif block in ['sz', 'SZ']:
            print('block for shenzhen')
            market = 0
            page = [0, 1]
        elif block in ['cyb', 'CYB']:
            print('block for chuang ye ban')
            market = 0
            page = [7, 8]
        else:
            pass
        code_list_df = pandas.DataFrame()
        with self.tdx_api.connect(self.IP, self.PORT):
            for pn in page:
                data = self.tdx_api.get_security_list(market, pn * 1000)
                data = pandas.DataFrame(data)
                print(data)
                code_list_df = code_list_df.append(data, ignore_index=True)
        return code_list_df

    def get_base_finace_tdx(self):
        with self.tdx_api.connect(self.IP, self.PORT):
            data = self.tdx_api.get_finance_info(0, '000001')
            data = pandas.Series(data)
            print(data)

    def get_min_data(self):
        from pytdx.params import TDXParams
        with self.tdx_api.connect(self.IP, self.PORT):
            data = self.tdx_api.get_history_minute_time_data(
                TDXParams.MARKET_SH, self.code, 20161209)
            data = pandas.DataFrame(data)
            print(data)

    #TODO: 需要确定 0: buy  1 : sell
    def get_tick_data(self):
        """
        历史分笔交易:time 顺序; price ; vol ;buyorsell [1:] [0:];

        sh 60 13000-14000


        Parameters
        ----------

        Returns
        -------

        """
        data = pandas.DataFrame()
        with self.tdx_api.connect(self.IP, self.PORT):
            for i in [2000, 0000]:
                df = self.tdx_api.get_history_transaction_data(
                    TDXParams.MARKET_SH, "600547", i, 2000, 20160308)
                df = pandas.DataFrame(df)

                data = data.append(df, ignore_index=True)

        return data

    def get_tick_today(self):
        """
        Get every time the each deal for today.每组数最大len 2 k 所以要确定的数据长度

        Parameters
        ----------
        self: 

        Returns
        -------

        """

        with self.tdx_api.connect(self.IP, self.PORT):
            data = pandas.DataFrame()
            for i in [0, 2000]:
                df = self.tdx_api.get_transaction_data(self.__market,
                                                       self.code, i, 2000)
                df = pandas.DataFrame(df)
                data = data.append(df, ignore_index=True)

        return data

    def get_block(self):
        with self.tdx_api.connect(self.IP, self.PORT):
            data = self.tdx_api.get_and_parse_block_info("block.dat")
            data = pandas.DataFrame(data)
            print(data)

    def get_market_segment_list(self, mkt):
        data = self.get_page_tdx(mkt)
        self.code_list = pandas.DataFrame()
        pbar = tqdm(total=len(data.code))
        mkt_hard = self.mkt_segment[mkt]
        for idx, __code in enumerate(data.code):
            pbar.update(1)
            if __code.startswith(mkt_hard, 0, 2):
                self.code_list = self.code_list.append(data.loc[idx],
                                                       ignore_index=True)
        return self.code_list

    def get_sh_list(self):
        return self.get_market_segment_list('sh')

    def get_sz_list(self):
        return self.get_market_segment_list('sz')

    def get_cyb_list(self):
        return self.get_market_segment_list('cyb')
예제 #44
0
def QA_fetch_get_stock_day(code, start_date, end_date, if_fq='00', level='day', ip=best_ip, port=7709):
    api = TdxHq_API()
    with api.connect(ip, port):

        if level in ['day', 'd', 'D', 'DAY', 'Day']:
            level = 9
        elif level in ['w', 'W', 'Week', 'week']:
            level = 5
        elif level in ['month', 'M', 'm', 'Month']:
            level = 6
        elif level in ['Q', 'Quarter', 'q']:
            level = 10
        elif level in ['y', 'Y', 'year', 'Year']:
            level = 11

        data = pd.concat([api.to_df(api.get_security_bars(level, __select_market_code(
            code), code, (9 - i) * 800, 800)) for i in range(10)], axis=0)
        if if_fq in ['00', 'bfq']:
            data = data.assign(date=data['datetime'].apply(lambda x: str(x[0:10]))).assign(code=str(code))\
                .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\
                .set_index('date', drop=False, inplace=False)\
                .drop(['year', 'month', 'day', 'hour',
                       'minute', 'datetime'], axis=1)[start_date:end_date]
            return data.assign(date=data['date'].apply(lambda x: str(x)[0:10]))
        elif if_fq in ['01', 'qfq']:
            xdxr_data = QA_fetch_get_stock_xdxr(code)

            info = xdxr_data[xdxr_data['category'] == 1]

            bfq_data = data\
                .assign(date=pd.to_datetime(data['datetime'].apply(lambda x: x[0:10])))\
                .assign(code=str(code))\
                .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\
                .set_index('date', drop=False, inplace=False)\
                .drop(['year', 'month', 'day', 'hour',
                       'minute', 'datetime'], axis=1)

            bfq_data['if_trade'] = True
            data = pd.concat([bfq_data, info[['category']]
                              [bfq_data.index[0]:]], axis=1)

            data['date'] = data.index
            data['if_trade'].fillna(value=False, inplace=True)
            data = data.fillna(method='ffill')
            data = pd.concat([data, info[['fenhong', 'peigu', 'peigujia',
                                          'songzhuangu']][bfq_data.index[0]:]], axis=1)
            data = data.fillna(0)

            data['preclose'] = (data['close'].shift(1) * 10 - data['fenhong'] + data['peigu']
                                * data['peigujia']) / (10 + data['peigu'] + data['songzhuangu'])
            data['adj'] = (data['preclose'].shift(-1) /
                           data['close']).fillna(1)[::-1].cumprod()
            data['open'] = data['open'] * data['adj']
            data['high'] = data['high'] * data['adj']
            data['low'] = data['low'] * data['adj']
            data['close'] = data['close'] * data['adj']
            data['preclose'] = data['preclose'] * data['adj']

            data = data[data['if_trade']]
            return data.drop(['fenhong', 'peigu', 'peigujia', 'songzhuangu', 'if_trade', 'category'], axis=1)[data['open'] != 0].assign(date=data['date'].apply(lambda x: str(x)[0:10]))[start_date:end_date]

        elif if_fq in ['03', 'ddqfq']:
            xdxr_data = QA_fetch_get_stock_xdxr(code)

            info = xdxr_data[xdxr_data['category'] == 1]

            bfq_data = data\
                .assign(date=pd.to_datetime(data['datetime'].apply(lambda x: x[0:10])))\
                .assign(code=str(code))\
                .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\
                .set_index('date', drop=False, inplace=False)\
                .drop(['year', 'month', 'day', 'hour',
                       'minute', 'datetime'], axis=1)

            bfq_data['if_trade'] = True
            data = pd.concat([bfq_data, info[['category']]
                              [bfq_data.index[0]:end_date]], axis=1)

            data['date'] = data.index
            data['if_trade'].fillna(value=False, inplace=True)
            data = data.fillna(method='ffill')
            data = pd.concat([data, info[['fenhong', 'peigu', 'peigujia',
                                          'songzhuangu']][bfq_data.index[0]:end_date]], axis=1)
            data = data.fillna(0)

            data['preclose'] = (data['close'].shift(1) * 10 - data['fenhong'] + data['peigu']
                                * data['peigujia']) / (10 + data['peigu'] + data['songzhuangu'])
            data['adj'] = (data['preclose'].shift(-1) /
                           data['close']).fillna(1)[::-1].cumprod()
            data['open'] = data['open'] * data['adj']
            data['high'] = data['high'] * data['adj']
            data['low'] = data['low'] * data['adj']
            data['close'] = data['close'] * data['adj']
            data['preclose'] = data['preclose'] * data['adj']

            data = data[data['if_trade']]
            return data.drop(['fenhong', 'peigu', 'peigujia', 'songzhuangu', 'if_trade', 'category'], axis=1)[data['open'] != 0].assign(date=data['date'].apply(lambda x: str(x)[0:10]))[start_date:end_date]

        elif if_fq in ['02', 'hfq']:
            xdxr_data = QA_fetch_get_stock_xdxr(code)

            info = xdxr_data[xdxr_data['category'] == 1]

            bfq_data = data\
                .assign(date=pd.to_datetime(data['datetime'].apply(lambda x: x[0:10])))\
                .assign(code=str(code))\
                .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\
                .set_index('date', drop=False, inplace=False)\
                .drop(['year', 'month', 'day', 'hour',
                       'minute', 'datetime'], axis=1)

            bfq_data['if_trade'] = True
            data = pd.concat([bfq_data, info[['category']]
                              [bfq_data.index[0]:]], axis=1)

            data['date'] = data.index
            data['if_trade'].fillna(value=False, inplace=True)
            data = data.fillna(method='ffill')
            data = pd.concat([data, info[['fenhong', 'peigu', 'peigujia',
                                          'songzhuangu']][bfq_data.index[0]:]], axis=1)
            data = data.fillna(0)

            data['preclose'] = (data['close'].shift(1) * 10 - data['fenhong'] + data['peigu']
                                * data['peigujia']) / (10 + data['peigu'] + data['songzhuangu'])
            data['adj'] = (data['preclose'].shift(-1) /
                           data['close']).fillna(1).cumprod()
            data['open'] = data['open'] / data['adj']
            data['high'] = data['high'] / data['adj']
            data['low'] = data['low'] / data['adj']
            data['close'] = data['close'] / data['adj']
            data['preclose'] = data['preclose'] / data['adj']
            data = data[data['if_trade']]
            return data.drop(['fenhong', 'peigu', 'peigujia', 'songzhuangu', 'if_trade', 'category'], axis=1)[data['open'] != 0].assign(date=data['date'].apply(lambda x: str(x)[0:10]))[start_date:end_date]

        elif if_fq in ['04', 'ddhfq']:
            xdxr_data = QA_fetch_get_stock_xdxr(code)

            info = xdxr_data[xdxr_data['category'] == 1]

            bfq_data = data\
                .assign(date=pd.to_datetime(data['datetime'].apply(lambda x: x[0:10])))\
                .assign(code=str(code))\
                .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\
                .set_index('date', drop=False, inplace=False)\
                .drop(['year', 'month', 'day', 'hour',
                       'minute', 'datetime'], axis=1)

            bfq_data['if_trade'] = True
            data = pd.concat([bfq_data, info[['category']]
                              [bfq_data.index[0]:end_date]], axis=1)

            data['date'] = data.index
            data['if_trade'].fillna(value=False, inplace=True)
            data = data.fillna(method='ffill')
            data = pd.concat([data, info[['fenhong', 'peigu', 'peigujia',
                                          'songzhuangu']][bfq_data.index[0]:end_date]], axis=1)
            data = data.fillna(0)

            data['preclose'] = (data['close'].shift(1) * 10 - data['fenhong'] + data['peigu']
                                * data['peigujia']) / (10 + data['peigu'] + data['songzhuangu'])
            data['adj'] = (data['preclose'].shift(-1) /
                           data['close']).fillna(1).cumprod()
            data['open'] = data['open'] / data['adj']
            data['high'] = data['high'] / data['adj']
            data['low'] = data['low'] / data['adj']
            data['close'] = data['close'] / data['adj']
            data['preclose'] = data['preclose'] / data['adj']
            data = data[data['if_trade']]
            return data.drop(['fenhong', 'peigu', 'peigujia', 'songzhuangu', 'if_trade', 'category'], axis=1)[data['open'] != 0].assign(date=data['date'].apply(lambda x: str(x)[0:10]))[start_date:end_date]
예제 #45
0
class TDXData(DataSource):
    def __init__(self, db_interface: DBInterface = None, host: str = None, port: int = None):
        super().__init__(db_interface)
        if host is None:
            conf = get_global_config()
            host = conf['tdx_server']['host']
            port = conf['tdx_server']['port']
        self.api = TdxHq_API()
        self.host = host
        self.port = port
        self._factor_param = utils.load_param('tdx_param.json')
        self.stock_ticker = StockTickers(db_interface)

    def connect(self):
        self.api.connect(self.host, self.port)

    def __enter__(self):
        self.connect()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.api.disconnect()

    def update_stock_minute(self):
        """更新股票分钟行情"""
        table_name = '股票分钟行情'
        db_timestamp = self.db_interface.get_latest_timestamp(table_name, dt.datetime(2015, 1, 1))
        start_date = self.calendar.offset(db_timestamp.date(), 1)
        end_date = dt.datetime.today()
        dates = self.calendar.select_dates(start_date, end_date)
        for date in dates:
            self.get_stock_minute(date)

    def get_stock_minute(self, date: dt.datetime) -> None:
        """获取 ``date`` 的股票分钟行情"""
        minute_data = self._get_stock_minute(date)
        auction_time = date + dt.timedelta(hours=9, minutes=25)
        auction_db_data = self.db_interface.read_table('股票集合竞价数据', columns=['成交价', '成交量', '成交额'], dates=auction_time)
        df = self.left_shift_minute_data(minute_data=minute_data, auction_db_data=auction_db_data)

        self.db_interface.insert_df(df, '股票分钟行情')

    def _get_stock_minute(self, date: dt.datetime) -> pd.DataFrame:
        num_days = self.calendar.days_count(date, dt.date.today())
        start_index = num_days * 60 * 4
        tickers = self.stock_ticker.ticker(date)

        storage = []
        with tqdm(tickers) as pbar:
            for ticker in tickers:
                pbar.set_description(f'下载 {ticker} 在 {date} 的分钟数据')
                code, market = self._split_ticker(ticker)
                data = self.api.get_security_bars(category=8, market=market, code=code, start=start_index, count=240)
                data = self._formatting_data(data, ticker)
                storage.append(data)
                pbar.update()

        df = pd.concat(storage)
        return df

    def _formatting_data(self, info: OrderedDict, ticker: str) -> pd.DataFrame:
        df = pd.DataFrame(info)
        df['datetime'] = df['datetime'].apply(self.str2datetime)
        df = df.drop(['year', 'month', 'day', 'hour', 'minute'], axis=1).rename(self._factor_param['行情数据'], axis=1)
        df['ID'] = ticker

        df = df.set_index(['DateTime', 'ID'], drop=True)
        return df

    @staticmethod
    def _split_ticker(ticker: str) -> [str, int]:
        code, market_str = ticker.split('.')
        market = 0 if market_str == 'SZ' else 1
        return code, market

    @staticmethod
    def str2datetime(date: str) -> dt.datetime:
        return dt.datetime.strptime(date, '%Y-%m-%d %H:%M')
예제 #46
0
def QA_fetch_get_stock_xdxr(code, ip='221.231.141.60', port=7709):
    api = TdxHq_API()
    market_code = __select_market_code(code)
    with api.connect():
        return api.to_df(api.get_xdxr_info(market_code, code))
예제 #47
0
class StdQuotes(object):
    """股票市场实时行情"""
    bestip = ('47.103.48.45', 7709)

    def __init__(self, **kwargs):

        try:
            default = settings.get('SERVER').get('HQ')[0]
            self.bestip = config.get('BESTIP').get('HQ', default)
        except ValueError:
            self.config = None

        self.client = TdxHq_API(**kwargs)

    def traffic(self):
        with self.client.connect(*self.bestip):
            return self.client.get_traffic_stats()

    def quotes(self, symbol=[]):
        '''
        获取实时日行情数据

        :param symbol: 股票代码
        :return: pd.dataFrame or None
        '''

        logger.debug(type(logger))

        if type(symbol) is str:
            symbol = [symbol]

        with self.client.connect(*self.bestip):
            symbol = get_stock_markets(symbol)
            result = self.client.get_security_quotes(symbol)

            return to_data(result)

    def bars(self, symbol='000001', frequency='9', start='0', offset='100'):
        '''
        获取实时日K线数据

        :param symbol: 股票代码
        :param frequency: 数据类别
        :param market: 证券市场
        :param start: 开始位置
        :param offset: 每次获取条数
        :return: pd.dataFrame or None
        '''
        with self.client.connect(*self.bestip):
            market = get_stock_market(symbol)
            result = self.client.get_security_bars(int(frequency), int(market),
                                                   str(symbol), int(start),
                                                   int(offset))

            return to_data(result)

    def stock_count(self, market=MARKET_SH):
        '''
        获取市场股票数量

        :param market: 股票市场代码 sh 上海, sz 深圳
        :return: pd.dataFrame or None
        '''
        with self.client.connect(*self.bestip):
            result = self.client.get_security_count(market=market)
            return result

    def stocks(self, market=MARKET_SH):
        '''
        获取股票列表

        :param market:
        :return:
        '''
        with self.client.connect(*self.bestip):
            counts = self.client.get_security_count(market=market)
            stocks = None

            for start in tqdm(range(0, counts, 1000)):
                result = self.client.get_security_list(market=market,
                                                       start=start)
                stocks = pandas.concat(
                    [stocks, to_data(result)],
                    ignore_index=True) if start > 1 else to_data(result)

            return stocks

    def index_bars(self,
                   symbol='000001',
                   frequency='9',
                   start='0',
                   offset='100'):
        '''
        获取指数k线

        :param symbol:
        :param frequency:
        :param start:
        :param offset:
        :return:
        '''
        with self.client.connect(*self.bestip):
            market = get_stock_market(symbol)
            result = self.client.get_index_bars(frequency=frequency,
                                                market=market,
                                                code=symbol,
                                                start=start,
                                                count=offset)

            return to_data(result)

    def minute(self, symbol=''):
        '''
        获取实时分时数据

        :param market: 证券市场
        :param symbol: 股票代码
        :return: pd.DataFrame
        '''
        with self.client.connect(*self.bestip):
            market = get_stock_market(symbol)
            result = self.client.get_minute_time_data(market=market,
                                                      code=symbol)
            return to_data(result)

    def minutes(self, symbol='', date='20191023'):
        '''
        分时历史数据

        :param market:
        :param symbol:
        :param date:
        :return: pd.dataFrame or None
        '''
        with self.client.connect(*self.bestip):
            market = get_stock_market(symbol)
            result = self.client.get_history_minute_time_data(market=market,
                                                              code=symbol,
                                                              date=date)

            return to_data(result)

    def transaction(self, symbol='', start=0, offset=10):
        '''
        查询分笔成交

        :param market: 市场代码
        :param symbol: 股票代码
        :param start: 起始位置
        :param offset: 请求数量
        :return: pd.dataFrame or None
        '''
        with self.client.connect(*self.bestip):
            market = get_stock_market(symbol)
            result = self.client.get_transaction_data(int(market), symbol,
                                                      int(start), int(offset))

            return to_data(result)

    def transactions(self, symbol='', start=0, offset=10, date='20170209'):
        '''
        查询历史分笔成交
        参数:市场代码, 股票代码,起始位置,日期 数量 如: 0,000001,0,10,20170209


        :param symbol: 股票代码
        :param start: 起始位置
        :param offset: 数量
        :param date: 日期
        :return: pd.dataFrame or None
        '''
        with self.client.connect(*self.bestip):
            market = get_stock_market(symbol, string=False)
            result = self.client.get_history_transaction_data(market=market,
                                                              code=symbol,
                                                              start=start,
                                                              count=offset,
                                                              date=date)

            return to_data(result)

    def F10C(self, symbol=''):
        '''
        查询公司信息目录

        :param market: 市场代码
        :param symbol: 股票代码
        :return: pd.dataFrame or None
        '''
        with self.client.connect(*self.bestip):
            market = get_stock_market(symbol)
            result = self.client.get_company_info_category(int(market), symbol)

            return result

    def F10(self, symbol='', name=''):
        '''
        读取公司信息详情

        :param name: 公司 F10 标题
        :param symbol: 股票代码
        :return: pd.dataFrame or None
        '''
        with self.client.connect(*self.bestip):
            result = {}
            market = get_stock_market(symbol, string=False)

            frequency = self.client.get_company_info_category(
                int(market), symbol)

            if name:
                for x in frequency:
                    if x['name'] == name:
                        return self.client.get_company_info_content(
                            market=market,
                            code=symbol,
                            filename=x['filename'],
                            start=x['start'],
                            length=x['length'])

            for x in frequency:
                result[x['name']] = self.client.get_company_info_content(
                    market=market,
                    code=symbol,
                    filename=x['filename'],
                    start=x['start'],
                    length=x['length'])
            else:
                pass

            return result

    def xdxr(self, symbol=''):
        '''
        读取除权除息信息

        :param market: 市场代码
        :param symbol: 股票代码
        :return: pd.dataFrame or None
        '''
        with self.client.connect(*self.bestip):
            market = get_stock_market(symbol)
            result = self.client.get_xdxr_info(int(market), symbol)

            return to_data(result)

    def finance(self, symbol='000001'):
        '''
        读取财务信息

        :param symbol:
        :return:
        '''
        with self.client.connect(*self.bestip):
            market = get_stock_market(symbol)
            result = self.client.get_finance_info(market=market, code=symbol)

            return to_data(result)

    def k(self, symbol='', begin=None, end=None):
        '''
        读取k线信息

        :param symbol:
        :param begin: 开始日期
        :param end: 截止日期
        :return: pd.dataFrame or None
        '''
        with self.client.connect(*self.bestip):
            result = self.client.get_k_data(symbol, begin, end)
            return to_data(result)

    def index(self,
              symbol='000001',
              market=MARKET_SH,
              frequency='9',
              start=1,
              offset=2):
        '''
        获取指数k线

        K线种类:
        - 0 5分钟K线
        - 1 15分钟K线
        - 2 30分钟K线
        - 3 1小时K线
        - 4 日K线
        - 5 周K线
        - 6 月K线
        - 7 1分钟
        - 8 1分钟K线
        - 9 日K线
        - 10 季K线
        - 11 年K线

        :param symbol: 股票代码
        :param frequency: 数据类别
        :param market: 证券市场
        :param start: 开始位置
        :param offset: 每次获取条数
        :return: pd.dataFrame or None
        '''
        with self.client.connect(*self.bestip):
            result = self.client.get_index_bars(int(frequency), int(market),
                                                str(symbol), int(start),
                                                int(offset))
            return to_data(result)

    def block(self, tofile="block.dat"):
        '''
        获取证券板块信息

        :param tofile:
        :return: pd.dataFrame or None
        '''
        with self.client.connect(*self.bestip):
            result = self.client.get_and_parse_block_info(tofile)
            return to_data(result)
예제 #48
0
class PytdxApi:
    """TDX数据服务类"""

    def __init__(self):
        """Constructor"""
        self.connect_status: bool = False
        self.login_status: bool = False

        self.hq_api = None  # 行情API
        self.conc_code_num = 50  # 并发获取行情的股票个数

        # 行情订阅
        self.active = False
        self.run_subscribe = Thread(target=self.get_realtime_data)
        self.symbols = list()
        self.symbols_split = list()

    def connect_api(self, host: str = "", port: int = 0):
        """连接行情api"""
        # 连接行情API并检查连接情况
        try:
            if not self.connect_status:
                self.hq_api = TdxHq_API()
                self.hq_api.connect(host, port)
                self.connect_status = True
                self.login_status = True
                self.subscribe_start()

        except Exception as e:
            return e

    def get_realtime_quotes(self, quotes_list: list):
        """获取实时行情数据"""
        data = self.hq_api.get_security_quotes(quotes_list)
        return data

    def get_realtime_data(self):
        """获取实时行情切片"""
        try:
            while self.active:
                if not self.symbols_split:
                    sleep(1)
                    continue

                data = list()
                for symbols in self.symbols_split:
                    d = self.get_realtime_quotes(symbols)
                    data.extend(d)

                self.on_tick_data(data)
                sleep(2)
        except:
            error = dict()
            error["error_id"] = "pytdx"
            error["error_msg"] = "行情订阅失败"
            self.on_error(error)

    def get_transaction_count(self, market: int) -> int:
        """
        查询市场标的数量
        """
        return self.hq_api.get_security_count(market)

    def get_transaction_list(self, market: int, start: int) -> list:
        """查询市场标的列表"""
        return self.hq_api.get_security_list(market, start)

    def subscribe_start(self):
        """启动行情订阅"""
        self.active = True
        self.run_subscribe.start()

    def subscribe(self, symbol: Any):
        """订阅行情数据"""
        if isinstance(symbol, tuple):
            if symbol not in self.symbols:
                self.symbols.append(symbol)
        elif isinstance(symbol, list):
            for s in symbol:
                if s not in self.symbols:
                    self.symbols.append(s)
        else:
            error = dict()
            error["error_id"] = "pytdx"
            error["error_msg"] = f"订阅标的代码格式不正确{symbol}"
            self.on_error(error)
            return

        symbol_split = self.get_code_split()
        self.symbols_split = copy(symbol_split)

    def subscribe_close(self):
        """关闭订阅"""
        if self.active:
            self.active = False
            self.run_subscribe.join()

    def get_transaction_info(self):
        """获取所有合约信息"""
        for exchange in list(exchange_map.values()):
            count = self.get_transaction_count(exchange)
            for c in range(0, count, 1000):
                symbols = self.get_transaction_list(exchange, c)
                for symbol in symbols:
                    symbol["exchange"] = exchange
                    if symbol["code"][:2] in ["60", "30", "688", "00"]:
                        symbol["product"] = 3
                    else:
                        symbol["product"] = 2

                    self.on_contract_info(symbol, False)

            self.on_contract_info({"exchange": exchange}, True)

    def get_all_stock(self):
        """获取所有股票数据"""
        stocks = list()

        for exchange in list(exchange_map.values()):
            count = self.get_transaction_count(exchange)
            for s in range(0, count, 1000):
                d = self.get_transaction_list(exchange, s)
                stocks.extend(d)

        l = len(stocks) - 1
        for i, stock in enumerate(stocks):
            if stock["code"][:1] in ["60", "30", "688", "00"]:
                if i == l:
                    self.on_contract_info(stock, True)
                else:
                    self.on_contract_info(stock, False)

    def on_contract_info(self, data: dict, last: bool) -> None:
        """"""
        pass

    def on_tick_data(self, data):
        """订阅数据处理"""
        pass

    def on_error(self, err):
        """接口错误处理"""
        pass

    @staticmethod
    def generate_symbols(symbols: list):
        """组装symbols数据,pytdx接收的是以市场代码和标的代码组成的元祖的list"""
        new_symbols = []

        for symbol in symbols:
            code, exchange = symbol.split(".")
            new_symbol = (exchange_map[exchange], code)
            new_symbols.append(new_symbol)

        return new_symbols

    @staticmethod
    def get_fast_ip():
        """获取最快IP"""
        host = "210.51.39.201"
        port = 7709

        return host, port

    @staticmethod
    def check_symbol(symbol: str):
        """检查标的格式"""
        if symbol:
            code, market = symbol.split(".")
            market = exchange_map.get(market)
            return code, market

        else:
            return False

    def get_code_split(self):
        """获得切割好的股票代码段"""
        code_split_list = []
        for i in range(0, len(self.symbols) + 1, self.conc_code_num):
            code_split = self.symbols[i : i + self.conc_code_num]
            code_split_list.append(code_split)

        return code_split_list

    def exit(self):
        """数据服务关闭"""
        # 关闭订阅
        self.subscribe_close()

        # 关闭接口
        self.login_status = False
        self.connect_status = False
        self.hq_api.disconnect()
        self.hq_api = None
예제 #49
0
def test_all_functions(multithread, heartbeat, auto_retry, raise_exception):

    api = TdxHq_API(multithread=multithread, heartbeat=heartbeat,
                    auto_retry=auto_retry, raise_exception=raise_exception)
    with api.connect(time_out=30):
        log.info("获取股票行情")
        stocks = api.get_security_quotes([(0, "000001"), (1, "600300")])
        assert stocks is not None
        assert type(stocks) is list

        # 方法2
        stocks = api.get_security_quotes(0, "000001")
        assert stocks is not None
        assert type(stocks) is list

        # 方法3
        stocks = api.get_security_quotes((0, "000001"))
        assert stocks is not None
        assert type(stocks) is list

        log.info("获取k线")
        data = api.get_security_bars(9, 0, '000001', 4, 3)
        assert data is not None
        assert type(data) is list
        assert len(data) == 3

        log.info("获取 深市 股票数量")
        assert api.get_security_count(0) > 0

        log.info("获取股票列表")
        stocks = api.get_security_list(1, 0)
        assert stocks is not None
        assert type(stocks) is list
        assert len(stocks) > 0

        log.info("获取指数k线")
        data = api.get_index_bars(9, 1, '000001', 1, 2)
        assert data is not None
        assert type(data) is list
        assert len(data) == 2

        log.info("查询分时行情")
        data = api.get_minute_time_data(TDXParams.MARKET_SH, '600300')
        assert data is not None

        log.info("查询历史分时行情")
        data = api.get_history_minute_time_data(
            TDXParams.MARKET_SH, '600300', 20161209)
        assert data is not None
        assert type(data) is list
        assert len(data) > 0

        log.info("查询分时成交")
        data = api.get_transaction_data(TDXParams.MARKET_SZ, '000001', 0, 30)
        assert data is not None
        assert type(data) is list

        log.info("查询历史分时成交")
        data = api.get_history_transaction_data(
            TDXParams.MARKET_SZ, '000001', 0, 10, 20170209)

        assert data is not None
        assert type(data) is list
        assert len(data) == 10

        log.info("查询公司信息目录")
        data = api.get_company_info_category(TDXParams.MARKET_SZ, '000001')
        assert data is not None
        assert type(data) is list
        assert len(data) > 0

        start = data[0]['start']
        length = data[0]['length']
        log.info("读取公司信息-最新提示")
        data = api.get_company_info_content(
            0, '000001', '000001.txt', start, length)
        assert data is not None
        assert len(data) > 0

        log.info("读取除权除息信息")
        data = api.get_xdxr_info(1, '600300')
        assert data is not None
        assert type(data) is list
        assert len(data) > 0

        log.info("读取财务信息")
        data = api.get_finance_info(0, '000001')
        assert data is not None
        assert type(data) is OrderedDict
        assert len(data) > 0

        log.info("日线级别k线获取函数")
        data = api.get_k_data('000001', '2017-07-01', '2017-07-10')
        assert type(data) is pd.DataFrame
        assert len(data) == 6

        log.info("获取板块信息")
        data = api.get_and_parse_block_info(TDXParams.BLOCK_FG)
        assert data is not None
        assert type(data) is list
        assert len(data) > 0
예제 #50
0
class TBStockData:

    __serverList = []
    _bestIP = []
    __bestIPFile = ''
    __tdx = None
    _lastBaseHistList = pd.DataFrame()
    _xdxrData = None


    def __init__(self, autoIP = False):
        self.__serverList = hq_hosts
        self.__bestIPFile = os.path.dirname(os.path.realpath(__file__)) + '/best.ip'

        if autoIP:
            self.getBestIP()
        else:
            if os.path.exists(self.__bestIPFile):
                with open(self.__bestIPFile, 'r') as f:
                    data = f.read()
                    self._bestIP = json.loads(data)

    def ping(self, ip, port):
        api = TdxHq_API()
        time1 = datetime.datetime.now()

        try:
            with api.connect(ip, int(port)):
                if len(api.get_security_list(0, 1)) > 800:
                    return datetime.datetime.now() - time1
                else:
                    return datetime.timedelta(9, 9, 0)
        except:
            return datetime.timedelta(9, 9, 0)

    def getBestIP(self):

        pingTimeList = [self.ping(x[1], x[2]) for x in self.__serverList]
        self._bestIP = self.__serverList[pingTimeList.index(min(pingTimeList))]

        with open(self.__bestIPFile, 'w') as f:
            f.write(json.dumps(self._bestIP))

    def showAllIP(self):
        for item in self.__serverList:
            print item[0],'\t', item[1], '\t', item[2]

    def _connect(self):

        if self.__tdx is None:
            if not self._bestIP:
                self.getBestIP()

            #self.__tdx = TdxHq_API(heartbeat=True, auto_retry=True)
            self.__tdx = TdxHq_API(auto_retry=True)
            self.__tdx.connect(self._bestIP[1], int(self._bestIP[2]))

    #计算量比
    def _setVolRaito(self, row):
        date = row.name
        histList = self._lastBaseHistList[:date]
        if len(histList) < 6:
            return np.nan

        return round((histList['vol'].values[-1] / 240) / (histList[-6:-1]['vol'].sum() / 1200), 3)

    #计算各种指标
    def getData(self, df = pd.DataFrame(), indexs=['turnover', 'vol', 'ma', 'macd', 'kdj', 'cci', 'bbi', 'sar', 'trix']):

        indexs = [x.lower() for x in indexs]
        histList = pd.DataFrame()

        if not df.empty:
            histList = df.copy()
        elif not self._lastBaseHistList.empty:
            histList = self._lastBaseHistList.copy()

        if histList.empty:
            return None

        dayKStatus = False
        try:
            if int(time.mktime(time.strptime(str(histList.index[-1]), "%Y-%m-%d %X"))) - int(time.mktime(time.strptime(str(histList.index[-2]), "%Y-%m-%d %X"))) > 43200:
                #日线以上行情
                dayKStatus = True
        except:
            dayKStatus = True

        #计算涨幅
        histList['p_change'] = histList['close'].pct_change().round(5) * 100

        #量比
        histList['vol_ratio'] = histList.apply(self._setVolRaito, axis=1)

        #振幅
        histList['amp'] = ((histList['high'] - histList['low']) / histList.shift()['close'] * 100).round(3)

        #计算换手率
        if self._xdxrData is None:
            xdxrData = self.getXdxr(str(histList['code'].values[0]))
        else:
            xdxrData = self._xdxrData
        info = xdxrData[xdxrData['liquidity_after'] > 0][['liquidity_after', 'shares_after']]

        if dayKStatus:
            startDate = str(histList.index[0])[0:10]
            endDate = str(histList.index[-1])[0:10]
            info1 = info[info.index <= startDate][-1:]
            info = info1.append(info[info.index >= startDate]).drop_duplicates()
            info = info.reindex(pd.date_range(info1.index[-1], endDate))
            info = info.resample('1D').last().fillna(method='pad')[startDate:endDate]
            #info['date'] = info.index
            #info['date'] = info['date'].dt.strftime('%Y-%m-%d')
            #info = info.set_index('date')

            circulate = info['liquidity_after'] * 10000
            capital = info['shares_after'] * 10000
        else:
            circulate = info['liquidity_after'].values[-1] * 10000
            capital = info['shares_after'].values[-1] * 10000

        #histList['circulate'] = (circulate / 10000 / 10000).round(4)

        if 'turnover' in indexs and dayKStatus:
            histList['turnover'] = (histList['vol'] * 100 / circulate).round(5) * 100
            histList['turnover5'] = talib.MA(histList['turnover'].values, timeperiod=5).round(3)

        #stockstats转换,主要是用来计算KDJ等相关指标
        #用talib计算KDJ时会与现有软件偏差大
        ss = StockDataFrame.retype(histList[['high','low','open','close']])

        #MACD计算
        if 'macd' in indexs:
            difList, deaList, macdList = talib.MACD(histList['close'].values, fastperiod=12, slowperiod=26, signalperiod=9)
            macdList = macdList * 2
            histList['macd_dif'] = difList.round(3)
            histList['macd_dea'] = deaList.round(3)
            histList['macd_value'] = macdList.round(3)
            histList['macd_value_ma'] = 0
            try:
                histList['macd_value_ma'] = talib.MA(histList['macd_value'].values, timeperiod=5).round(3)
            except:
                pass
            histList['macd_cross_status'] = 0
            macdPosList = histList['macd_dif'] > histList['macd_dea']
            histList.loc[macdPosList[(macdPosList == True) & (macdPosList.shift() == False)].index, 'macd_cross_status'] = 1
            histList.loc[macdPosList[(macdPosList == False) & (macdPosList.shift() == True)].index, 'macd_cross_status'] = -1
            #histList[['macd_cross_status']] = histList[['macd_cross_status']].fillna(method='pad')

        #KDJ计算
        if 'kdj' in indexs:
            histList['kdj_k'] = ss['kdjk'].round(3)
            histList['kdj_d'] = ss['kdjd'].round(3)
            histList['kdj_j'] = ss['kdjj'].round(3)
            histList['kdj_cross_status'] = 0
            kdjPosList = histList['kdj_k'] >= histList['kdj_d']
            histList.loc[kdjPosList[(kdjPosList == True) & (kdjPosList.shift() == False)].index, 'kdj_cross_status'] = 1
            histList.loc[kdjPosList[(kdjPosList == False) & (kdjPosList.shift() == True)].index, 'kdj_cross_status'] = -1
            #histList[['kdj_cross_status']] = histList[['kdj_cross_status']].fillna(method='pad')

        #CCI计算
        if 'cci' in indexs:
            histList['cci'] = ss['cci'].round(3)

        #ma相关计算
        if 'ma' in indexs:
            histList['ma5'] = talib.MA(histList['close'].values, timeperiod=5).round(3)
            histList['ma10'] = talib.MA(histList['close'].values, timeperiod=10).round(3)
            histList['ma20'] = talib.MA(histList['close'].values, timeperiod=20).round(3)
            histList['ma30'] = talib.MA(histList['close'].values, timeperiod=30).round(3)
            histList['ma60'] = talib.MA(histList['close'].values, timeperiod=60).round(3)
            histList['ma240'] = talib.MA(histList['close'].values, timeperiod=240).round(3)
            histList[['ma5', 'ma10', 'ma20', 'ma30', 'ma60', 'ma240']] = histList[['ma5', 'ma10', 'ma20', 'ma30', 'ma60', 'ma240']].fillna(0)

        #成交量计算
        if 'vol' in indexs:
            histList['vol5'] = talib.MA(histList['vol'].values, timeperiod=5).round(3)
            histList['vol10'] = talib.MA(histList['vol'].values, timeperiod=10).round(3)
            histList['vol20'] = talib.MA(histList['vol'].values, timeperiod=20).round(3)
            histList['vol_zoom'] = (histList['vol'] / histList['vol5'] * 1.0).round(3)
            histList['vol5_vol10_cross_status'] = 0
            volumePosList = histList['vol5'] >= histList['vol10']
            histList.loc[volumePosList[(volumePosList == True) & (volumePosList.shift() == False)].index, 'vol5_vol10_cross_status'] = 1
            histList.loc[volumePosList[(volumePosList == False) & (volumePosList.shift() == True)].index, 'vol5_vol10_cross_status'] = -1
            del volumePosList
            histList['vol5_vol20_cross_status'] = 0
            volumePosList = histList['vol5'] >= histList['vol20']
            histList.loc[volumePosList[(volumePosList == True) & (volumePosList.shift() == False)].index, 'vol5_vol20_cross_status'] = 1
            histList.loc[volumePosList[(volumePosList == False) & (volumePosList.shift() == True)].index, 'vol5_vol20_cross_status'] = -1
            del volumePosList
            histList['vol10_vol20_cross_status'] = 0
            volumePosList = histList['vol10'] >= histList['vol20']
            histList.loc[volumePosList[(volumePosList == True) & (volumePosList.shift() == False)].index, 'vol10_vol20_cross_status'] = 1
            histList.loc[volumePosList[(volumePosList == False) & (volumePosList.shift() == True)].index, 'vol10_vol20_cross_status'] = -1
            #histList[['vol5_vol10_cross_status', 'vol5_vol20_cross_status', 'vol10_vol20_cross_status']] = histList[['vol5_vol10_cross_status', 'vol5_vol20_cross_status', 'vol10_vol20_cross_status']].fillna(method='pad')

        #bbi计算
        if 'bbi' in indexs:
            ma3 = talib.MA(histList['close'].values, timeperiod=3)
            ma6 = talib.MA(histList['close'].values, timeperiod=6)
            ma12 = talib.MA(histList['close'].values, timeperiod=12)
            ma24 = talib.MA(histList['close'].values, timeperiod=24)
            histList['bbi'] = (ma3 + ma6 + ma12 + ma24) / 4
            histList['bbi'] = histList['bbi'].round(3)

        #SAR计算
        if 'sar' in indexs:
            sarList = talib.SAR(histList['high'].values, histList['low'].values, acceleration=0.04, maximum=0.2)
            histList['sar'] = sarList.round(3)
            histList['sar_cross_status'] = 0
            sarPosList = histList['close'] >= histList['sar']
            histList.loc[sarPosList[(sarPosList == True) & (sarPosList.shift() == False)].index, 'sar_cross_status'] = 1
            histList.loc[sarPosList[(sarPosList == False) & (sarPosList.shift() == True)].index, 'sar_cross_status'] = -1

        #计算TRIX
        if 'trix' in indexs:
            histList['trix'] = np.nan
            histList['trma'] = np.nan
            histList['trix_diff'] = np.nan
            try:
                trix = talib.TRIX(histList['close'].values, 12)
                trma = talib.MA(trix, timeperiod=20)
                histList['trix'] = trix.round(3)
                histList['trma'] = trma.round(3)
                histList['trix_diff'] = histList['trix'] - histList['trma']
                histList['trix_cross_status'] = 0
                trixPosList = histList['trix'] >= histList['trma']
                histList.loc[trixPosList[(trixPosList == True) & (trixPosList.shift() == False)].index, 'trix_cross_status'] = 1
                histList.loc[trixPosList[(trixPosList == False) & (trixPosList.shift() == True)].index, 'trix_cross_status'] = -1
                #histList[['trix_cross_status']] = histList[['trix_cross_status']].fillna(method='pad')
            except:
                pass

        if 'cyc' in indexs:
            avePrice = histList['amount'] / (histList['vol'] * 100)
            histList['cyc5'] = talib.MA(avePrice.values, timeperiod=5).round(3)
            histList['cyc13'] = talib.MA(avePrice.values, timeperiod=13).round(3)
            histList['cyc34'] = talib.MA(avePrice.values, timeperiod=34).round(3)
            #histList['cycx'] = talib.EMA(histList['close'].values, timeperiod=histList['vol'].values * 100 / circulate).round(3)
            histList['cyc5_cyc13_cross_status'] = 0
            volumePosList = histList['cyc5'] >= histList['cyc13']
            histList.loc[volumePosList[(volumePosList == True) & (volumePosList.shift() == False)].index, 'cyc5_cyc13_cross_status'] = 1
            histList.loc[volumePosList[(volumePosList == False) & (volumePosList.shift() == True)].index, 'cyc5_cyc13_cross_status'] = -1
            del volumePosList
            histList['cyc13_cyc34_cross_status'] = 0
            volumePosList = histList['cyc13'] >= histList['cyc34']
            histList.loc[volumePosList[(volumePosList == True) & (volumePosList.shift() == False)].index, 'cyc13_cyc34_cross_status'] = 1
            histList.loc[volumePosList[(volumePosList == False) & (volumePosList.shift() == True)].index, 'cyc13_cyc34_cross_status'] = -1
            del volumePosList

        if 'boll' in indexs:
            up, mid, low = talib.BBANDS(
                histList['close'].values,
                timeperiod=20,
                # number of non-biased standard deviations from the mean
                nbdevup=2,
                nbdevdn=2,
                # Moving average type: simple moving average here
                matype=0)
            histList['boll_up'] = up.round(3)
            histList['boll_mid'] = mid.round(3)
            histList['boll_low'] = low.round(3)


        return histList

    #整理开始,结束时间,并计算相差天数
    def _getDate(self, start, end):
        if not end:
            end = time.strftime('%Y-%m-%d',time.localtime())

        if not start:
            t = int(time.mktime(time.strptime(str(end), '%Y-%m-%d'))) - 86400 * 800
            start = str(time.strftime('%Y-%m-%d',time.localtime(t)))

        startTimestamp = int(time.mktime(time.strptime(str(start), '%Y-%m-%d')))
        endTimestamp = int(time.mktime(time.strptime(str(end), '%Y-%m-%d')))
        diffDayNum = int((time.time() - startTimestamp) / 86400)
        if diffDayNum <= 0:
            diffDayNum = 1

        return start, end, diffDayNum

    #得到市场代码
    def getMarketCode(self, code):
        code = str(code)
        if code[0] in ['5', '6', '9'] or code[:3] in ["009", "126", "110", "201", "202", "203", "204"]:
            return 1
        return 0

    #时间整理
    def _dateStamp(self, date):
        datestr = str(date)[0:10]
        date = time.mktime(time.strptime(datestr, '%Y-%m-%d'))
        return date

    #整理时间
    def _timeStamp(self, _time):
        if len(str(_time)) == 10:
            # yyyy-mm-dd格式
            return time.mktime(time.strptime(_time, '%Y-%m-%d'))
        elif len(str(_time)) == 16:
                # yyyy-mm-dd hh:mm格式
            return time.mktime(time.strptime(_time, '%Y-%m-%d %H:%M'))
        else:
            timestr = str(_time)[0:19]
            return time.mktime(time.strptime(timestr, '%Y-%m-%d %H:%M:%S'))


    #得到除权信息
    def getXdxr(self, code):

        self._connect()

        category = {
            '1': '除权除息', '2': '送配股上市', '3': '非流通股上市', '4': '未知股本变动', '5': '股本变化',
            '6': '增发新股', '7': '股份回购', '8': '增发新股上市', '9': '转配股上市', '10': '可转债上市',
            '11': '扩缩股', '12': '非流通股缩股', '13':  '送认购权证', '14': '送认沽权证'}

        data = self.__tdx.to_df(self.__tdx.get_xdxr_info(self.getMarketCode(code), code))

        if len(data) >= 1:
            data = data\
                .assign(date=pd.to_datetime(data[['year', 'month', 'day']], format='%Y-%m-%d'))\
                .drop(['year', 'month', 'day'], axis=1)\
                .assign(category_meaning=data['category'].apply(lambda x: category[str(x)]))\
                .assign(code=str(code))\
                .rename(index=str, columns={'panhouliutong': 'liquidity_after',
                                            'panqianliutong': 'liquidity_before', 'houzongguben': 'shares_after',
                                            'qianzongguben': 'shares_before'})\
                .set_index('date', drop=False, inplace=False)

            xdxrData = data.assign(date=data['date'].apply(lambda x: str(x)[0:10]))
            #xdxrData = xdxrData.set_index('date')
            self._xdxrData = xdxrData
            return xdxrData
        else:
            return None


    #得到股本
    def getGuben(self, code):
        self._connect()

        if self._xdxrData is None:
            xdxrData = self.getXdxr(code)
        else:
            xdxrData = self._xdxrData
        info = xdxrData[xdxrData['liquidity_after'] > 0][['liquidity_after', 'shares_after']]

        circulate = info['liquidity_after'].values[-1] * 10000
        capital = info['shares_after'].values[-1] * 10000

        return capital,circulate


    #按天得到标准数据
    '''
    ktype = D(天)/W(周)/M(月)/Q(季)/Y(年)
    autype = bfq(不复权)/hfq(后复权)/qfq(前复权)
    '''
    def getDays(self, code, ktype = 'D', start = '', end = '', autype = 'qfq', indexs = ['turnover', 'vol', 'ma', 'macd', 'kdj', 'cci', 'bbi', 'sar', 'trix']):
        startDate, endDate, diffDayNum = self._getDate(start, end)

        self._connect()

        ktypeCode = 9
        if ktype.lower() == 'd':
            ktypeCode = 9
        elif ktype.lower() == 'w':
            ktypeCode = 5
        elif ktype.lower() == 'm':
            ktypeCode = 6
        elif ktype.lower() == 'q':
            ktypeCode = 10
        elif ktype.lower() == 'y':
            ktypeCode = 11

        histList = pd.concat([self.__tdx.to_df(self.__tdx.get_security_bars(ktypeCode, self.getMarketCode(code), code, (int(diffDayNum / 800) - i) * 800, 800)) for i in range(int(diffDayNum / 800) + 1)], axis=0)

        if histList.empty:
            return None

        histList = histList[histList['open'] != 0]
        histList = histList[histList['vol'] > 1]

        if not autype or autype == 'bfq':
            histList = histList.assign(date=histList['datetime'].apply(lambda x: str(x[0:10]))).assign(code=str(code))\
                    .assign(date_stamp=histList['datetime'].apply(lambda x: self._dateStamp(str(x)[0:10])))

            histList = histList.drop(['year', 'month', 'day', 'hour', 'minute', 'datetime', 'date_stamp'], axis=1)
            histList = histList.set_index('date')
            histList = histList[startDate:endDate]
            self._lastBaseHistList = histList

            histList['p_change'] = histList['close'].pct_change().round(5) * 100

            if indexs:
                return self.getData(indexs=indexs)
            else:
                return histList

        elif autype == 'qfq':

            bfqData = histList.assign(date=pd.to_datetime(histList['datetime'].apply(lambda x: str(x[0:10])))).assign(code=str(code))\
                .assign(date_stamp=histList['datetime'].apply(lambda x: self._dateStamp(str(x)[0:10])))
            bfqData = bfqData.set_index('date')

            bfqData = bfqData.drop(
                ['year', 'month', 'day', 'hour', 'minute', 'datetime'], axis=1)

            xdxrData = self.getXdxr(code)
            if xdxrData is not None:
                info = xdxrData[xdxrData['category'] == 1]
                bfqData['if_trade'] = True
                data = pd.concat([bfqData, info[['category']]
                                  [bfqData.index[0]:]], axis=1)

                #data['date'] = data.index
                data['if_trade'].fillna(value=False, inplace=True)
                data = data.fillna(method='ffill')
                data = pd.concat([data, info[['fenhong', 'peigu', 'peigujia',
                                              'songzhuangu']][bfqData.index[0]:]], axis=1)
                data = data.fillna(0)

                data['preclose'] = (data['close'].shift(1) * 10 - data['fenhong'] + data['peigu']
                                    * data['peigujia']) / (10 + data['peigu'] + data['songzhuangu'])
                data['adj'] = (data['preclose'].shift(-1) /
                               data['close']).fillna(1)[::-1].cumprod()
                data['open'] = data['open'] * data['adj']
                data['high'] = data['high'] * data['adj']
                data['low'] = data['low'] * data['adj']
                data['close'] = data['close'] * data['adj']
                data['preclose'] = data['preclose'] * data['adj']
                data = data[data['if_trade']]

                histList = data.drop(['fenhong', 'peigu', 'peigujia', 'songzhuangu', 'if_trade', 'category', 'preclose', 'date_stamp', 'adj'], axis=1)
                histList = histList[startDate:endDate]
                self._lastBaseHistList = histList

                histList['p_change'] = histList['close'].pct_change().round(5) * 100

                if indexs:
                    return self.getData(indexs=indexs)
                else:
                    return histList
            else:
                bfqData['preclose'] = bfqData['close'].shift(1)
                bfqData['adj'] = 1

                histList = bfqData.drop(['preclose', 'date_stamp', 'adj'], axis=1)
                histList = histList[startDate:endDate]
                self._lastBaseHistList = histList

                if indexs:
                    return self.getData(indexs=indexs)
                else:
                    return histList

        elif autype == 'hfq':
            xdxrData = self.getXdxr(code)

            info = xdxrData[xdxrData['category'] == 1]

            bfqData = histList.assign(date=histList['datetime'].apply(lambda x: x[0:10])).assign(code=str(code))\
                .assign(date_stamp=histList['datetime'].apply(lambda x: self._dateStamp(str(x)[0:10])))
            bfqData = bfqData.set_index('date')

            bfqData = bfqData.drop(
                ['year', 'month', 'day', 'hour', 'minute', 'datetime'], axis=1)

            bfqData['if_trade'] = True
            data = pd.concat([bfqData, info[['category']]
                              [bfqData.index[0]:]], axis=1)

            data['if_trade'].fillna(value=False, inplace=True)
            data = data.fillna(method='ffill')
            data = pd.concat([data, info[['fenhong', 'peigu', 'peigujia',
                                          'songzhuangu']][bfqData.index[0]:]], axis=1)
            data = data.fillna(0)

            data['preclose'] = (data['close'].shift(1) * 10 - data['fenhong'] + data['peigu']
                                * data['peigujia']) / (10 + data['peigu'] + data['songzhuangu'])
            data['adj'] = (data['preclose'].shift(-1) /
                           data['close']).fillna(1).cumprod()
            data['open'] = data['open'] / data['adj']
            data['high'] = data['high'] / data['adj']
            data['low'] = data['low'] / data['adj']
            data['close'] = data['close'] / data['adj']
            data['preclose'] = data['preclose'] / data['adj']
            data = data[data['if_trade']]

            histList = data.drop(['fenhong', 'peigu', 'peigujia', 'songzhuangu', 'if_trade', 'category', 'preclose', 'date_stamp', 'adj'], axis=1)
            histList = histList[startDate:endDate]
            self._lastBaseHistList = histList

            histList['p_change'] = histList['close'].pct_change().round(5) * 100

            if indexs:
                return self.getData(indexs=indexs)
            else:
                return histList

    #按分钟得到标准数据
    '''
    ktype = 1/5/15/30/60  分钟
    '''
    def getMins(self, code, ktype = 1, start = '', end = '', indexs=['vol', 'ma', 'macd', 'kdj', 'cci', 'bbi', 'sar', 'trix']):
        startDate, endDate, diffDayNum = self._getDate(start, end)

        self._connect()

        ktypeCode = 8
        if int(ktype) == 1:
            ktypeCode = 8
            diffDayNum = 240 * diffDayNum
        elif int(ktype) == 5:
            ktypeCode = 0
            diffDayNum = 48 * diffDayNum
        elif int(ktype) == 15:
            ktypeCode = 1
            diffDayNum = 16 * diffDayNum
        elif int(ktype) == 30:
            ktypeCode = 2
            diffDayNum = 8 * diffDayNum
        elif int(ktype) == 60:
            ktypeCode = 3
            diffDayNum = 4 * diffDayNum

        if diffDayNum > 20800:
            diffDayNum = 20800

        histList = pd.concat([self.__tdx.to_df(self.__tdx.get_security_bars(ktypeCode, self.getMarketCode(
            str(code)), str(code), (int(diffDayNum / 800) - i) * 800, 800)) for i in range(int(diffDayNum / 800) + 1)], axis=0)

        if histList.empty:
            return None

        histList = histList\
            .assign(datetime=pd.to_datetime(histList['datetime']), code=str(code))\
            .assign(date=histList['datetime'].apply(lambda x: str(x)[0:10]))\
            .assign(date_stamp=histList['datetime'].apply(lambda x: self._dateStamp(x)))\
            .assign(time_stamp=histList['datetime'].apply(lambda x: self._timeStamp(x)))

        histList['date'] = histList['datetime']
        histList = histList.drop(['year', 'month', 'day', 'hour', 'minute', 'datetime', 'date_stamp', 'time_stamp'], axis=1)
        histList = histList.set_index('date')
        histList = histList[startDate:endDate]
        self._lastBaseHistList = histList

        histList['p_change'] = histList['close'].pct_change().round(5) * 100
        histList['vol'] = histList['vol'] / 100.0

        if indexs:
            return self.getData(indexs=indexs)
        else:
            return histList


    #按天得到指数日k线
    '''
    ktype = D(天)/W(周)/M(月)/Q(季)/Y(年)
    '''
    def getIndexDays(self, code, ktype = 'D', start = '', end = '', indexs=['turnover', 'vol', 'ma', 'macd', 'kdj', 'cci', 'bbi', 'sar', 'trix']):
        startDate, endDate, diffDayNum = self._getDate(start, end)

        self._connect()

        ktypeCode = 9
        if ktype.lower() == 'd':
            ktypeCode = 9
        elif ktype.lower() == 'w':
            ktypeCode = 5
        elif ktype.lower() == 'm':
            ktypeCode = 6
        elif ktype.lower() == 'q':
            ktypeCode = 10
        elif ktype.lower() == 'y':
            ktypeCode = 11

        if str(code)[0] in ['5', '1']:  # ETF
            data = pd.concat([self.__tdx.to_df(self.__tdx.get_security_bars(
                ktypeCode, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (int(diffDayNum / 800) - i) * 800, 800)) for i in range(int(diffDayNum / 800) + 1)], axis=0)
        else:
            data = pd.concat([self.__tdx.to_df(self.__tdx.get_index_bars(
                ktypeCode, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (int(diffDayNum / 800) - i) * 800, 800)) for i in range(int(diffDayNum / 800) + 1)], axis=0)

        histList = data.assign(date=data['datetime'].apply(lambda x: str(x[0:10]))).assign(code=str(code))\
            .assign(date_stamp=data['datetime'].apply(lambda x: self._dateStamp(str(x)[0:10])))\
            .assign(code=code)

        if histList.empty:
            return None

        histList = histList.drop(['year', 'month', 'day', 'hour', 'minute', 'datetime', 'date_stamp', 'up_count', 'down_count'], axis=1)
        histList = histList.set_index('date')
        histList = histList[startDate:endDate]
        self._lastBaseHistList = histList

        histList['p_change'] = histList['close'].pct_change().round(5) * 100

        if indexs:
            return self.getData(indexs=indexs)
        else:
            return histList

    #按分钟得到标准数据
    '''
    ktype = 1/5/15/30/60  分钟
    '''
    def getIndexMins(self, code, ktype = 1, start = '', end = '', indexs=['vol', 'ma', 'macd', 'kdj', 'cci', 'bbi', 'sar', 'trix']):
        startDate, endDate, diffDayNum = self._getDate(start, end)

        self._connect()

        ktypeCode = 8
        if int(ktype) == 1:
            ktypeCode = 8
            diffDayNum = 240 * diffDayNum
        elif int(ktype) == 5:
            ktypeCode = 0
            diffDayNum = 48 * diffDayNum
        elif int(ktype) == 15:
            ktypeCode = 1
            diffDayNum = 16 * diffDayNum
        elif int(ktype) == 30:
            ktypeCode = 2
            diffDayNum = 8 * diffDayNum
        elif int(ktype) == 60:
            ktypeCode = 3
            diffDayNum = 4 * diffDayNum

        if diffDayNum > 20800:
            diffDayNum = 20800

        if str(code)[0] in ['5', '1']:  # ETF
            data = pd.concat([self.__tdx.to_df(self.__tdx.get_security_bars(
                ktypeCode, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (int(diffDayNum / 800) - i) * 800, 800)) for i in range(int(diffDayNum / 800) + 1)], axis=0)
        else:
            data = pd.concat([self.__tdx.to_df(self.__tdx.get_index_bars(
                ktypeCode, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (int(diffDayNum / 800) - i) * 800, 800)) for i in range(int(diffDayNum / 800) + 1)], axis=0)

        histList = data.assign(datetime=pd.to_datetime(data['datetime']), code=str(code))\
            .assign(date=data['datetime'].apply(lambda x: str(x)[0:10]))\
            .assign(date_stamp=data['datetime'].apply(lambda x: self._dateStamp(x)))\
            .assign(time_stamp=data['datetime'].apply(lambda x: self._timeStamp(x)))

        if histList.empty:
            return None

        histList['date'] = histList['datetime']
        histList = histList.drop(['year', 'month', 'day', 'hour', 'minute', 'datetime', 'date_stamp', 'time_stamp', 'up_count', 'down_count'], axis=1)
        histList = histList.set_index('date')
        histList = histList[startDate:endDate]
        self._lastBaseHistList = histList

        histList['p_change'] = histList['close'].pct_change().round(5) * 100

        if indexs:
            return self.getData(indexs=indexs)
        else:
            return histList

    #实时逐笔
    '''
    0买 1卖 2中性
    '''
    def getRealtimeTransaction(self, code):
        self._connect()

        try:
            data = pd.concat([self.__tdx.to_df(self.__tdx.get_transaction_data(
                self.getMarketCode(str(code)), code, (2 - i) * 2000, 2000)) for i in range(3)], axis=0)
            if 'value' in data.columns:
                data = data.drop(['value'], axis=1)
            data = data.dropna()
            day = datetime.date.today()
            histList = data.assign(date=str(day)).assign(datetime=pd.to_datetime(data['time'].apply(lambda x: str(day) + ' ' + str(x))))\
                .assign(code=str(code)).assign(order=range(len(data.index)))

            histList['money'] = histList['price'] * histList['vol'] * 100
            histList['type'] = histList['buyorsell']
            histList['type'].replace([0,1,2], ['B','S','N'], inplace = True)

            histList = histList.drop(['order', 'buyorsell'], axis=1).reset_index()
            return histList
        except:
            return None

    #历史逐笔
    '''
    0买 1卖 2中性
    '''
    def getHistoryTransaction(self, code, date):
        self._connect()

        try:
            data = pd.concat([self.__tdx.to_df(self.__tdx.get_history_transaction_data(
                self.getMarketCode(str(code)), code, (2 - i) * 2000, 2000, int(str(date).replace('-', '')))) for i in range(3)], axis=0)
            if 'value' in data.columns:
                data = data.drop(['value'], axis=1)
            data = data.dropna()
            #day = datetime.date.today()
            day = date
            histList = data.assign(date=str(day)).assign(datetime=pd.to_datetime(data['time'].apply(lambda x: str(day) + ' ' + str(x))))\
                .assign(code=str(code)).assign(order=range(len(data.index)))

            histList['money'] = histList['price'] * histList['vol'] * 100
            histList['type'] = histList['buyorsell']
            histList['type'].replace([0,1,2], ['B','S','N'], inplace = True)

            histList = histList.drop(['order', 'buyorsell'], axis=1).reset_index()
            return histList
        except:
            return None

    #实时分时数据
    def getRealtimeMinuteTime(self, code):
        self._connect()

        date = str(time.strftime('%Y-%m-%d',time.localtime()))

        morningData = pd.date_range(start=str(date) + ' 09:31', end=str(date) + ' 11:30', freq = 'min')
        morningDF = pd.DataFrame(index=morningData)


        afternoonData = pd.date_range(start=str(date) + ' 13:01',end=str(date) + ' 15:00', freq = 'min')
        afternoonDF = pd.DataFrame(index=afternoonData)
        timeData = morningDF.append(afternoonDF)

        histList = self.__tdx.to_df(self.__tdx.get_minute_time_data(
                self.getMarketCode(str(code)), code))

        #非标准均价计算
        money = histList['price'] * histList['vol'] * 100
        histList['money'] = money.round(2)
        totalMoney = money.cumsum()
        totalVol = histList['vol'].cumsum()
        histList['ave'] = totalMoney / (totalVol * 100)
        histList['ave'] = histList['ave'].round(3)

        histList['datetime'] = timeData.index[0:len(histList)]
        histList['date'] = histList['datetime'].apply(lambda x: x.strftime('%Y-%m-%d'))
        histList['time'] = histList['datetime'].apply(lambda x: x.strftime('%H:%M'))

        histList = histList.reset_index()

        return histList

    #历史分时数据
    def getHistoryMinuteTime(self, code, date):
        self._connect()

        morningData = pd.date_range(start=str(date) + ' 09:31', end=str(date) + ' 11:30', freq = 'min')
        morningDF = pd.DataFrame(index=morningData)


        afternoonData = pd.date_range(start=str(date) + ' 13:01',end=str(date) + ' 15:00', freq = 'min')
        afternoonDF = pd.DataFrame(index=afternoonData)
        timeData = morningDF.append(afternoonDF)

        histList = self.__tdx.to_df(self.__tdx.get_history_minute_time_data(
                self.getMarketCode(str(code)), code, int(str(date).replace('-', ''))))

        #非标准均价计算
        money = histList['price'] * histList['vol'] * 100
        histList['money'] = money.round(2)
        totalMoney = money.cumsum()
        totalVol = histList['vol'].cumsum()
        histList['ave'] = totalMoney / (totalVol * 100)
        histList['ave'] = histList['ave'].round(3)

        histList['datetime'] = timeData.index[0:len(histList)]
        histList['date'] = histList['datetime'].apply(lambda x: x.strftime('%Y-%m-%d'))
        histList['time'] = histList['datetime'].apply(lambda x: x.strftime('%H:%M'))

        histList = histList.reset_index()

        return histList


    #实时报价(五档行情)
    '''
    market => 市场
    active1 => 活跃度
    price => 现价
    last_close => 昨收
    open => 开盘
    high => 最高
    low => 最低
    reversed_bytes0 => 保留
    reversed_bytes1 => 保留
    vol => 总量
    cur_vol => 现量
    amount => 总金额
    s_vol => 内盘
    b_vol => 外盘
    reversed_bytes2 => 保留
    reversed_bytes3 => 保留
    bid1 => 买一价
    ask1 => 卖一价
    bid_vol1 => 买一量
    ask_vol1 => 卖一量
    bid2 => 买二价
    ask2 => 卖二价
    bid_vol2 => 买二量
    ask_vol2 => 卖二量
    bid3 => 买三价
    ask3 => 卖三价
    bid_vol3 => 买三量
    ask_vol3 => 卖三量
    bid4 => 买四价
    ask4 => 卖四价
    bid_vol4 => 买四量
    ask_vol4 => 卖四量
    bid5 => 买五价
    ask5 => 卖五价
    bid_vol5 => 买五量
    ask_vol5 => 卖五量
    reversed_bytes4 => 保留
    reversed_bytes5 => 保留
    reversed_bytes6 => 保留
    reversed_bytes7 => 保留
    reversed_bytes8 => 保留
    reversed_bytes9 => 涨速
    active2 => 活跃度
    '''
    def getRealtimeQuotes(self, codeList):
        self._connect()

        itemList = []
        for item in codeList:
            itemList.append((self.getMarketCode(item), item))

        histList = self.__tdx.to_df(self.__tdx.get_security_quotes(itemList))
        histList = histList.set_index('code')

        return histList

    #计算指定日期成交量细节
    def getVolAnalysis(self, code, date):
        self._connect()

        if str(time.strftime('%Y-%m-%d',time.localtime())) == str(date):
            if int(time.strftime('%H%M',time.localtime())) > 1600:
                volList = self.getHistoryTransaction(code, date)
            else:
                volList = self.getRealtimeTransaction(code)
        else:
            volList = self.getHistoryTransaction(code, date)

        if volList is None:
            return None

        guben,circulate = self.getGuben(code)

        if not self._lastBaseHistList.empty:
            histList = self._lastBaseHistList.copy()
        else:
            histList = self.getDays(code, end=date, indexs=[])

        #涨停单数量
        limitVol = round(histList[-5:]['vol'].mean() * 0.0618)
        #超大单,先转成市值,再转回成手数
        superVol = float(circulate) * float(histList['close'].values[-1]) * 0.000618 / float(histList['close'].values[-1]) / 100
        #大单
        bigVol = round(superVol * 0.518)
        #中单
        middleVol = round(superVol * 0.382)
        #小单
        smallVol = round(superVol * 0.191)

        #买单统计
        buyVolList = volList[volList['type'] == 'B']
        totalBuyVolNum = buyVolList['vol'].sum()
        mainBuyVolNum = buyVolList[buyVolList['vol'] >= bigVol]['vol'].sum()
        limitBuyVolNum = math.ceil(buyVolList[(buyVolList['vol'] >= limitVol)]['vol'].sum() / limitVol)
        superBuyVolNum = math.ceil(buyVolList[(buyVolList['vol'] < limitVol) & (buyVolList['vol'] >= superVol)]['vol'].sum() / superVol)
        bigBuyVolNum = math.ceil(buyVolList[(buyVolList['vol'] < superVol) & (buyVolList['vol'] >= bigVol)]['vol'].sum() / bigVol)
        middleBuyVolNum = math.ceil(buyVolList[(buyVolList['vol'] < bigVol) & (buyVolList['vol'] >= middleVol)]['vol'].sum() / middleVol)
        smallBuyVolNum = math.ceil(buyVolList[(buyVolList['vol'] < middleVol) & (buyVolList['vol'] >= smallVol)]['vol'].sum() / smallVol)
        microBuyVolNum = len(buyVolList[(buyVolList['vol'] < smallVol)])
        #print limitBuyVolNum,superBuyVolNum,bigBuyVolNum,middleBuyVolNum,smallBuyVolNum,microBuyVolNum

        #卖单统计
        sellVolList = volList[volList['type'] == 'S']
        totalSellVolNum = sellVolList['vol'].sum()
        mainSellVolNum = sellVolList[sellVolList['vol'] >= bigVol]['vol'].sum()
        limitSellVolNum = math.ceil(sellVolList[(sellVolList['vol'] >= limitVol)]['vol'].sum() / limitVol)
        superSellVolNum = math.ceil(sellVolList[(sellVolList['vol'] < limitVol) & (sellVolList['vol'] >= superVol)]['vol'].sum() / superVol)
        bigSellVolNum = math.ceil(sellVolList[(sellVolList['vol'] < superVol) & (sellVolList['vol'] >= bigVol)]['vol'].sum() / bigVol)
        middleSellVolNum = math.ceil(sellVolList[(sellVolList['vol'] < bigVol) & (sellVolList['vol'] >= middleVol)]['vol'].sum() / middleVol)
        smallSellVolNum = math.ceil(sellVolList[(sellVolList['vol'] < middleVol) & (sellVolList['vol'] >= smallVol)]['vol'].sum() / smallVol)
        microSellVolNum = len(sellVolList[(sellVolList['vol'] < smallVol)])
        #print limitSellVolNum,superSellVolNum,bigSellVolNum,middleSellVolNum,smallSellVolNum,microSellVolNum

        #计算吸筹线
        #主力标准吸筹金额
        mainBaseMoney = round(histList['close'].values[-1] * circulate * 0.001 / 10000 / 10000, 4)
        #主力强力吸筹金额
        mainBigMoney = round(histList['close'].values[-1] * circulate * 0.003 / 10000 / 10000, 4)

        #资金统计
        totalMoney = round(volList['money'].sum() / 10000 / 10000, 4)
        totalBuyMoney = round(buyVolList['money'].sum() / 10000 / 10000, 4)
        totalSellMoney = round(sellVolList['money'].sum() / 10000 / 10000, 4)
        totalAbsMoney = round(totalBuyMoney - totalSellMoney, 3)
        mainMoney = round(volList[volList['vol'] >= bigVol]['money'].sum() / 10000 / 10000, 4)
        mainBuyMoney = round(buyVolList[buyVolList['vol'] >= bigVol]['money'].sum() / 10000 / 10000, 4)
        mainSellMoney = round(sellVolList[sellVolList['vol'] >= bigVol]['money'].sum() / 10000 / 10000, 4)
        mainAbsMoney = round(mainBuyMoney - mainSellMoney, 3)

        mainRate = 0
        try:
            mainRate = round((mainBuyMoney + mainSellMoney) / totalMoney * 100, 2)
        except:
            pass

        mainBuyRate = 0
        try:
            mainBuyRate = round(mainBuyMoney / (mainBuyMoney + mainSellMoney) * 100, 2)
        except:
            pass
        #print totalAbsMoney,mainAbsMoney,totalMoney,totalBuyMoney,totalSellMoney,mainBuyMoney,mainSellMoney,mainRate,mainBuyRate

        #成交笔数
        volNum = len(volList)

        #平均每笔交易价格
        aveTradePrice = round(totalMoney / volNum * 10000 * 10000, 2)

        #平均每股买价格
        avePerShareBuyPrice = 0
        try:
            avePerShareBuyPrice = round(totalBuyMoney * 10000 * 10000 / (totalBuyVolNum * 100), 3)
        except:
            pass

        #主力平均每股买价格
        mainAvePerShareBuyPrice = 0
        try:
            mainAvePerShareBuyPrice = round(mainBuyMoney * 10000 * 10000 / (mainBuyVolNum * 100), 3)
        except:
            pass

        #平均每股卖价格
        avePerShareSellPrice = 0
        try:
            avePerShareSellPrice = round(totalSellMoney * 10000 * 10000 / (totalSellVolNum * 100), 3)
        except:
            pass

        #主力平均每股卖价格
        mainAvePerShareSellPrice = 0
        try:
            mainAvePerShareSellPrice = round(mainSellMoney * 10000 * 10000 / (mainSellVolNum * 100), 3)
        except:
            pass

        #print totalMoney,volNum,aveVolPrice * 10000 * 10000
        statData = {}
        statData['limit_buy_vol_num'] = limitBuyVolNum
        statData['super_buy_vol_num'] = superBuyVolNum
        statData['big_buy_vol_num'] = bigBuyVolNum
        statData['middle_buy_vol_num'] = middleBuyVolNum
        statData['small_buy_vol_num'] = smallBuyVolNum
        statData['micro_buy_vol_num'] = microBuyVolNum
        statData['limit_sell_vol_num'] = limitSellVolNum
        statData['super_sell_vol_num'] = superSellVolNum
        statData['big_sell_vol_num'] = bigSellVolNum
        statData['middle_sell_vol_num'] = middleSellVolNum
        statData['small_sell_vol_num'] = smallSellVolNum
        statData['micro_sell_vol_num'] = microSellVolNum
        statData['total_abs_money'] = totalAbsMoney
        statData['main_abs_money'] = mainAbsMoney
        statData['total_money'] = totalMoney
        statData['total_buy_money'] = totalBuyMoney
        statData['total_sell_money'] = totalSellMoney
        statData['main_money'] = mainMoney
        statData['main_buy_money'] = mainBuyMoney
        statData['main_sell_money'] = mainSellMoney
        statData['main_rate'] = mainRate
        statData['main_buy_rate'] = mainBuyRate
        statData['trade_num'] = volNum
        statData['vol_num'] = volList['vol'].sum()
        statData['ave_trade_price'] = aveTradePrice
        statData['main_base_money'] = mainBaseMoney
        statData['main_big_money'] = mainBigMoney
        statData['ave_per_share_buy_price'] = avePerShareBuyPrice
        statData['ave_per_share_sell_price'] = avePerShareSellPrice
        statData['main_ave_per_share_buy_price'] = mainAvePerShareBuyPrice
        statData['main_ave_per_share_sell_price'] = mainAvePerShareSellPrice
        statData['circulate_money'] = round(circulate * histList['close'].values[-1] / 10000 / 10000, 4)

        return statData

    #输出ebk文件
    def outputEbk(self, stockList, ebkPath = ''):

        if len(ebkPath) <= 0:
            ebkPath = os.getcwd() + '/' + sys.argv[0][0:-3] + '.' + str(time.strftime('%Y%m%d',time.localtime())) + '.ebk'

        if not isinstance(stockList,list):
            return False

        fp = open(ebkPath, "a")
        fp.write('\r\n')    #ebk第一行为空行
        for code in stockList:
            if self.getMarketCode(code) == 1:
                fp.write('1' + code)
            else:
                fp.write('0' + code)

            fp.write('\r\n')

        fp.close()

        return True

    #输出sel文件
    def outputSel(self, stockList, selPath = ''):
        import struct

        if len(selPath) <= 0:
            selPath = os.getcwd() + '/' + sys.argv[0][0:-3] + '.' + str(time.strftime('%Y%m%d',time.localtime())) + '.sel'

        if not isinstance(stockList,list):
            return False

        stocks = []
        for code in stockList:
            if self.getMarketCode(code) == 1:
                stocks.append('\x07\x11' + code)
            else:
                stocks.append('\x07\x21' + code)

        with open(selPath, 'ab') as fp:
            data = struct.pack('H', len(stocks)).decode() + ''.join(stocks)
            fp.write(data.encode())

        return True

    #ebk to sel
    def ebk2sel(self, ebkPath):
        import struct

        if not os.path.exists(ebkPath):
            return False

        selPath = ebkPath.replace('.ebk', '.sel')

        stocks = []
        with open(ebkPath, 'r') as ebkfp:
            for code in ebkfp:
                code = code.strip()
                if len(code) > 0:
                    if self.getMarketCode(code[1:]) == 1:
                        stocks.append('\x07\x11' + code[1:])
                    else:
                        stocks.append('\x07\x21' + code[1:])

        with open(selPath, 'wb') as selfp:
            data = struct.pack('H', len(stocks)).decode() + ''.join(stocks)
            selfp.write(data.encode())


        return True

    #sel to ebk
    def sel2ebk(self, selPath):
        import struct

        if not os.path.exists(selPath):
            return False

        ebkPath = selPath.replace('.sel', '.ebk')

        with open(selPath, 'rb') as selfp:
            ebkfp = open(ebkPath, "a")
            cnt = struct.unpack('<H', selfp.read(2))[0]
            for _ in range(cnt):
                data = selfp.readline(8).decode()
                exch = '1' if data[1] == '\x11' else '0'
                code = exch + data[2:]

                ebkfp.write(code + '\r\n')

            ebkfp.close()

        return True
예제 #51
0
class Engine:
    def __init__(self, *args, **kwargs):
        if kwargs.pop('best_ip', False):
            self.ip = self.best_ip
        else:
            self.ip = '14.17.75.71'

        self.ip = kwargs.pop('ip', '14.17.75.71')

        self.thread_num = kwargs.pop('thread_num', 1)

        if not PY2 and self.thread_num != 1:
            self.use_concurrent = True
        else:
            self.use_concurrent = False

        self.api = TdxHq_API(args, kwargs)
        if self.use_concurrent:
            self.apis = [
                TdxHq_API(args, kwargs) for i in range(self.thread_num)
            ]
            self.executor = ThreadPoolExecutor(self.thread_num)

    def connect(self):
        self.api.connect(self.ip)
        if self.use_concurrent:
            for api in self.apis:
                api.connect(self.ip)
        return self

    def __enter__(self):
        return self

    def exit(self):
        self.api.disconnect()
        if self.use_concurrent:
            for api in self.apis:
                api.disconnect()

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.api.disconnect()
        if self.use_concurrent:
            for api in self.apis:
                api.disconnect()

    def quotes(self, code):
        code = [code] if not isinstance(code, list) else code
        code = self.security_list[self.security_list.code.isin(
            code)].index.tolist()
        data = [
            self.api.to_df(
                self.api.get_security_quotes(code[80 * pos:80 * (pos + 1)]))
            for pos in range(int(len(code) / 80) + 1)
        ]
        return pd.concat(data)
        # data = data[['code', 'open', 'high', 'low', 'price']]
        # data['datetime'] = datetime.datetime.now()
        # return data.set_index('code', drop=False, inplace=False)

    def stock_quotes(self):
        code = self.stock_list.index.tolist()
        if self.use_concurrent:
            res = {
                self.executor.submit(self.apis[pos % self.thread_num].get_security_quotes,
                                     code[80 * pos:80 * (pos + 1)]) \
                for pos in range(int(len(code) / 80) + 1)}
            return pd.concat([self.api.to_df(dic.result()) for dic in res])
        else:
            data = [
                self.api.to_df(
                    self.api.get_security_quotes(code[80 * pos:80 *
                                                      (pos + 1)]))
                for pos in range(int(len(code) / 80) + 1)
            ]
            return pd.concat(data)

    @lazyval
    def security_list(self):
        return pd.concat([
            pd.concat([
                self.api.to_df(self.api.get_security_list(
                    j, i * 1000)).assign(sse=0 if j == 0 else 1).set_index(
                        ['sse', 'code'], drop=False)
                for i in range(int(self.api.get_security_count(j) / 1000) + 1)
            ],
                      axis=0) for j in range(2)
        ],
                         axis=0)

    @lazyval
    def stock_list(self):
        aa = map(stock_filter, self.security_list.index.tolist())
        return self.security_list[list(aa)]

    @lazyval
    def best_ip(self):
        return select_best_ip()

    @lazyval
    def concept(self):
        return self.api.to_df(
            self.api.get_and_parse_block_info(TDXParams.BLOCK_GN))

    @lazyval
    def index(self):
        return self.api.to_df(
            self.api.get_and_parse_block_info(TDXParams.BLOCK_SZ))

    @lazyval
    def fengge(self):
        return self.api.to_df(
            self.api.get_and_parse_block_info(TDXParams.BLOCK_FG))

    @lazyval
    def customer_block(self):
        return CustomerBlockReader().get_df(CUSTOMER_BLOCK_PATH)

    @lazyval
    def gbbq(self):
        df = GbbqReader().get_df(GBBQ_PATH).query('category == 1')
        df['datetime'] = pd.to_datetime(df['datetime'], format='%Y%m%d')
        return df

    def get_security_type(self, code):
        if code in self.security_list.code.values:
            return self.security_list[self.security_list.code ==
                                      code]['sse'].as_matrix()[0]
        else:
            raise SecurityNotExists()

    def get_security_bars(self, code, freq, index=False):
        if index:
            exchange = self.get_security_type(code)
            func = self.api.get_index_bars
        else:
            exchange = get_stock_type(code)
            func = self.api.get_security_bars

        df = pd.DataFrame()
        if freq in ['1d', 'day']:
            freq = 9
        elif freq in ['1m', 'min']:
            freq = 8
        else:
            raise Exception("1d and 1m frequency supported only")

        res = []
        start = 0
        while True:
            data = func(freq, exchange, code, start, 800)
            if not data:
                break
            res = data + res
            start += 800

        df = self.api.to_df(res).drop(
            ['year', 'month', 'day', 'hour', 'minute'], axis=1)
        df['datetime'] = pd.to_datetime(df.datetime)
        df['code'] = code
        return df.set_index('datetime')

    def _get_transaction(self, code, date):
        res = []
        start = 0
        while True:
            data = self.api.get_history_transaction_data(
                get_stock_type(code), code, start, 2000, date)
            if not data:
                break
            start += 2000
            res = data + res

        if len(res) == 0:
            return pd.DataFrame()
        df = self.api.to_df(res).assign(date=date)
        df.index = pd.to_datetime(str(date) + " " + df["time"])
        df['code'] = code
        return df.drop("time", axis=1)

    def time_and_price(self, code):
        start = 0
        res = []
        exchange = self.get_security_type(code)
        while True:
            data = self.api.get_transaction_data(exchange, code, start, 2000)
            if not data:
                break
            res = data + res
            start += 2000

        df = self.api.to_df(res)
        df.time = pd.to_datetime(
            str(pd.to_datetime('today').date()) + " " + df['time'])
        df.loc[0, 'time'] = df.time[1]
        return df.set_index('time')

    @classmethod
    def minute_bars_from_transaction(cls, transaction, freq):
        if transaction.empty:
            return pd.DataFrame()
        data = transaction['price'].resample(freq,
                                             label='right',
                                             closed='left').ohlc()

        data['volume'] = transaction['vol'].resample(freq,
                                                     label='right',
                                                     closed='left').sum()
        data['code'] = transaction['code'][0]

        return fillna(data)

    def get_k_data(self, code, start, end, freq):
        if isinstance(start, str) or isinstance(end, str):
            start = pd.Timestamp(start)
            end = pd.Timestamp(end)
        sessions = pd.date_range(start, end)
        trade_days = map(int, sessions.strftime("%Y%m%d"))

        if freq == '1m':
            freq = '1 min'

        if freq == '1d':
            freq = '24 H'

        res = []
        for trade_day in trade_days:
            df = Engine.minute_bars_from_transaction(
                self._get_transaction(code, trade_day), freq)
            if df.empty:
                continue
            res.append(df)

        if len(res) != 0:
            return pd.concat(res)
        return pd.DataFrame()
예제 #52
0
if __name__ == '__main__':
    import os
    import time
    starttime = time.time()

    dest_dir = "c:\\stock"
    tdx_server = '119.147.212.81'
    tdx_port = 7709
    quotations = ['stock', 'fund']

    connect = sqlite3.connect(dest_dir + "\\stock.db")
    create_database(connect)

    from pytdx.hq import TdxHq_API, TDXParams
    api = TdxHq_API()
    api.connect(tdx_server, tdx_port)

    add_count = 0
    """
    print("导入股票代码表")
    add_count = import_stock_name(connect, api, 'SH', quotations)
    add_count += import_stock_name(connect, api, 'SZ', quotations)
    print("新增股票数:", add_count)

    print("\n导入上证日线数据")
    add_count = import_data(connect, 'SH', 'DAY', quotations, api, dest_dir, progress=ProgressBar)
    print("\n导入数量:", add_count)

    print("\n导入深证日线数据")
    add_count = import_data(connect, 'SZ', 'DAY', quotations, api, dest_dir, progress=ProgressBar)
    print("\n导入数量:", add_count)
예제 #53
0
                ("bid4", self._cal_price(price, bid4)),
                ("ask4", self._cal_price(price, ask4)),
                ("bid_vol4", bid_vol4),
                ("ask_vol4", ask_vol4),
                ("bid5", self._cal_price(price, bid5)),
                ("ask5", self._cal_price(price, ask5)),
                ("bid_vol5", bid_vol5),
                ("ask_vol5", ask_vol5),
                ("reversed_bytes4", reversed_bytes4),
                ("reversed_bytes5", reversed_bytes5),
                ("reversed_bytes6", reversed_bytes6),
                ("reversed_bytes7", reversed_bytes7),
                ("reversed_bytes8", reversed_bytes8),
                ("reversed_bytes9", reversed_bytes9 / 100.0),  # 涨速
                ("active2", active2)
            ])
            stocks.append(one_stock)
        return stocks

    def _cal_price(self, base_p, diff):
        return float(base_p + diff) / 100


if __name__ == '__main__':
    from pytdx.hq import TdxHq_API
    api = TdxHq_API()
    with api.connect():
        #print(api.to_df(api.get_security_quotes([(0, '102672'), (0, '002672')])))
        print(
            api.to_df(api.get_security_quotes([(0, '101612'), (0, '002672')])))
예제 #54
0
def QA_fetch_get_stock_info(code, ip=best_ip, port=7709):
    '股票财务数据'
    api = TdxHq_API()
    market_code = __select_market_code(code)
    with api.connect(ip, port):
        return api.to_df(api.get_finance_info(market_code, code))
예제 #55
0
    def __call__(self):
        total_count = 0
        try:
            if self.config.getboolean('hdf5', 'enable', fallback=True):
                sqlite_file = "{}/stock.db".format(self.config['hdf5']['dir'])
                connect = sqlite3.connect(sqlite_file, timeout=1800)
                pytdx_import_weight = pytdx_import_weight_to_sqlite
                self.logger.debug('use sqlite import weight')
            else:
                db_config = {
                    'user': self.config['mysql']['usr'],
                    'password': self.config['mysql']['pwd'],
                    'host': self.config['mysql']['host'],
                    'port': self.config['mysql']['port']
                }
                connect = mysql.connector.connect(**db_config)
                pytdx_import_weight = pytdx_import_weight_to_mysql
                self.logger.debug('use mysql import weight')

        except Exception as e:
            #self.queue.put([self.msg_name, str(e), -1, 0, total_count])
            self.queue.put([self.msg_name, 'INFO', str(e), 0, 0])
            self.queue.put([self.msg_name, '', 0, None, total_count])
            return

        try:
            """
            download_dir = self.dest_dir + "/downloads"
            if not os.path.lexists(download_dir):
                os.makedirs(download_dir)

            self.queue.put([self.msg_name, '正在下载钱龙权息信息...', 0, 0, 0])
            net_file = urllib.request.urlopen(
                'http://www.qianlong.com.cn/download/history/weight.rar', timeout=60
            )
            buffer = net_file.read()

            self.queue.put([self.msg_name, '钱龙权息信息下载完成,正在校验是否存在更新...', 0, 0, 0])
            new_md5 = hashlib.md5(buffer).hexdigest()

            dest_filename = download_dir + '/weight.rar'
            old_md5 = None
            if os.path.exists(dest_filename):
                with open(dest_filename, 'rb') as oldfile:
                    old_md5 = hashlib.md5(oldfile.read()).hexdigest()

            #如果没变化不需要解压导入
            if new_md5 != old_md5:
                with open(dest_filename, 'wb') as file:
                    file.write(buffer)

                self.queue.put([self.msg_name, '正在解压钱龙权息信息...', 0, 0, 0])
                x = os.system('unrar x -o+ -inul {} {}'.format(dest_filename, download_dir))
                if x != 0:
                    raise Exception("无法找到unrar命令!")

                self.queue.put([self.msg_name, '正在导入钱龙权息数据...', 0, 0, 0])
                total_count = qianlong_import_weight(connect, download_dir + '/weight', 'SH')
                total_count += qianlong_import_weight(connect, download_dir + '/weight', 'SZ')
                self.queue.put([self.msg_name, '导入钱龙权息数据完毕!', 0, 0, total_count])

            else:
                self.queue.put([self.msg_name, '钱龙权息数据无变化', 0, 0, 0])
            """

            hosts = search_best_tdx()
            api = TdxHq_API()
            api.connect(hosts[0][2], hosts[0][3])

            self.queue.put([self.msg_name, '正在导入权息数据...', 0, 0, 0])
            total_count = pytdx_import_weight(api, connect, "SH")
            total_count += pytdx_import_weight(api, connect, "SZ")
            self.queue.put([self.msg_name, '导入权息数据完毕!', 0, 0, total_count])

            #self.queue.put([self.msg_name, '下载通达信财务信息(上证)...', 0, 0, 0])
            #x = pytdx_import_finance(connect, api, "SH")

            #self.queue.put([self.msg_name, '下载通达信财务信息(深证)...', 0, 0, 0])
            #x += pytdx_import_finance(connect, api, "SZ")
            #self.queue.put([self.msg_name, '导入通达信财务信息完毕!', 0, 0, x])

            api.disconnect()

        except Exception as e:
            self.logger.error(e)
            #self.queue.put([self.msg_name, str(e), -1, 0, total_count])
            self.queue.put([self.msg_name, 'INFO', str(e), 0, 0])
        finally:
            connect.commit()
            connect.close()

        self.queue.put([self.msg_name, '', 0, None, total_count])
예제 #56
0
class TdxData:
    def __init__(self):
        self.api = TdxHq_API(heartbeat=True)
        self.dbUtil = DBUtil.getInstance()

    def get_security_quotes(self, code, type):
        return self.api.get_security_quotes([(type, code)])

    # 支持板块及个股
    def days(self, code, type, bk=False, all=False, day=5):
        category = int(config.getByKey('TDX_CATEGORY'))
        try:
            with self.api.connect(TDX_IP, TDX_PORT):
                data = []
                if all:
                    if bk:
                        for i in range(10):
                            data += self.api.get_index_bars(
                                category, type, code, (9 - i) * 800, 800)
                    else:
                        for i in range(10):
                            data += self.api.get_security_bars(
                                category, type, code, (9 - i) * 800, 800)
                    if len(data) > 0:
                        df = self.api.to_df(data).drop([
                            'amount', 'year', 'month', 'day', 'hour', 'minute'
                        ],
                                                       axis=1)
                        df['trade_date'] = df['datetime'].apply(
                            lambda x: x[0:10].replace('-', ''))
                        df = df.drop(['datetime'], axis=1)
                        df = df.sort_values(by=['trade_date'],
                                            axis=0,
                                            ascending=False)
                        return df
                    else:
                        return self.api.to_df(data)
                else:
                    if bk:
                        data = self.api.get_index_bars(category, type, code, 0,
                                                       day)  # 返回DataFrame
                    else:
                        data = self.api.get_security_bars(
                            category, type, code, 0, day)
                    if len(data) > 0:
                        df = self.api.to_df(data).drop([
                            'amount', 'year', 'month', 'day', 'hour', 'minute'
                        ],
                                                       axis=1)
                        df['trade_date'] = df['datetime'].apply(
                            lambda x: x[0:10].replace('-', ''))
                        df = df.drop(['datetime'], axis=1)
                        df = df.sort_values(by=['trade_date'],
                                            axis=0,
                                            ascending=False)
                        return df
                    else:
                        return self.api.to_df(data)
        except Exception as e:
            logging.info("暂不支持类型,代码:%s:%s" % (code, e))
            return self.api.to_df([])

    # F10 查询公司信息目录
    def get_company_info_category(self, code, type):
        with self.api.connect(TDX_IP, TDX_PORT):
            df = pd.DataFrame(self.api.get_company_info_category(type, code))
            df['txt'] = None
            return df
        return []

    def get_company_info_content(self, code, type, df):
        with self.api.connect(TDX_IP, TDX_PORT):
            return self.api.get_company_info_content(type, code,
                                                     df['filename'].values[0],
                                                     df['start'].values[0],
                                                     df['length'].values[0])
        return ""

    # 查询财务数据
    def get_finance_info(self, code, type):
        with self.api.connect(TDX_IP, TDX_PORT):
            return self.api.get_finance_info(type, code)
        return ''

    # 每年更新一次,板块个股关系
    def updateBk(self):
        with self.api.connect(TDX_IP, TDX_PORT):
            """
            # 获取股票所属板块信息
            # 板块相关参数
            BLOCK_SZ = "block_zs.dat"
            BLOCK_FG = "block_fg.dat"
            BLOCK_GN = "block_gn.dat"
            BLOCK_DEFAULT = "block.dat"
            """
            bk_zs = self.api.to_df(
                self.api.get_and_parse_block_info("block_zs.dat"))  #指数板块
            bk_fg = self.api.to_df(
                self.api.get_and_parse_block_info("block_fg.dat"))  #风格板块
            bk_gn = self.api.to_df(
                self.api.get_and_parse_block_info("block_gn.dat"))  #概念板块
            bk_default = self.api.to_df(
                self.api.get_and_parse_block_info("block.dat"))  # 默认
            self.dbUtil.to_sql(bk_gn,
                               'stock_bk_gn',
                               if_exists='replace',
                               index=False,
                               dtype=STOCK_BK_DTYPE)
            self.dbUtil.to_sql(bk_fg,
                               'stock_bk_fg',
                               if_exists='replace',
                               index=False,
                               dtype=STOCK_BK_DTYPE)
            self.dbUtil.to_sql(bk_zs,
                               'stock_bk_zs',
                               if_exists='replace',
                               index=False,
                               dtype=STOCK_BK_DTYPE)
            self.dbUtil.to_sql(bk_default,
                               'stock_bk_default',
                               if_exists='replace',
                               index=False,
                               dtype=STOCK_BK_DTYPE)

            # 获取股票列表
            tmp1 = self.api.to_df(self.api.get_security_list(0, 0))  # 深圳
            tmp1['type'] = 0
            tmp2 = self.api.to_df(self.api.get_security_list(1, 0))  # 上海
            tmp2['type'] = 1
            tmp = tmp1.append(tmp2)
            self.dbUtil.to_sql(tmp,
                               'stock_bk',
                               if_exists='replace',
                               index=False,
                               dtype=STOCK_BK)

    def updateGD(self, code, type):
        url = 'http://emweb.securities.eastmoney.com/PC_HSF10/ShareholderResearch/ShareholderResearchAjax?code=%s%s' % (
            type.lower(), code)
        html = urllib.request.urlopen(url).read()
        # 将字符串转换成字典
        data = json.loads(html.decode('utf-8'))
        # gdrs 股东人数,sdgd 十大股东 ,sdltgd 十大流通股东
        df_gdrs = pd.DataFrame(data['gdrs'])
        df_gdrs['code'] = code
        try:
            db_df_gdrs = self.dbUtil.read_sql(
                "select * from stock_gdrs where code ='%s'" % code)
            # 数据合并
            df_gdrs = df_gdrs.append(db_df_gdrs).drop_duplicates(
                subset=['code', 'rq', 'gdmc'], keep='last')
        except Exception as e:
            pass
        self.dbUtil.to_sql(df_gdrs,
                           'stock_gdrs',
                           if_exists='append',
                           index=False,
                           dtype=STOCK_GDRS_DTYPE)
        sdgd = []
        for i in range(len(data['sdgd'])):
            sdgd += data['sdgd'][i]['sdgd']
        df_sdgd = pd.DataFrame(sdgd)
        df_sdgd['code'] = code
        try:
            db_df_sdgd = self.dbUtil.read_sql(
                "select * from stock_sdgd where code ='%s'" % code)
            df_sdgd = df_sdgd.append(db_df_sdgd).drop_duplicates(
                subset=['code', 'rq', 'gdmc'], keep='last')
        except Exception as e:
            pass
        self.dbUtil.to_sql(df_sdgd,
                           'stock_sdgd',
                           if_exists='append',
                           index=False,
                           dtype=STOCK_SDGD_DTYPE)
        sdltgd = []
        for i in range(len(data['sdltgd'])):
            sdltgd += data['sdltgd'][i]['sdltgd']
        df_sdltgd = pd.DataFrame(sdltgd)
        df_sdltgd['code'] = code

        # 获取后与数据库中的数据进行merge,首次表不存在,会抛异常
        try:
            db_df_sdltgd = self.dbUtil.read_sql(
                "select * from stock_sdltgd where code ='%s'" % code)
            df_sdltgd = df_sdltgd.append(db_df_sdltgd).drop_duplicates(
                subset=['code', 'rq', 'gdmc'], keep='last')
        except Exception as e:
            pass
        self.dbUtil.to_sql(df_sdltgd,
                           'stock_sdltgd',
                           if_exists='append',
                           index=False,
                           dtype=STOCK_SDGD_DTYPE)

    # 没季度更新一次
    def updateGDs(self):
        codes = self.dbUtil.read_sql("select ts_code from stock_basic")
        tmp = codes['ts_code'].str.split('.', expand=True)
        for index, row in tmp.iterrows():
            try:
                self.updateGD(row[0], row[1])
                logging.info('%s更新结束,当前索引%s' % (row[0], index))
            except Exception as e:
                logging.info('%s更新失败,当前索引%s' % (row[0], index))

    # 分红
    # 分红地址http://data.eastmoney.com/yjfp/201812.html
    def updateFh(self, rq):
        url = 'http://data.eastmoney.com/DataCenter_V3/yjfp/getlist.ashx?filter=(ReportingPeriod=^%s^)' % rq
        html = requests.get(url)
        # 将字符串转换成字典
        data = json.loads(html.text)['data']
        if len(data) == 0:
            return 0
        df = pd.DataFrame(data)
        df['ReportingPeriod'] = df['ReportingPeriod'].apply(lambda x: x[0:10])
        # 首次需要将df_fh制空,因为表还不存在
        if self.dbUtil.is_exist("stock_fh"):
            db_fh = self.dbUtil.read_sql(
                "select * from stock_fh where ReportingPeriod = '%s'" %
                df['ReportingPeriod'][0])
            if db_fh.empty:  # 不存在当前日期的分红信息,进行拼接
                self.dbUtil.to_sql(df,
                                   'stock_fh',
                                   if_exists='append',
                                   index=False)
                return 1
            else:
                pass
        else:
            self.dbUtil.to_sql(df, 'stock_fh', if_exists='append', index=False)
            return 1

    # 更新历年分红
    def updateFhYears(self):
        now = int(time.strftime("%Y", time.localtime())) + 1
        lastYear = int(self._getFhMaxYear())
        for i in range(lastYear, now):  #初始化时开启
            type = self.updateFh('%s-06-30' % i)
            logging.info('%s-06-30%s' % (i, '成功' if type == 1 else '失败'))
            self.updateFh('%s-12-31' % i)
            logging.info('%s-12-31%s' % (i, '成功' if type == 1 else '失败'))

    def _getFhMaxYear(self):
        if self.dbUtil.is_exist('stock_fh'):
            try:
                df = self.dbUtil.read_sql(
                    'select substr(max(t.ReportingPeriod ),0,5) year from stock_fh t'
                )
                return df['year'][0].values
            except Exception as e:
                pass
        return 1991

    @classmethod
    def getInstance(cls):
        if not hasattr(TdxData, "_instance"):
            TdxData._instance = TdxData()
        return TdxData._instance
예제 #57
0
def QA_fetch_get_stock_day(code, start_date, end_date, if_fq='00', frequence='day', ip=best_ip['stock'], port=7709):
    """获取日线及以上级别的数据


    Arguments:
        code {str:6} -- code 是一个单独的code 6位长度的str
        start_date {str:10} -- 10位长度的日期 比如'2017-01-01'
        end_date {str:10} -- 10位长度的日期 比如'2018-01-01'

    Keyword Arguments:
        if_fq {str} -- '00'/'bfq' -- 不复权 '01'/'qfq' -- 前复权 '02'/'hfq' -- 后复权 '03'/'ddqfq' -- 定点前复权 '04'/'ddhfq' --定点后复权
        frequency {str} -- day/week/month/quarter/year 也可以是简写 D/W/M/Q/Y
        ip {str} -- [description] (default: best_ip['stock']) ip可以通过select_best_ip()函数重新获取
        port {int} -- [description] (default: {7709})


    Returns:
        pd.DataFrame/None -- 返回的是dataframe,如果出错比如只获取了一天,而当天停牌,返回None

    Exception:
        如果出现网络问题/服务器拒绝, 会出现socket:time out 尝试再次获取/更换ip即可, 本函数不做处理
    """

    api = TdxHq_API()
    with api.connect(ip, port, time_out=0.7):

        if frequence in ['day', 'd', 'D', 'DAY', 'Day']:
            frequence = 9
        elif frequence in ['w', 'W', 'Week', 'week']:
            frequence = 5
        elif frequence in ['month', 'M', 'm', 'Month']:
            frequence = 6
        elif frequence in ['quarter', 'Q', 'Quarter', 'q']:
            frequence = 10
        elif frequence in ['y', 'Y', 'year', 'Year']:
            frequence = 11
        start_date = str(start_date)[0:10]
        today_ = datetime.date.today()
        lens = QA_util_get_trade_gap(start_date, today_)

        data = pd.concat([api.to_df(api.get_security_bars(frequence, _select_market_code(
            code), code, (int(lens / 800) - i) * 800, 800)) for i in range(int(lens / 800) + 1)], axis=0)

        # 这里的问题是: 如果只取了一天的股票,而当天停牌, 那么就直接返回None了
        if len(data) < 1:
            return None
        data = data[data['open'] != 0]

        if if_fq in ['00', 'bfq']:
            data = data.assign(date=data['datetime'].apply(lambda x: str(x[0:10]))).assign(code=str(code))\
                .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10]))).set_index('date', drop=False, inplace=False)

            return data.drop(['year', 'month', 'day', 'hour', 'minute', 'datetime'], axis=1)[start_date:end_date].assign(date=data['date'].apply(lambda x: str(x)[0:10]))

        elif if_fq in ['01', 'qfq']:

            xdxr_data = QA_fetch_get_stock_xdxr(code)
            bfq_data = data.assign(date=pd.to_datetime(data['datetime'].apply(lambda x: str(x[0:10])))).assign(code=str(code))\
                .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10]))).set_index('date', drop=False, inplace=False)
            bfq_data = bfq_data.drop(
                ['year', 'month', 'day', 'hour', 'minute', 'datetime'], axis=1)
            #
            if xdxr_data is not None:
                info = xdxr_data[xdxr_data['category'] == 1]
                bfq_data['if_trade'] = True
                data = pd.concat([bfq_data, info[['category']]
                                  [bfq_data.index[0]:]], axis=1)

                data['date'] = data.index
                data['if_trade'].fillna(value=False, inplace=True)
                data = data.fillna(method='ffill')
                data = pd.concat([data, info[['fenhong', 'peigu', 'peigujia',
                                              'songzhuangu']][bfq_data.index[0]:]], axis=1)
                data = data.fillna(0)

                data['preclose'] = (data['close'].shift(1) * 10 - data['fenhong'] + data['peigu']
                                    * data['peigujia']) / (10 + data['peigu'] + data['songzhuangu'])
                data['adj'] = (data['preclose'].shift(-1) /
                               data['close']).fillna(1)[::-1].cumprod()
                data['open'] = data['open'] * data['adj']
                data['high'] = data['high'] * data['adj']
                data['low'] = data['low'] * data['adj']
                data['close'] = data['close'] * data['adj']
                data['preclose'] = data['preclose'] * data['adj']

                data = data[data['if_trade']]
                return data.drop(['fenhong', 'peigu', 'peigujia', 'songzhuangu', 'if_trade', 'category'], axis=1)[data['open'] != 0].assign(date=data['date'].apply(lambda x: str(x)[0:10]))[start_date:end_date]
            else:

                bfq_data['preclose'] = bfq_data['close'].shift(1)
                bfq_data['adj'] = 1
                return bfq_data[start_date:end_date]
        elif if_fq in ['03', 'ddqfq']:
            xdxr_data = QA_fetch_get_stock_xdxr(code)

            info = xdxr_data[xdxr_data['category'] == 1]

            bfq_data = data\
                .assign(date=pd.to_datetime(data['datetime'].apply(lambda x: x[0:10])))\
                .assign(code=str(code))\
                .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\
                .set_index('date', drop=False, inplace=False)\
                .drop(['year', 'month', 'day', 'hour',
                       'minute', 'datetime'], axis=1)

            bfq_data['if_trade'] = True
            data = pd.concat([bfq_data, info[['category']]
                              [bfq_data.index[0]:end_date]], axis=1)

            data['date'] = data.index
            data['if_trade'].fillna(value=False, inplace=True)
            data = data.fillna(method='ffill')
            data = pd.concat([data, info[['fenhong', 'peigu', 'peigujia',
                                          'songzhuangu']][bfq_data.index[0]:end_date]], axis=1)
            data = data.fillna(0)

            data['preclose'] = (data['close'].shift(1) * 10 - data['fenhong'] + data['peigu']
                                * data['peigujia']) / (10 + data['peigu'] + data['songzhuangu'])
            data['adj'] = (data['preclose'].shift(-1) /
                           data['close']).fillna(1)[::-1].cumprod()
            data['open'] = data['open'] * data['adj']
            data['high'] = data['high'] * data['adj']
            data['low'] = data['low'] * data['adj']
            data['close'] = data['close'] * data['adj']
            data['preclose'] = data['preclose'] * data['adj']

            data = data[data['if_trade']]
            return data.drop(['fenhong', 'peigu', 'peigujia', 'songzhuangu', 'if_trade', 'category'], axis=1)[data['open'] != 0].assign(date=data['date'].apply(lambda x: str(x)[0:10]))[start_date:end_date]

        elif if_fq in ['02', 'hfq']:
            xdxr_data = QA_fetch_get_stock_xdxr(code)

            info = xdxr_data[xdxr_data['category'] == 1]

            bfq_data = data\
                .assign(date=pd.to_datetime(data['datetime'].apply(lambda x: x[0:10])))\
                .assign(code=str(code))\
                .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\
                .set_index('date', drop=False, inplace=False)\
                .drop(['year', 'month', 'day', 'hour',
                       'minute', 'datetime'], axis=1)

            bfq_data['if_trade'] = True
            data = pd.concat([bfq_data, info[['category']]
                              [bfq_data.index[0]:]], axis=1)

            data['date'] = data.index
            data['if_trade'].fillna(value=False, inplace=True)
            data = data.fillna(method='ffill')
            data = pd.concat([data, info[['fenhong', 'peigu', 'peigujia',
                                          'songzhuangu']][bfq_data.index[0]:]], axis=1)
            data = data.fillna(0)

            data['preclose'] = (data['close'].shift(1) * 10 - data['fenhong'] + data['peigu']
                                * data['peigujia']) / (10 + data['peigu'] + data['songzhuangu'])
            data['adj'] = (data['preclose'].shift(-1) /
                           data['close']).fillna(1).cumprod()
            data['open'] = data['open'] / data['adj']
            data['high'] = data['high'] / data['adj']
            data['low'] = data['low'] / data['adj']
            data['close'] = data['close'] / data['adj']
            data['preclose'] = data['preclose'] / data['adj']
            data = data[data['if_trade']]
            return data.drop(['fenhong', 'peigu', 'peigujia', 'songzhuangu', 'if_trade', 'category'], axis=1)[data['open'] != 0].assign(date=data['date'].apply(lambda x: str(x)[0:10]))[start_date:end_date]

        elif if_fq in ['04', 'ddhfq']:
            xdxr_data = QA_fetch_get_stock_xdxr(code)

            info = xdxr_data[xdxr_data['category'] == 1]

            bfq_data = data\
                .assign(date=pd.to_datetime(data['datetime'].apply(lambda x: x[0:10])))\
                .assign(code=str(code))\
                .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\
                .set_index('date', drop=False, inplace=False)\
                .drop(['year', 'month', 'day', 'hour',
                       'minute', 'datetime'], axis=1)

            bfq_data['if_trade'] = True
            data = pd.concat([bfq_data, info[['category']]
                              [bfq_data.index[0]:end_date]], axis=1)

            data['date'] = data.index
            data['if_trade'].fillna(value=False, inplace=True)
            data = data.fillna(method='ffill')
            data = pd.concat([data, info[['fenhong', 'peigu', 'peigujia',
                                          'songzhuangu']][bfq_data.index[0]:end_date]], axis=1)
            data = data.fillna(0)

            data['preclose'] = (data['close'].shift(1) * 10 - data['fenhong'] + data['peigu']
                                * data['peigujia']) / (10 + data['peigu'] + data['songzhuangu'])
            data['adj'] = (data['preclose'].shift(-1) /
                           data['close']).fillna(1).cumprod()
            data['open'] = data['open'] / data['adj']
            data['high'] = data['high'] / data['adj']
            data['low'] = data['low'] / data['adj']
            data['close'] = data['close'] / data['adj']
            data['preclose'] = data['preclose'] / data['adj']
            data = data[data['if_trade']]
            return data.drop(['fenhong', 'peigu', 'peigujia', 'songzhuangu', 'if_trade', 'category'], axis=1)[data['open'] != 0].assign(date=data['date'].apply(lambda x: str(x)[0:10]))[start_date:end_date]
예제 #58
0
class PYTDXService():
    """pytdx数据服务类"""
    def __init__(self):
        """Constructor"""
        self.connected = False  # 数据服务连接状态
        self.hq_api = None  # 行情API

    def connect_api(self):
        """连接API"""
        # 连接增强行情API并检查连接情况
        try:
            if not self.connected:
                host = SETTINGS["TDX_HOST"]
                port = SETTINGS["TDX_PORT"]
                self.hq_api = TdxHq_API()
                self.hq_api.connect(host, port)
                self.connected = True
            return True
        except Exception:
            raise ConnectionError("pytdx连接错误")

    def get_realtime_data(self, symbol: str):
        """获取股票实时数据"""
        try:
            symbols = self.generate_symbols(symbol)
            df = self.hq_api.to_df(self.hq_api.get_security_quotes(symbols))
            return df
        except Exception:
            raise ValueError("股票数据获取失败")

    def get_history_transaction_data(self, symbol, date):
        """
        查询历史分笔数据
        get_history_transaction_data(TDXParams.MARKET_SZ, '000001', 0, 10, 20170209)
        参数:市场代码, 股票代码, 起始位置, 数量, 日期
        输出[time, price, vol, buyorsell(0:buy, 1:sell, 2:平)]
        """
        # 获得标的
        code, market = self.check_symbol(symbol)

        # 设置参数
        check_date = int(date)
        count = 2000
        data_list = []
        position = [6000, 4000, 2000, 0]
        for start in position:
            data = self.hq_api.to_df(
                self.hq_api.get_history_transaction_data(
                    market, code, start, count, check_date))
            data_list.append(data)

        df = pd.concat(data_list)
        df.drop_duplicates(inplace=True)
        return df

    @staticmethod
    def generate_symbols(symbol: str):
        """组装symbols数据,pytdx接收的是以市场代码和标的代码组成的元祖的list"""
        new_symbols = []
        code, exchange = symbol.split('.')
        new_symbols.append((exchange_map[exchange], code))

        return new_symbols

    @staticmethod
    def check_symbol(symbol: str):
        """检查标的格式"""
        if symbol:
            code, market = symbol.split('.')
            market = exchange_map.get(market)
            return code, market

        else:
            return False

    def close(self):
        """数据服务关闭"""
        self.connected = False
        self.hq_api.disconnect()
예제 #59
0
    def _run(self):
        src_dir = self.config['tdx']['dir']
        dest_dir = self.config['hdf5']['dir']
        hdf5_import_progress = {'SH': {'DAY': 0, '1MIN': 0, '5MIN': 0},
                                'SZ': {'DAY': 0, '1MIN': 0, '5MIN': 0}}
        trans_progress = {'SH': 0, 'SZ': 0}
        time_progress = {'SH': 0, 'SZ': 0}

        #正在导入代码表
        self.send_message(['INFO', '导入股票代码表'])

        connect = sqlite3.connect(dest_dir + "/stock.db")
        create_database(connect)

        pytdx_api = TdxHq_API()
        pytdx_api.connect(self.hosts[0][2], self.hosts[0][3])

        count = import_stock_name(connect, pytdx_api, 'SH', self.quotations)
        if count > 0:
            self.send_message(['INFO', '上证新增股票数:%s' % count])
        count = import_stock_name(connect, pytdx_api, 'SZ', self.quotations)
        if count > 0:
            self.send_message(['INFO', '深证新增股票数:%s' % count])

        self.process_list.clear()
        for task in self.tasks:
            p = Process(target=task)
            self.process_list.append(p)
            p.start()

        finished_count = len(self.tasks)
        while finished_count > 0:
            message = self.queue.get()
            taskname, market, ktype, progress, total = message
            if progress is None:
                finished_count -= 1
                if taskname in ('IMPORT_KDATA', 'IMPORT_TRANS', 'IMPORT_TIME'):
                    self.send_message([taskname, 'FINISHED', market, ktype, total])
                else:
                    self.send_message([taskname, 'FINISHED'])
                continue

            if taskname == 'IMPORT_WEIGHT':
                if market == 'INFO':
                    self.send_message(['INFO', ktype])
                self.send_message([taskname, market, total])
            elif taskname == 'IMPORT_FINANCE':
                self.send_message([taskname, progress])
            elif taskname == 'IMPORT_KDATA':
                hdf5_import_progress[market][ktype] = progress
                current_progress = (hdf5_import_progress['SH'][ktype] + hdf5_import_progress['SZ'][ktype]) // 2
                self.send_message([taskname, ktype, current_progress])
            elif taskname == 'IMPORT_TRANS':
                trans_progress[market] = progress
                current_progress = (trans_progress['SH'] + trans_progress['SZ']) // 2
                self.send_message([taskname, ktype, current_progress])
            elif taskname == 'IMPORT_TIME':
                time_progress[market] = progress
                current_progress = (time_progress['SH'] + time_progress['SZ']) // 2
                self.send_message([taskname, ktype, current_progress])
            else:
                print("Unknow task: ", taskname)