예제 #1
0
def get_a_quote_by_tdx(code_list):
    """
    获取A股市场行情,该接口只获取A股市场行情
    其他的行情使用拓展行情接口
    code_list:数字或者字符串格式的list,调用def standard_tdx_code(code_list)来格式化市场信息及code
    """

    if len(code_list) == 0:
        return pd.DataFrame(columns=stock_tdx_columns)
    # 一次最多获取50只股票的实时行情,如果code_list 多于50只,则50只股票取一次行情,然后进行拼接
    tdx_api = TdxHq_API()
    if len(code_list) >= 50:
        tmp = div_list(code_list, 50)
        df_tmp = pd.DataFrame(columns=stock_tdx_columns)
        if tdx_api.connect('119.147.212.81', 7709):
            for tmp_list in tmp:
                tmp_list = standard_tdx_code(tmp_list)
                tdx_data = tdx_api.to_df(tdx_api.get_security_quotes(tmp_list))
                df_tmp = pd.concat([df_tmp, tdx_data])
            df_tmp = df_tmp[stock_tdx_columns]
    else:
        tmp = standard_tdx_code(code_list)
        if tdx_api.connect('119.147.212.81', 7709):
            tdx_data = tdx_api.to_df(tdx_api.get_security_quotes(tmp))
            df_tmp = tdx_data[stock_tdx_columns]

    tdx_api.disconnect()
    return process_tdx_price(df_tmp)
예제 #2
0
    def quote_TDX(ds_tuple):
        api = TdxHq_API()
        if api.connect('119.147.212.81', 7709):
            MainCodeData = api.get_security_quotes([(1, code)])
            n = ceil(len(ds_tuple) / 80)
            for i in range(n):
                if i == 0:
                    quot = api.get_security_quotes(ds_tuple[i * 80:(i + 1) *
                                                            80])  #每次最多请求80个数据?
                else:
                    quot_add = api.get_security_quotes(
                        ds_tuple[i * 80:(i + 1) * 80])
                    quot = quot + quot_add

            api.disconnect()
            return quot, MainCodeData
예제 #3
0
 def original_quotes(code, best_ip):
     api = TdxHq_API()
     api.connect(best_ip)
     now = datetime.now()
     data = [
         api.get_security_quotes(code[80 * pos:80 * (pos + 1)])
         for pos in range(int(len(code) / 80) + 1)
     ]
     return (datetime.now() - now).total_seconds()
예제 #4
0
def request_data(stklist, parse_one_result, ip, port):
    """请求失败将抛出异常"""
    api = TdxHq_API()
    hku_check(api.connect(ip, port),
              'Failed connect tdx ({}:{})!'.format(ip, port))
    quotes_list = api.get_security_quotes(stklist)
    result = [parse_one_result(q)
              for q in quotes_list] if quotes_list is not None else []
    return [r for r in result if r is not None]
예제 #5
0
def original_quotes():
    api = TdxHq_API()
    api.connect(best_ip)
    now = datetime.now()
    #data=api.get_security_quotes((get_market(x), x))
    #print(data)
    data = [api.get_security_quotes([(get_market(x), x) for x in code[80 * pos:80 * (pos + 1)]]) for pos in range(int(len(code) / 80) + 1)]

    
    return data[0:-1]
예제 #6
0
파일: Tdx.py 프로젝트: Rgveda/TradingLib
 def __hq_tick(self, code):
     api = TdxHq_API()
     ip, port = self.__hq.get()
     with api.connect(ip, port):
         df = api.get_security_quotes(code)
         if df is not None:
             df = api.to_df(df)
         api.disconnect()
         self.__hq.put((ip, port))
         return df
예제 #7
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)
예제 #8
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)
예제 #9
0
파일: myfunc.py 프로젝트: admwby1hy/my
def get_up_count(webname='ths'):

    try:
        api = TdxHq_API()
        with api.connect('119.147.212.81', 7709):
            data = api.get_security_quotes([(1, '880005')])
            this_count = data[0]['price']
            return int(this_count)

    except Exception as e:
        headers = {
            'User-Agent':
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
            '(KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
        }

        if webname == 'ths':
            try:
                #从同花顺取值
                url = 'http://q.10jqka.com.cn/api.php?t=indexflash&'
                html = requests.get(url, headers=headers)
                jsoninfo = json.loads(html.text)
                this_count = jsoninfo['zdfb_data']['znum']
                return this_count

            except Exception as e:
                #从东方财富取值
                url = 'http://push2.eastmoney.com/api/qt/ulist.np/get?fid=f3&pi=0&pz=20&po=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&fields=f104&np=1&secids=1.000001,0.399001'
                html = requests.get(url, headers=headers)
                jsoninfo = json.loads(html.text)
                this_count = jsoninfo['data']['diff'][0]['f104'] + jsoninfo[
                    'data']['diff'][1]['f104'] - 30
                return this_count

        if webname == 'dfcf':
            try:
                #从东方财富取值
                url = 'http://push2.eastmoney.com/api/qt/ulist.np/get?fid=f3&pi=0&pz=20&po=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&fields=f104&np=1&secids=1.000001,0.399001'
                html = requests.get(url, headers=headers)
                jsoninfo = json.loads(html.text)
                this_count = jsoninfo['data']['diff'][0]['f104'] + jsoninfo[
                    'data']['diff'][1]['f104'] - 30
                return this_count

            except Exception as e:
                #从同花顺取值
                url = 'http://q.10jqka.com.cn/api.php?t=indexflash&'
                html = requests.get(url, headers=headers)
                jsoninfo = json.loads(html.text)
                this_count = jsoninfo['zdfb_data']['znum']
                return this_count
예제 #10
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)
예제 #11
0
def get_quote_by_tdx(code_list):
    '''
    使用通达信接口获取股票实时行情
    :param code_list: 股票代码list
    :return: df
    '''
    tdx_code = stander_stock_code(code_list, 'tdx')
    if not tdx_code:
        return pd.DataFrame()

    api = TdxHq_API()
    with api.connect('119.147.212.81', 7709):
        data = api.to_df(api.get_security_quotes(tdx_code))
        data = data[stock_tdx_columns]
        return data
예제 #12
0
def get_quote_by_tdx2(code_list, isbTDX):
    '''
    使用通达信接口获取股票实时行情
    该方法带有市场信息,主要是对于一些ETF或者lof行情,不能用0开头还是6开头来判断是上海市场还是深圳市场
    :param code_list: 股票代码list,带市场信息
    :param isbTDX:true,带有通达信标准获取信息行情的内容
    :return: df
    '''
    if not isbTDX:
        return pd.DataFrame()

    api = TdxHq_API()
    with api.connect('119.147.212.81', 7709):
        data = api.to_df(api.get_security_quotes(code_list))
        if data.empty:
            return pd.DataFrame()
        data = data[stock_tdx_columns]
        return data
예제 #13
0
def test_hq():
    import pprint

    api = TdxHq_API(multithread=False)
    with api.connect(time_out=30):
        for i in range(100):
            stocks = api.get_security_quotes([(0, "000001"), (1, "600993")])
            #print(stocks)
            #print(type(stocks))
            print(stocks[1].get('code'), stocks[1].get('price'),
                  stocks[1].get('bid1'), stocks[1].get('bid_vol1'),
                  stocks[1].get('ask1'), stocks[1].get('ask_vol1'))

            #data = api.get_transaction_data(TDXParams.MARKET_SH, '601818', 0, 100)
            #pprint.pprint(data)
            #print('time:{},price:{},vol:{},buyorsell:{}'.format(data[0].get('time'), data[0].get('price'), data[0].get('vol'), data[0].get('buyorsell')))

            time.sleep(1.5)
예제 #14
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("股票数据获取失败")

    @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

    def close(self):
        """数据服务关闭"""
        self.connected = False
        self.hq_api.disconnect()
예제 #15
0
class tdxApi:
    def __init__(self):
        self.ipset = [(v[1], v[2]) for v in hq_hosts]
        random.shuffle(self.ipset)
        self.ippool = AvailableIPPool(TdxHq_API, self.ipset)
        self.primary_ip, _ = self.ippool.sync_get_top_n(2)
        self.api = TdxHq_API(multithread=True, heartbeat=True, auto_retry=True)

    def connect(self):
        self.api.connect(self.primary_ip[0], self.primary_ip[1])

    def release(self):
        self.api.disconnect()

    def getQuotes(self, stock_list):
        datas = self.api.get_security_quotes(stock_list)
        if datas is None:
            return None
        else:
            return self.api.to_df(datas)

    def getList(self, market, index):
        df = self.api.to_df(self.api.get_security_list(market, index))
        return df

    def getCount(self, market=0):
        return self.api.get_security_count(market)

    def getMinQuotes(self, market, stock_code):
        datas = self.api.get_minute_time_data(market, stock_code)
        if datas is None:
            return None

        return self.api.to_df(datas)

    def getMinQuotesHis(self, market, stock_code, date):
        datas = self.api.get_history_minute_time_data(market, stock_code, date)
        if datas is None:
            return None

        return self.api.to_df(datas)
예제 #16
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)
예제 #17
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)
예제 #18
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
예제 #19
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
예제 #20
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())
예제 #21
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)
예제 #22
0
    def single_client_benchmark(ip):

        def _log(msg):
            click.echo("HQ_BENCHMARK: [{:15s}] {} ".format(ip, datetime.datetime.now()) + msg)

        def _grouped_list(stocks):
            return [stocks[i:i + GET_QUOTES_PER_GROUPS] for i in range(0, len(stocks), GET_QUOTES_PER_GROUPS)]

        _log("start benchmark")

        total_time = connecting_time = get_security_count_time = get_security_list_time = get_security_quotes_time = num = 0

        start_time = time.time()
        last_time = start_time

        try:
            api = TdxHq_API(multithread=True)

            port = 7709

            if ":" in ip:
                ip, port = ip.split(':')
                port = int(port)

            with api.connect(ip=ip, port=port):
                _log("connected")
                cur_time = time.time()
                connecting_time = cur_time - last_time
                last_time = cur_time
                _log("connecting time is {}".format(connecting_time))

                num = api.get_security_count(0)
                _log("all shenzhen market stock count is {}".format(num))

                cur_time = time.time()
                get_security_count_time = cur_time - last_time
                last_time = cur_time
                _log("get_security_count_time is {}".format(get_security_count_time))

                all = []
                for i in range((num // 1000) + 1):
                    offset = i * 1000
                    section = api.get_security_list(0, offset)
                    all = all + section

                cur_time = time.time()
                get_security_list_time = cur_time - last_time
                last_time = cur_time

                _log("get_security_list_time is {}".format(get_security_list_time))

                codes = [one['code'] for one in all]

                results = []
                for stocks in _grouped_list(codes):
                    req_list = [(0, code) for code in stocks]
                    one_results = api.get_security_quotes(req_list)
                    results = results + one_results

                cur_time = time.time()
                get_security_quotes_time = cur_time - last_time
                last_time = cur_time
                _log("get_security_quotes_time is {}".format(get_security_quotes_time))

                total_time = last_time - start_time

                _log("total_time is {}".format(total_time))

            _log("end benchmark")
        except Exception as e:
            _log("hit exception " + str(e))

        return {
            "ip": ip,
            "total_time": total_time,
            "connecting_time": connecting_time,
            "get_security_count_time": get_security_count_time,
            "get_security_list_time": get_security_list_time,
            "get_security_quotes_time": get_security_quotes_time,
            "security_count": num
        }
예제 #23
0
파일: Tdx.py 프로젝트: MuzhiWang/QuantTest
class TDX_GW(object):

    __lc_min_bar_reader = None
    __daily_bar_reader = None
    __tdx_api = None
    __connected_ip = '119.147.212.81'
    __connected_port = 7709

    def __init__(self):
        self.__lc_min_bar_reader = lc_min_bar_reader.TdxLCMinBarReader()
        self.__daily_bar_reader = TdxDailyBarReader()
        self.__block_reader = block_reader.BlockReader()
        self.__tdx_api = TdxHq_API()
        self.__cfg_provider = ConfigProvider.ConfigProvider()


    def get_local_stock_bars(self, file_path: str, stock_date_type: StockDataType):
        if stock_date_type == StockDataType.ONE_MIN or \
            stock_date_type == StockDataType.FIVE_MINS:
            # start = time.time()
            # df = self.__lc_min_bar_reader.get_df(file_path)
            data = self.__lc_min_bar_reader.parse_data_by_file(file_path)
            df = pd.DataFrame(data=data)
            # df = df['date', 'open', 'high', 'low', 'close', 'amount', 'volume']
            # print(f"TDX get 1min bar time spent: {(time.time() - start) * 1000} ms")

            return df[['date', 'open', 'high', 'low', 'close', 'amount', 'volume']]
        elif stock_date_type == StockDataType.DAILY:
            data = self.__daily_bar_reader.get_df(file_path).reset_index()
            data['date'] = data['date'].dt.strftime('%Y-%m-%d')
            return data[['date', 'open', 'high', 'low', 'close', 'amount', 'volume']]
        else:
            raise UnimplementedException

    def get_local_stock_bars_raw_data(self, file_path: str, stock_date_type: StockDataType):
        if stock_date_type == StockDataType.ONE_MIN or \
            stock_date_type == StockDataType.FIVE_MINS:
            return self.__lc_min_bar_reader.parse_data_by_file(file_path)
        elif stock_date_type == StockDataType.DAILY:
            return self.__daily_bar_reader.parse_data_by_file(file_path)
        else:
            raise UnimplementedException

    def get_local_block(self):
        file_path = self.__cfg_provider.get_tdx_block_directory_path()
        return self.__block_reader.get_df(file_path, BlockReader_TYPE_GROUP)

    def get_realtime_stock_1min_bars(self, market: str, stock_id: str):
        with self.__tdx_api.connect(self.__connected_ip, self.__connected_port):
            market_code = self.__get_market_code(market)
            df = self.__tdx_api.to_df(
                self.__tdx_api.get_security_bars(8, market_code, stock_id, 0, 10))  # 返回DataFrame
            return df

    def get_realtime_stocks_quotes(self, stock_ids: []):
        stock_list = []
        for id in stock_ids:
            stock_list.append((com_utils.get_stock_market(id), id))
        with self.__tdx_api.connect(self.__connected_ip, self.__connected_port):
            return self.__tdx_api.get_security_quotes(stock_list)

    def get_history_minute_time_data(self, market: str, stock_id: str, date: int):
        with self.__tdx_api.connect(self.__connected_ip, self.__connected_port):
            market_code = self.__get_market_code(market)
            df = self.__tdx_api.to_df(
                self.__tdx_api.get_history_minute_time_data(market_code, stock_id, date))
            return df

    def get_xdxr_info(self, market: str, stock_id: str):
        with self.__tdx_api.connect(self.__connected_ip, self.__connected_port):
            market_code = self.__get_market_code(market)
            df = self.__tdx_api.to_df(
                self.__tdx_api.get_xdxr_info(market_code, stock_id))
            return df

    def test(self):
        with self.__tdx_api.connect(self.__connected_ip, self.__connected_port):
            return self.__tdx_api.get_history_minute_time_data(0, '000001', '2019-05-05')

    def __get_market_code(self, market: str):
        if market == cfg.MARKET.SHANGHAI:
            return 1
        elif market == cfg.MARKET.SHENZHEN:
            return 0
        else:
            raise UnimplementedException
예제 #24
0

def get_all_stock():
    df = ts.get_stock_basics()
    df['stock'] = df.index
    df = df.sort_values(by=['stock'], ascending=True)
    df['stock'] = df.stock.map(lambda x:
                               (1 if str(x).startswith('60') else 0, x))
    return df['stock'].tolist()


if __name__ == '__main__':
    stocks = get_all_stock()
    api = TdxHq_API()
    if api.connect('119.147.212.81', 7709):
        data = api.get_security_quotes(stocks[0:200])
        print(data)
        api.disconnect()

    # ips = [(v[1], v[2]) for v in hq_hosts]
    # # 获取5个随机ip作为ip池
    # random.shuffle(ips)
    # ips5 = ips[:5]
    #
    # ## IP 池对象
    # ippool = AvailableIPPool(TdxHq_API, ips5)
    #
    # ## 选出M, H
    # primary_ip, hot_backup_ip = ippool.sync_get_top_n(2)
    #
    # print("make pool api")
예제 #25
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')])))
예제 #26
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()
예제 #27
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)
예제 #28
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
예제 #29
0
            ])
            stocks.append(one_stock)
        return stocks

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

    def _format_time(self, time_stamp):
        """
        format time from reversed_bytes0
        by using method from https://github.com/rainx/pytdx/issues/187
        """
        time = time_stamp[:-6] + ':'
        if int(time_stamp[-6:-4]) < 60:
            time += '%s:' % time_stamp[-6:-4]
            time += '%06.3f' % (int(time_stamp[-4:]) * 60 / 10000.0)
        else:
            time += '%02d:' % (int(time_stamp[-6:]) * 60 / 1000000)
            time += '%06.3f' % (
                (int(time_stamp[-6:]) * 60 % 1000000) * 60 / 1000000.0)
        return time


if __name__ == '__main__':
    from pytdx.hq import TdxHq_API
    api = TdxHq_API()
    with api.connect('182.131.7.211', 7709):
        #print(api.to_df(api.get_security_quotes([(0, '102672'), (0, '002672')])))
        print(
            api.to_df(api.get_security_quotes([(0, '000677'), (0, '002672')])))
예제 #30
0
##pip install pytdx
from pytdx.hq import TdxHq_API

api = TdxHq_API()

api.connect('59.173.18.140', 7709)
print("获取股票行情")

data = api.get_k_data('000002', '2005-07-01', '2017-07-10')

data2 = api.get_xdxr_info(1, '600300')

print(data2)

print("获取股票行情")
stocks = api.get_security_quotes([(0, "000002"), (1, "600300")])

print(stocks)
print("获取k线")
data = api.get_security_bars(9, 0, '000001', 4, 3)
print(data)
print("获取 深市 股票数量")
print(api.get_security_count(0))
print("获取股票列表")
stocks = api.get_security_list(1, 255)
print(stocks)
print("获取指数k线")
data = api.get_index_bars(9, 1, '000001', 1, 2)
print(data)
print("查询分时行情")
data = api.get_minute_time_data(1, '600300')
예제 #31
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
예제 #32
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()
예제 #33
0
파일: engine.py 프로젝트: nopain1573/tdx-1
class Engine:
    concurrent_thread_count = 50

    def __init__(self, *args, **kwargs):
        if 'ip' in kwargs:
            self.ip = kwargs.pop('ip')
        else:
            if kwargs.pop('best_ip', False):
                self.ip = self.best_ip
            else:
                self.ip = '14.17.75.71'
        if 'concurrent_thread_count' in kwargs:
            self.concurrent_thread_count = kwargs.pop(
                'concurrent_thread_count', 50)
        self.thread_num = kwargs.pop('thread_num', 1)

        self.api = TdxHq_API(args, kwargs, raise_exception=True)

    def connect(self):
        self.api.connect(self.ip)
        return self

    def __enter__(self):
        return self

    def exit(self):
        self.api.disconnect()

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.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()
        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 block(self):
        return self.api.to_df(
            self.api.get_and_parse_block_info(TDXParams.BLOCK_DEFAULT))

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

    def xdxr(self, code):
        df = self.api.to_df(
            self.api.get_xdxr_info(self.get_security_type(code), code))
        if df.empty:
            return df
        df['datetime'] = pd.to_datetime((df.year * 10000 + df.month * 100 +
                                         df.day).apply(lambda x: str(x)))
        return df.drop(['year', 'month', 'day'], axis=1).set_index('datetime')

    @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()

    @retry(3)
    def get_security_bars(self, code, freq, start=None, end=None, 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

        if start:
            start = start.tz_localize(None)
        if end:
            end = end.tz_localize(None)

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

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

            if start and pd.to_datetime(data[0]['datetime']) < start:
                break
        try:
            df = self.api.to_df(res).drop(
                ['year', 'month', 'day', 'hour', 'minute'], axis=1)
            df['datetime'] = pd.to_datetime(df.datetime)
            df.set_index('datetime', inplace=True)
            if freq == 9:
                df.index = df.index.normalize()
        except ValueError:  # 未上市股票,无数据
            logger.warning("no k line data for {}".format(code))
            # return pd.DataFrame({
            #     'amount': [0],
            #     'close': [0],
            #     'open': [0],
            #     'high': [0],
            #     'low': [0],
            #     'vol': [0],
            #     'code': code
            # },
            #     index=[start]
            # )
            return pd.DataFrame()
        close = [df.close.values[-1]]
        if start:
            df = df.loc[lambda df: start <= df.index]
        if end:
            df = df.loc[lambda df: df.index.normalize() <= end]

        if df.empty:
            # return pd.DataFrame({
            #     'amount': [0],
            #     'close': close,
            #     'open': close,
            #     'high': close,
            #     'low': close,
            #     'vol': [0],
            #     'code': code
            # },
            #     index=[start]
            # )
            return df
        else:
            if int(df['vol'][-1]) <= 0 and end == df.index[-1] and len(
                    df) == 1:  # 成交量为0,当天返回的是没开盘的数据
                return pd.DataFrame()
            df['code'] = code
            return df

    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.loc[0, 'time'] = df.time[1]
        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()
        mask = transaction.index < transaction.index[0].normalize(
        ) + pd.Timedelta('12 H')

        def resample(transaction):
            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 data

        morning = resample(transaction[mask])
        afternoon = resample(transaction[~mask])
        if morning.empty and afternoon.empty:
            return pd.DataFrame()
        if not afternoon.empty:
            morning.index.values[-1] = afternoon.index[0] - pd.Timedelta(
                '1 min')

        df = pd.concat([morning, afternoon])

        return fillna(df)

    def _get_k_data(self, code, freq, sessions):
        trade_days = map(int, sessions.strftime("%Y%m%d"))
        if freq == '1m':
            freq = '1 min'

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

        res = []
        concurrent_count = self.concurrent_thread_count
        jobs = []
        for trade_day in trade_days:
            # df = Engine.minute_bars_from_transaction(self._get_transaction(code, trade_day), freq)
            reqevent = gevent.spawn(Engine.minute_bars_from_transaction,
                                    self._get_transaction(code, trade_day),
                                    freq)
            jobs.append(reqevent)
            if len(jobs) >= concurrent_count:
                gevent.joinall(jobs, timeout=30)
                for j in jobs:
                    if j.value is not None and not j.value.empty:
                        res.append(j.value)
                jobs.clear()
        gevent.joinall(jobs, timeout=30)
        for j in jobs:
            if j.value is not None and not j.value.empty:
                res.append(j.value)
        jobs.clear()
        if len(res) != 0:
            return pd.concat(res)
        return pd.DataFrame()

    def get_k_data(self, code, start, end, freq, check=True):
        if isinstance(start, str) or isinstance(end, str):
            start = pd.Timestamp(start)
            end = pd.Timestamp(end)
        if check:
            daily_bars = self.get_security_bars(code, '1d', start, end)
            if daily_bars is None or daily_bars.empty:
                return daily_bars
            sessions = daily_bars.index
        else:
            sessions = pd.bdate_range(start,
                                      end,
                                      weekmask='Mon Tue Wed Thu Fri')
        df = self._get_k_data(code, freq, sessions)

        def check_df(freq, df, daily_bars):
            if freq == '1m':
                need_check = pd.DataFrame({
                    'open':
                    df['open'].resample('1D').first(),
                    'high':
                    df['high'].resample('1D').max(),
                    'low':
                    df['low'].resample('1D').min(),
                    'close':
                    df['close'].resample('1D').last(),
                    'volume':
                    df['volume'].resample('1D').sum()
                }).dropna()
            else:
                need_check = df

            if daily_bars.shape[0] != need_check.shape[0]:
                logger.warning("{} merged {}, expected {}".format(
                    code, need_check.shape[0], daily_bars.shape[0]))
                need_check = fillna(
                    need_check.reindex(daily_bars.index, copy=False))
            diff = daily_bars[['open',
                               'close']] == need_check[['open', 'close']]
            res = (diff.open) & (diff.close)
            sessions = res[res == False].index
            return sessions

        if not df.empty:
            if check:
                sessions = check_df(freq, df, daily_bars)
                if sessions.shape[0] != 0:
                    logger.info(
                        "fixing data for {}-{} with sessions: {}".format(
                            code, freq, sessions))
                    fix = self._get_k_data(code, freq, sessions)
                    df.loc[fix.index] = fix
            return df
        return df