用Python拆解年报数据:三指标验证万邦医药机构抢筹
发布时间:2026/8/31 3:13:11来源:尧图网络
机构为何盯上万邦医药年报里这三个数据我用 Python 拆给你看在股票社区里“机构抢筹”四个字几乎每天都会出现在各种标题里。但你只要多问一句“机构为什么买”“数据上该怎么验证”大多数人就答不上来了。多数人看到标题就跟着情绪走价格一跌又恐慌离场最终亏在没有验证的猜测里。其实这件事完全可以用代码拆开来看。上市公司的年报、季报是公开披露的里面包含股东结构、财务指标、现金流等大量硬数据。机构买入股票最终会在股东名册、持股比例和利润质量上留下痕迹。与其听别人讲“资金在进”不如写个脚本把数据拉下来自行检查一次。这篇文章以万邦医药为样本演示一套用 Python AkShare 做年报数据分析的完整流程。重点只拆三个数据股东户数变化、机构持股比例变动、净利润现金含量。文章会给出可运行的代码也会说明其中容易踩坑的地方比如接口版本变动、数据披露时滞、财务口径差异等。所有数据仅用于技术研究演示不构成任何投资建议。1. 这篇文章真正要解决的问题先说清楚这篇文章不回答“万邦医药能不能买”回答的是另一个问题——当市场都在讨论“机构抢筹”时怎么用公开数据验证这种说法。很多人在判断股票时依赖两个来源K线图和新闻标题。K线只能反映价格难以反映筹码分布新闻标题则是结果出现后才写出来的叙事天然带有滞后性和选择性。真正能用来验证机构行为的是上市公司定期报告里的三组数据股东户数、前十大股东持股情况和现金流量表数据。这个项目适合三类读者。第一类是普通投资者想摆脱道听途说学会自己读年报。第二类是量化或数据分析方向的开发者想练习把金融数据接口、pandas 处理、可视化汇总成一个完整项目。第三类是 Python 学习者想用一个贴近真实场景的项目来巩固数据清洗和指标计算能力。从技术角度看这套流程可以抽象为四步获取数据、清洗数据、计算指标、输出结论。四步跑通之后换任何一只股票都只需要改一行代码。这也是本文的价值所在——它不是一个一次性脚本而是一个可以复用的财务分析框架。2. 三个核心指标的底层逻辑与适用场景在写代码之前需要先把三个指标背后的逻辑讲清楚。否则代码跑完了你也不知道结果意味着什么。2.1 股东户数筹码集中还是分散股东户数通俗讲就是持有这只股票的人数。A 股市场的股东户数会定期披露通常每周或每月更新一次。这个指标的价值在于观察筹码分布。假设一只股票总股本不变股东户数持续下降说明持股者数量在减少人均持股数在上升筹码正在向少数人集中。这种集中状态往往对应大资金或机构在收集筹码机构建仓需要时间不会一次性扫货而散户在这个过程中往往因为震荡被洗出局户数就会下降。反过来股东户数快速上升通常意味着散户在大量涌入。这未必是坏事也可能是行情活跃的信号但在判断“机构是否抢筹”的时候户数下降比上升更有说服力。需要注意一点股东户数是一个结果而非原因。它只能告诉你筹码在集中还是分散无法告诉你集中到谁手里。所以要配合第二个指标来看。2.2 机构持股比例机构到底在加仓还是减仓“机构”不是一个抽象概念它在定期报告里对应具体的持股实体公募基金、社保基金、保险资金、券商自营、境外投资机构QFII等。它们买入股票后会出现在前十大股东或前十大流通股东名单中。计算逻辑很简单把前十大流通股东中的机构持仓数量加总除以流通股本就得到机构持股比例。再对比上一报告期的数值就能看出机构是在净买入还是净卖出。但这个指标有两个天然的局限性。第一是披露滞后年报数据反映的是 12 月 31 日的股东名册等我们看到时已经过去数月。第二是只披露前十大如果机构持仓量较小、排不进前十大就无法观察到。所以机构持股比例更适合作为中长线判断依据不适合用来捕捉短线资金动向。2.3 净利润现金含量报表利润的“含金量”第三个指标很多人会忽略但恰恰是辨别“好利润”和“纸面利润”的关键。净利润现金含量的计算公式为净利润现金含量 经营活动产生的现金流量净额 ÷ 净利润如果这个比值长期大于 1说明公司每赚 1 元净利润就有超过 1 元的经营现金流入账利润有真金白银支撑。如果比值长期低于 0.7甚至为负就说明利润可能沉淀在应收账款、存货或其他非现金项目里看起来赚钱实际上没有现金落袋。机构资金体量大对流动性和财务质量要求高现金流不健康的公司很难成为重仓对象。因此净利润现金含量是判断“机构为什么会看上这家公司”的重要辅助指标。三个指标单独看都有说服力但也都有漏洞。只看利润和现金流看不到谁在买只看股东户数看不到买入主体的性质只看机构持股又容易忽略筹码集中趋势。把三者合在一起才能构成一个相互验证的框架。3. 环境准备Python AkShare 数据源搭建开始实操之前先准备环境。本文所有代码基于 Python 3.8 及以上版本所有依赖都可以通过 pip 安装。核心依赖只有三个pandas负责数据处理和指标计算akshare负责从公开数据源抓取 A 股行情、财务和股东数据matplotlib负责绘图辅助观察趋势推荐使用国内镜像安装速度更快。pip install pandas akshare matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simpleAkShare 是当前 Python 生态里使用门槛比较低的金融数据接口库它把东方财富、新浪财经等公开数据源封装成了统一的 Python 方法不需要申请 API Key直接调用即可。但 AkShare 有一个特点需要提前说明它依赖上游网页接口财报页面结构一旦调整接口名称和返回字段就可能变化。所以本文代码如果直接运行报错优先检查 akshare 是否是最新版本并去官方文档搜索对应接口。pip install --upgrade akshare在代码里可以用下面的方式确认版本import akshare as ak print(ak.__version__)版本确认之后就可以开始写采集代码了。4. 数据采集一次抓全年报、股东与行情数据这一章分三步采集数据历史行情、财务指标、股东户数。代码都保持最小可用结构方便你复制后直接修改。4.1 获取个股历史行情历史行情不直接参与三个指标的计算但它可以用来辅助观察股价走势与股东户数变化之间的关系。# 文件路径fetch_price.py import akshare as ak import pandas as pd # 万邦医药的股票代码实际分析其他股票时替换即可 stock_code 301520 df_price ak.stock_zh_a_hist( symbolstock_code, perioddaily, start_date20220101, end_date20241231, adjustqfq ) print(df_price.tail(10))ak.stock_zh_a_hist是 AkShare 中稳定的接口之一返回日线行情。adjustqfq表示前复权会把分红送转因素计入价格避免除权导致价格突变影响判断。输出字段一般包括日期、开盘、收盘、最高、最低、成交量、成交额等。不同版本字段名可能略有差异建议先执行print(df_price.columns.tolist())查看列名。4.2 获取财务指标财务指标的获取有多种接口这里使用东方财富的财务分析指标接口它能一次返回多个报告期的数据字段比较全。# 文件路径fetch_financial.py import akshare as ak stock_code 301520 df_financial ak.stock_financial_analysis_indicator(symbolstock_code) # 查看列名定位需要的字段 print(df_financial.columns.tolist())运行后你会看到大量财务指标列包括每股收益、净资产收益率、营业总收入、净利润、经营活动产生的现金流量净额等。由于列名在不同版本中可能存在差异建议先打印列名再根据关键词筛选。如果你想要的是三大报表原始数据也可以使用新浪财经的财务摘要接口df_abstract ak.stock_financial_abstract(symbolsz301520) print(df_abstract.head())注意这里股票代码带上了sz前缀。深市股票用sz沪市股票用sh这个前缀在部分接口中不可省略。4.3 获取股东户数股东户数是判断筹码集中度的核心数据。AkShare 中可以通过股东户数接口获取它返回每次定期披露的户数和户数变化情况。# 文件路径fetch_holder.py import akshare as ak stock_code 301520 try: df_holder ak.stock_zh_a_gdhs(symbolstock_code) print(df_holder.tail(10)) except Exception as e: print(接口调用失败可能原因是 AkShare 版本过旧或接口名变更) print(e)这个接口在部分 AkShare 版本中返回值可能带市场前缀或者函数名有细微变化。如果运行报错不要急着改业务逻辑先升级 AkShare再到官方文档里搜索“股东户数”关键词核对函数名。到这里三类数据都有了。下面进入数据处理阶段。5. 数据处理计算三大核心指标数据抓到之后最重要的工作是把原始数据转换成可用于判断的指标。整个过程包括缺失值处理、字段筛选、计算变化率和合并结果。5.1 指标1股东户数变化率股东户数接口返回的数据一般是按报告期排列的每一行代表一次统计截止日的数据。我们需要计算“最新户数相对上一期的变化幅度”。# 文件路径calc_holder.py import pandas as pd # 假设 df_holder 已经通过 ak.stock_zh_a_gdhs 获取 # 先标准化列名不同版本可能叫“最新户数”或“股东户数” print(df_holder.columns.tolist()) # 将户数列转为数值类型 holder_col [col for col in df_holder.columns if 最新户数 in col] if holder_col: df_holder[户数] pd.to_numeric(df_holder[holder_col[0]], errorscoerce) # 计算环比变化率 df_holder[户数变化率] df_holder[户数].pct_change() * 100 # 只看统计截止日期、户数和变化率 result_holder df_holder[df_holder.columns[-3:]] print(result_holder.tail(10))判断逻辑是如果近几个报告期的户数变化率持续为负说明筹码在集中与“机构抢筹”的叙事方向一致如果户数变化率大幅为正说明散户在进场筹码反而在分散。5.2 指标2机构持股比例变动机构持股比例可以通过前十大流通股东数据计算。由于不同 AkShare 版本中机构持股接口差异较大这里给出一个通用步骤第一筛选出前十大流通股东中的机构实体典型的关键词包括“基金”“社保”“保险”“证券”“境外”等。第二将机构的持股数量加总除以当期流通股本得到机构持股比例。# 文件路径calc_institution.py import pandas as pd # 假设 df_holder_detail 是前十大流通股东明细 # 实际列名以接口返回为准这里做演示 # 需要的字段大致有股东名称、持股数量、流通股本、报告期 df df_holder_detail.copy() # 过滤出机构股东关键词可根据实际股东名调整 institution_keywords [基金, 社保, 保险, 证券, QFII, 香港中央结算] mask df[股东名称].apply( lambda x: any(k in str(x) for k in institution_keywords) ) df_inst df[mask] # 计算机构持股比例 df_inst[机构持股比例] df_inst[持股数量] / df_inst[流通股本] * 100 # 按报告期汇总 inst_ratio df_inst.groupby(报告期)[机构持股比例].sum().reset_index() print(inst_ratio)这里有一个容易踩坑的地方很多上市公司的大股东本身就是自然人股东或员工持股平台不要把它们当成机构。机构识别需要结合股东名称判断不能只看持股数量大就认为是机构。如果要在代码里简化识别可以先把所有非自然人和非关联方的大额股东视为广义机构再做人工复核。做研究时人工复核必不可少。5.3 指标3净利润现金含量净利润现金含量的计算只需要两个字段净利润和经营活动产生的现金流量净额。这两个字段大概率都在财务分析指标接口的返回结果中。# 文件路径calc_cash_ratio.py import pandas as pd # 从财务指标数据中筛选目标列 # 先打印列名再按关键词匹配 print(df_financial.columns.tolist()) net_profit_col [col for col in df_financial.columns if 净利润 in col and 元 in col] cashflow_col [col for col in df_financial.columns if 现金流量净额 in col] # 构建结果表 result_fin pd.DataFrame() result_fin[报告期] df_financial[日期] if 日期 in df_financial.columns else df_financial.iloc[:, 0] if net_profit_col and cashflow_col: result_fin[净利润] pd.to_numeric(df_financial[net_profit_col[0]], errorscoerce) result_fin[经营现金流净额] pd.to_numeric(df_financial[cashflow_col[0]], errorscoerce) result_fin[净利润现金含量] result_fin[经营现金流净额] / result_fin[净利润] print(result_fin.tail(10))需要强调的是财务上“净利润”和“经营现金流净额”可能存在单季报年化口径不一致的问题。做分析时优先用年报数据跨报告期比较时也要保证口径相同。6. 结果可视化与结论模板三个指标都计算出来后把它们放到一张图上观察趋势是最直观的验证方式。# 文件路径plot_summary.py import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False fig, axes plt.subplots(3, 1, figsize(12, 10), sharexFalse) # 1. 股东户数趋势 axes[0].plot(result_holder[统计截止日期], result_holder[户数], markero) axes[0].set_title(股东户数变化趋势) axes[0].tick_params(axisx, rotation45) # 2. 机构持股比例趋势 axes[1].plot(inst_ratio[报告期], inst_ratio[机构持股比例], markero) axes[1].set_title(机构持股比例变化趋势) axes[1].tick_params(axisx, rotation45) # 3. 净利润现金含量 axes[2].bar(result_fin[报告期].astype(str), result_fin[净利润现金含量]) axes[2].axhline(y1, colorred, linestyle--) axes[2].set_title(净利润现金含量红线为1.0参考线) axes[2].tick_params(axisx, rotation45) plt.tight_layout() plt.show()绘图本身不难真正有价值的是图形的解读模板。如果股东户数持续下降同时机构持股比例上升且净利润现金含量长期大于 1那么“机构抢筹”这个叙事就有了三重数据支撑。反之如果机构持股比例在上升但股东户数也在暴增说明筹码在分散这个时候的上涨更多是散户情绪驱动而不是机构吸筹。如果净利润现金含量长期低于 0.5即使机构持股比例在上升也要警惕机构可能是在赌困境反转而不是因为公司基本面扎实而买入。这两种逻辑对应的持有策略完全不同。记住图表的目的是辅助判断不是代替判断。任何单一图形信号都不能直接作为交易依据。7. 常见问题与排查思路在实际运行过程中最容易出问题的环节集中在数据源接口和字段匹配上。下面列出几个高频问题。问题现象可能原因排查方式解决方案调用 AkShare 接口报错AkShare 版本过旧或上游接口变更执行pip show akshare查看版本升级到最新版查阅官方文档搜索接口名返回数据的列名与示例不一致不同接口版本或不同数据源返回格式不同打印df.columns.tolist()检查列名按实际列名调整筛选逻辑股东户数出现大量 NaN部分报告期字段为空检查原始数据缺失情况用dropna()或向前填充处理财务指标中净利润为负数公司当期亏损检查报告期是否包含亏损季度负数时现金含量无意义需单独说明机构持股比例计算偏低只统计了前十大流通股东对比流通股本数据是否准确补充基金重仓或其他机构持仓数据源图形中文显示为方块matplotlib 缺少中文字体设置rcParams中文字体改用 SimHei 或系统中文字体还有一个常见误区是把“净利润现金含量 0”直接理解为造假。事实上处于高速扩张期的公司经营性现金流经常为负因为钱都压在了存货和应收账款上。也就是说现金流差不一定代表公司差但至少说明这家公司在现金创造能力上存在压力。分析时要结合行业和公司阶段来看。8. 数据边界、误用风险与合规提醒用年报数据验证机构行为看似客观但它存在几个天然的数据边界必须在分析时保持清醒。第一定期报告的数据有披露滞后。年报反映的是 12 月 31 日的股东名册等你看到数据时机构可能已经调仓。所以它更适合做中长线判断不适合做短线决策。第二前十大股东只是持仓的一部分。机构可以通过多个账户分散持股也可以持股未达到前十大标准但累计规模很大。因此机构持股比例是下限值不是准确值。第三这里用到的数据源都是抓取第三方财经网站数据质量和更新频率由上游决定。做研究可以但正式投资决策前建议以交易所和巨潮资讯网披露的原始 PDF 年报为准。最重要的一点是合规边界本文全部内容属于数据分析技术演示不构成买入、卖出或持有的投资建议。A 股市场风险较高任何决策都要基于完整的信息和自己的风险承受能力不要因为一篇数据文章就做出仓位调整。9. 总结与进阶方向现在你已经掌握了一套完整的年报数据分析流程从 AkShare 获取行情、财务和股东数据用 pandas 清洗并计算三大核心指标再通过可视化辅助判断机构行为。这套流程最大的价值是通用性把股票代码换成任何一家上市公司代码主体都不需要大改。下一步可以做的事情还有不少。第一把数据源扩展到北向资金和龙虎榜数据观察更细粒度的资金动向。第二用 NLP 方法解析年报中的“管理层讨论与分析”文本把定性信息也纳入分析框架。第三把三个指标封装成函数加上自动评分做成一个简单的财务体检工具。第四如果你对量化感兴趣可以把这个分析框架接入回测系统验证指标组合的历史有效性。这篇文章的核心内容建议收藏备用。等下一次再看到“机构疯狂抢筹”的标题时你至少知道去哪里找数据、怎么算指标以及如何判断新闻里的叙事是否经得起检验。工具和代码只是起点真正重要的是你开始用数据去追问结论的习惯。
网站建设高端定制企业官网