优化导入数据时对退市股票的处理

This commit is contained in:
fasiondog 2024-09-04 02:03:28 +08:00
parent 894e210395
commit 9f3dbb078e
6 changed files with 69 additions and 26 deletions

View File

@ -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)
# 股票名称发生变化,更新股票名称;如果原无效,则置为有效

View File

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

View File

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

View File

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

View File

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

View File

@ -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]