基金持股数据统计分析用Python追踪机构持仓变化与抱团效应基金持股数据是追踪机构动向的重要窗口。每只股票被多少基金持有、基金在增持还是减持这些信息能帮我们判断机构对某只股票的态度。我之前写了一套基金持股分析工具把全市场的基金持股数据系统地分析了一遍。数据用的是基金持股接口time/f10/jjcg/{股票代码}返回该股票最近500家左右的基金持股情况按截止日期倒序排列每周六9点更新。字段包括基金名称、持有数量、持有市值等。importjsonimportosimportpandasaspdimportnumpyasnpfromcollectionsimportdefaultdict data_dirD:/stock_datadefread_jjcg(dm):file_pathos.path.join(data_dir,time,f10,jjcg,dm)ifnotos.path.exists(file_path):returnNonewithopen(file_path,r,encodingutf-8)asf:datajson.load(f)returndatadefread_gplist():file_pathos.path.join(data_dir,base,gplist)withopen(file_path,r,encodingutf-8)asf:datajson.load(f)returndata第一个分析单只股票的基金持股变化。追踪某只股票被多少基金持有基金在增持还是减持。defanalyze_fund_holding(dm):dataread_jjcg(dm)ifnotdataorlen(data)0:returnNoneby_datedefaultdict(list)foritemindata:jzrqitem.get(截止日期,)by_date[jzrq].append(item)datessorted(by_date.keys(),reverseTrue)iflen(dates)2:returnNonelatest_datedates[0]prev_datedates[1]latest_fundsby_date[latest_date]prev_fundsby_date[prev_date]latest_namesset(f.get(基金名称,)forfinlatest_funds)prev_namesset(f.get(基金名称,)forfinprev_funds)new_inlatest_names-prev_names exitedprev_names-latest_names latest_total_volsum(f.get(持有数量,0)forfinlatest_funds)prev_total_volsum(f.get(持有数量,0)forfinprev_funds)vol_change(latest_total_vol-prev_total_vol)/prev_total_volifprev_total_vol0else0result{dm:dm,latest_date:latest_date,prev_date:prev_date,latest_fund_count:len(latest_funds),prev_fund_count:len(prev_funds),new_funds:len(new_in),exited_funds:len(exited),vol_change:vol_change}iflen(new_in)len(exited)*2andvol_change0.1:result[signal]基金大幅增持result[score]72eliflen(exited)len(new_in)*2andvol_change-0.1:result[signal]基金大幅减持result[score]33else:result[signal]基金持仓稳定result[score]52returnresult第二个分析全市场基金抱团检测。找出被最多基金持有的股票这些就是抱团股。defscan_fund_clustering(top_n30):gp_listread_gplist()results[]forgpingp_list:dmgp[股票代码]mcgp[股票名称]dataread_jjcg(dm)ifnotdataorlen(data)0:continueby_datedefaultdict(list)foritemindata:jzrqitem.get(截止日期,)by_date[jzrq].append(item)ifnotby_date:continuelatest_datemax(by_date.keys())latest_fundsby_date[latest_date]total_valuesum(f.get(持有市值,0)forfinlatest_funds)results.append({dm:dm,mc:mc,fund_count:len(latest_funds),total_value:total_value,date:latest_date})dfpd.DataFrame(results).sort_values(fund_count,ascendingFalse).head(top_n)print(基金持股数量TOP{}.format(top_n))print(df.to_string(indexFalse))returndf被基金持有数量最多的股票就是市场公认的核心资产。当这些股票的基金持有数量开始下降时说明抱团在瓦解。第三个分析基金净增持扫描。找出基金净增持最多的股票。defscan_fund_net_increase(top_n30):gp_listread_gplist()results[]forgpingp_list:dmgp[股票代码]mcgp[股票名称]resultanalyze_fund_holding(dm)ifresultisNone:continueifresult.get(score,50)65:results.append({dm:dm,mc:mc,fund_count:result[latest_fund_count],new_funds:result[new_funds],vol_change:result[vol_change],score:result[score]})dfpd.DataFrame(results).sort_values(vol_change,ascendingFalse).head(top_n)print(基金净增持TOP{}.format(top_n))print(df.to_string(indexFalse))returndf第四个分析头部基金动向追踪。专门追踪几家知名公募基金的持仓变化。deftrack_top_funds(fund_names):gp_listread_gplist()resultsdefaultdict(list)forgpingp_list:dmgp[股票代码]mcgp[股票名称]dataread_jjcg(dm)ifnotdata:continuelatest_datemax(item.get(截止日期,)foritemindata)foritemindata:ifitem.get(截止日期,)!latest_date:continuefund_nameitem.get(基金名称,)fortargetinfund_names:iftargetinfund_name:results[target].append({dm:dm,mc:mc,vol:item.get(持有数量,0),value:item.get(持有市值,0)})forfund_name,holdingsinresults.items():dfpd.DataFrame(holdings).sort_values(value,ascendingFalse).[:10]print({}最新重仓股TOP10.format(fund_name))print(df.to_string(indexFalse))returnresults几个使用经验。第一基金持股数据是季度披露的有滞后性但基金的动作往往领先股价1到2个月。第二基金持有数量变化比持有市值变化更有参考价值因为市值会随股价波动。第三头部基金的动向比小基金更准建议重点追踪易方达、中欧、景顺长城等知名公募。第四基金抱团股瓦解前会有征兆——基金数量还在增加但股价不涨了说明新基金在接盘但老基金在撤退。我用的数据来源是ig50的本地数据接口基金持股接口每周六更新覆盖500家左右的基金做这种机构持仓分析很方便。接口说明time/f10/jjcg/{股票代码} - 基金持股本地路径数据存放目录/time/f10/jjcg/{股票代码}更新频率每周六9点更新耗时约9小时数据格式[{}…]按截止日期倒序主要字段截止日期、基金名称、持有数量股、持有市值元等数据覆盖每只股票最近500家左右的基金持股情况资料参考ig50