企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# 主题龙头类 > 来源: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) ```