示例#1
0
def QA_fetch_get_index_min(code, start, end, level='1min', ip=best_ip, port=7709):
    '指数分钟线'
    api = TdxHq_API()
    type_ = ''
    if str(level) in ['5', '5m', '5min', 'five']:
        level, type_ = 0, '5min'
    elif str(level) in ['1', '1m', '1min', 'one']:
        level, type_ = 8, '1min'
    elif str(level) in ['15', '15m', '15min', 'fifteen']:
        level, type_ = 1, '15min'
    elif str(level) in ['30', '30m', '30min', 'half']:
        level, type_ = 2, '30min'
    elif str(level) in ['60', '60m', '60min', '1h']:
        level, type_ = 3, '60min'
    with api.connect(ip, port):
        if str(code)[0] in ['5', '1']:  # ETF
            data = pd.concat([api.to_df(api.get_security_bars(
                level, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (25 - i) * 800, 800)) for i in range(26)], axis=0)
        else:
            data = pd.concat([api.to_df(api.get_index_bars(
                level, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (25 - i) * 800, 800)) for i in range(26)], axis=0)
        data = data\
            .assign(datetime=pd.to_datetime(data['datetime']), code=str(code))\
            .drop(['year', 'month', 'day', 'hour', 'minute'], axis=1, inplace=False)\
            .assign(date=data['datetime'].apply(lambda x: str(x)[0:10]))\
            .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(x)))\
            .assign(time_stamp=data['datetime'].apply(lambda x: QA_util_time_stamp(x)))\
            .assign(type=type_).set_index('datetime', drop=False, inplace=False)[start:end]
        # data
        return data.assign(datetime=data['datetime'].apply(lambda x: str(x)))
示例#2
0
def QA_fetch_get_index_day(code, start_date, end_date, level='day', ip=best_ip, port=7709):
    '指数日线'
    api = TdxHq_API()
    if level in ['day', 'd', 'D', 'DAY', 'Day']:
        level = 9
    elif level in ['w', 'W', 'Week', 'week']:
        level = 5
    elif level in ['month', 'M', 'm', 'Month']:
        level = 6
    elif level in ['Q', 'Quarter', 'q']:
        level = 10
    elif level in ['y', 'Y', 'year', 'Year']:
        level = 11

    with api.connect(ip, port):
        if str(code)[0] in ['5', '1']:  # ETF
            data = pd.concat([api.to_df(api.get_security_bars(
                level, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (25 - i) * 800, 800)) for i in range(26)], axis=0)
        else:
            data = pd.concat([api.to_df(api.get_index_bars(
                level, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (25 - i) * 800, 800)) for i in range(26)], axis=0)
        data = data.assign(date=data['datetime'].apply(lambda x: str(x[0:10]))).assign(code=str(code))\
            .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\
            .set_index('date', drop=False, inplace=False)\
            .drop(['year', 'month', 'day', 'hour',
                   'minute', 'datetime'], axis=1)[start_date:end_date]
        return data.assign(date=data['date'].apply(lambda x: str(x)[0:10]))
示例#3
0
 def _get_bars(self, market, code, ktype):
     data = []
     tdx_market = self._trans_market(market)
     if tdx_market is None:
         print("tdx_market == None")
         return data
     
     tdx_ktype = self._trans_ktype(ktype)
     if tdx_ktype is None:
         print("tdx_ktype == None")
         return data
     
     try:
         ip = self.getParam('ip')
         port = self.getParam('port')
     except:
         ip = '119.147.212.81'
         port = 7709
         
     api = TdxHq_API(raise_exception=True)
     
     with api.connect(ip, port):
         if (market == 'SH' and code[:3] == '000') \
               or (market == 'SZ'  and code[:2] == '39'):
             for i in range(self._max[ktype]):
                 data += api.get_index_bars(tdx_ktype, tdx_market, code,
                                        (self._max[ktype]-1-i)*800,800)
         else:
             for i in range(self._max[ktype]):
                 data += api.get_security_bars(tdx_ktype, tdx_market, code,
                                             (self._max[ktype]-1-i)*800,800)
             
     return data
示例#4
0
def QA_fetch_get_index_day(code, start_date, end_date, level='day', ip=best_ip, port=7709):
    '指数日线'
    api = TdxHq_API()
    if level in ['day', 'd', 'D', 'DAY', 'Day']:
        level = 9
    elif level in ['w', 'W', 'Week', 'week']:
        level = 5
    elif level in ['month', 'M', 'm', 'Month']:
        level = 6
    elif level in ['Q', 'Quarter', 'q']:
        level = 10
    elif level in ['y', 'Y', 'year', 'Year']:
        level = 11

    with api.connect(ip, port):
        if str(code)[0] in ['5', '1']:  # ETF
            data = pd.concat([api.to_df(api.get_security_bars(
                level, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (25 - i) * 800, 800)) for i in range(26)], axis=0)
        else:
            data = pd.concat([api.to_df(api.get_index_bars(
                level, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (25 - i) * 800, 800)) for i in range(26)], axis=0)
        data = data.assign(date=data['datetime'].apply(lambda x: str(x[0:10]))).assign(code=str(code))\
            .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\
            .set_index('date', drop=False, inplace=False)\
            .drop(['year', 'month', 'day', 'hour',
                   'minute', 'datetime'], axis=1)[start_date:end_date]
        return data.assign(date=data['date'].apply(lambda x: str(x)[0:10]))
示例#5
0
文件: QATdx.py 项目: zr8091/QUANTAXIS
def QA_fetch_get_index_day(code, start_date, end_date, frequence='day', ip=best_ip['stock']['ip'], port=best_ip['stock']['port']):
    '指数日线'
    api = TdxHq_API()
    if frequence in ['day', 'd', 'D', 'DAY', 'Day']:
        frequence = 9
    elif frequence in ['w', 'W', 'Week', 'week']:
        frequence = 5
    elif frequence in ['month', 'M', 'm', 'Month']:
        frequence = 6
    elif frequence in ['Q', 'Quarter', 'q']:
        frequence = 10
    elif frequence in ['y', 'Y', 'year', 'Year']:
        frequence = 11

    with api.connect(ip, port):

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

        if str(code)[0] in ['5', '1']:  # ETF
            data = pd.concat([api.to_df(api.get_security_bars(
                frequence, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (int(lens / 800) - i) * 800, 800)) for i in range(int(lens / 800) + 1)], axis=0)
        else:
            data = pd.concat([api.to_df(api.get_index_bars(
                frequence, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (int(lens / 800) - i) * 800, 800)) for i in range(int(lens / 800) + 1)], axis=0)
        data = data.assign(date=data['datetime'].apply(lambda x: str(x[0:10]))).assign(code=str(code))\
            .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\
            .set_index('date', drop=False, inplace=False)\
            .assign(code=code)\
            .drop(['year', 'month', 'day', 'hour',
                   'minute', 'datetime'], axis=1)[start_date:end_date]
        return data.assign(date=data['date'].apply(lambda x: str(x)[0:10]))
示例#6
0
def QA_fetch_get_index_min(code, start, end, level='1min', ip=best_ip, port=7709):
    api = TdxHq_API()
    type_ = ''
    if str(level) in ['5', '5m', '5min', 'five']:
        level, type_ = 0, '5min'
    elif str(level) in ['1', '1m', '1min', 'one']:
        level, type_ = 8, '1min'
    elif str(level) in ['15', '15m', '15min', 'fifteen']:
        level, type_ = 1, '15min'
    elif str(level) in ['30', '30m', '30min', 'half']:
        level, type_ = 2, '30min'
    elif str(level) in ['60', '60m', '60min', '1h']:
        level, type_ = 3, '60min'
    with api.connect(ip, port):
        if str(code)[0] in ['5', '1']:  # ETF
            data = pd.concat([api.to_df(api.get_security_bars(
                level, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (25 - i) * 800, 800)) for i in range(26)], axis=0)
        else:
            data = pd.concat([api.to_df(api.get_index_bars(
                level, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (25 - i) * 800, 800)) for i in range(26)], axis=0)
        data = data\
            .assign(datetime=pd.to_datetime(data['datetime']), code=str(code))\
            .drop(['year', 'month', 'day', 'hour', 'minute'], axis=1, inplace=False)\
            .assign(date=data['datetime'].apply(lambda x: str(x)[0:10]))\
            .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(x)))\
            .assign(time_stamp=data['datetime'].apply(lambda x: QA_util_time_stamp(x)))\
            .assign(type=type_).set_index('datetime', drop=False, inplace=False)[start:end]
        # data
        return data.assign(datetime=data['datetime'].apply(lambda x: str(x)))
示例#7
0
文件: Index.py 项目: frankluxi/Test
 def _getKLineData(self):
     api = TdxHq_API(auto_retry=True)
     if api.connect('119.147.212.81', 7709):
         self._KLineData = api.to_df(
             api.get_index_bars(9, 1, self._stockCode, 0,
                                self._stockOberCount))  # 返回DataFrame
         # print(self._KLineData)
         api.disconnect()
示例#8
0
def QA_fetch_get_index_min(code, start, end, frequence='1min', ip=None, port=None):
    '指数分钟线'
    global best_ip
    if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None:
        best_ip = select_best_ip()
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None:
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    else:
        pass
    api = TdxHq_API()
    type_ = ''

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

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

        if str(code)[0] in ['5', '1']:  # ETF
            data = pd.concat([api.to_df(api.get_security_bars(
                frequence, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (int(lens / 800) - i) * 800, 800)) for i in range(int(lens / 800) + 1)], axis=0)
        else:
            data = pd.concat([api.to_df(api.get_index_bars(
                frequence, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (int(lens / 800) - i) * 800, 800)) for i in range(int(lens / 800) + 1)], axis=0)
        data = data\
            .assign(datetime=pd.to_datetime(data['datetime']), code=str(code))\
            .drop(['year', 'month', 'day', 'hour', 'minute'], axis=1, inplace=False)\
            .assign(code=code)\
            .assign(date=data['datetime'].apply(lambda x: str(x)[0:10]))\
            .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(x)))\
            .assign(time_stamp=data['datetime'].apply(lambda x: QA_util_time_stamp(x)))\
            .assign(type=type_).set_index('datetime', drop=False, inplace=False)[start:end]
        # data
        return data.assign(datetime=data['datetime'].apply(lambda x: str(x)))
示例#9
0
文件: QATdx.py 项目: leegb/QUANTAXIS
def QA_fetch_get_index_day(code, start_date, end_date, ip=best_ip, port=7709):
    '指数日线'
    QA_util_log_info(code)
    api = TdxHq_API()
    with api.connect(ip, port):
        data = pd.concat([api.to_df(api.get_index_bars(
            9, 1 if str(code)[0] in ['0', '8', '9'] else 0, str(code), (9 - i) * 800, 800)) for i in range(10)], axis=0)
        data = data.assign(date=data['datetime'].apply(lambda x: str(x[0:10]))).assign(code=str(code))\
            .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\
            .set_index('date', drop=False, inplace=False)\
            .drop(['year', 'month', 'day', 'hour',
                   'minute', 'datetime'], axis=1)[start_date:end_date]
        return data.assign(date=data['date'].apply(lambda x: str(x)[0:10]))
示例#10
0
def QA_fetch_get_index_day(code, start_date, end_date, frequence='day', ip=None, port=None):
    """指数日线
    1- sh
    0 -sz
    Arguments:
        code {[type]} -- [description]
        start_date {[type]} -- [description]
        end_date {[type]} -- [description]
    
    Keyword Arguments:
        frequence {str} -- [description] (default: {'day'})
        ip {[type]} -- [description] (default: {None})
        port {[type]} -- [description] (default: {None})
    
    Returns:
        [type] -- [description]
    """

    ip, port = get_mainmarket_ip(ip, port)
    api = TdxHq_API()
    if frequence in ['day', 'd', 'D', 'DAY', 'Day']:
        frequence = 9
    elif frequence in ['w', 'W', 'Week', 'week']:
        frequence = 5
    elif frequence in ['month', 'M', 'm', 'Month']:
        frequence = 6
    elif frequence in ['Q', 'Quarter', 'q']:
        frequence = 10
    elif frequence in ['y', 'Y', 'year', 'Year']:
        frequence = 11

    with api.connect(ip, port):

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

        if str(code)[0] in ['5', '1']:  # ETF
            data = pd.concat([api.to_df(api.get_security_bars(
                frequence, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (int(lens / 800) - i) * 800, 800)) for i in range(int(lens / 800) + 1)], axis=0)
        else:
            data = pd.concat([api.to_df(api.get_index_bars(
                frequence, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (int(lens / 800) - i) * 800, 800)) for i in range(int(lens / 800) + 1)], axis=0)
        data = data.assign(date=data['datetime'].apply(lambda x: str(x[0:10]))).assign(code=str(code))\
            .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\
            .set_index('date', drop=False, inplace=False)\
            .assign(code=code)\
            .drop(['year', 'month', 'day', 'hour',
                   'minute', 'datetime'], axis=1)[start_date:end_date]
        return data.assign(date=data['date'].apply(lambda x: str(x)[0:10]))
示例#11
0
def QA_fetch_get_index_day(code, start_date, end_date, frequence='day', ip=None, port=None):
    '指数日线'
    global best_ip
    if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None:
        best_ip = select_best_ip()
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None:
        ip = best_ip['stock']['ip']
        port = best_ip['stock']['port']
    else:
        pass
    api = TdxHq_API()
    if frequence in ['day', 'd', 'D', 'DAY', 'Day']:
        frequence = 9
    elif frequence in ['w', 'W', 'Week', 'week']:
        frequence = 5
    elif frequence in ['month', 'M', 'm', 'Month']:
        frequence = 6
    elif frequence in ['Q', 'Quarter', 'q']:
        frequence = 10
    elif frequence in ['y', 'Y', 'year', 'Year']:
        frequence = 11

    with api.connect(ip, port):

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

        if str(code)[0] in ['5', '1']:  # ETF
            data = pd.concat([api.to_df(api.get_security_bars(
                frequence, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (int(lens / 800) - i) * 800, 800)) for i in range(int(lens / 800) + 1)], axis=0)
        else:
            data = pd.concat([api.to_df(api.get_index_bars(
                frequence, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (int(lens / 800) - i) * 800, 800)) for i in range(int(lens / 800) + 1)], axis=0)
        data = data.assign(date=data['datetime'].apply(lambda x: str(x[0:10]))).assign(code=str(code))\
            .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\
            .set_index('date', drop=False, inplace=False)\
            .assign(code=code)\
            .drop(['year', 'month', 'day', 'hour',
                   'minute', 'datetime'], axis=1)[start_date:end_date]
        return data.assign(date=data['date'].apply(lambda x: str(x)[0:10]))
示例#12
0
def QA_fetch_get_index_day(code,
                           start_date,
                           end_date,
                           ip='119.147.212.81',
                           port=7709):
    api = TdxHq_API()
    start_date = QA_util_get_real_date(start_date, trade_date_sse, 1)
    end_date = QA_util_get_real_date(end_date, trade_date_sse, -1)
    with api.connect(ip, port):
        data = []
        for i in range(10):
            data += api.get_index_bars(9, 1, code, (9 - i) * 800, 800)
        data = api.to_df(data)
        data['date'] = data['datetime'].apply(lambda x: x[0:10])
        data['date'] = pd.to_datetime(data['date'])
        data = data.set_index('date', drop=False)
        data = data.drop(
            ['year', 'month', 'day', 'hour', 'minute', 'datetime'], axis=1)

        return data[start_date:end_date]
示例#13
0
def ping(ip, port=7709, multithread=False):
    #print(ip, port, multithread)
    api = TdxHq_API(multithread=multithread)
    success = False
    starttime = time.time()
    try:
        with api.connect(ip, port, time_out=1):
            #x = api.get_security_count(0)
            x = api.get_index_bars(7, 1, '000001', 1, 800)
            if x:
                success = True
            y = api.get_security_bars(7, 0, '000001', 800, 800)
            if x and y:
                success = True

    except Exception as e:
        success = False
        #print(e)

    endtime = time.time()
    #print(success, endtime - starttime)
    return (success, endtime - starttime, ip, port)
def download_index_bars(index_code, freq='day', market=None):
    """获取指数
    market -> 市场代码 0:深圳,1:上海
    """
    if not market:
        if stock_code[0] == '3':
            market = 0
        else:
            market = 1
    category = FREQUENT[freq]

    api = TdxHq_API()
    with api.connect('119.147.212.81', 7709):
        index = 0
        stock_data = []
        while True:
            older_data = api.get_index_bars(category, market, index_code, index * 800, 800)
            if older_data:
                stock_data = older_data + stock_data
                index += 1
            else:
                break
        stock_df = api.to_df(stock_data) # 返回DataFrame
    return stock_df[ct.STOCK_COLS]
示例#15
0
from pytdx.hq import TdxHq_API
import pandas as pd
import datetime

from Event.Event import EventType
from Stock.AnalyseKLine import AnalyseKLine
#dd = DIFNewHighLogic()
from Stock.KLine import KLine, KLineType

api = TdxHq_API(auto_retry=True)
if api.connect('119.147.212.81', 7709):
    data = api.to_df(api.get_index_bars(9, 1, '000905', 0, 500))  # 返回DataFrame
    start = datetime.datetime.now()
    ak = KLine(KLineType.LINE_1_D)
    ak.updateKLineData(data)
    end = datetime.datetime.now()
    print(end - start)
    print("*" * 50)
    print(ak.getData())
    print("*" * 50)

    api.disconnect()
quit()
示例#16
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
示例#17
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)
示例#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
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')
print(data)
print("查询历史分时行情")
data = api.get_history_minute_time_data(1, '600300', 20161209)
print(data)
print("查询分时成交")
data = api.get_transaction_data(1, '000002', 0, 30)
print(data)
print("查询历史分时成交")
data = api.get_history_transaction_data(2, '600302', 0, 10, 20170209)
print(data)
print("查询公司信息目录")
data = api.get_company_info_category(1, '000003')
示例#20
0
class TdxHelper:
    ip_list = [{
        'ip': '119.147.212.81',
        'port': 7709
    }, {
        'ip': '60.12.136.250',
        'port': 7709
    }]

    def __init__(self):
        #连接tdx接口
        self.api = TdxHq_API()
        if not self.api.connect('60.12.136.250', 7709):
            print("服务器连接失败!")

        # pandas数据显示设置
        pd.set_option('display.max_columns', None)  # 显示所有列
        #pd.set_option('display.max_rows', None)  # 显示所有行

        # mysql对象
        self.mysql = mysqlHelper(config.mysql_host, config.mysql_username,
                                 bluedothe.mysql_password, config.mysql_dbname)

        # pandas的mysql对象
        self.engine = create_engine(
            f'mysql+pymysql://{config.mysql_username}:{bluedothe.mysql_password}@{config.mysql_host}/{config.mysql_dbname}?charset=utf8'
        )

    #断开tdx接口连接
    def close_connect(self):
        self.api.disconnect()

    #获取k线,最后一个参数day,说明需要获取的数量,本接口只获取从最近交易日往前的数据
    #输入参数:五个参数分别为:category(k线),市场代码(0:深圳,1:上海),股票代码,开始位置(从最近交易日向前取,0表示最近交易日),返回的记录条数
    #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线
    #返回值:open,close,high,low,vol,amount,year,month,day,hour,minute,datetime
    # csv格式:code,ts_code,trade_date(缩写),trade_time,time_index,open,high,low,close,amount,volume
    def get_security_bars(self, category, market, code, start=0, count=240):
        dict = {0: 'SZ', 1: 'SH'}
        ts_code = code + "." + dict[market]
        order = [
            'code', 'ts_code', 'trade_date', 'trade_time', 'time_index',
            'open', 'high', 'low', 'close', 'amount', 'volume'
        ]
        #df = self.api.get_security_bars(9, 0, '000001', 0, 10)  # 返回普通list
        df = self.api.to_df(
            self.api.get_security_bars(category, market, code, start,
                                       count))  # 返回DataFrame
        if df.empty: return df

        df.insert(0, 'ts_code', ts_code)
        df.insert(0, 'code', code)
        df['trade_time'] = df['datetime'].apply(lambda x: str(x)[11:19])
        df['time_index'] = df['trade_time'].apply(
            lambda x: datatime_util.stockTradeTime2Index(x))
        df['trade_date'] = df['datetime'].apply(
            lambda x: (str(x)[0:10]).replace('-', ''))
        df.rename(columns={'vol': 'volume'}, inplace=True)
        df.drop(['year', 'month', 'day', 'hour', 'minute', 'datetime'],
                axis=1,
                inplace=True)
        df['volume'] = df['volume'].apply(lambda x: int(x))  #取整
        df.loc[df['amount'] == 5.877471754111438e-39,
               'amount'] = 0  #列值根据条件筛选后修改为0
        df = df[order]

        filename = config.tdx_csv_minline1_all + ts_code + ".csv"
        if os.path.isfile(filename):
            df.to_csv(filename,
                      index=False,
                      mode='a',
                      header=False,
                      sep=',',
                      encoding="utf_8_sig")
        else:
            df.to_csv(filename,
                      index=False,
                      mode='w',
                      header=True,
                      sep=',',
                      encoding="utf_8_sig")
            print("新增加的一分钟all股票数据:", filename)

    # 获取1分钟k线,最后一个参数说明需要获取的数量,本接口只获取从最近交易日往前的数据
    # 输入参数:五个参数分别为:category(k线),市场代码(0:深圳,1:上海),股票代码,开始位置(从最近交易日向前取,0表示最近交易日),返回的记录条数
    # 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线
    # 返回值:open,close,high,low,vol,amount,year,month,day,hour,minute,datetime
    # csv格式:code,ts_code,trade_date(缩写),trade_time,time_index,open,high,low,close,amount,volume
    def get_security_bars_minute1(self, category, market, code, start, count):
        dict = {0: 'SZ', 1: 'SH'}
        ts_code = code + "." + dict[market]
        order = [
            'code', 'ts_code', 'trade_date', 'trade_time', 'time_index',
            'open', 'high', 'low', 'close', 'amount', 'volume'
        ]
        # df = self.api.get_security_bars(9, 0, '000001', 0, 10)  # 返回普通list
        df = self.api.to_df(
            self.api.get_security_bars(category, market, code, start,
                                       count))  # 返回DataFrame
        if df.empty: return

        df.insert(0, 'ts_code', ts_code)
        df.insert(0, 'code', code)
        df['trade_time'] = df['datetime'].apply(lambda x: str(x)[11:19])
        df['time_index'] = df['trade_time'].apply(
            lambda x: datatime_util.stockTradeTime2Index(x))
        df['trade_date'] = df['datetime'].apply(
            lambda x: (str(x)[0:10]).replace('-', ''))
        df.rename(columns={'vol': 'volume'}, inplace=True)
        df.drop(['year', 'month', 'day', 'hour', 'minute', 'datetime'],
                axis=1,
                inplace=True)
        df['volume'] = df['volume'].apply(lambda x: int(x))  # 取整
        df.loc[df['amount'] == 5.877471754111438e-39,
               'amount'] = 0  # 列值根据条件筛选后修改为0
        df = df[order]

        #过滤掉停牌的数据,在tdx中,停牌股票也能取到数据,价格是前一交易日的收盘价,所以只能用成交量或成交金额为0来判断
        #1按日期分组后取出成交量为0的日期;2循环过滤掉成交量为0的日期的数据。
        dfg = df.groupby(by='trade_date').mean()  #分组
        dfg['trade_date'] = dfg.index
        dfg = dfg[dfg.volume == 0]  #条件过滤,保留满足条件的数据
        for trade_date in dfg['trade_date'].values:
            df = df[(df['trade_date'] != trade_date)]  # 每个条件要用括号()括起来

        return df

    #可以获取多只股票的行情信息
    #返回值:market,code,active1,price,last_close,open,high,low,reversed_bytes0,reversed_bytes1,vol,cur_vol,amount,s_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 get_security_quotes(self):
        df = self.api.to_df(
            self.api.get_security_quotes([(0, '000001'), (1, '600300')]))
        print(df)

    # 获取市场股票数量
    #返回值:value
    def get_security_count(self):
        df = self.api.to_df(self.api.get_security_count(0))  #0 - 深圳, 1 - 上海
        print(df)

    # 获取股票列表,返回值里面除了股票,还有国债等
    #返回值:code,volunit,decimal_point,name,pre_close
    def get_security_list(self):
        df = self.api.to_df(self.api.get_security_list(
            0, 10000))  # 市场代码, 起始位置 如: 0,0 或 1,100
        print(df)

    # 获取指数k线
    #输入参数同股票k线接口
    # 返回值:open,close,high,low,vol,amount,year,month,day,hour,minute,datetime,up_count  down_count
    def get_index_bars(self):
        index_dict_cn = {
            "上证指数": "999999",
            "深证成指": "399001",
            "中小板指": "399005",
            "创业板指": "399006",
            "深证综指": "399106",
            "上证50": "000016",
            "沪深300": "000300"
        }
        index_dict = {
            "sh": "999999",
            "sz": "399001",
            "zxb": "399005",
            "cyb": "399006",
            "szz": "399106",
            "sz50": "000016",
            "hs300": "000300"
        }
        for key in index_dict.keys():
            df = self.api.to_df(
                self.api.get_index_bars(9, 1, index_dict[key], 0, 2))
            print(df)

    # 查询分时行情,最近交易日的数据,一分钟一条记录
    #返回值:price,vol
    def get_minute_time_data(self):
        df = self.api.to_df(self.api.get_minute_time_data(
            1, '600300'))  #市场代码, 股票代码
        print(df)

    # 查询历史分时行情
    # 返回值:price,vol
    def get_history_minute_time_data(self):
        df = self.api.to_df(
            self.api.get_history_minute_time_data(TDXParams.MARKET_SH,
                                                  '603887',
                                                  20200420))  #市场代码, 股票代码,时间
        print(df)

    # 查询分笔成交,最近交易日数据
    #返回值:time,price,vol,num,buyorsell
    def get_transaction_data(self):
        df = self.api.to_df(
            self.api.get_transaction_data(TDXParams.MARKET_SZ, '000001', 0,
                                          30))  #市场代码, 股票代码,起始位置, 数量
        print(df)

    # 查询历史分笔成交
    #返回值:time,price,vol,buyorsell
    def get_history_transaction_data(self):
        df = self.api.to_df(
            self.api.get_history_transaction_data(
                TDXParams.MARKET_SZ, '000001', 0, 10,
                20170209))  #市场代码, 股票代码,起始位置,日期 数量
        print(df)

    # 查询公司信息目录,返回的不是具体数据
    #返回值:name,filename,start,length
    def get_company_info_category(self):
        df = self.api.to_df(
            self.api.get_company_info_category(TDXParams.MARKET_SZ,
                                               '000001'))  #市场代码, 股票代码
        print(df)

    # 读取公司信息详情
    #返回值:value
    def get_company_info_content(self):
        df = self.api.to_df(
            self.api.get_company_info_content(
                0, '000001', '000001.txt', 0,
                1000))  #市场代码, 股票代码, 文件名, 起始位置, 数量
        print(df)

    # 读取除权除息信息
    #返回值:year,month,day,category,name,fenhong,peigujia,songzhuangu,peigu
    def get_xdxr_info(self):
        df = self.api.to_df(self.api.get_xdxr_info(1, '600300'))  #市场代码, 股票代码
        print(df)

    # 读取财务信息
    #返回值:market,code,liutongguben,province,industry,updated_date,ipo_date,zongguben,guojiagu,faqirenfarengu,farengu,bgu,hgu,zhigonggu,
    #zongzichan,liudongzichan,gudingzichan,wuxingzichan,gudongrenshu,liudongfuzhai,changqifuzhai,zibengongjijin,jingzichan,zhuyingshouru,
    #zhuyinglirun,yingshouzhangkuan,yingyelirun,touzishouyu,jingyingxianjinliu,zongxianjinliu,cunhuo,lirunzonghe,shuihoulirun,jinglirun,weifenlirun,baoliu1,baoliu2
    def get_finance_info(self):
        df = self.api.to_df(self.api.get_finance_info(1,
                                                      '600300'))  #市场代码, 股票代码
        print(df)

    # 读取k线信息
    # 返回值:value
    def get_k_data(self):
        df = self.api.to_df(
            self.api.get_k_data('600300', '2017-07-03',
                                '2017-07-10'))  #股票代码, 开始时间, 结束时间
        print(df)

    # 读取板块信息
    #返回值:blockname, block_type, code_index, code
    """   BLOCK_SZ = "block_zs.dat";BLOCK_FG = "block_fg.dat";BLOCK_GN = "block_gn.dat";BLOCK_DEFAULT = "block.dat"  """

    def get_and_parse_block_info(self):
        ##指数板块 风格板块  概念板块  一般板块
        block_filename = [
            "block_zs.dat", "block_fg.dat", "block_gn.dat", "block.dat"
        ]
        for block in block_filename:
            df = self.api.to_df(
                self.api.get_and_parse_block_info(block))  #板块文件名称
            filename = config.tdx_csv_block + block[0:-4] + ".csv"
            if os.path.isfile(filename):
                os.remove(filename)
                df.to_csv(filename,
                          index=False,
                          mode='w',
                          header=True,
                          sep=',',
                          encoding="utf_8_sig")
            else:
                df.to_csv(filename,
                          index=False,
                          mode='w',
                          header=True,
                          sep=',',
                          encoding="utf_8_sig")

    # 读取板块信息,多个类型封装到一个df对象中返回
    # 返回值:data_source, block_category, block_type, block_name, block_code, ts_code, create_time
    def update_block_member(self):
        ##指数板块 风格板块  概念板块  一般板块
        #block_filename = ["block_zs.dat", "block_fg.dat", "block_gn.dat", "block.dat"]
        block_filename = ["block_zs.dat", "block_fg.dat",
                          "block_gn.dat"]  #block.dat中的数据都包含在其他版块里了,这个可以去掉
        data_source = "tdx"
        dfall = None
        for block in block_filename:
            df = self.api.to_df(
                self.api.get_and_parse_block_info(block))  # 板块文件名称
            df['data_source'] = data_source
            if block == "block.dat":
                df['block_category'] = data_source + ".yb"
            else:
                df['block_category'] = data_source + "." + block[6:8]
            df['block_type'] = df['block_type'].map(lambda x: str(x))
            df['block_type'] = df['block_category'].str.cat(
                df['block_type'], sep=".")  #, sep = "."
            df['block_code'] = ""  #使用pd直接插入到数据库时,字段不能是None值
            df['ts_code'] = df['code'].apply(lambda x: x + ".SH"
                                             if x[0:1] == "6" else x + ".SZ")
            if (dfall is not None) and (not dfall.empty):
                dfall = dfall.append(df, ignore_index=True)
            else:
                dfall = df
        if (dfall is None) or (dfall.empty): return None

        dfall.rename(columns={'blockname': 'block_name'}, inplace=True)
        dfall['create_time'] = time.strftime('%Y-%m-%d %H:%M:%S',
                                             time.localtime(time.time()))
        dfall = dfall[[
            'data_source', 'block_category', 'block_type', 'block_name',
            'block_code', 'ts_code', 'create_time'
        ]]  #列重排序

        #分组统计
        dfg = dfall.groupby(by=[
            'data_source', 'block_category', 'block_type', 'block_name',
            'block_code'
        ],
                            as_index=False).count()  # 分组求每组数量
        dfg.rename(columns={'ts_code': 'member_count'},
                   inplace=True)  #ts_code列数值为汇总值,需要重命名
        dfg['create_time'] = time.strftime(
            '%Y-%m-%d %H:%M:%S',
            time.localtime(time.time()))  #create_time列数值为汇总值,需要重新赋值
        delete_condition = f"data_source = '{data_source}'"
        mysql_script.df2db_update(delete_condition=delete_condition,
                                  block_basic_df=dfg,
                                  block_member_df=dfall)
        return (len(dfg), len(dfall))

    #获取一段时间的1分钟数据,因为每次调用接口只能返回3天的分钟数据(240*3),需要分多次调用
    #返回值:0没有提取到数据;1提取到数据
    def get_minute1_data(self, category, market, code, start_date, end_date):
        init_start_date = start_date.replace('-', '')
        init_end_date = end_date.replace('-', '')
        day = datatime_util.diffrentPeriod(datatime_util.DAILY, start_date,
                                           end_date)
        df = self.get_security_bars_minute1(category, market, code, 0,
                                            240 * 3)  # 返回DataFrame
        if df is None or df.empty:
            print('{0}没有交易数据'.format(code))
            return 0
        print(market, '--', code, '--', start_date, '--', end_date)
        #print("最大值:",df.groupby('datetime').max())
        #print(df.describe())   #df数据统计
        data_start_date = df.min()['trade_date']
        data_end_date = df.max()['trade_date']

        start_date = start_date.replace('-', '')
        end_date = end_date.replace('-', '')
        if data_end_date < start_date or end_date < data_start_date:
            print("采集时间在数据范围之外,退出函数")
            return 0
        elif end_date > data_end_date:
            end_date = data_end_date

        if start_date < data_start_date:
            #最近三天的数据中,去掉无用的数据后即是最终数据
            #需要取的数据还有三天前的数据,需要继续向前取
            n = (day - 3) // 3
            m = (day - 3) % 3
            for i in range(0, n):
                dfn = self.get_security_bars_minute1(category, market, code,
                                                     240 * 3 * (i + 1),
                                                     240 * 3)  # 返回DataFrame
                if (dfn is not None) and (not dfn.empty):
                    df = dfn.append(df, ignore_index=True)
            if m > 0:
                dfn = self.get_security_bars_minute1(category, market, code,
                                                     240 * 3 * (n + 1),
                                                     240 * m)
                if (dfn is not None) and (not dfn.empty):
                    df = dfn.append(df, ignore_index=True)

        df = df.sort_values(by=['trade_date', 'time_index'],
                            axis=0,
                            ascending=True)
        #过滤掉start_date, end_date之外的数据
        df = df[(df['trade_date'] >= str(init_start_date)) &
                (df['trade_date'] <= str(init_end_date))]  #每个条件要用括号()括起来

        dict = {0: 'SZ', 1: 'SH'}
        ts_code = code + "." + dict[market]
        filename = config.tdx_csv_minline1_all + ts_code + ".csv"
        if os.path.isfile(filename):
            df.to_csv(filename,
                      index=False,
                      mode='a',
                      header=False,
                      sep=',',
                      encoding="utf_8_sig")
            print("更新一分钟all股票数据:", filename)
        else:
            df.to_csv(filename,
                      index=False,
                      mode='w',
                      header=True,
                      sep=',',
                      encoding="utf_8_sig")
            print("新增加的一分钟all股票数据:", filename)
示例#21
0
class SP(object):
    def __init__(self,userid="account4",rate=1.2,products="1",limit=2,total=1000000,mock=True,server="http://192.168.118.1:65000"):
        if products == "1":
            self.products = {'880414': {'args': (3, 12, 90), 'stocklst': {}}, '880456': {'args': (6, 28, 40), 'stocklst': {}}, 
                             '880476': {'args': (5, 20, 90), 'stocklst': {}}, '880440': {'args': (4, 8, 85),  'stocklst': {}}, 
                             '880424': {'args': (4, 16, 110),'stocklst': {}}, '880448': {'args': (3, 14, 60), 'stocklst': {}}, 
                             '880454': {'args': (4, 8, 85),  'stocklst': {}}, '880493': {'args': (3, 24, 55), 'stocklst': {}}, 
                             '880344': {'args': (4, 4, 30),  'stocklst': {}}, '880301': {'args': (6, 20, 30), 'stocklst': {}}, 
                             '880464': {'args': (4, 14, 50), 'stocklst': {}}, '880459': {'args': (3, 16, 80), 'stocklst': {}}, 
                             '880380': {'args': (5, 22, 70), 'stocklst': {}}, '880472': {'args': (3, 32, 170),'stocklst': {}}, 
                             '880421': {'args': (3, 16, 45), 'stocklst': {}}, '880471': {'args': (4, 12, 40), 'stocklst': {}}, 
                             '880453': {'args': (6, 14, 30), 'stocklst': {}}, '880350': {'args': (4, 26, 30), 'stocklst': {}}, 
                             '880447': {'args': (5, 20, 170),'stocklst': {}}, '880351': {'args': (3, 6, 65),  'stocklst': {}}, 
                             '880390': {'args': (3, 14, 65), 'stocklst': {}}, '880406': {'args': (4, 16, 50), 'stocklst': {}}, 
                             '880305': {'args': (3, 14, 95), 'stocklst': {}}, '880492': {'args': (3, 30, 105),'stocklst': {}}, 
                             '880387': {'args': (5, 20, 70), 'stocklst': {}}, '880418': {'args': (4, 16, 100),'stocklst': {}}, 
                             '880367': {'args': (5, 14, 110),'stocklst': {}}, '880398': {'args': (5, 26, 100),'stocklst': {}}, 
                             '880437': {'args': (4, 8, 85),  'stocklst': {}}, '880474': {'args': (4, 24, 45), 'stocklst': {}}, 
                             '880324': {'args': (6, 22, 75), 'stocklst': {}}, '880335': {'args': (3, 12, 75), 'stocklst': {}}, 
                             '880372': {'args': (6, 20, 105),'stocklst': {}}, '880491': {'args': (4, 16, 20), 'stocklst': {}}, 
                             '880490': {'args': (3, 26, 110),'stocklst': {}}, '880431': {'args': (7, 12, 40), 'stocklst': {}}, 
                             '880432': {'args': (3, 10, 110),'stocklst': {}}, '880318': {'args': (4, 20, 90), 'stocklst': {}}, 
                             '880497': {'args': (3, 8, 40),  'stocklst': {}}, '880494': {'args': (3, 30, 110),'stocklst': {}}, 
                             '880400': {'args': (3, 10, 90), 'stocklst': {}}, '880360': {'args': (3, 16, 70), 'stocklst': {}}, 
                             '880310': {'args': (3, 12, 20), 'stocklst': {}}, '880423': {'args': (5, 16, 30), 'stocklst': {}}, 
                             '880430': {'args': (7, 12, 25), 'stocklst': {}}, '880422': {'args': (6, 8, 35),  'stocklst': {}}, 
                             '880465': {'args': (4, 12, 95), 'stocklst': {}}, '880482': {'args': (3, 20, 180),'stocklst': {}}, 
                             '880355': {'args': (3, 18, 45), 'stocklst': {}}, '880473': {'args': (3, 6, 40),  'stocklst': {}}, 
                             '880446': {'args': (3, 8, 45),  'stocklst': {}}, '880452': {'args': (3, 32, 90), 'stocklst': {}}, 
                             '880455': {'args': (5, 6, 20),  'stocklst': {}}, '880399': {'args': (3, 8, 85),  'stocklst': {}}, 
                             '880330': {'args': (5, 12, 80), 'stocklst': {}}, '880489': {'args': (3, 18, 190),'stocklst': {}}}
        elif products == "2": #资金比较少是,选择配置部分行业
            self.products = {'880414': {'args': (3, 12, 90), 'stocklst': {}}, '880456': {'args': (6, 28, 40), 'stocklst': {}}, 
                            '880476': {'args': (5, 20, 90), 'stocklst': {}}, '880440': {'args': (4, 8, 85),  'stocklst': {}}, 
                            '880424': {'args': (4, 16, 110),'stocklst': {}}, '880448': {'args': (3, 14, 60), 'stocklst': {}}, 
                            '880454': {'args': (4, 8, 85),  'stocklst': {}}, '880493': {'args': (3, 24, 55), 'stocklst': {}}, 
                             '880344': {'args': (4, 4, 30),  'stocklst': {}}, '880301': {'args': (6, 20, 30), 'stocklst': {}}, 
                             '880464': {'args': (4, 14, 50), 'stocklst': {}}, '880459': {'args': (3, 16, 80), 'stocklst': {}}, 
                             '880380': {'args': (5, 22, 70), 'stocklst': {}}, '880472': {'args': (3, 32, 170),'stocklst': {}}, 
                             '880421': {'args': (3, 16, 45), 'stocklst': {}}, '880471': {'args': (4, 12, 40), 'stocklst': {}}, 
                             '880453': {'args': (6, 14, 30), 'stocklst': {}}, '880350': {'args': (4, 26, 30), 'stocklst': {}}, 
                             '880447': {'args': (5, 20, 170),'stocklst': {}}, '880351': {'args': (3, 6, 65),  'stocklst': {}}, 
                             '880390': {'args': (3, 14, 65), 'stocklst': {}}, '880406': {'args': (4, 16, 50), 'stocklst': {}}, 
                             '880305': {'args': (3, 14, 95), 'stocklst': {}}, '880492': {'args': (3, 30, 105),'stocklst': {}}, 
                             '880387': {'args': (5, 20, 70), 'stocklst': {}}, '880418': {'args': (4, 16, 100),'stocklst': {}},
                             }
        self.server = server
        self.datatype = 1
        self.userid = userid
        self.limit = limit
        self.api = TdxHq_API(heartbeat=True)
        self.trader = None
        self.trading = False
        self.mock = mock
        
        self.rate = rate #持仓杠杆率
        self.total = total #默认持仓资金
        self.TDX_IP_SETS = STOCK_IP_SETS
        
        self.file_incon = FILE_INCON
        self.file_tdxhy = FILE_TDXHY
        self.file_tdxzs = FILE_TDXZS
        
    
    def connect(self):
        for ip in self.TDX_IP_SETS:
            try:
                if self.api.connect(ip, 7709):
                    return 
            except:
                pass
    
    def getdata(self,product,market=1,number=5000,pn=400):
        data = []
        for i in range(int(number/pn)+1):
            temp = self.api.get_index_bars(self.datatype, market, product, (int(number/pn)-i)*pn,pn)
            
            if not temp or len(temp)<pn:
                self.connect()
                for _ in range(2):
                    temp = self.api.get_index_bars(self.datatype, market, product, (int(number/pn)-i)*pn,pn)
                    if not temp or len(temp)<pn:
                        logger.info("record not reach the limit!")
                    else:
                        break   
            data += temp
        df = self.api.to_df(data)[["open","close","high","low","datetime"]]
        df.set_index("datetime",inplace=True,drop=False)
        return df
    
    def disconnect(self):
        logger.info("[DISCONNECT]:statrt disconnect!!!!!")
        if self.istradeday:
            self.api.disconnect()
        logger.info("[DISCONNECT]:disconnect finished!!!!!")
    
    def updatetotal(self):
        '''更新总资金
        '''
        accountinfo,holdlists = self.trader.position()
        nhg = holdlists[holdlists[u"证券代码"].map(lambda x:x in ["SZRQ88","SHRQ88"])][u"最新市值"].sum()
        self.total = accountinfo.ix["总资产"]["人民币"]-nhg
        return self.total
    
    def set_permoney(self):
        '''单个品种资金上限
        '''
        self.permoney = self.total * self.rate /len(self.products)
        return self.permoney
    
    def _get_incon(self,):
        '''获取行业分类代码
        '''
        f= open(self.file_incon, "rb")
        data = f.read()
        strings = data.decode("gbk", 'ignore').rstrip("\x00").replace("\r\n","\n")
        data = strings.split("######") 
        rst = {}
        for hystr in data:
            key = re.findall(r'#.*',hystr)
            if key == ['#TDXNHY']:
                hylst = hystr.replace("#TDXNHY","").strip("\n").split("\n")
                for item in hylst:
                    k,v = item.split("|")
                    rst[k] = [v]
        return rst

    def _get_tdxhy(self,islocal=True):
        '''获取股票和行业对应列表
        '''
        if islocal:
            stocklist = HY_WEIGHT.keys()
        else:
            stocklist = list(ts.get_stock_basics().index)  #获取全市场股票代码
        
        rst = self._get_incon()
        f= open(self.file_tdxhy, "rb")
        data = f.read().decode("gbk", 'ignore').rstrip("\x00").replace("\r\n","\n").strip("\n").split("\n")
                
        for i in data:
            _,code,tdxhy,_,_ = i.split("|")
            if tdxhy != "T00" and code in stocklist:
                rst[tdxhy].append(code)
        return rst

    def _get_tdxzs(self,islocal=True):
        '''生成通达性版块代码对应股票列表
        '''
        dct = {}
        rst = self._get_tdxhy(islocal=islocal)
        f= open(self.file_tdxzs, "rb")
        data = f.read().decode("gbk", 'ignore').rstrip("\x00").replace("\r\n","\n").strip("\n").split("\n")
        for i in data:
            name,code,_,_,_,hy = i.split("|")
            code = int(code)
            if 880301<=code and 880497>=code and hy in rst.keys() :
                k = hy[:5]
                if not dct.__contains__(k):
                    dct[k] = {"name":"","code":"","stocklist":[]}
                if k==hy: 
                    dct[k]["name"] = name
                    dct[k]["code"] = code
                dct[k]["stocklist"].extend(rst[hy][1:])
        return dct

    def get_tdxhy_list(self,islocal=True):
        '''获取通达信行业板块指数对应的股票列表
        '''
        return self._get_tdxzs(islocal)
    
    def get_weight(self,htlist={},islocal=True):
        '''获取行业板块个股权重,流动市值为权重系数
                   备注:回测是为方便处理,以最后一天的权重系数作为历史上的权重
        '''
        if islocal:
            self.weight = HY_WEIGHT
        else:
            if not htlist:
                htlist = self.get_tdxhy_list(islocal)
            tasks = []
            for v in htlist.values():
                tasks.append(gevent.spawn(self.get_latest_ltsz,v["stocklist"]))
            gevent.joinall(tasks)
            
        return self.weight
 
    def get_latest_ltsz(self,stocks=[]):
        '''获取最新流通市值,千万为单位,取整
        '''
        unit = 10000000
        for code in stocks:
            mk = self._select_market_code(code)
            print(mk,code)
            try:
                ltgb = self.api.get_finance_info(mk,code)["liutongguben"]
                price = self.api.get_security_bars(4,mk,code,0,1)[0]["close"]
                ltsz = int(ltgb*price/unit)
                self.weight[code] = ltsz
            except:
                print("*****",code)
        return 
    
    def set_instrument(self):
        '''设置交易股票
        '''
        func = lambda x :1 if x.startswith("6") else 0
        weight = self.get_weight()
        for v in self.get_tdxhy_list().values():
            code = str(v["code"])
            if not self.products.__contains__(code):continue
            
            stocks = [(i,weight[i]) for i in v["stocklist"]]
            limit_stocks = sorted(stocks,key=lambda x:x[1],reverse=True)[:self.limit]
            total = sum([i[1] for i  in limit_stocks])
            for i in limit_stocks:
                market = func(i[0])
                price = self.api.get_security_bars(4,market,i[0],0,1)[0]["close"]
                number = int(self.permoney*i[1]/total/price/100)*100
                self.products[code]["stocklst"][i[0]] = number
        return self.products

    def judgetradeday(self,):
        today = datetime.datetime.today().date().strftime('%Y-%m-%d')
        df = ts.trade_cal()
        return df[(df["calendarDate"]==today)].isOpen.values[0]

    @property
    def istradeday(self):
        if not hasattr(self, "_istradeday"):
            self._istradeday = self.judgetradeday()
        return self._istradeday
    
    def initial(self):
        '''每天初始化设置
        '''
        logger.info("[INITIAL]:start initial !!!!!!")
        if not self.istradeday:
            self.trading = False
            return 
        self.trading = True
        logger.info("[INITIAL]:try to create connect... ")
        self.connect()
        self.trader = trade(UserID=self.userid,api=self.api,mock=self.mock,server=self.server)
        logger.info("[INITIAL]:connect successful!")
        
        logger.info("[INITIAL]:initial account info...")
        self.updatetotal() #更新账户总资金
        self.set_permoney() #设置单个品种资金上限
        logger.info("[INITIAL]:set per product money limit:{}".format(self.permoney))
        self.set_instrument() #设置交易股票和手数
        logger.info("[INITIAL]:set stock list succcessful !!!")
        logger.info("[INITIAL]:initial finished!!!!!!")

    def handledata(self,df,args=[]):
        df.loc[:,"number"] = range(df.shape[0]) 
        s,m,l = args
        for i in args:#5 15 60 D
            key = str(5*i)
            df.loc[:,key+"high"] = df["high"].rolling(i).max()
            df.loc[:,key+"low"] = df["low"].rolling(i).min()
            df.loc[:,key+"atr"] = (df[key+"high"]-df[key+"low"]).rolling(10*i).mean()
            df.loc[:,key+"med"] = (df[key+"high"]+df[key+"low"])/2
            df.loc[:,key+"HH"] = df[key+"med"] + 1.5*df[key+"atr"]
            df.loc[:,key+"LL"] = df[key+"med"] - 1.5*df[key+"atr"]
            df.loc[:,key+'HHmax'] = df[key+'HH'].rolling(10*i).max()
            df.loc[:,key+'LLmin'] = df[key+'LL'].rolling(10*i).min()
            df.loc[df[key+'HH']>=df[key+'HHmax'],key+'hmark'] = df["number"]
            df.loc[df[key+'LL']<=df[key+'LLmin'],key+'lmark'] = df["number"]
            df[key+'hmark'].fillna(method="ffill",inplace=True)
            df[key+'hmark'].fillna(0,inplace=True)
            
            df[key+'lmark'].fillna(method="ffill",inplace=True)
            df[key+'lmark'].fillna(0,inplace=True)
            
            df.loc[:,key+'UP'] = df[key+'hmark'] >= df[key+'lmark']
#             debuginfo.append({key+'hmark':df.iloc[-1][key+'hmark'],key+'lmark':df.iloc[-1][key+'lmark']})
            
        df.fillna(method="ffill",inplace=True)
        df.dropna(inplace=True)
#         logger.info("trademessage:{}".format(debuginfo))
        result = (df.iloc[-1][str(5*l)+"UP"] >0)&(df.iloc[-1][str(5*s)+"UP"]>0)    
        result |= (df.iloc[-1][str(5*l)+"UP"]>0)&(df.iloc[-1][str(5*m)+"UP"]>0) 
        result |= (df.iloc[-1][str(5*l)+"UP"]<=0)&(df.iloc[-1][str(5*m)+"UP"]>0)&(df.iloc[-1][str(5*s)+"UP"]>0)    
        return result
    
    def sync(self,idx,director=True):
        stocks = self.products[idx]["stocklst"]
        for stock,number in stocks.items():
            if not director: number = 0 #空信号,清仓
            
            #判断现有持仓
            try:
                code = stock
                h_number = self.hd_df.ix[code]["证券数量"]
            except:
                h_number = 0
            logger.info("[RUN]:{},{},{}".format(stock,h_number,number))
        
            #补仓差
            cangcha = int((number-h_number)/100)*100
            
            if h_number>0 and abs(cangcha)/h_number<0.2: #如果有持仓,同时仓差小于10% 不进行更改,为了处理频繁加减仓达到问题
                continue 
                 
            if cangcha>0:
                logger.info("[RUN]:buy code:{}, number:{}".format(stock,number-h_number))
                self.buy(stock,cangcha)
            elif cangcha<0:
                couldsell = self.hd_df.ix[code]["可卖数量"]
                logger.info("[RUN]:sell code:{}, number:{},couldsell:{}".format(stock,h_number-number,couldsell))
                if couldsell >0:
                    self.sell(stock,min(-cangcha,couldsell))
#     
    def buy(self,stock,number):
        self.trader.buy(stock, number)
    
    def sell(self,stock,number):
        self.trader.sell(stock, number)
    
    def check_position(self,status):
        '''检查仓位情况
        '''
        self.handleposition()
        handlelist = []
        
        for ins,v in status.items():
            if ins not in self.g_df.index :
                handlelist.append(ins)
            elif self.g_df.ix[ins]["Position"] != v["number"]:
                handlelist.append(ins)
            
        return handlelist
    
    def handleposition(self):
        '''计算多仓,空仓,以及昨仓和今仓
        '''
        self.trader.cancelorder() #先尝试撤单
        _,holdlists = self.trader.position()
        self.hd_df = holdlists
        if holdlists.shape[0]>0:
            self.hd_df.set_index("证券代码",inplace=True)
            self.hd_df.index = self.hd_df.index.astype(np.str).map(lambda x:x if len(x)>=6 else "0"*(6-len(x))+x)
            
        return self.hd_df
    
    def run(self):
        logger.info("[RUN]:start run !!!!!")
        if not self.trading:
            return
        
        self.handleposition()
        
        rst = {}
        for idx in list(self.products.keys()):
            director = self.handledata(self.getdata(idx,market=1),self.products[idx]["args"]) #用指数出信号
            logger.info("[RUN]:trademessage: block:{}, director:{}".format(idx,director))
            self.sync(idx,director)
            rst[idx] = {"up":director,"number":self.products[idx]["stocklst"],"product":idx}
        
        logger.info("[RUN]:lastest position status:{}".format(rst))
        logger.info("[RUN]:run finished !!!!!")    
示例#22
0
class SP(object):
    def __init__(self,
                 userid="account1",
                 number=2,
                 mock=True,
                 server="http://192.168.118.1:65000"):
        ''' 根据实际账户资金,以股指1手为基本对冲单位进行配置。
        '''
        self.products = {
            '000905': {
                'args': (3, 6, 65),
                'stocklst': {
                    "510500": 0
                }
            }
        }
        self.datatype = 0
        self.userid = userid
        self.api = TdxHq_API(heartbeat=True)
        self.trader = None
        self.trading = False
        self.mock = mock
        self.permoney = 200  #指数一个点对应的金额
        self.number = number  #指数的倍数
        self.server = server

        self.TDX_IP_SETS = STOCK_IP_SETS
        if mock: self.judgerate = 100
        else: self.judgerate = 10

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

    def getdata(self, product, market=1, number=10000, pn=400):
        data = []
        for i in range(int(number / pn) + 1):
            temp = self.api.get_index_bars(self.datatype, market, product,
                                           (int(number / pn) - i) * pn, pn)

            if not temp or len(temp) < pn:
                for _ in range(2):
                    temp = self.api.get_index_bars(self.datatype, market,
                                                   product,
                                                   (int(number / pn) - i) * pn,
                                                   pn)
                    if not temp or len(temp) < pn:
                        logger.info("record not reach the limit!")
                    else:
                        break
            try:
                data += temp
            except:
                self.connect()

        df = self.api.to_df(data)[["open", "close", "high", "low", "datetime"]]
        df.set_index("datetime", inplace=True, drop=False)
        return df

    def disconnect(self):
        logger.info("[DISCONNECT]:statrt disconnect!!!!!")
        if self.istradeday:
            self.api.disconnect()
        logger.info("[DISCONNECT]:disconnect finished!!!!!")

    def set_number(self):
        '''设置日内交易的单次手数
        '''
        price = self.api.get_security_quotes([(1, '510500')])[0]["last_close"]
        index_price = self.api.get_security_quotes([(1, '000905')
                                                    ])[0]["last_close"]

        self.products["000905"]["stocklst"]["510500"] = int(
            index_price * self.number * self.permoney / price /
            self.judgerate) * 100

    def judgetradeday(self, ):
        today = datetime.datetime.today().date().strftime('%Y-%m-%d')
        df = ts.trade_cal()
        return df[(df["calendarDate"] == today)].isOpen.values[0]

    @property
    def istradeday(self):
        if not hasattr(self, "_istradeday"):
            self._istradeday = self.judgetradeday()
        return self._istradeday

    def initial(self):
        '''每天初始化设置
        '''
        logger.info("[INITIAL]:start initial !!!!")
        if not self.istradeday:
            self.trading = False
            return
        self.trading = True
        logger.info("[INITIAL]:try to create connect... ")
        self.connect()
        self.trader = trade(UserID=self.userid,
                            api=self.api,
                            mock=self.mock,
                            server=self.server)
        logger.info("[INITIAL]:connect successful!")

        self.set_number()  #设置手数
        logger.info("[INITIAL]:initial finished !!!!!")

    def handledata(self, df, args=[]):
        df.loc[:, "number"] = range(df.shape[0])
        s, m, l = args
        for i in args:  #5 15 60 D
            key = str(5 * i)
            df.loc[:, key + "high"] = df["high"].rolling(i).max()
            df.loc[:, key + "low"] = df["low"].rolling(i).min()
            df.loc[:, key + "atr"] = (df[key + "high"] -
                                      df[key + "low"]).rolling(10 * i).mean()
            df.loc[:, key + "med"] = (df[key + "high"] + df[key + "low"]) / 2
            df.loc[:, key + "HH"] = df[key + "med"] + 1.5 * df[key + "atr"]
            df.loc[:, key + "LL"] = df[key + "med"] - 1.5 * df[key + "atr"]
            df.loc[:, key + 'HHmax'] = df[key + 'HH'].rolling(10 * i).max()
            df.loc[:, key + 'LLmin'] = df[key + 'LL'].rolling(10 * i).min()
            df.loc[df[key + 'HH'] >= df[key + 'HHmax'],
                   key + 'hmark'] = df["number"]
            df.loc[df[key + 'LL'] <= df[key + 'LLmin'],
                   key + 'lmark'] = df["number"]
            df[key + 'hmark'].fillna(method="ffill", inplace=True)
            df[key + 'hmark'].fillna(0, inplace=True)

            df[key + 'lmark'].fillna(method="ffill", inplace=True)
            df[key + 'lmark'].fillna(0, inplace=True)

            df.loc[:, key + 'UP'] = df[key + 'hmark'] >= df[key + 'lmark']


#             debuginfo.append({key+'hmark':df.iloc[-1][key+'hmark'],key+'lmark':df.iloc[-1][key+'lmark']})

        df.fillna(method="ffill", inplace=True)
        df.dropna(inplace=True)
        #         logger.info("trademessage:{}".format(debuginfo))
        result = (df.iloc[-1][str(5 * l) + "UP"] >
                  0) & (df.iloc[-1][str(5 * s) + "UP"] > 0)
        result |= (df.iloc[-1][str(5 * l) + "UP"] >
                   0) & (df.iloc[-1][str(5 * m) + "UP"] > 0)
        result |= (df.iloc[-1][str(5 * l) + "UP"] <= 0) & (df.iloc[-1][
            str(5 * m) + "UP"] > 0) & (df.iloc[-1][str(5 * s) + "UP"] > 0)
        return result

    def sync(self, idx, director=True):
        stocks = self.products[idx]["stocklst"]
        for stock, number in stocks.items():
            if not director: number = 2 * number  #空信号,清仓
            else: number = 4 * number

            #判断现有持仓
            try:
                h_number = self.hd_df.ix[stock]["证券数量"]

            except:
                h_number = 0

            #补仓差
            cangcha = int((number - h_number) / 100) * 100

            if h_number > 0 and abs(
                    cangcha
            ) / number < 0.05:  #如果有持仓,同时仓差小于5% 不进行更改,为了处理频繁加减仓达到问题
                return

            if cangcha > 0:
                logger.info("[RUN]:buy code:{}, number:{}".format(
                    stock, number - h_number))
                self.buy(stock, cangcha)
            elif cangcha < 0:
                logger.info("[RUN]:sell code:{}, number:{}".format(
                    stock, h_number - number))
                lastholdnumber = self.hd_df.ix[stock]["可卖数量"]
                self.sell(stock, min(-cangcha, lastholdnumber))

    def buy(self, stock, number, jump=0.02):
        self.trader.buy(stock, number, jump=jump)

    def sell(self, stock, number, jump=0.02):
        self.trader.sell(stock, number, jump=jump)

    def check_position(self, status):
        '''检查仓位情况
        '''
        self.handleposition()
        handlelist = []

        for ins, v in status.items():
            if ins not in self.g_df.index:
                handlelist.append(ins)
            elif self.g_df.ix[ins]["Position"] != v["number"]:
                handlelist.append(ins)

        return handlelist

    def handleposition(self):
        '''计算多仓,空仓,以及昨仓和今仓
        '''
        self.trader.cancelorder()  #先尝试撤单
        _, holdlists = self.trader.position()
        self.hd_df = holdlists
        if holdlists.shape[0] > 0:
            self.hd_df.set_index("证券代码", inplace=True)
            self.hd_df.index = self.hd_df.index.astype(np.str)
        return self.hd_df

    def run(self):

        logger.info("[RUN]:start run !!!!!")
        if not self.trading:
            return

        self.handleposition()

        rst = {}
        for idx in list(self.products.keys()):
            director = self.handledata(self.getdata(idx, market=1),
                                       self.products[idx]["args"])  #用指数出信号
            logger.info("[RUN]:trademessage: block:{}, director:{}".format(
                idx, director))
            self.sync(idx, director)
            rst[idx] = {
                "up": director,
                "number": self.products[idx]["stocklst"],
                "product": idx
            }

        logger.info("[RUN]:lastest position status:{}".format(rst))
        logger.info("[RUN]:run finished !!!!!")

    def nhg(self):
        '''尾盘自动进行逆回购
        '''
        if not self.mock:
            self.trader.autobuy()
示例#23
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
示例#24
0
文件: quotes.py 项目: tobybird/mootdx
class StdQuotes(object):
    """股票市场实时行情"""

    # __slots__ =
    def __init__(self, **kwargs):
        self.config = None

        try:
            self.config = json.loads(
                os.path.join(os.environ['HOME'], '.mootdx/config.josn'))
        except Exception as e:
            self.config = None

        self.client = TdxHq_API(**kwargs)

        if not self.config:
            self.bestip = os.environ.setdefault("MOOTDX_SERVER",
                                                '202.108.253.131:7709')
            self.bestip = self.bestip.split(':')
            self.bestip[1] = int(self.bestip[1])
        else:
            self.bestip = self.config.get('SERVER')

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

        :param symbol: 股票代码
        :param category: 数据类别
        :param market: 证券市场
        :param start: 开始位置
        :param offset: 每次获取条数
        :return: pd.dataFrame or None
        '''
        market = get_stock_market(symbol)

        with self.client.connect(*self.bestip):
            data = self.client.get_security_bars(int(category), int(market),
                                                 str(symbol), int(start),
                                                 int(offset))
            return self.client.to_df(data)

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

        :param market: 证券市场
        :param symbol: 股票代码
        :return: pd.DataFrame
        '''
        market = get_stock_market(symbol)

        with self.client.connect(*self.bestip):
            data = self.client.get_minute_time_data(int(market), symbol)
            return self.client.to_df(data)

    # 分时历史数据
    def minute_his(self, symbol='', datetime='20161209'):
        '''
        分时历史数据

        :param market:
        :param symbol:
        :param datetime:
        :return: pd.dataFrame or None
        '''
        market = get_stock_market(symbol)

        with self.client.connect(*self.bestip):
            data = self.client.get_history_minute_time_data(
                int(market), symbol, datetime)
            return self.client.to_df(data)

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

        :param market: 市场代码
        :param symbol: 股票代码
        :param start: 起始位置
        :param offset: 请求数量
        :return: pd.dataFrame or None
        '''
        market = get_stock_market(symbol)

        with self.client.connect(*self.bestip):
            data = self.client.get_transaction_data(int(market), symbol,
                                                    int(start), int(market))
            return self.client.to_df(data)

    def trans_his(self, symbol='', start=0, offset=10, date=''):
        '''
        查询历史分笔成交

        :param market: 市场代码
        :param symbol: 股票代码
        :param start: 起始位置
        :param offset: 数量
        :param date: 日期
        :return: pd.dataFrame or None
        '''
        market = get_stock_market(symbol)

        with self.client.connect(*self.bestip):
            data = self.client.get_history_transaction_data(
                int(market), symbol, int(start), int(offset), date)
            return self.client.to_df(data)

    def company(self, symbol='', detail='category', *args, **kwargs):
        '''
        企业信息获取

        :param symbol:
        :param detail:
        :param args:
        :param kwargs:
        :return:
        '''
        pass

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

        :param market: 市场代码
        :param symbol: 股票代码
        :return: pd.dataFrame or None
        '''
        market = get_stock_market(symbol)

        with self.client.connect(*self.bestip):
            data = self.client.get_company_info_category(int(market), symbol)
            return self.client.to_df(data)

    def company_content(self, symbol='', file='', start=0, offset=10):
        '''
        读取公司信息详情

        :param market: 市场代码
        :param symbol: 股票代码
        :param file: 文件名
        :param start: 起始位置
        :param offset: 数量
        :return: pd.dataFrame or None
        '''
        market = get_stock_market(symbol)

        with self.client.connect(*self.bestip):
            data = self.client.get_company_info_content(
                int(market), symbol, file, int(start), int(offset))
            return self.client.to_df(data)

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

        :param market: 市场代码
        :param symbol: 股票代码
        :return: pd.dataFrame or None
        '''
        market = get_stock_market(symbol)

        with self.client.connect(*self.bestip):
            data = self.client.get_xdxr_info(int(market), symbol)
            return self.client.to_df(data)

    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):
            data = self.client.get_k_data(symbol, begin, end)
            return data

    def index(self,
              symbol='000001',
              market='sh',
              category='9',
              start='0',
              offset='100'):
        '''
        获取指数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 category: 数据类别
        :param market: 证券市场
        :param start: 开始位置
        :param offset: 每次获取条数
        :return: pd.dataFrame or None
        '''
        market = 1 if market == 'sh' else 0

        with self.client.connect(*self.bestip):
            data = self.client.get_index_bars(int(category), int(market),
                                              str(symbol), int(start),
                                              int(offset))
            return self.client.to_df(data)

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

        :param tofile:
        :return: pd.dataFrame or None
        '''
        with self.client.connect(*self.bestip):
            data = self.client.get_and_parse_block_info(tofile)
            return self.client.to_df(data)

    def batch(self, method='', offset=100, *args, **kwargs):
        '''
        批量下载相关数据

        :param method:
        :param offset:
        :return:
        '''

        pass