def QA_fetch_get_stock_transaction_realtime(code, ip=None, port=None): '实时分笔成交 包含集合竞价 buyorsell 1--sell 0--buy 2--盘前' global best_ip if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None: best_ip = select_best_ip() ip = best_ip['stock']['ip'] port = best_ip['stock']['port'] elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None: ip = best_ip['stock']['ip'] port = best_ip['stock']['port'] else: pass api = TdxHq_API() try: with api.connect(ip, port): data = pd.DataFrame() data = pd.concat([api.to_df(api.get_transaction_data( _select_market_code(str(code)), code, (2 - i) * 2000, 2000)) for i in range(3)], axis=0) if 'value' in data.columns: data = data.drop(['value'], axis=1) data = data.dropna() day = datetime.date.today() return data.assign(date=str(day)).assign(datetime=pd.to_datetime(data['time'].apply(lambda x: str(day) + ' ' + str(x))))\ .assign(code=str(code)).assign(order=range(len(data.index))).set_index('datetime', drop=False, inplace=False) except: return None
def QA_fetch_get_stock_block(ip=None, port=None): '板块数据' global best_ip if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None: best_ip = select_best_ip() ip = best_ip['stock']['ip'] port = best_ip['stock']['port'] elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None: ip = best_ip['stock']['ip'] port = best_ip['stock']['port'] else: pass api = TdxHq_API() with api.connect(ip, port): data = pd.concat([api.to_df(api.get_and_parse_block_info("block_gn.dat")).assign(type='gn'), api.to_df(api.get_and_parse_block_info( "block.dat")).assign(type='yb'), api.to_df(api.get_and_parse_block_info( "block_zs.dat")).assign(type='zs'), api.to_df(api.get_and_parse_block_info("block_fg.dat")).assign(type='fg')]) if len(data) > 10: return data.assign(source='tdx').drop(['block_type', 'code_index'], axis=1).set_index('code', drop=False, inplace=False).drop_duplicates() else: QA_util_log_info('Wrong with fetch block ')
def QA_fetch_get_stock_xdxr(code, ip=None, port=None): '除权除息' global best_ip if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None: best_ip = select_best_ip() ip = best_ip['stock']['ip'] port = best_ip['stock']['port'] elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None: ip = best_ip['stock']['ip'] port = best_ip['stock']['port'] else: pass api = TdxHq_API() market_code = _select_market_code(code) with api.connect(ip, port): category = { '1': '除权除息', '2': '送配股上市', '3': '非流通股上市', '4': '未知股本变动', '5': '股本变化', '6': '增发新股', '7': '股份回购', '8': '增发新股上市', '9': '转配股上市', '10': '可转债上市', '11': '扩缩股', '12': '非流通股缩股', '13': '送认购权证', '14': '送认沽权证'} data = api.to_df(api.get_xdxr_info(market_code, code)) if len(data) >= 1: data = data\ .assign(date=pd.to_datetime(data[['year', 'month', 'day']]))\ .drop(['year', 'month', 'day'], axis=1)\ .assign(category_meaning=data['category'].apply(lambda x: category[str(x)]))\ .assign(code=str(code))\ .rename(index=str, columns={'panhouliutong': 'liquidity_after', 'panqianliutong': 'liquidity_before', 'houzongguben': 'shares_after', 'qianzongguben': 'shares_before'})\ .set_index('date', drop=False, inplace=False) return data.assign(date=data['date'].apply(lambda x: str(x)[0:10])) else: return None
def QA_fetch_get_stock_min(code, start, end, level='1min', ip=best_ip, port=7709): api = TdxHq_API() type_ = '' if str(level) in ['5', '5m', '5min', 'five']: level, type_ = 0, '5min' elif str(level) in ['1', '1m', '1min', 'one']: level, type_ = 8, '1min' elif str(level) in ['15', '15m', '15min', 'fifteen']: level, type_ = 1, '15min' elif str(level) in ['30', '30m', '30min', 'half']: level, type_ = 2, '30min' elif str(level) in ['60', '60m', '60min', '1h']: level, type_ = 3, '60min' with api.connect(ip, port): data = pd.concat([api.to_df(api.get_security_bars(level, __select_market_code( str(code)), str(code), (25 - i) * 800, 800)) for i in range(26)], axis=0) data = data\ .assign(datetime=pd.to_datetime(data['datetime']), code=str(code))\ .drop(['year', 'month', 'day', 'hour', 'minute'], axis=1, inplace=False)\ .assign(date=data['datetime'].apply(lambda x: str(x)[0:10]))\ .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(x)))\ .assign(time_stamp=data['datetime'].apply(lambda x: QA_util_time_stamp(x)))\ .assign(type=type_).set_index('datetime', drop=False, inplace=False)[start:end] return data.assign(datetime=data['datetime'].apply(lambda x: str(x)))
def QA_fetch_get_stock_realtime(code=['000001', '000002'], ip=best_ip, port=7709): api = TdxHq_API() __data = pd.DataFrame() code = [code] if type(code) is str else code async def _get_security_quotes(__code): """ """ assert isinstance(__code, str) data=await api.get_security_quotes([(__select_market_code(__code), __code)]) data=api.to_df(data) data['datetime'] = datetime.datetime.now() return data[['datetime', 'code', 'open', 'high', 'low', 'price']] with api.connect(ip, port): coroutines = [asyncio.ensure_future( _get_security_quotes(code_)) for code_ in code] print(coroutines) try: loop = asyncio.get_event_loop() except RuntimeError: loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) res = loop.run_until_complete(asyncio.gather(*coroutines)) print(res) return res
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
def ping(ip): __time1 = datetime.datetime.now() api = TdxHq_API() try: with api.connect(ip, 7709): if len(api.get_security_list(0, 1)) > 800: return datetime.datetime.now() - __time1 except: return datetime.timedelta(9, 9, 0)
def ping(ip): api = TdxHq_API() __time1 = datetime.datetime.now() try: with api.connect(ip, 7709): if len(api.get_security_list(0, 1)) > 800: return datetime.datetime.now() - __time1 except: print('Bad REPSONSE %s' % ip) return datetime.timedelta(9, 9, 0)
def api(retry_count=3): for _ in range(retry_count): try: api = TdxHq_API(heartbeat=True) api.connect(ct._get_server(), ct.T_PORT) except Exception as e: print(e) else: return api raise IOError(ct.NETWORK_URL_ERROR_MSG)
def QA_fetch_get_stock_realtime(code=['000001', '000002'], ip=best_ip, port=7709): api = TdxHq_API() __data = pd.DataFrame() with api.connect(ip, port): code = [code] if type(code) is str else code for id_ in range(int(len(code) / 80) + 1): __data = __data.append(api.to_df(api.get_security_quotes( [(__select_market_code(x), x) for x in code[80 * id_:80 * (id_ + 1)]]))) __data['datetime'] = datetime.datetime.now() data = __data[['datetime', 'code', 'open', 'high', 'low', 'price']] return data.set_index('code', drop=False, inplace=False)
def _test_speed(self, ip, port=7709): api = TdxHq_API(raise_exception=True, auto_retry=False) _time = datetime.datetime.now() try: with api.connect(ip, port, time_out=0.05): if len(api.get_security_list(0, 1)) > 800: return (datetime.datetime.now() - _time).total_seconds() else: return datetime.timedelta(9, 9, 0).total_seconds() except Exception as e: return datetime.timedelta(9, 9, 0).total_seconds()
def get_tdx_kdata(security_item, start, end): api = TdxHq_API() with api.connect(): # open close high low vol amount date code # KDATA_COLUMN = ['timestamp', 'code', 'low', 'open', 'close', 'high', 'volume', 'turnover', 'securityId'] df = api.get_k_data(security_item['code'], start, end) df = df[['date', 'code', 'low', 'open', 'close', 'high', 'vol', 'amount']] df['securityId'] = df['code'].apply(lambda x: 'stock_{}_{}'.format(get_exchange(x), x)) df['vol'] = df['vol'].apply(lambda x: x * 100) df.columns = KDATA_COLUMN return df
def QA_fetch_get_stock_latest(code, ip=best_ip, port=7709): code = [code] if isinstance(code, str) else code api = TdxHq_API(multithread=True) with api.connect(ip, port): data = pd.concat([api.to_df(api.get_security_bars( 9, __select_market_code(item), item, 0, 1)).assign(code=item) for item in code], axis=0) return data\ .assign(date=pd.to_datetime(data['datetime'] .apply(lambda x: x[0:10])), date_stamp=data['datetime'] .apply(lambda x: QA_util_date_stamp(str(x[0:10]))))\ .set_index('date', drop=False)\ .drop(['year', 'month', 'day', 'hour', 'minute', 'datetime'], axis=1)
def QA_fetch_get_stock_info(code, ip=None, port=None): '股票基本信息' global best_ip if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None: best_ip = select_best_ip() ip = best_ip['stock']['ip'] port = best_ip['stock']['port'] elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None: ip = best_ip['stock']['ip'] port = best_ip['stock']['port'] else: pass api = TdxHq_API() market_code = _select_market_code(code) with api.connect(ip, port): return api.to_df(api.get_finance_info(market_code, code))
def __call__(self): count = 0 connect = sqlite3.connect(self.sqlitefile) try: progress = ProgressBar(self) api = TdxHq_API() api.connect(self.ip, self.port) count = import_time(connect, self.market, self.quotations, api, self.dest_dir, max_days=self.max_days, progress=progress) except Exception as e: print(e) finally: connect.commit() connect.close() self.queue.put([self.task_name, self.market, 'TIME', None, count])
def ping(ip, port=7709, multithread=False): api = TdxHq_API(multithread=multithread) success = False starttime = time.time() try: with api.connect(ip, port, time_out=1): #x = api.get_security_count(0) #x = api.get_index_bars(7, 1, '000001', 800, 100) x = api.get_security_bars(7, 0, '000001', 800, 100) if x: success = True except Exception as e: success = False endtime = time.time() return (success, endtime - starttime, ip, port)
def QA_fetch_get_stock_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): data = pd.concat([api.to_df(api.get_security_bars(frequence, _select_market_code( str(code)), str(code), (int(lens / 800) - i) * 800, 800)) for i in range(int(lens / 800) + 1)], axis=0) data = data\ .assign(datetime=pd.to_datetime(data['datetime']), code=str(code))\ .drop(['year', 'month', 'day', 'hour', 'minute'], axis=1, inplace=False)\ .assign(date=data['datetime'].apply(lambda x: str(x)[0:10]))\ .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(x)))\ .assign(time_stamp=data['datetime'].apply(lambda x: QA_util_time_stamp(x)))\ .assign(type=type_).set_index('datetime', drop=False, inplace=False)[start:end] return data.assign(datetime=data['datetime'].apply(lambda x: str(x)))
def __init__(self, thread_num=2, timeout=1, *args, **kwargs): self.thread_num = thread_num self._queue = queue.Queue(maxsize=200) self.api_no_connection = TdxHq_API() self._api_worker = Thread( target=self.api_worker, args=(), name='API Worker') self._api_worker.start() self.timeout = timeout self.executor = ThreadPoolExecutor(self.thread_num)
def QA_fetch_get_stock_list(type_='stock', ip=best_ip, port=7709): api = TdxHq_API() with api.connect(ip, port): data = pd.concat([pd.concat([api.to_df(api.get_security_list(j, i * 1000)).assign(sse='sz' if j == 0 else 'sh').set_index( ['code', 'sse'], drop=False) for i in range(int(api.get_security_count(j) / 1000) + 1)], axis=0) for j in range(2)], axis=0) if type_ in ['stock', 'gp']: return pd.concat([data[data['sse'] == 'sz'][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 10000 <= 30][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 100000 != 2], data[data['sse'] == 'sh'][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 100000 == 6]]).assign(code=data['code'].apply(lambda x: str(x))) elif type_ in ['index', 'zs']: return pd.concat([data[data['sse'] == 'sz'][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 1000 >= 399], data[data['sse'] == 'sh'][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 1000 == 0]]).sort_index().assign(code=data['code'].apply(lambda x: str(x))) elif type_ in ['etf', 'ETF']: return pd.concat([data[data['sse'] == 'sz'][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 10000 == 15], data[data['sse'] == 'sh'][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 10000 == 51]]).sort_index().assign(code=data['code'].apply(lambda x: str(x))) else: return data.assign(code=data['code'].apply(lambda x: str(x)))
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]))
def QA_fetch_get_security_bars(code, _type, lens, ip=None, port=None): """按bar长度推算数据 Arguments: code {[type]} -- [description] _type {[type]} -- [description] lens {[type]} -- [description] Keyword Arguments: ip {[type]} -- [description] (default: {best_ip}) port {[type]} -- [description] (default: {7709}) Returns: [type] -- [description] """ global best_ip if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None: best_ip = select_best_ip() ip = best_ip['stock']['ip'] port = best_ip['stock']['port'] elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None: ip = best_ip['stock']['ip'] port = best_ip['stock']['port'] else: pass api = TdxHq_API() with api.connect(ip, port): data = pd.concat([api.to_df(api.get_security_bars(_select_type(_type), _select_market_code( code), code, (i - 1) * 800, 800)) for i in range(1, int(lens / 800) + 2)], axis=0) data = data\ .assign(datetime=pd.to_datetime(data['datetime']), code=str(code))\ .drop(['year', 'month', 'day', 'hour', 'minute'], axis=1, inplace=False)\ .assign(date=data['datetime'].apply(lambda x: str(x)[0:10]))\ .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(x)))\ .assign(time_stamp=data['datetime'].apply(lambda x: QA_util_time_stamp(x)))\ .assign(type=_type).set_index('datetime', drop=False, inplace=False).tail(lens) if data is not None: return data else: return None
def ping(ip, port=7709, type_='stock'): api = TdxHq_API() apix = TdxExHq_API() __time1 = datetime.datetime.now() try: if type_ in ['stock']: with api.connect(ip, port, time_out=0.7): if len(api.get_security_list(0, 1)) > 800: return datetime.datetime.now() - __time1 else: print('BAD RESPONSE {}'.format(ip)) return datetime.timedelta(9, 9, 0) elif type_ in ['future']: with apix.connect(ip, port, time_out=0.7): if apix.get_instrument_count() > 10000: return datetime.datetime.now() - __time1 else: print('️Bad FUTUREIP REPSONSE {}'.format(ip)) return datetime.timedelta(9, 9, 0) except: print('BAD RESPONSE {}'.format(ip)) return datetime.timedelta(9, 9, 0)
def QA_fetch_get_stock_latest(code, ip=None, port=None): global best_ip if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None: best_ip = select_best_ip() ip = best_ip['stock']['ip'] port = best_ip['stock']['port'] elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None: ip = best_ip['stock']['ip'] port = best_ip['stock']['port'] else: pass code = [code] if isinstance(code, str) else code api = TdxHq_API(multithread=True) with api.connect(ip, port): data = pd.concat([api.to_df(api.get_security_bars( 9, _select_market_code(item), item, 0, 1)).assign(code=item) for item in code], axis=0) return data\ .assign(date=pd.to_datetime(data['datetime'] .apply(lambda x: x[0:10])), date_stamp=data['datetime'] .apply(lambda x: QA_util_date_stamp(str(x[0:10]))))\ .set_index('date', drop=False)\ .drop(['year', 'month', 'day', 'hour', 'minute', 'datetime'], axis=1)
def QA_fetch_get_stock_transaction(code, start, end, retry=2, ip=None, port=None): '历史分笔成交 buyorsell 1--sell 0--buy 2--盘前' global best_ip if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None: best_ip = select_best_ip() ip = best_ip['stock']['ip'] port = best_ip['stock']['port'] elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None: ip = best_ip['stock']['ip'] port = best_ip['stock']['port'] else: pass api = TdxHq_API() real_start, real_end = QA_util_get_real_datelist(start, end) if real_start is None: return None real_id_range = [] with api.connect(ip, port): data = pd.DataFrame() for index_ in range(trade_date_sse.index(real_start), trade_date_sse.index(real_end) + 1): try: data_ = __QA_fetch_get_stock_transaction( code, trade_date_sse[index_], retry, api) if len(data_) < 1: return None except: QA_util_log_info('Wrong in Getting {} history transaction data in day {}'.format( code, trade_date_sse[index_])) else: QA_util_log_info('Successfully Getting {} history transaction data in day {}'.format( code, trade_date_sse[index_])) data = data.append(data_) if len(data) > 0: return data.assign(datetime=data['datetime'].apply(lambda x: str(x)[0:19])) else: return None
def QA_fetch_get_stock_transaction(code, start, end, retry=2, ip=best_ip, port=7709): api = TdxHq_API() real_start, real_end = QA_util_get_real_datelist(start, end) real_id_range = [] with api.connect(ip, port): data = pd.DataFrame() for index_ in range(trade_date_sse.index(real_start), trade_date_sse.index(real_end) + 1): try: data_ = __QA_fetch_get_stock_transaction( code, trade_date_sse[index_], retry, api) if len(data_) < 1: return None except: QA_util_log_info('Wrong in Getting %s history transaction data in day %s' % ( code, trade_date_sse[index_])) else: QA_util_log_info('Successfully Getting %s history transaction data in day %s' % ( code, trade_date_sse[index_])) data = data.append(data_) return data.assign(datetime=data['datetime'].apply(lambda x: str(x)[0:19]))
def QA_fetch_depth_market_data(code=['000001', '000002'], ip=None, port=None): global best_ip if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None: best_ip = select_best_ip() ip = best_ip['stock']['ip'] port = best_ip['stock']['port'] elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None: ip = best_ip['stock']['ip'] port = best_ip['stock']['port'] else: pass api = TdxHq_API() __data = pd.DataFrame() with api.connect(ip, port): code = [code] if type(code) is str else code for id_ in range(int(len(code) / 80) + 1): __data = __data.append(api.to_df(api.get_security_quotes( [(_select_market_code(x), x) for x in code[80 * id_:80 * (id_ + 1)]]))) __data['datetime'] = datetime.datetime.now() data = __data[['datetime', 'active1', 'active2', 'last_close', 'code', 'open', 'high', 'low', 'price', 'cur_vol', 's_vol', 'b_vol', 'vol', 'ask1', 'ask_vol1', 'bid1', 'bid_vol1', 'ask2', 'ask_vol2', 'bid2', 'bid_vol2', 'ask3', 'ask_vol3', 'bid3', 'bid_vol3', 'ask4', 'ask_vol4', 'bid4', 'bid_vol4', 'ask5', 'ask_vol5', 'bid5', 'bid_vol5']] return data.set_index(['datetime', 'code'], drop=False, inplace=False)
def QA_fetch_get_stock_list(type_='stock', ip=None, port=None): global best_ip if ip is None and port is None and best_ip['stock']['ip'] is None and best_ip['stock']['port'] is None: best_ip = select_best_ip() ip = best_ip['stock']['ip'] port = best_ip['stock']['port'] elif ip is None and port is None and best_ip['stock']['ip'] is not None and best_ip['stock']['port'] is not None: ip = best_ip['stock']['ip'] port = best_ip['stock']['port'] else: pass api = TdxHq_API() with api.connect(ip, port): data = pd.concat([pd.concat([api.to_df(api.get_security_list(j, i * 1000)).assign(sse='sz' if j == 0 else 'sh').set_index( ['code', 'sse'], drop=False) for i in range(int(api.get_security_count(j) / 1000) + 1)], axis=0) for j in range(2)], axis=0) #data.code = data.code.apply(int) sz = data.query('sse=="sz"') sh = data.query('sse=="sh"') sz = sz.assign(sec=sz.code.apply(for_sz)) sh = sh.assign(sec=sh.code.apply(for_sh)) if type_ in ['stock', 'gp']: return pd.concat([sz, sh]).query('sec=="stock_cn"').sort_index().assign(name=data['name'].apply(lambda x: str(x)[0:6])) elif type_ in ['index', 'zs']: return pd.concat([sz, sh]).query('sec=="index_cn"').sort_index().assign(name=data['name'].apply(lambda x: str(x)[0:6])) #.assign(szm=data['name'].apply(lambda x: ''.join([y[0] for y in lazy_pinyin(x)])))\ #.assign(quanpin=data['name'].apply(lambda x: ''.join(lazy_pinyin(x)))) elif type_ in ['etf', 'ETF']: return pd.concat([sz, sh]).query('sec=="etf_cn"').sort_index().assign(name=data['name'].apply(lambda x: str(x)[0:6])) else: return data.assign(code=data['code'].apply(lambda x: str(x))).assign(name=data['name'].apply(lambda x: str(x)[0:6]))
def QA_fetch_depth_market_data(code=['000001', '000002'], ip=best_ip['stock'], port=7709): api = TdxHq_API() __data = pd.DataFrame() with api.connect(ip, port): code = [code] if type(code) is str else code for id_ in range(int(len(code) / 80) + 1): __data = __data.append( api.to_df( api.get_security_quotes([ (_select_market_code(x), x) for x in code[80 * id_:80 * (id_ + 1)] ]))) __data['datetime'] = datetime.datetime.now() data = __data[[ 'datetime', 'active1', 'active2', 'last_close', 'code', 'open', 'high', 'low', 'price', 'cur_vol', 's_vol', 'b_vol', 'vol', 'ask1', 'ask_vol1', 'bid1', 'bid_vol1', 'ask2', 'ask_vol2', 'bid2', 'bid_vol2', 'ask3', 'ask_vol3', 'bid3', 'bid_vol3', 'ask4', 'ask_vol4', 'bid4', 'bid_vol4', 'ask5', 'ask_vol5', 'bid5', 'bid_vol5' ]] return data.set_index(['datetime', 'code'], drop=False, inplace=False)
def api_worker(self): data = [] if self._queue.qsize() < 80: for item in info_ip_list: _sec = self._test_speed(item) if _sec < 0.1: try: self._queue.put( TdxHq_API(heartbeat=False).connect(ip=item, time_out=0.05)) except: pass else: self._queue_clean() Timer(0, self.api_worker).start() Timer(300, self.api_worker).start()
def connect(self): if self.isstock: self.api = TdxHq_API(heartbeat=self.heartbeat) port = 7709 TDX_IP_SETS = self.TDX_IP_SETS_STOCK else: self.api = TdxExHq_API(heartbeat=self.heartbeat) port = 7727 TDX_IP_SETS = self.TDX_IP_SETS for ip in TDX_IP_SETS: try: if self.api.connect(ip, port): return except: pass
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]))
def api_worker(self): data = [] if self._queue.qsize() < 80: for item in stock_ip_list: _sec = self._test_speed(ip=item['ip'], port=item['port']) if _sec < 0.1: try: self._queue.put( TdxHq_API(heartbeat=False).connect( ip=item['ip'], port=item['port'])) except: pass else: self._queue_clean() Timer(0, self.api_worker).start() Timer(300, self.api_worker).start()
def __hq_list(self, market): assert self.__hq.qsize() > 0 api = TdxHq_API() ip, port = self.__hq.get() with api.connect(ip, port): df = list() for start in range(0, api.get_security_count(market=market), 1000): df.append(api.to_df(api.get_security_list(market, start))) api.disconnect() self.__hq.put((ip, port)) df = pandas.concat(df, sort=False).assign(sse=market) df = df[[ 'code', 'volunit', 'decimal_point', 'name', 'pre_close', 'sse' ]].dropna() df = df.assign(sse='sh' if market == CODE_MARKET_SH else 'sz', sec=get_code_type(df.code.tolist(), market)) return df return None
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)))
def QA_fetch_get_stock_list(type_='stock', ip=best_ip, port=7709): api = TdxHq_API() with api.connect(ip, port): data = pd.concat([ pd.concat([ api.to_df(api.get_security_list(j, i * 1000)).assign( sse='sz' if j == 0 else 'sh').set_index(['code', 'sse'], drop=False) for i in range(int(api.get_security_count(j) / 1000) + 1) ], axis=0) for j in range(2) ], axis=0) if type_ in ['stock', 'gp']: return pd.concat([ data[data['sse'] == 'sz'][data.assign( code=data['code'].apply(lambda x: int(x)))['code'] // 10000 <= 30] [data.assign( code=data['code'].apply(lambda x: int(x)))['code'] // 100000 != 2][data.assign( code=data['code'].apply(lambda x: int(x)))['code'] // 100000 != 1], data[data['sse'] == 'sh'][data.assign( code=data['code'].apply(lambda x: int(x)))['code'] // 100000 == 6] ]).assign(code=data['code'].apply(lambda x: str(x))).assign( name=data['name'].apply(lambda x: str(x)[0:4])) #.assign(szm=data['name'].apply(lambda x: ''.join([y[0] for y in lazy_pinyin(x)])))\ #.assign(quanpin=data['name'].apply(lambda x: ''.join(lazy_pinyin(x)))) elif type_ in ['index', 'zs']: return pd.concat([data[data['sse'] == 'sz'][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 1000 >= 399], data[data['sse'] == 'sh'][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 1000 == 0]]) \ .sort_index()\ .assign(name=data['name'].apply(lambda x: str(x)[0:4]))\ .assign(code=data['code'].apply(lambda x: str(x))) #.assign(szm=data['name'].apply(lambda x: ''.join([y[0] for y in lazy_pinyin(x)])))\ #.assign(quanpin=data['name'].apply(lambda x: ''.join(lazy_pinyin(x)))) elif type_ in ['etf', 'ETF']: return pd.concat([data[data['sse'] == 'sz'][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 10000 == 15], data[data['sse'] == 'sh'][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 10000 == 51]]).sort_index().assign(code=data['code'].apply(lambda x: str(x))).assign(name=data['name'].apply(lambda x: str(x)[0:4]))\ #.assign(szm=data['name'].apply(lambda x: ''.join([y[0] for y in lazy_pinyin(x)])))\ #.assign(quanpin=data['name'].apply(lambda x: ''.join(lazy_pinyin(x)))) else: return data.assign( code=data['code'].apply(lambda x: str(x))).assign( name=data['name'].apply(lambda x: str(x)[0:4]))
def api_worker(self): # 将IP列表随机排序,避免只使用列表前面的IP地址 ip_list = stock_ip_list random.shuffle(ip_list) for item in ip_list: if self._queue.full(): return _sec = self._test_speed(ip=item['ip'], port=item['port']) if _sec < self.timeout * 3: try: self._queue.put( TdxHq_API(heartbeat=False).connect( ip=item['ip'], port=item['port'], time_out=self.timeout * 2)) except: pass Timer(300, self.api_worker).start()
def QA_fetch_get_index_min(code, start, end, frequence='1min', ip=None, port=None): '指数分钟线' ip, port = get_mainmarket_ip(ip, port) api = TdxHq_API() type_ = '' start_date = str(start)[0:10] today_ = datetime.date.today() lens = QA_util_get_trade_gap(start_date, today_) if str(frequence) in ['5', '5m', '5min', 'five']: frequence, type_ = 0, '5min' lens = 48 * lens elif str(frequence) in ['1', '1m', '1min', 'one']: frequence, type_ = 8, '1min' lens = 240 * lens elif str(frequence) in ['15', '15m', '15min', 'fifteen']: frequence, type_ = 1, '15min' lens = 16 * lens elif str(frequence) in ['30', '30m', '30min', 'half']: frequence, type_ = 2, '30min' lens = 8 * lens elif str(frequence) in ['60', '60m', '60min', '1h']: frequence, type_ = 3, '60min' lens = 4 * lens if lens > 20800: lens = 20800 with api.connect(ip, port): 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)))
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]))
def QA_fetch_get_stock_list(type_='stock', ip=best_ip, port=7709): api = TdxHq_API() with api.connect(ip, port): data = pd.concat([pd.concat([api.to_df(api.get_security_list(j, i * 1000)).assign(sse='sz' if j == 0 else 'sh').set_index( ['code', 'sse'], drop=False) for i in range(int(api.get_security_count(j) / 1000) + 1)], axis=0) for j in range(2)], axis=0) if type_ in ['stock', 'gp']: return pd.concat([data[data['sse'] == 'sz'][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 10000 <= 30][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 100000 != 2], data[data['sse'] == 'sh'][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 100000 == 6]]).assign(code=data['code'].apply(lambda x: str(x))) elif type_ in ['index', 'zs']: return pd.concat([data[data['sse'] == 'sz'][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 1000 >= 399], data[data['sse'] == 'sh'][data.assign(code=data['code'].apply(lambda x: int(x)))['code'] // 1000 == 0]]).sort_index().assign(code=data['code'].apply(lambda x: str(x))) else: return data.assign(code=data['code'].apply(lambda x: str(x)))
def get_stock_list(type_='stock', ip=None, port=None): ip, port = get_mainmarket_ip(ip, port) api = TdxHq_API() with api.connect(ip, port): data = pd.concat([ pd.concat([ api.to_df(api.get_security_list(j, i * 1000)).assign( sse='sz' if j == 0 else 'sh').set_index(['code', 'sse'], drop=False) for i in range(int(api.get_security_count(j) / 1000) + 1) ], axis=0, sort=False) for j in range(2) ], axis=0, sort=False) # data.code = data.code.apply(int) sz = data.query('sse=="sz"') sh = data.query('sse=="sh"') sz = sz.assign(sec=sz.code.apply(for_sz)) sh = sh.assign(sec=sh.code.apply(for_sh)) if type_ in ['stock', 'gp']: return pd.concat( [sz, sh], sort=False).query('sec=="stock_cn"').sort_index().assign( name=data['name'].apply(lambda x: str(x)[0:6])) elif type_ in ['index', 'zs']: return pd.concat( [sz, sh], sort=False).query('sec=="index_cn"').sort_index().assign( name=data['name'].apply(lambda x: str(x)[0:6])) # .assign(szm=data['name'].apply(lambda x: ''.join([y[0] for y in lazy_pinyin(x)])))\ # .assign(quanpin=data['name'].apply(lambda x: ''.join(lazy_pinyin(x)))) elif type_ in ['etf', 'ETF']: return pd.concat( [sz, sh], sort=False).query('sec=="etf_cn"').sort_index().assign( name=data['name'].apply(lambda x: str(x)[0:6])) else: return data.assign( code=data['code'].apply(lambda x: str(x))).assign( name=data['name'].apply(lambda x: str(x)[0:6]))
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]))
def __init__(self, rootPath="./stock_data"): # load config file self.parser_config("config.conf") # init database self.stock = StockDatabase() self.stock.init_db("config.conf") # tushare pro config ts.set_token(self.tushare_key) self.pro = ts.pro_api() # connect tdx self.api = TdxHq_API(auto_retry=True, raise_exception=True) self.rootPath = rootPath self._stock_cache = self.rootPath + "/stock_cache/" create_if_not_exists(self._stock_cache) self._stock_daily_data_cache_path = self.rootPath + "/daily_data/" create_if_not_exists(self._stock_daily_data_cache_path) self._all_stock_info_cache_path = self.rootPath + "/stock_info/" create_if_not_exists(self._all_stock_info_cache_path) self._stock_extend_data_cache_path = self.rootPath + "/stock_extend/" create_if_not_exists(self._stock_extend_data_cache_path) self._stock_rights_path = self.rootPath + "/stock_rights_cache/" create_if_not_exists(self._stock_rights_path) self.get_all_stock_info()
def connect_tdx(date, universe, market_dict, path, fix_universe): # 修复bug new_code = lambda c: "{}.XSHG".format(c) \ if c[0] == "6" else "{}.XSHE".format(c) int_date = int(date.replace("-", "")) save_path = path + "\\Date{}.csv".format(int_date) idx = [i * 2000 for i in range(6)] with TdxHq_API(heartbeat=True, auto_retry=True) as con_api: with con_api.connect(): access = [] try: universe = universe(date) universe = list(set(universe).union(fix_universe)) except: universe = fix_universe for code in universe: gc.collect() # 小内存使用 market = market_dict[code[0]] tmp = [ con_api.to_df( con_api.get_history_transaction_data( market, code, s, e, int_date)) for s, e in zip(idx[:-1], idx[1:]) ] tmp.reverse() tmp = pd.concat(tmp, axis=0) tmp["date"] = date tmp["code"] = new_code(code) access.append(tmp) access = pd.concat(access, axis=0) access.to_csv(save_path, encoding="utf_8_sig") print("Level-1逐笔数据@{}".format(date)) time.sleep(0.5) gc.collect()
class PYTDXService(): """pytdx数据服务类""" def __init__(self): """Constructor""" self.connected = False # 数据服务连接状态 self.hq_api = None # 行情API def connect_api(self): """连接API""" # 连接增强行情API并检查连接情况 try: if not self.connected: host = SETTINGS["TDX_HOST"] port = SETTINGS["TDX_PORT"] self.hq_api = TdxHq_API() self.hq_api.connect(host, port) self.connected = True return True except Exception: raise ConnectionError("pytdx连接错误") def get_realtime_data(self, symbol: str): """获取股票实时数据""" try: symbols = self.generate_symbols(symbol) df = self.hq_api.to_df(self.hq_api.get_security_quotes(symbols)) return df except Exception: raise ValueError("股票数据获取失败") @staticmethod def generate_symbols(symbol: str): """组装symbols数据,pytdx接收的是以市场代码和标的代码组成的元祖的list""" new_symbols = [] code, exchange = symbol.split('.') new_symbols.append((exchange_map[exchange], code)) return new_symbols def close(self): """数据服务关闭""" self.connected = False self.hq_api.disconnect()
def _get_bankinfo_tdx(self): ''' 通过通达信获取板块信息 :return: ''' # 创建TDX对象 api = TdxHq_API() with api.connect('218.108.98.244', 7709): # 概念 bank_gn = api.get_and_parse_block_info(TDXParams.BLOCK_GN) # 风格 bank_fg = api.get_and_parse_block_info(TDXParams.BLOCK_FG) # 指数 bank_zs = api.get_and_parse_block_info(TDXParams.BLOCK_SZ) bank_gn_list = [] for bank in bank_gn: bank_gn_list.append([bank['blockname'], '概念', bank['code']]) bank_fg_list = [] for bank in bank_fg: bank_fg_list.append([bank['blockname'], '风格', bank['code']]) bank_zs_list = [] for bank in bank_zs: bank_zs_list.append([bank['blockname'], '指数', bank['code']]) bank_gn_list.extend(bank_fg_list) bank_gn_list.extend(bank_zs_list) df_bank_stocks = pd.DataFrame(bank_gn_list, columns=['bank_name', 'bank_type', 'stock_code']) df_bank = df_bank_stocks[['bank_name', 'bank_type']].drop_duplicates() # 先删除原表数据 BankBasicInfo.objects.all().delete() # 新增板块数据。每次更新板块数据,都要先删除旧数据,再重建新数据。因为板块内的个股是会变动的 for bank in df_bank.values: # name stocks bank_type bank_desc bankinfo = BankBasicInfo() bankinfo.name = bank[0] bankinfo.bank_type = bank[1] bankinfo.bank_desc = bank[1] bankinfo.save() stocks = df_bank_stocks[df_bank_stocks['bank_name'] == bank[0]] bankinfo.stocks.set(StockBasicInfo.objects.filter(code__in=list(stocks['stock_code'])))
def QA_fetch_get_index_list(ip=None, port=None): """获取指数列表 Keyword Arguments: ip {[type]} -- [description] (default: {None}) port {[type]} -- [description] (default: {None}) Returns: [type] -- [description] """ ip, port = get_mainmarket_ip(ip, port) api = TdxHq_API() with api.connect(ip, port): data = pd.concat([pd.concat([api.to_df(api.get_security_list(j, i * 1000)).assign(sse='sz' if j == 0 else 'sh').set_index( ['code', 'sse'], drop=False) for i in range(int(api.get_security_count(j) / 1000) + 1)], axis=0) for j in range(2)], axis=0) #data.code = data.code.apply(int) sz = data.query('sse=="sz"') sh = data.query('sse=="sh"') sz = sz.assign(sec=sz.code.apply(for_sz)) sh = sh.assign(sec=sh.code.apply(for_sh)) return pd.concat([sz, sh]).query('sec=="index_cn"').sort_index().assign(name=data['name'].apply(lambda x: str(x)[0:6]))
def __hq_bars(self, code, offset, frequency=9, index=False): assert self.__hq.qsize() > 0 api = TdxHq_API() if index is True: market_func = get_index_market bars_func = api.get_index_bars else: market_func = get_code_market bars_func = api.get_security_bars ip, port = self.__hq.get() with api.connect(ip, port): df = list() for _code in code: market = market_func(_code) for _start, _count in offset: df.append( api.to_df( bars_func(frequency, market, _code, _start, _count)).assign(code=_code)) api.disconnect() self.__hq.put((ip, port)) if len(df) < 1: return None return pandas.concat(df, sort=False)
class PYTDXService(): """pytdx数据服务类""" def __init__(self): """Constructor""" self.connected = False # 数据服务连接状态 self.hq_api = None # 行情API def connect_api(self): """连接API""" # 连接增强行情API并检查连接情况 try: if not self.connected: host = SETTINGS["TDX_HOST"] port = SETTINGS["TDX_PORT"] self.hq_api = TdxHq_API() self.hq_api.connect(host, port) self.connected = True return True except Exception: raise ConnectionError("pytdx连接错误") def get_realtime_data(self, symbol: str): """获取股票实时数据""" try: symbols = self.generate_symbols(symbol) df = self.hq_api.to_df(self.hq_api.get_security_quotes(symbols)) return df except Exception: raise ValueError("股票数据获取失败") def get_history_transaction_data(self, symbol, date): """ 查询历史分笔数据 get_history_transaction_data(TDXParams.MARKET_SZ, '000001', 0, 10, 20170209) 参数:市场代码, 股票代码, 起始位置, 数量, 日期 输出[time, price, vol, buyorsell(0:buy, 1:sell, 2:平)] """ # 获得标的 code, market = self.check_symbol(symbol) # 设置参数 check_date = int(date) count = 2000 data_list = [] position = [6000, 4000, 2000, 0] for start in position: data = self.hq_api.to_df( self.hq_api.get_history_transaction_data( market, code, start, count, check_date)) data_list.append(data) df = pd.concat(data_list) df.drop_duplicates(inplace=True) return df @staticmethod def generate_symbols(symbol: str): """组装symbols数据,pytdx接收的是以市场代码和标的代码组成的元祖的list""" new_symbols = [] code, exchange = symbol.split('.') new_symbols.append((exchange_map[exchange], code)) return new_symbols @staticmethod def check_symbol(symbol: str): """检查标的格式""" if symbol: code, market = symbol.split('.') market = exchange_map.get(market) return code, market else: return False def close(self): """数据服务关闭""" self.connected = False self.hq_api.disconnect()
class TDX(object): ''' This class is tong da xin data source. We can use it to get down the stock datas. Tushare can't get minter line and or year line. TDX can search index of stock and funds. ''' def __init__(self): self.tdx_api = TdxHq_API() self.__ip = '119.147.212.81' #输入IP self.__port = 7709 #端口 self.__code = '600200' self.__market = 1 #市场代码 0:深圳,1:上海 self._startdate = "2017-01-01" self.today = datetime.date.today() self._enddate = datetime.datetime.strftime(self.today, '%Y-%m-%d') self.__mkt_segment = { 'sh': '60', "sz": '00', "cyb": "30", } #segment 当前板块开始字符串 def __str__(self): return 'TDX object (code : %s)' % self.code @property def IP(self): # self.IP return self.__ip @property def PORT(self): return self.__port @property def code(self): #定义stock code 属性 return self.__code @code.setter #设定code def code(self, code_input): """ The setter of the code property """ if not isinstance(code_input, str): #确定是否是字符串 raise ValueError('the code must string!') if not len(code_input) == 6: #确定长度 raise ValueError('the code value error,the len must SIX !') if code_input.startswith('60'): #确定表头 self.__market = 1 elif code_input.startswith('00'): self.__market = 0 elif code_input.startswith('30'): self.__market = 0 else: raise ValueError('this code is not stock code') self.__code = code_input @property def startdate(self): #开始日期 return self._startdate @startdate.setter #设置日期 def startdate(self, date_input): """ The setter of the start date property """ if not isinstance(date_input, str): raise ValueError('the date must string!') if not len(date_input) == 8: raise ValueError( 'the date value error,the date formet must xxxx-xx-xx !') self._startdate = date_input @property #结束日期 def enddate(self): return self._enddate @enddate.setter def enddate(self, date_input): """ The setter of the start date property """ if not isinstance(date_input, str): raise ValueError('the date must string!') if not len(date_input) == 8: raise ValueError( 'the date value error,the date formet must xxxx-xx-xx !') self._enddate = date_input def get_day_data_tdx(self): #获取K line with self.tdx_api.connect(self.IP, self.PORT): data = self.tdx_api.get_k_data(self.code, self.startdate, self.enddate) data = pandas.DataFrame(data) data.date = data.date.apply( lambda x: datetime.datetime.strptime(x, "%Y-%m-%d")) return data #TODO: 现在是用800点进行计数,以后会细化功能 def get_k_data_tdx(self, k_mode=9): """ 获取k 线图,总计800 点 Parameters ---------- k_mode= 0-11 0 5分钟K线 1 15分钟K线 2 30分钟K线 3 1小时K线 4 日K线 5 周K线 6 月K线 7 1分钟 8 1分钟K线 9 日K线 10 季K线 11 年K线 Returns ------- """ with self.tdx_api.connect(self.self.IP, self.self.PORT): data = self.tdx_api.get_security_bars(k_mode, self.__market, self.code, 0, 800) data = pandas.DataFrame(data) #data.date = data.date.apply( # lambda x: datetime.datetime.strptime(x, "%Y-%m-%d")) return data def len_market(self): #市场有多少只股票 with self.tdx_api.connect(self.IP, self.PORT): _len = self.tdx_api.get_security_count(self.__market) return _len def get_page_tdx(self, block=None): if block is None: market = 1 page = [0] elif block in ['sh', 'SH']: market = 1 page = [13, 14] elif block in ['sz', 'SZ']: print('block for shenzhen') market = 0 page = [0, 1] elif block in ['cyb', 'CYB']: print('block for chuang ye ban') market = 0 page = [7, 8] else: pass code_list_df = pandas.DataFrame() with self.tdx_api.connect(self.IP, self.PORT): for pn in page: data = self.tdx_api.get_security_list(market, pn * 1000) data = pandas.DataFrame(data) print(data) code_list_df = code_list_df.append(data, ignore_index=True) return code_list_df def get_base_finace_tdx(self): with self.tdx_api.connect(self.IP, self.PORT): data = self.tdx_api.get_finance_info(0, '000001') data = pandas.Series(data) print(data) def get_min_data(self): from pytdx.params import TDXParams with self.tdx_api.connect(self.IP, self.PORT): data = self.tdx_api.get_history_minute_time_data( TDXParams.MARKET_SH, self.code, 20161209) data = pandas.DataFrame(data) print(data) #TODO: 需要确定 0: buy 1 : sell def get_tick_data(self): """ 历史分笔交易:time 顺序; price ; vol ;buyorsell [1:] [0:]; sh 60 13000-14000 Parameters ---------- Returns ------- """ data = pandas.DataFrame() with self.tdx_api.connect(self.IP, self.PORT): for i in [2000, 0000]: df = self.tdx_api.get_history_transaction_data( TDXParams.MARKET_SH, "600547", i, 2000, 20160308) df = pandas.DataFrame(df) data = data.append(df, ignore_index=True) return data def get_tick_today(self): """ Get every time the each deal for today.每组数最大len 2 k 所以要确定的数据长度 Parameters ---------- self: Returns ------- """ with self.tdx_api.connect(self.IP, self.PORT): data = pandas.DataFrame() for i in [0, 2000]: df = self.tdx_api.get_transaction_data(self.__market, self.code, i, 2000) df = pandas.DataFrame(df) data = data.append(df, ignore_index=True) return data def get_block(self): with self.tdx_api.connect(self.IP, self.PORT): data = self.tdx_api.get_and_parse_block_info("block.dat") data = pandas.DataFrame(data) print(data) def get_market_segment_list(self, mkt): data = self.get_page_tdx(mkt) self.code_list = pandas.DataFrame() pbar = tqdm(total=len(data.code)) mkt_hard = self.mkt_segment[mkt] for idx, __code in enumerate(data.code): pbar.update(1) if __code.startswith(mkt_hard, 0, 2): self.code_list = self.code_list.append(data.loc[idx], ignore_index=True) return self.code_list def get_sh_list(self): return self.get_market_segment_list('sh') def get_sz_list(self): return self.get_market_segment_list('sz') def get_cyb_list(self): return self.get_market_segment_list('cyb')
def __init__(self): self.api = TdxHq_API(heartbeat=True) self.dbUtil = DBUtil.getInstance()
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
def QA_fetch_get_stock_day(code, start_date, end_date, if_fq='00', level='day', ip=best_ip, port=7709): api = TdxHq_API() with api.connect(ip, port): if level in ['day', 'd', 'D', 'DAY', 'Day']: level = 9 elif level in ['w', 'W', 'Week', 'week']: level = 5 elif level in ['month', 'M', 'm', 'Month']: level = 6 elif level in ['Q', 'Quarter', 'q']: level = 10 elif level in ['y', 'Y', 'year', 'Year']: level = 11 data = pd.concat([api.to_df(api.get_security_bars(level, __select_market_code( code), code, (9 - i) * 800, 800)) for i in range(10)], axis=0) if if_fq in ['00', 'bfq']: data = data.assign(date=data['datetime'].apply(lambda x: str(x[0:10]))).assign(code=str(code))\ .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\ .set_index('date', drop=False, inplace=False)\ .drop(['year', 'month', 'day', 'hour', 'minute', 'datetime'], axis=1)[start_date:end_date] return data.assign(date=data['date'].apply(lambda x: str(x)[0:10])) elif if_fq in ['01', 'qfq']: xdxr_data = QA_fetch_get_stock_xdxr(code) info = xdxr_data[xdxr_data['category'] == 1] bfq_data = data\ .assign(date=pd.to_datetime(data['datetime'].apply(lambda x: x[0:10])))\ .assign(code=str(code))\ .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\ .set_index('date', drop=False, inplace=False)\ .drop(['year', 'month', 'day', 'hour', 'minute', 'datetime'], axis=1) bfq_data['if_trade'] = True data = pd.concat([bfq_data, info[['category']] [bfq_data.index[0]:]], axis=1) data['date'] = data.index data['if_trade'].fillna(value=False, inplace=True) data = data.fillna(method='ffill') data = pd.concat([data, info[['fenhong', 'peigu', 'peigujia', 'songzhuangu']][bfq_data.index[0]:]], axis=1) data = data.fillna(0) data['preclose'] = (data['close'].shift(1) * 10 - data['fenhong'] + data['peigu'] * data['peigujia']) / (10 + data['peigu'] + data['songzhuangu']) data['adj'] = (data['preclose'].shift(-1) / data['close']).fillna(1)[::-1].cumprod() data['open'] = data['open'] * data['adj'] data['high'] = data['high'] * data['adj'] data['low'] = data['low'] * data['adj'] data['close'] = data['close'] * data['adj'] data['preclose'] = data['preclose'] * data['adj'] data = data[data['if_trade']] return data.drop(['fenhong', 'peigu', 'peigujia', 'songzhuangu', 'if_trade', 'category'], axis=1)[data['open'] != 0].assign(date=data['date'].apply(lambda x: str(x)[0:10]))[start_date:end_date] elif if_fq in ['03', 'ddqfq']: xdxr_data = QA_fetch_get_stock_xdxr(code) info = xdxr_data[xdxr_data['category'] == 1] bfq_data = data\ .assign(date=pd.to_datetime(data['datetime'].apply(lambda x: x[0:10])))\ .assign(code=str(code))\ .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\ .set_index('date', drop=False, inplace=False)\ .drop(['year', 'month', 'day', 'hour', 'minute', 'datetime'], axis=1) bfq_data['if_trade'] = True data = pd.concat([bfq_data, info[['category']] [bfq_data.index[0]:end_date]], axis=1) data['date'] = data.index data['if_trade'].fillna(value=False, inplace=True) data = data.fillna(method='ffill') data = pd.concat([data, info[['fenhong', 'peigu', 'peigujia', 'songzhuangu']][bfq_data.index[0]:end_date]], axis=1) data = data.fillna(0) data['preclose'] = (data['close'].shift(1) * 10 - data['fenhong'] + data['peigu'] * data['peigujia']) / (10 + data['peigu'] + data['songzhuangu']) data['adj'] = (data['preclose'].shift(-1) / data['close']).fillna(1)[::-1].cumprod() data['open'] = data['open'] * data['adj'] data['high'] = data['high'] * data['adj'] data['low'] = data['low'] * data['adj'] data['close'] = data['close'] * data['adj'] data['preclose'] = data['preclose'] * data['adj'] data = data[data['if_trade']] return data.drop(['fenhong', 'peigu', 'peigujia', 'songzhuangu', 'if_trade', 'category'], axis=1)[data['open'] != 0].assign(date=data['date'].apply(lambda x: str(x)[0:10]))[start_date:end_date] elif if_fq in ['02', 'hfq']: xdxr_data = QA_fetch_get_stock_xdxr(code) info = xdxr_data[xdxr_data['category'] == 1] bfq_data = data\ .assign(date=pd.to_datetime(data['datetime'].apply(lambda x: x[0:10])))\ .assign(code=str(code))\ .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\ .set_index('date', drop=False, inplace=False)\ .drop(['year', 'month', 'day', 'hour', 'minute', 'datetime'], axis=1) bfq_data['if_trade'] = True data = pd.concat([bfq_data, info[['category']] [bfq_data.index[0]:]], axis=1) data['date'] = data.index data['if_trade'].fillna(value=False, inplace=True) data = data.fillna(method='ffill') data = pd.concat([data, info[['fenhong', 'peigu', 'peigujia', 'songzhuangu']][bfq_data.index[0]:]], axis=1) data = data.fillna(0) data['preclose'] = (data['close'].shift(1) * 10 - data['fenhong'] + data['peigu'] * data['peigujia']) / (10 + data['peigu'] + data['songzhuangu']) data['adj'] = (data['preclose'].shift(-1) / data['close']).fillna(1).cumprod() data['open'] = data['open'] / data['adj'] data['high'] = data['high'] / data['adj'] data['low'] = data['low'] / data['adj'] data['close'] = data['close'] / data['adj'] data['preclose'] = data['preclose'] / data['adj'] data = data[data['if_trade']] return data.drop(['fenhong', 'peigu', 'peigujia', 'songzhuangu', 'if_trade', 'category'], axis=1)[data['open'] != 0].assign(date=data['date'].apply(lambda x: str(x)[0:10]))[start_date:end_date] elif if_fq in ['04', 'ddhfq']: xdxr_data = QA_fetch_get_stock_xdxr(code) info = xdxr_data[xdxr_data['category'] == 1] bfq_data = data\ .assign(date=pd.to_datetime(data['datetime'].apply(lambda x: x[0:10])))\ .assign(code=str(code))\ .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\ .set_index('date', drop=False, inplace=False)\ .drop(['year', 'month', 'day', 'hour', 'minute', 'datetime'], axis=1) bfq_data['if_trade'] = True data = pd.concat([bfq_data, info[['category']] [bfq_data.index[0]:end_date]], axis=1) data['date'] = data.index data['if_trade'].fillna(value=False, inplace=True) data = data.fillna(method='ffill') data = pd.concat([data, info[['fenhong', 'peigu', 'peigujia', 'songzhuangu']][bfq_data.index[0]:end_date]], axis=1) data = data.fillna(0) data['preclose'] = (data['close'].shift(1) * 10 - data['fenhong'] + data['peigu'] * data['peigujia']) / (10 + data['peigu'] + data['songzhuangu']) data['adj'] = (data['preclose'].shift(-1) / data['close']).fillna(1).cumprod() data['open'] = data['open'] / data['adj'] data['high'] = data['high'] / data['adj'] data['low'] = data['low'] / data['adj'] data['close'] = data['close'] / data['adj'] data['preclose'] = data['preclose'] / data['adj'] data = data[data['if_trade']] return data.drop(['fenhong', 'peigu', 'peigujia', 'songzhuangu', 'if_trade', 'category'], axis=1)[data['open'] != 0].assign(date=data['date'].apply(lambda x: str(x)[0:10]))[start_date:end_date]
def QA_fetch_get_stock_info(code, ip=best_ip, port=7709): '股票财务数据' api = TdxHq_API() market_code = __select_market_code(code) with api.connect(ip, port): return api.to_df(api.get_finance_info(market_code, code))
def QA_fetch_get_stock_block(ip=best_ip, port=7709): '板块数据' api = TdxHq_API() with api.connect(ip, port): data = pd.concat([api.to_df(api.get_and_parse_block_info("block_gn.dat")), api.to_df(api.get_and_parse_block_info("block.dat")), api.to_df(api.get_and_parse_block_info( "block_zs.dat")), api.to_df(api.get_and_parse_block_info("block_fg.dat"))]) if len(data) > 10: return data.assign(source='tdx').set_index('code', drop=False, inplace=False) else: QA_util_log_info('Wrong with fetch block ')
if __name__ == '__main__': import os import time starttime = time.time() dest_dir = "c:\\stock" tdx_server = '119.147.212.81' tdx_port = 7709 quotations = ['stock', 'fund'] connect = sqlite3.connect(dest_dir + "\\stock.db") create_database(connect) from pytdx.hq import TdxHq_API, TDXParams api = TdxHq_API() api.connect(tdx_server, tdx_port) add_count = 0 """ print("导入股票代码表") add_count = import_stock_name(connect, api, 'SH', quotations) add_count += import_stock_name(connect, api, 'SZ', quotations) print("新增股票数:", add_count) print("\n导入上证日线数据") add_count = import_data(connect, 'SH', 'DAY', quotations, api, dest_dir, progress=ProgressBar) print("\n导入数量:", add_count) print("\n导入深证日线数据") add_count = import_data(connect, 'SZ', 'DAY', quotations, api, dest_dir, progress=ProgressBar)
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
''' Created on 2017年11月16日 @author: Coder_J ''' from pytdx.hq import TdxHq_API from datetime import datetime api = TdxHq_API() # def select_best_ip(): # QA_util_log_info('Selecting the Best Server IP of TDX') # listx = ['218.75.126.9', '115.238.90.165', # '124.160.88.183', '60.12.136.250', '218.108.98.244', '218.108.47.69', # '14.17.75.71', '180.153.39.51'] # data = [ping(x) for x in listx] # QA_util_log_info('===The BEST SERVER is : %s ===' % # (listx[data.index(min(data))])) # return listx[data.index(min(data))] # best_ip = select_best_ip() def s1(): if api.connect('119.147.212.81', 7709): # ... same codes... data = api.to_df(api.get_security_bars(9, 0, '000001', 0, 5)) # 返回DataFrame print(data) api.disconnect()
def test_raise_excepiton(): api = TdxHq_API(raise_exception=True) with pytest.raises(TdxConnectionError): with api.connect('8.8.8.8'): pass
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