主题龙头类
最后更新于:2022-04-01 21:57:25
# 主题龙头类
> 来源:https://uqer.io/community/share/54c3348ff9f06c276f651a49
本代码用于挖掘主题的龙头股
+ 先由通联提供的有关主题的API获得所有主题ID,储存为文档`20140601_20150123theme_list.txt`
+ 由API函数`DataAPI.ThemeTickersGet`获得所有各个主题对应个股
+ 由相关个股的日涨幅和市值,计算主题的每天收益
+ 滚动计算主题5天的涨幅,找到主题涨幅最高的时间区间
+ 在这个时间区间内,计算主题相关个股的涨幅
+ 找到涨幅最高的个股,即为该主题的龙头股
```py
datetime.today()
datetime.datetime(2015, 1, 24, 13, 28, 42, 799154)
```
读取主题id文件,获得所有主题的相关个股,储存在`info`中
```py
f1 = read('20140601_20150123theme_list.txt') #从这个文档中读取所有的主题id
themeId_list = f1.split(',')
tk2id = lambda x:x+'.XSHG' if x[0]=='6' else x+'.XSHE'
#由于ThemeTickersGet对于数据量有限制,一次调用1000个主题数据
num_up = 1000 #每一次调取多少个主题的信息
thm_tk_dic = {} #储存每个主题包含的个股
tk_list = set([]) #tk_list储存了所有相关个股
num = len(themeId_list)/num_up #一次调取num_up个主题,要调用num次
beginDate = '20140601' #开始时间
endDate = '20150123' #结束时间
if num>0:
info = pd.DataFrame({})
for i in range(num):
info_sub = DataAPI.ThemeTickersGet(beginDate=beginDate,endDate=endDate,themeID=themeId_list[i*num_up:(i+1)*num_up]) #获取主题相关的个股
info = pd.concat([info,info_sub]) #将数据连接
info_sub = DataAPI.ThemeTickersGet(beginDate=beginDate,endDate=endDate,themeID=themeId_list[(i+1)*num_up:])
info = pd.concat([info,info_sub])
else:
info = DataAPI.ThemeTickersGet(beginDate=beginDate,endDate=endDate,themeID=themeId_list)
```
将主题与个股对应,`thm_tk_dic`储存了每个主题对应的个股,`key`是主题名称,`value`是与主题相关的个股列表
```py
info = info[['themeName','ticker','secShortName']] #只取这几列数据
group_info = info.groupby('themeName') #根据主题名称分类
for theme,group in group_info:
theme_tk = group['ticker'].tolist()
if len(theme_tk[0])!=6:
continue
if len(theme_tk)>10:
thm_tk_dic[theme] = theme_tk #获得某个主题下相关的个股
tk_list |= set(theme_tk) #所有的个股
```
利用`DataAPI.SecIDGet`获得个股对应的名称,便于最后展示
```py
#获得个股代码与名称的对应
tk_list = list(tk_list)
num_name = len(tk_list)/1000
if num_name>0:
tk_name_pd = pd.DataFrame({})
for i in range(num_name):
sub = DataAPI.SecIDGet(ticker=tk_list[1000*i:1000*(i+1)],field='secShortName') #获取证券简称
tk_name_pd = pd.concat([tk_name_pd,sub])
sub = DataAPI.SecIDGet(ticker=tk_list[1000*(i+1):],field='secShortName')
tk_name_pd = pd.concat([tk_name_pd,sub])
else:
tk_name_pd = DataAPI.SecIDGet(ticker=tk_list,field='secShortName')
tk_name_dic = dict(zip(tk_name_pd.ticker,tk_name_pd.secShortName)) #获得个股代码与名字对应的字典,便于最后展示
```
获得所有股票在一段日期内的日行情数据,便于计算个股每日涨幅和主题涨幅
```py
#由于API对访问量有限制,每次只能调取50个股票的日线数据,故采用限制每次调用次数,循环调用的方法
len_stk = 50 #每次调用len_stk只个股
num_stk = len(tk_list)/len_stk #要调用num_stk次
#获得tk_list中所有个股的日线信息
if num_stk>0:
mkt_stk_info = pd.DataFrame({})
for i in range(num_stk):
info = DataAPI.MktEqudGet(ticker=tk_list[i*len_stk:(i+1)*len_stk],beginDate=beginDate,endDate=endDate,field=['ticker','preClosePrice','closePrice','marketValue'])
mkt_stk_info = pd.concat([mkt_stk_info,info])
info = DataAPI.MktEqudGet(ticker=tk_list[(i+1)*len_stk:],beginDate=beginDate,endDate=endDate,field=['ticker','preClosePrice','closePrice','marketValue'])
mkt_stk_info = pd.concat([mkt_stk_info,info])
else:
mkt_stk_info = DataAPI.MktEqudGet(ticker=tk_list,beginDate=beginDate,endDate=endDate,field=['ticker','preClosePrice','closePrice','marketValue'])
mkt_stk_info = mkt_stk_info[['ticker','tradeDate','preClosePrice','closePrice','marketValue']]
```
计算主题每日涨幅
```py
thm_date_inc_dic = {} #记录了每个主题每天的涨幅,key是日期,value是主题涨幅
for key in thm_tk_dic.keys():
thm_date_inc_dic[key] = {}
for theme,stocks in thm_tk_dic.items():
mkt_info = mkt_stk_info[mkt_stk_info['ticker'].isin(stocks) ]
mkt_info['increase'] = (mkt_info['closePrice']-mkt_info['preClosePrice'])/mkt_info['preClosePrice'] #计算主题涨幅
gp_date = mkt_info.groupby('tradeDate')
for date,group in gp_date:
thm_inc = sum(group['marketValue']*group['increase'])/sum(group['marketValue']) #某天的主题收益
thm_date_inc_dic[theme][date] = thm_inc
```
计算主题滚动5日的涨幅之和,找到主题涨幅最大的时间区间
```py
thm_date_inc_pd = pd.DataFrame(thm_date_inc_dic) #生成dataframe,index是日期,columns是主题名称
window = 5 #统计5天的主题收益之和
thm_5d_inc_pd = pd.rolling_sum(thm_date_inc_pd,window=window) #计算滚动和
id_max_list_begin = thm_5d_inc_pd.dropna().values.argmax(axis=0) #由于最初的window-1行值为NA,舍弃之后得到的下标便是最大和的开始下标
pl2date = lambda x,:list(thm_5d_inc_pd.index)[x:x+window] #由开始下标获得这段时间区间,即获得[2014-06-03,2014-06-04,...]这样的列表
date_list = map(pl2date,id_max_list_begin)
max_date_periods = {} #储存每个主题获得最高收益的时间区间
for i in range(len(date_list)):
theme = thm_date_inc_pd.columns[i] #主题名称
date = date_list[i] #对应的时间区间
max_date_periods[theme] = date
```
计算在上述时间区间内个股的涨幅,涨幅最大的即为该主题的龙头股
```py
thm_leadStk_dic = {} #记录每个主题的龙头股
for theme,stock_list in thm_tk_dic.items():
date_list = max_date_periods[theme]
flt_thm_stk_info = mkt_stk_info[(mkt_stk_info['ticker'].isin(stock_list)) & (mkt_stk_info['tradeDate'].isin(date_list))] #获取这些个股在这段时期内的日线数据
grouped = flt_thm_stk_info.groupby('ticker')
stk_inc_dic = {}
for stk,group in grouped:
stk_inc = (group['closePrice'].iloc[-1]-group['preClosePrice'].iloc[0])/group['preClosePrice'].iloc[0] #获取个股在这段时间内的收益
stk_inc_dic[stk] = stk_inc
thm_leadStk_dic[theme] = sorted(stk_inc_dic.keys(),key=lambda x:stk_inc_dic[x],reverse = True)[0] #排序,获得该主题的龙头股
```
将主题和龙头股写成`dataframe`形式,便于展示
```py
thm_leadStk_pd = pd.DataFrame.from_dict(thm_leadStk_dic,orient='index').reset_index() #由字典生成dataframe
thm_leadStk_pd.rename(columns={0:'ticker'},inplace=True) #重命名,便于下一步merge
lead_tk_list = list(thm_leadStk_pd['ticker'])
tk2nm = lambda x:tk_name_dic[x]
#tk2nm = lambda x:
lead_name_list = map(tk2nm,lead_tk_list)
name_pd = pd.DataFrame({'shortname':lead_name_list})
answer = pd.concat([thm_leadStk_pd,name_pd],axis=1)
answer.rename(columns={'index':u'主题名称','ticker':u'个股代码','shortname':u'个股简称'},inplace=True) #重命名
answer
```
| | 主题名称 | 个股代码 | 个股简称 |
| --- | --- |
| 0 | 金融机具股 | 601818 | 光大银行 |
| 1 | 银联 | 601818 | 光大银行 |
| 2 | 公路运输股 | 601939 | 建设银行 |
| 3 | 小额贷款股 | 601818 | 光大银行 |
| 4 | LBS股 | 600118 | 中国卫星 |
| 5 | 智能电表 | 300085 | 银之杰 |
| 6 | 国资整合 | 601299 | 中国北车 |
| 7 | 硝酸铵股 | 002217 | *ST合泰 |
| 8 | 镍氢电池股 | 600549 | 厦门钨业 |
| 9 | 国产手机 | 600050 | 中国联通 |
| 10 | 浦东新区 | 601901 | 方正证券 |
| 11 | 特高压 | 000709 | 河北钢铁 |
| 12 | 特高压股 | 300265 | 通光线缆 |
| 13 | 数字地图 | 600717 | 天津港 |
| 14 | 白色石墨烯股 | 000009 | 中国宝安 |
| 15 | 淘宝 | 000002 | 万科A |
| 16 | 电子支付 | 002095 | 生意宝 |
| 17 | PE(化工) | 600028 | 中国石化 |
| 18 | 核电主设备股 | 300411 | 金盾股份 |
| 19 | 兽药 | 000826 | 桑德环境 |
| 20 | 沪港通股 | 601099 | 太平洋 |
| 21 | 甲基叔丁基醚股 | 000151 | 中成股份 |
| 22 | 体育文化 | 601901 | 方正证券 |
| 23 | 品牌服装 | 002503 | 搜于特 |
| 24 | 多晶硅股 | 600151 | 航天机电 |
| 25 | 丁二醇股 | 000151 | 中成股份 |
| 26 | TVOS股 | 300079 | 数码视讯 |
| 27 | 光电子材料 | 002261 | 拓维信息 |
| 28 | 珠海航展 | 600990 | 四创电子 |
| 29 | 农用机械股 | 300159 | 新研股份 |
| ... | ... | ... | ... |
| 1301 | 德州本地股 | 601106 | 中国一重 |
| 1302 | 制冷剂股 | 000550 | 江铃汽车 |
| 1303 | 微信股 | 600109 | 国金证券 |
| 1304 | 保健品 | 600530 | 交大昂立 |
| 1305 | 抗寒 | 600188 | 兖州煤业 |
| 1306 | 社保股 | 002501 | 利源精制 |
| 1307 | 神舟十号 | 601988 | 中国银行 |
| 1308 | WAPI | 002439 | 启明星辰 |
| 1309 | 光电子材料股 | 002261 | 拓维信息 |
| 1310 | 广东自贸区股 | 600185 | 格力地产 |
| 1311 | 空调股 | 300411 | 金盾股份 |
| 1312 | 德州本地 | 601106 | 中国一重 |
| 1313 | 雅安地震 | 002314 | 雅致股份 |
| 1314 | 新疆建设股 | 000562 | 宏源证券 |
| 1315 | 甲醇股 | 600188 | 兖州煤业 |
| 1316 | 陕甘宁区 | 600185 | 格力地产 |
| 1317 | 电解铝 | 601600 | 中国铝业 |
| 1318 | 电子信息股 | 000901 | 航天科技 |
| 1319 | 油气 | 601857 | 中国石油 |
| 1320 | 机床 | 603011 | 合锻股份 |
| 1321 | 人工智能 | 002230 | 科大讯飞 |
| 1322 | 机制纸 | 000488 | 晨鸣纸业 |
| 1323 | 铝股 | 600595 | 中孚实业 |
| 1324 | 金属新材料股 | 600888 | 新疆众和 |
| 1325 | 指纹识别 | 300248 | 新开普 |
| 1326 | 小米概念 | 000333 | 美的集团 |
| 1327 | 地沟油检测 | 600028 | 中国石化 |
| 1328 | 江苏沿海地区 | 000425 | 徐工机械 |
| 1329 | 电线电缆 | 002692 | 远程电缆 |
| 1330 | 风电股 | 600163 | 福建南纸 |
```
1331 rows × 3 columns
```
```py
datetime.today()
datetime.datetime(2015, 1, 24, 13, 33, 44, 786650)
```
';