主题龙头类

来源:https://uqer.io/community/share/54c3348ff9f06c276f651a49

本代码用于挖掘主题的龙头股

  • 先由通联提供的有关主题的API获得所有主题ID,储存为文档20140601_20150123theme_list.txt
  • 由API函数DataAPI.ThemeTickersGet获得所有各个主题对应个股
  • 由相关个股的日涨幅和市值,计算主题的每天收益
  • 滚动计算主题5天的涨幅,找到主题涨幅最高的时间区间
  • 在这个时间区间内,计算主题相关个股的涨幅
  • 找到涨幅最高的个股,即为该主题的龙头股
  1. datetime.today()
  2. datetime.datetime(2015, 1, 24, 13, 28, 42, 799154)

读取主题id文件,获得所有主题的相关个股,储存在info

  1. f1 = read('20140601_20150123theme_list.txt') #从这个文档中读取所有的主题id
  2. themeId_list = f1.split(',')
  3. tk2id = lambda x:x+'.XSHG' if x[0]=='6' else x+'.XSHE'
  4. #由于ThemeTickersGet对于数据量有限制,一次调用1000个主题数据
  5. num_up = 1000 #每一次调取多少个主题的信息
  6. thm_tk_dic = {} #储存每个主题包含的个股
  7. tk_list = set([]) #tk_list储存了所有相关个股
  8. num = len(themeId_list)/num_up #一次调取num_up个主题,要调用num次
  9. beginDate = '20140601' #开始时间
  10. endDate = '20150123' #结束时间
  11. if num>0:
  12. info = pd.DataFrame({})
  13. for i in range(num):
  14. info_sub = DataAPI.ThemeTickersGet(beginDate=beginDate,endDate=endDate,themeID=themeId_list[i*num_up:(i+1)*num_up]) #获取主题相关的个股
  15. info = pd.concat([info,info_sub]) #将数据连接
  16. info_sub = DataAPI.ThemeTickersGet(beginDate=beginDate,endDate=endDate,themeID=themeId_list[(i+1)*num_up:])
  17. info = pd.concat([info,info_sub])
  18. else:
  19. info = DataAPI.ThemeTickersGet(beginDate=beginDate,endDate=endDate,themeID=themeId_list)

将主题与个股对应,thm_tk_dic储存了每个主题对应的个股,key是主题名称,value是与主题相关的个股列表

  1. info = info[['themeName','ticker','secShortName']] #只取这几列数据
  2. group_info = info.groupby('themeName') #根据主题名称分类
  3. for theme,group in group_info:
  4. theme_tk = group['ticker'].tolist()
  5. if len(theme_tk[0])!=6:
  6. continue
  7. if len(theme_tk)>10:
  8. thm_tk_dic[theme] = theme_tk #获得某个主题下相关的个股
  9. tk_list |= set(theme_tk) #所有的个股

利用DataAPI.SecIDGet获得个股对应的名称,便于最后展示​

  1. #获得个股代码与名称的对应
  2. tk_list = list(tk_list)
  3. num_name = len(tk_list)/1000
  4. if num_name>0:
  5. tk_name_pd = pd.DataFrame({})
  6. for i in range(num_name):
  7. sub = DataAPI.SecIDGet(ticker=tk_list[1000*i:1000*(i+1)],field='secShortName') #获取证券简称
  8. tk_name_pd = pd.concat([tk_name_pd,sub])
  9. sub = DataAPI.SecIDGet(ticker=tk_list[1000*(i+1):],field='secShortName')
  10. tk_name_pd = pd.concat([tk_name_pd,sub])
  11. else:
  12. tk_name_pd = DataAPI.SecIDGet(ticker=tk_list,field='secShortName')
  13. tk_name_dic = dict(zip(tk_name_pd.ticker,tk_name_pd.secShortName)) #获得个股代码与名字对应的字典,便于最后展示

获得所有股票在一段日期内的日行情数据,便于计算个股每日涨幅和主题涨幅

  1. #由于API对访问量有限制,每次只能调取50个股票的日线数据,故采用限制每次调用次数,循环调用的方法
  2. len_stk = 50 #每次调用len_stk只个股
  3. num_stk = len(tk_list)/len_stk #要调用num_stk次
  4. #获得tk_list中所有个股的日线信息
  5. if num_stk>0:
  6. mkt_stk_info = pd.DataFrame({})
  7. for i in range(num_stk):
  8. info = DataAPI.MktEqudGet(ticker=tk_list[i*len_stk:(i+1)*len_stk],beginDate=beginDate,endDate=endDate,field=['ticker','preClosePrice','closePrice','marketValue'])
  9. mkt_stk_info = pd.concat([mkt_stk_info,info])
  10. info = DataAPI.MktEqudGet(ticker=tk_list[(i+1)*len_stk:],beginDate=beginDate,endDate=endDate,field=['ticker','preClosePrice','closePrice','marketValue'])
  11. mkt_stk_info = pd.concat([mkt_stk_info,info])
  12. else:
  13. mkt_stk_info = DataAPI.MktEqudGet(ticker=tk_list,beginDate=beginDate,endDate=endDate,field=['ticker','preClosePrice','closePrice','marketValue'])
  14. mkt_stk_info = mkt_stk_info[['ticker','tradeDate','preClosePrice','closePrice','marketValue']]

计算主题每日涨幅

  1. thm_date_inc_dic = {} #记录了每个主题每天的涨幅,key是日期,value是主题涨幅
  2. for key in thm_tk_dic.keys():
  3. thm_date_inc_dic[key] = {}
  4. for theme,stocks in thm_tk_dic.items():
  5. mkt_info = mkt_stk_info[mkt_stk_info['ticker'].isin(stocks) ]
  6. mkt_info['increase'] = (mkt_info['closePrice']-mkt_info['preClosePrice'])/mkt_info['preClosePrice'] #计算主题涨幅
  7. gp_date = mkt_info.groupby('tradeDate')
  8. for date,group in gp_date:
  9. thm_inc = sum(group['marketValue']*group['increase'])/sum(group['marketValue']) #某天的主题收益
  10. thm_date_inc_dic[theme][date] = thm_inc

计算主题滚动5日的涨幅之和,找到主题涨幅最大的时间区间

  1. thm_date_inc_pd = pd.DataFrame(thm_date_inc_dic) #生成dataframe,index是日期,columns是主题名称
  2. window = 5 #统计5天的主题收益之和
  3. thm_5d_inc_pd = pd.rolling_sum(thm_date_inc_pd,window=window) #计算滚动和
  4. id_max_list_begin = thm_5d_inc_pd.dropna().values.argmax(axis=0) #由于最初的window-1行值为NA,舍弃之后得到的下标便是最大和的开始下标
  5. pl2date = lambda x,:list(thm_5d_inc_pd.index)[x:x+window] #由开始下标获得这段时间区间,即获得[2014-06-03,2014-06-04,...]这样的列表
  6. date_list = map(pl2date,id_max_list_begin)
  7. max_date_periods = {} #储存每个主题获得最高收益的时间区间
  8. for i in range(len(date_list)):
  9. theme = thm_date_inc_pd.columns[i] #主题名称
  10. date = date_list[i] #对应的时间区间
  11. max_date_periods[theme] = date

计算在上述时间区间内个股的涨幅,涨幅最大的即为该主题的龙头股

  1. thm_leadStk_dic = {} #记录每个主题的龙头股
  2. for theme,stock_list in thm_tk_dic.items():
  3. date_list = max_date_periods[theme]
  4. flt_thm_stk_info = mkt_stk_info[(mkt_stk_info['ticker'].isin(stock_list)) & (mkt_stk_info['tradeDate'].isin(date_list))] #获取这些个股在这段时期内的日线数据
  5. grouped = flt_thm_stk_info.groupby('ticker')
  6. stk_inc_dic = {}
  7. for stk,group in grouped:
  8. stk_inc = (group['closePrice'].iloc[-1]-group['preClosePrice'].iloc[0])/group['preClosePrice'].iloc[0] #获取个股在这段时间内的收益
  9. stk_inc_dic[stk] = stk_inc
  10. thm_leadStk_dic[theme] = sorted(stk_inc_dic.keys(),key=lambda x:stk_inc_dic[x],reverse = True)[0] #排序,获得该主题的龙头股

将主题和龙头股写成dataframe形式,便于展示

  1. thm_leadStk_pd = pd.DataFrame.from_dict(thm_leadStk_dic,orient='index').reset_index() #由字典生成dataframe
  2. thm_leadStk_pd.rename(columns={0:'ticker'},inplace=True) #重命名,便于下一步merge
  3. lead_tk_list = list(thm_leadStk_pd['ticker'])
  4. tk2nm = lambda x:tk_name_dic[x]
  5. #tk2nm = lambda x:
  6. lead_name_list = map(tk2nm,lead_tk_list)
  7. name_pd = pd.DataFrame({'shortname':lead_name_list})
  8. answer = pd.concat([thm_leadStk_pd,name_pd],axis=1)
  9. answer.rename(columns={'index':u'主题名称','ticker':u'个股代码','shortname':u'个股简称'},inplace=True) #重命名
  10. answer
主题名称个股代码个股简称
0金融机具股601818光大银行
1银联601818光大银行
2公路运输股601939建设银行
3小额贷款股601818光大银行
4LBS股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生意宝
17PE(化工)600028中国石化
18核电主设备股300411金盾股份
19兽药000826桑德环境
20沪港通股601099太平洋
21甲基叔丁基醚股000151中成股份
22体育文化601901方正证券
23品牌服装002503搜于特
24多晶硅股600151航天机电
25丁二醇股000151中成股份
26TVOS股300079数码视讯
27光电子材料002261拓维信息
28珠海航展600990四创电子
29农用机械股300159新研股份
1301德州本地股601106中国一重
1302制冷剂股000550江铃汽车
1303微信股600109国金证券
1304保健品600530交大昂立
1305抗寒600188兖州煤业
1306社保股002501利源精制
1307神舟十号601988中国银行
1308WAPI002439启明星辰
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福建南纸
  1. 1331 rows × 3 columns
  1. datetime.today()
  2. datetime.datetime(2015, 1, 24, 13, 33, 44, 786650)