hikyuu2/hikyuu/data/common.py

177 lines
6.2 KiB
C++
Raw Normal View History

2018-11-06 01:25:52 +08:00
# coding:utf-8
#
# The MIT License (MIT)
#
2019-02-24 19:36:47 +08:00
# Copyright (c) 2010-2019 fasiondog/hikyuu
2018-11-06 01:25:52 +08:00
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
2018-10-21 01:56:30 +08:00
import requests
import re
import akshare as ak
2022-08-19 22:48:32 +08:00
import pandas as pd
2022-08-20 01:05:20 +08:00
import datetime
2022-08-19 22:48:32 +08:00
from hikyuu.util import *
2021-06-05 02:08:25 +08:00
2018-11-06 01:25:52 +08:00
class MARKET:
SH = 'SH'
SZ = 'SZ'
BJ = 'BJ'
2018-10-21 01:56:30 +08:00
2021-06-05 02:08:25 +08:00
g_market_list = [MARKET.SH, MARKET.SZ, MARKET.BJ]
2018-11-06 01:25:52 +08:00
class MARKETID:
SH = 1
SZ = 2
BJ = 3
2018-11-06 01:25:52 +08:00
2021-06-05 02:08:25 +08:00
2018-11-06 01:25:52 +08:00
class STOCKTYPE:
2018-11-25 16:46:07 +08:00
BLOCK = 0 #
2021-06-05 02:08:25 +08:00
A = 1 #A股
2018-11-06 01:25:52 +08:00
INDEX = 2 #
2021-06-05 02:08:25 +08:00
B = 3 #B股
FUND = 4 #ETF
ETF = 5 #ETF
ND = 6 #
BOND = 7 #
GEM = 8 #
START = 9 #
2018-10-21 01:56:30 +08:00
2018-11-04 11:23:07 +08:00
def get_stktype_list(quotations=None):
2018-11-06 01:25:52 +08:00
"""
:param quotations: 'stock' | 'fund' | 'bond'
:rtype: tuple
:return:
"""
2018-11-04 11:23:07 +08:00
if not quotations:
2018-10-21 01:56:30 +08:00
return (1, 2, 3, 4, 5, 6, 7, 8, 9)
2018-11-04 11:23:07 +08:00
result = []
for quotation in quotations:
new_quotation = quotation.lower()
if new_quotation == 'stock':
2021-06-05 02:08:25 +08:00
result += [STOCKTYPE.A, STOCKTYPE.INDEX, STOCKTYPE.B, STOCKTYPE.GEM, STOCKTYPE.START]
2018-11-04 11:23:07 +08:00
elif new_quotation == 'fund':
2018-11-06 01:25:52 +08:00
result += [STOCKTYPE.FUND, STOCKTYPE.ETF]
2018-11-04 11:23:07 +08:00
elif new_quotation == 'bond':
2018-11-06 01:25:52 +08:00
result += [STOCKTYPE.ND, STOCKTYPE.BOND]
2018-11-04 11:23:07 +08:00
else:
print('Unknow quotation: {}'.format(quotation))
return tuple(result)
2022-08-19 22:48:32 +08:00
@hku_catch(ret=[], trace=True)
@timeout(120)
def get_stk_code_name_list(market: str) -> list:
"""
:return: [{'code': 'code1': 'name': 'name1'}, ...]
"""
# 获取深圳股票代码表
if market == MARKET.SZ:
2022-08-19 22:48:32 +08:00
ind_list = ["A股列表", "B股列表"]
df = None
for ind in ind_list:
tmp_df = ak.stock_info_sz_name_code(ind)
tmp_df.rename(columns={'A股代码': 'code', 'A股简称': 'name'}, inplace=True)
df = pd.concat([df, tmp_df]) if df is not None else tmp_df
hku_info("获取深圳证券交易所股票数量: {}", len(df) if df is not None else 0)
return df[['code', 'name']].to_dict(orient='records') if df is not None else []
# 获取上证股票代码表
if market == MARKET.SH:
2022-08-19 22:48:32 +08:00
ind_list = ["主板A股", "主板B股", "科创板"]
df = None
for ind in ind_list:
2022-08-19 23:15:41 +08:00
tmp_df = ak.stock_info_sh_name_code(ind)
2022-08-19 22:48:32 +08:00
tmp_df.rename(columns={'': 'code', '': 'name'}, inplace=True)
df = pd.concat([df, tmp_df]) if df is not None else tmp_df
hku_info("获取上海证券交易所股票数量: {}", len(df) if df is not None else 0)
return df[['code', 'name']].to_dict(orient='records') if df is not None else []
# 获取北京股票代码表
if market == MARKET.BJ:
df = ak.stock_info_bj_name_code()
df.rename(columns={'': 'code', '': 'name'}, inplace=True)
2022-08-19 22:48:32 +08:00
hku_info("获取北京证券交易所股票数量: {}", len(df) if df is not None else 0)
return df[['code', 'name']].to_dict(orient='records') if df is not None else []
2022-08-19 22:48:32 +08:00
@hku_catch(ret=[], trace=True)
@timeout(120)
def get_index_code_name_list() -> list:
"""
IP10
:return: [{'market_code': 'SHxxx'}, ...]
"""
df = ak.stock_zh_index_spot()
return [{'market_code': df.loc[i][''].upper(), 'name': df.loc[i]['']} for i in range(len(df))]
2022-08-20 01:05:20 +08:00
g_fund_code_name_list = {}
for market in g_market_list:
g_fund_code_name_list[market] = []
g_last_get_fund_code_name_list_date = datetime.date(1990, 12, 9)
@hku_catch(ret=[], trace=True)
@timeout(60)
2022-08-20 01:05:20 +08:00
def get_fund_code_name_list(market: str) -> list:
2022-08-19 23:15:41 +08:00
"""
(: sina)
"""
2022-08-20 01:05:20 +08:00
# 保证一天只获取一次基金股票代码表,防止对 sina 的频繁访问
global g_last_get_fund_code_name_list_date
now = datetime.date.today()
if now <= g_last_get_fund_code_name_list_date:
return g_fund_code_name_list[market]
2022-08-19 23:15:41 +08:00
ind_list = "封闭式基金", "ETF基金", "LOF基金"
for ind in ind_list:
df = ak.fund_etf_category_sina(ind)
2022-08-20 01:05:20 +08:00
for i in range(len(df)):
loc = df.loc[i]
try:
code, name = str(loc['']), str(loc[''])
g_fund_code_name_list[code[:2].upper()].append(dict(code=code[2:], name=name))
except Exception as e:
hku_error("{}! {}", str(e), loc)
hku_info("获取基金列表数量: {}", len(g_fund_code_name_list[market]))
g_last_get_fund_code_name_list_date = now
return g_fund_code_name_list[market]
2022-08-19 23:15:41 +08:00
2022-08-19 22:48:32 +08:00
@hku_catch(ret=[], trace=True)
def get_new_holidays():
"""获取新的交易所休假日历"""
res = requests.get('https://www.tdx.com.cn/url/holiday/', timeout=60)
res.encoding = res.apparent_encoding
ret = re.findall(r'<textarea id="data" style="display:none;">([\s\w\d\W]+)</textarea>', res.text, re.M)[0].strip()
day = [d.split('|')[:4] for d in ret.split('\n')]
2022-08-19 23:15:41 +08:00
return [v[0] for v in day if v[2] == '']