diff --git a/hikyuu/data/pytdx_to_h5.py b/hikyuu/data/pytdx_to_h5.py index fdcf65cc..ef1cc343 100644 --- a/hikyuu/data/pytdx_to_h5.py +++ b/hikyuu/data/pytdx_to_h5.py @@ -101,6 +101,21 @@ def import_stock_name(connect, api, market, quotations=None): """ cur = connect.cursor() + deSet = set() # 记录退市证券 + if market == MARKET.SH: + df = ak.stock_info_sh_delist() + l = df[['公司代码', '公司简称']].to_dict(orient='records') if not df .empty else [] + for stock in l: + code = str(stock['公司代码']) + deSet.add(code) + elif market == MARKET.SZ: + for t in ['暂停上市公司', '终止上市公司']: + df = ak.stock_info_sz_delist(t) + l = df[['证券代码', '证券简称']].to_dict(orient='records') if not df.empty else [] + for stock in l: + code = str(stock['证券代码']) + deSet.add(code) + newStockDict = {} stk_list = get_stk_code_name_list(market) if not stk_list: @@ -110,18 +125,9 @@ def import_stock_name(connect, api, market, quotations=None): if not quotations or 'fund' in [v.lower() for v in quotations]: stk_list.extend(get_fund_code_name_list(market)) for stock in stk_list: - newStockDict[str(stock['code'])] = stock['name'] - if market == MARKET.SH: - df = ak.stock_info_sh_delist() - l = df[['公司代码', '公司简称']].to_dict(orient='records') if not df .empty else [] - for stock in l: - newStockDict[str(stock['公司代码'])] = stock['公司简称'] - elif market == MARKET.SZ: - for t in ['暂停上市公司', '终止上市公司']: - df = ak.stock_info_sz_delist(t) - l = df[['证券代码', '证券简称']].to_dict(orient='records') if not df.empty else [] - for stock in l: - newStockDict[str(stock['证券代码'])] = stock['证券简称'] + code = str(stock['code']) + if code not in deSet: + newStockDict[code] = stock['name'] marketid = get_marketid(connect, market) @@ -138,8 +144,8 @@ def import_stock_name(connect, api, market, quotations=None): oldstockid, oldcode, oldname, oldvalid = oldstock[0], oldstock[1], oldstock[2], int(oldstock[3]) oldStockDict[oldcode] = oldstockid - # 新的代码表中无此股票,则置为无效 - if (oldvalid == 1) and (oldcode not in newStockDict): + # 新的代码表中无此股票或者已退市,则置为无效 + if (oldvalid == 1) and ((oldcode not in newStockDict) or (oldcode in deSet)): cur.execute("update stock set valid=0 where stockid=%i" % oldstockid) # 股票名称发生变化,更新股票名称;如果原无效,则置为有效 diff --git a/hikyuu/data/pytdx_to_mysql.py b/hikyuu/data/pytdx_to_mysql.py index d37874f7..3c4a909e 100644 --- a/hikyuu/data/pytdx_to_mysql.py +++ b/hikyuu/data/pytdx_to_mysql.py @@ -122,6 +122,21 @@ def import_stock_name(connect, api, market, quotations=None): """ cur = connect.cursor() + deSet = set() # 记录退市证券 + if market == MARKET.SH: + df = ak.stock_info_sh_delist() + l = df[['公司代码', '公司简称']].to_dict(orient='records') if not df .empty else [] + for stock in l: + code = str(stock['公司代码']) + deSet.add(code) + elif market == MARKET.SZ: + for t in ['暂停上市公司', '终止上市公司']: + df = ak.stock_info_sz_delist(t) + l = df[['证券代码', '证券简称']].to_dict(orient='records') if not df.empty else [] + for stock in l: + code = str(stock['证券代码']) + deSet.add(code) + newStockDict = {} stk_list = get_stk_code_name_list(market) if not stk_list: @@ -131,7 +146,9 @@ def import_stock_name(connect, api, market, quotations=None): if not quotations or "fund" in [v.lower() for v in quotations]: stk_list.extend(get_fund_code_name_list(market)) for stock in stk_list: - newStockDict[str(stock["code"])] = stock["name"] + code = str(stock["code"]) + if code not in deSet: + newStockDict[code] = stock["name"] marketid = get_marketid(connect, market) @@ -156,7 +173,8 @@ def import_stock_name(connect, api, market, quotations=None): oldStockDict[oldcode] = oldstockid # 新的代码表中无此股票,则置为无效 - if (oldvalid == 1) and (oldcode not in newStockDict): + # if (oldvalid == 1) and (oldcode not in newStockDict): + if (oldvalid == 1) and ((oldcode not in newStockDict) or oldcode in deSet): cur.execute( "update `hku_base`.`stock` set valid=0 where stockid=%i" % oldstockid ) diff --git a/hikyuu/data/pytdx_weight_to_mysql.py b/hikyuu/data/pytdx_weight_to_mysql.py index 5e1e1699..2f8249af 100644 --- a/hikyuu/data/pytdx_weight_to_mysql.py +++ b/hikyuu/data/pytdx_weight_to_mysql.py @@ -38,7 +38,7 @@ def pytdx_import_weight_to_mysql(pytdx_api, connect, market): pytdx_market = to_pytdx_market(market) total_count = 0 - cur.execute("select stockid, code from `hku_base`.`stock` where marketid=%s" % (marketid)) + cur.execute("select stockid, code from `hku_base`.`stock` where marketid=%s and valid=1" % (marketid)) stockid_list = [x for x in cur.fetchall()] cur.close() diff --git a/hikyuu/data/pytdx_weight_to_sqlite.py b/hikyuu/data/pytdx_weight_to_sqlite.py index fb8fb0a8..57cb3961 100644 --- a/hikyuu/data/pytdx_weight_to_sqlite.py +++ b/hikyuu/data/pytdx_weight_to_sqlite.py @@ -35,7 +35,7 @@ def pytdx_import_weight_to_sqlite(pytdx_api, connect, market): pytdx_market = to_pytdx_market(market) total_count = 0 - stockid_list = cur.execute("select stockid, code from Stock where marketid=%s" % (marketid)) + stockid_list = cur.execute("select stockid, code from Stock where marketid=%s and valid=1" % (marketid)) stockid_list = [x for x in stockid_list] cur.close() diff --git a/hikyuu/fetcher/stock/zh_stock_a_pytdx.py b/hikyuu/fetcher/stock/zh_stock_a_pytdx.py index 3a3b3484..76fe520f 100644 --- a/hikyuu/fetcher/stock/zh_stock_a_pytdx.py +++ b/hikyuu/fetcher/stock/zh_stock_a_pytdx.py @@ -8,7 +8,7 @@ import datetime from pytdx.hq import TdxHq_API from hikyuu.data.common_pytdx import search_best_tdx - +from hikyuu import get_stock, constant from hikyuu.util import * @@ -16,6 +16,12 @@ from hikyuu.util import * def parse_one_result(quotes): result = {} hku_check_ignore(quotes, "Invalid input param!") + try: + result['datetime'] = datetime.datetime.combine( + datetime.date.today(), datetime.time.fromisoformat(quotes['servertime']) + ) + except: + return None result['market'] = 'SH' if quotes['market'] == 1 else 'SZ' result['code'] = quotes['code'] @@ -27,8 +33,13 @@ def parse_one_result(quotes): result['low'] = quotes['low'] # 今日最低价 result['bid'] = float(quotes['bid1']) # 竞买价,即“买一”报价 result['ask'] = float(quotes['ask1']) # 竞卖价,即“卖一”报价 - result['volume'] = float(quotes['vol']) # 成交的股票手数 - result['amount'] = round(quotes['amount'] / 1000.0, 2) # 成交金额,单位为“元”,若要以“万元”为成交金额的单位,需要把该值除以一万 + # 指数 volumn 需要乘以 0.01 + stk = get_stock(f"{result['market']}{result['code']}") + if not stk.is_null() and stk.type == constant.STOCKTYPE_INDEX: + result['volume'] = float(quotes['vol']) * 0.01 + else: + result['volume'] = float(quotes['vol']) # 成交的股票手数 + result['amount'] = round(quotes['amount'] * 0.0001, 2) # 成交金额,单位为“元”,若要以“万元”为成交金额的单位,需要把该值除以一万 result['bid1_amount'] = float(quotes['bid_vol1']) # “买一”申请4695股,即47手 result['bid1'] = float(quotes['bid1']) # “买一”报价 result['bid2_amount'] = float(quotes['bid_vol2']) @@ -49,13 +60,10 @@ def parse_one_result(quotes): result['ask4'] = float(quotes['ask4']) result['ask5_amount'] = float(quotes['ask_vol5']) result['ask5'] = float(quotes['ask5']) - result['datetime'] = datetime.datetime.combine( - datetime.date.today(), datetime.time.fromisoformat(quotes['servertime']) - ) return result -@hku_catch(ret=[]) +@ hku_catch(ret=[], trace=True) def request_data(api, stklist, parse_one_result): """请求失败将抛出异常""" quotes_list = api.get_security_quotes(stklist) @@ -63,6 +71,7 @@ def request_data(api, stklist, parse_one_result): return [r for r in result if r is not None] +@spend_time def get_spot(stocklist, ip, port, batch_func=None): api = TdxHq_API() hku_check(api.connect(ip, port), 'Failed connect tdx ({}:{})!'.format(ip, port)) diff --git a/hikyuu/interactive.py b/hikyuu/interactive.py index 6ab20873..af5cedb0 100644 --- a/hikyuu/interactive.py +++ b/hikyuu/interactive.py @@ -268,7 +268,17 @@ def select(cond, start=Datetime(201801010000), end=Datetime.now(), print_out=Tru def realtime_update_inner(source='qq', stk_list=None): if stk_list is None: - stk_list = sm + if source == 'qmt': + stk_list = [s for s in sm if s.valid and s.type in ( + constant.STOCKTYPE_A, constant.STOCKTYPE_INDEX, constant.STOCKTYPE_ETF, + constant.STOCKTYPE_GEM, constant.STOCKTYPE_START, constant.STOCKTYPE_A_BJ)] + else: + stk_list = [ + stk.market_code.lower() for stk in sm if stk.valid and stk.type in + (constant.STOCKTYPE_A, constant.STOCKTYPE_INDEX, constant.STOCKTYPE_GEM, + constant.STOCKTYPE_START, constant.STOCKTYPE_A_BJ) + ] + if source == 'qq': from hikyuu.fetcher.stock.zh_stock_a_sina_qq import get_spot stk_list = [s.market_code.lower() for s in stk_list]