Tushare Pro与Python实战:A股行情与财务数据获取全指南

📅 发布时间:2026/10/5 20:25:02
Tushare Pro与Python实战:A股行情与财务数据获取全指南
写这篇文章之前我先说个现实问题做量化分析或者单纯想研究A股的朋友十有八九都在数据获取上栽过跟头。要么是从第三方网站手动复制——慢、容易出错、格式乱七八糟要么是找一些付费数据源——价格不便宜个人玩玩根本扛不住还有一部分人守着老版Tushare不放结果接口老、数据不全、更新还慢。我两三年前也经历过这段折腾期后来切到Tushare Pro才算彻底安稳。这玩意儿免费能拿到的数据覆盖A股行情、财务指标、龙虎榜等多个维度关键是接口稳定代码写一次就可以长期复用。这篇文章我不讲虚的直接把怎么注册、怎么装库、怎么用Python调接口取数、怎么处理最常见的坑从头到尾给你捋一遍文中的代码都是我自己跑过能用的你照着抄就能跑出数据。我默认看这篇文章的你是这样的懂一点Python基础但没到精通程度想用A股行情和财务数据做分析、做研究或者为量化策略备数据以前可能被各种数据源坑过现在想找一套靠谱、免费、可持续的方案。如果你的情况跟这个描述基本吻合那Tushare Pro加Python这套组合拳应该是目前性价比最高的选择。1. 数据源选型为什么从老版Tushare迁移到Pro老版Tushare有很长一段时间几乎是国内个人量化爱好者的标配那时候没有太多选择老接口免费、不需要积分、直接pip装就能用。但是它的痛点也很明确数据字段少、更新频率跟不上、日线数据只保留有限历史、财务数据覆盖不完整而且接口服务时好时坏。我印象很深的一件事是有段时间老接口频繁超时靠它跑定时任务凌晨经常被报警邮件吵醒。Tushare Pro是团队在新架构上重写的一套数据服务解决的问题正好是老版的几个软肋。用一句话概括它用“积分制”替代了“完全免费无限制”用“结构化表接口”替代了“散装字段”用“增量更新快照”替代了“低频同步”。新用户注册后有基础积分能访问一部分核心接口日线行情、基础财务数据这些日常需求基本都能覆盖。如果后面有更高频或者更深度数据的需求可以通过完善资料、社区贡献等方式攒积分提升等级。积分制看起来是门槛其实是护城河。因为有了积分限制Tushare Pro对接口的并发、频率控制更有底气服务稳定性比老版好得多。我做了一个简单对比方便你理解两者差异维度老版TushareTushare Pro行情数据深度近一两年为主历史有缺失历史数据完整按交易日连续财务数据完整度字段有限更新慢三大报表、财务指标、业绩快报等分类齐全接口规范性松散参数不统一统一入参和返回格式文档清晰权限机制无限制但无保证积分制初始可覆盖核心接口典型使用方式一次性抓取按增量、按交易日持续拉取所以这个文章的主角是Tushare Pro不是老版。后面提到的所有接口和代码都以Pro版本为准。2. 环境准备注册Token、安装Python库与第一行取数代码2.1 注册账号并拿到你的专属TokenTushare Pro的所有数据请求都需要带上一个Token相当于你的身份凭证。注册流程没什么好说的用手机号注册、完善一下个人信息然后进入个人主页就能看到你的Token字符串一串长字母数字组合类似0e9d8c7b6a5f4e3d2c1b0a9f8e7d6c5b4a3f2e1d这种。Token非常重要别人拿到它就能消耗你的积分配额千万不要硬编码在代码里然后把代码发到公开仓库更不要往GitHub上传。一个稳妥的做法是把Token放到环境变量或者放在代码同目录的配置文件里并加入.gitignore。我自己的习惯是放在~/.tushare.conf这种本地权限严格的文件里然后代码中用os.environ去读取。你如果图省事写在代码顶部也能跑但注意别公开。2.2 安装Tushare库不要用老命令这一块是新手踩坑重灾区。你用pip install tushare安装的就是支持Pro接口的最新版Tushare库它兼容老接口也支持新接口。网上有些教程让你pip install tushare --upgrade这也没错但真正的关键点是版本号必须大于1.2.x最好直接用最新版。老版本库虽然也叫tushare但很多Pro接口根本不支持。建议你在虚拟环境里安装避免污染系统Python环境python -m venv tushare_env source tushare_env/bin/activate # Windows下是 tushare_env\Scripts\activate pip install --upgrade tushare pandas顺手把pandas装上Tushare Pro返回的数据是DataFrame格式pandas是标配。装完用下面的方式验证一下版本是否正常import tushare as ts print(ts.__version__)只要版本号在1.2.5以上后面代码基本都能跑。2.3 初始化连接与第一个请求拿到Token后初始化连接就三行代码import tushare as ts import pandas as pd # 初始化 pro ts.pro_api(你的token填在这里)然后拉一只股票最近几个交易日的日线数据验证整个链路是否通畅df pro.daily(ts_code000001.SZ, start_date20240101, end_date20240131) print(df.head()) print(df.shape)000001.SZ是平安银行的股票代码.SZ表示深圳市场.SH表示上海市场。如果返回了一个DataFrame包含trade_date、open、high、low、close、pre_close、change、pct_chg、vol、amount这些字段那说明环境完全OK可以往下走了。这里有一个容易忽略的点daily接口单次最多返回5000条记录而单次请求最大数据量是2000行超过会被截断。所以做长时间范围拉取的时候要么按年份循环要么按股票代码逐只拉不能指望一个接口调用就把所有数据拿全。这个我后面详细讲。3. 股票列表与交易日历所有数据操作的基石很多教程上来就教拉行情但真正做项目的时候你第一个需要的往往是两个基础表当天有多少只股票在交易、哪些交易日是可用的。这就像盖楼打地基没有这两张表后面所有操作都是瞎忙。3.1 获取全市场股票列表用stock_basic接口拿到全量股票基础信息# 获取所有上市股票的基本信息 stock_list pro.stock_basic(exchange, list_statusL, fieldsts_code,symbol,name,area,industry,market,list_date) print(stock_list.shape) print(stock_list.head())注意几个参数含义exchange指定交易所空字符串代表全部。你可以填SSE上交所、SZSE深交所、BSE北交所。list_status上市状态。L是上市D是退市P是暂停上市。做历史回测时应考虑包含退市股票避免幸存者偏差只看当前交易就填L。fields指定返回字段减少数据包体积。如果省略会返回所有字段比较罗嗦。这个接口返回的结果里ts_code是Tushare里的标准代码格式也是其他接口里最常用的关联键。我实际项目中会把这个表存到SQLite里每天收盘后更新一次后续所有股票代码的映射都查这张表。3.2 交易日历避免在非交易日踩坑另一个极其重要但容易被忽视的接口是trade_cal# 获取2024年所有交易日 cal pro.trade_cal(exchangeSSE, start_date20240101, end_date20241231) print(cal[cal[is_open] 1][cal_date].tolist()[:10])它返回一年的日历记录每个日期后面有个is_open字段1表示交易日0表示休市日。为什么要强调这个因为很多人拉数据的时候习惯用datetime.now()动态算日期然后直接去请求行情。但如果那天是周六、周日、国庆节接口会返回空数据或者报错程序就直接崩了。一个稳健的增量更新策略是先拿交易日历再基于日历去循环请求这样既不会漏数据也不会浪费请求次数。我见过有人每天拉行情前不管三七二十一先请求一遍最近14天的数据再本地去重这种做法又慢又浪费完全没必要。正确姿势是维护一张本地交易日表每次拉数据前计算出“上次本地数据日期”到“当前最近交易日”之间的交易日差集只拉差集部分。4. 核心实战用Python拉取A股行情数据行情数据是整个A股数据分析最基本的部分通常包括日线、周线、月线、复权因子等。Tushare Pro里面最常用的接口是daily、weekly、monthly此外还有adj_factor复权因子接口。我一个个过重点说复权因为这是很多人被坑得最多的地方。4.1 日线行情按股票还是按日期daily接口有两种常用姿势各有适用场景。方式一按股票代码拉取某只股票的时间序列。df pro.daily(ts_code600519.SH, start_date20200101, end_date20231231)这个适合研究单只股票或者少量股票时用。返回的记录里trade_date是升序排列的包含OHLCV开高低收量额等标准字段。方式二按交易日期拉取当天全市场行情快照。df pro.daily(trade_date20240603)这个适合做横截面分析比如算全市场当日所有股票的涨幅分布、成交量排名、筛选涨停股等。返回结果包含当天沪深两市所有交易中的股票。实际做数据分析项目时两种方式经常混合使用先用方式二拉全市场快照存库需要某只股票的历史序列时再本地filter而不是一遍遍请求接口。注意daily接口不带复权信息它返回的是未复权的原始价格。如果你直接拿它算收益率遇到分红送股的股票数据会出现断崖式跳空那种情况算出来的收益是错的。4.2 复权因子回测正确性的命根子复权是什么简单说股票分红、送转后股价会做除权除息处理导致价格出现人为的向下跳空。如果不做复权直接用原始价格计算的历史收益率曲线会严重失真尤其在回测时间跨度较长、涉及多次分红的股票上。就跟你量身高每次量的时候尺子都换了刻度量出来的数字没法直接比。Tushare Pro的复权因子在adj_factor接口adj pro.adj_factor(ts_code600519.SH, start_date20200101, end_date20231231) print(adj.head())返回的adj_factor是一个不断变化的因子序列通过它可以计算前复权和后复权价格。实际使用中直接把价格乘上因子再除以最新因子就得到前复权价。但更省事的方式是用ts.pro_bar方法它自动帮你处理复权。# 前复权 df_qfq ts.pro_bar(ts_code600519.SH, adjqfq, start_date20200101, end_date20231231) # 后复权 df_hfq ts.pro_bar(ts_code600519.SH, adjhfq, start_date20200101, end_date20231231) # 不复权 df_raw ts.pro_bar(ts_code600519.SH, adj, start_date20200101, end_date20231231)这里必须说明一点ts.pro_bar和pro.daily的时间参数格式可能有细微差别建议统一使用YYYYMMDD格式字符串传入避免踩坑。我自己实际使用时回测统一用前复权因为前复权价格能真实反映当前市值对应的价格水平做因子分析时也用前复权。但有一点要注意前复权计算依赖最新复权因子所以当股票发生新的分红除权后全历史复权价格会变化本地缓存数据需要重新拉取这个问题等你的策略跑起来后会遇到。4.3 分钟线与实时行情免费的边界在哪里很多人问Tushare Pro能拿分钟线吗能拿实时行情吗答案是可以但有门槛。分钟线接口通常需要更高的积分等级比如stk_mins接口新注册用户的积分不一定够。实时行情接口也有相应的权限控制。我的建议是如果你的需求以日线级别为主Tushare Pro的免费额度完全够用如果非要分钟级数据或者准实时tick免费方案里能用但比较局限积分不够的情况下可以先退而求其次用日线加复权因子做中低频策略。这个边界你自己心里要有数不要等到写了一半发现接口权限不够再回头换数据源那就被动了。5. 财务数据从财务指标到三大报表的完整取数路径财务数据是做基本面分析的基础。Tushare Pro的财务数据接口体系比较庞杂初次接触容易迷路。我按照“先概览、后明细”的顺序梳理一下。5.1 每日指标基本面筛选的快速通道daily_basic接口是基本面初筛利器一天一行包含PE、PB、PS、总市值、流通市值、换手率等常用指标basic pro.daily_basic(ts_code000001.SZ, start_date20240101, end_date20240201, fieldsts_code,trade_date,close,pe_ttm,pb,ps_ttm,total_mv,circ_mv) print(basic.head())这个接口的资金面意义在于它是按“日”更新的你可以在某一天拿到全市场所有股票的估值指标快照用来做截面的财务筛选。比如你想在2024年6月3日找出全市场PETTM小于20、PB小于3的股票直接用trade_date20240603一个请求拉全市场几百条记录然后本地过滤秒出结果。注意这里PE有pe和pe_ttm两种口径前者是静态市盈率后者是滚动市盈率做研究时尽量用pe_ttm它更能反映最新的盈利变化。总市值和流通市值的单位是万元不是元也不是亿元这个细节容易搞错。5.2 三大报表理解资产负债表、利润表、现金流量表除了每日指标Tushare Pro还提供完整的三大报表接口分别对应三个接口名报表类型接口名核心字段示例资产负债表balancesheet总资产、总负债、所有者权益利润表income营业收入、净利润、扣非净利润现金流量表cashflow经营现金流净额、投资现金流净额、筹资现金流净额调用方式大同小异以利润表为例income pro.income(ts_code000001.SZ, period20240331, fieldsts_code,ann_date,f_ann_date,end_date,report_type,revenue,operate_profit,total_profit,n_income) print(income.head())这里面坑很多我挑关键的讲。首先是end_date和ann_date的区别end_date是报告期截止日比如20240331表示2024年一季报ann_date是公告发布日期2024年一季报可能在4月底才发布。拉历史数据时一定要用ann_date过滤否则会出现“用未来数据”的前视偏差回测结果直接是假的。其次是report_type字段。同一报告期下同一家公司可能会返回多条记录比如一季报原始报告以及后续更新过的财报。通常在研究中使用report_type1的标准报表即可但如果公司发生过会计差错更正或重述你可能需要更复杂的处理。我一般会在拉取后按照ann_date排序去重只保留每个end_date最新发布的版本。5.3 财务指标的坑口径、单位与报告期这里集中说三个最容易出错的点。第一是单位。Tushare Pro的财务报表里金额字段单位是“元”但不同报表可能字段含义不同比如total_mv是“万元”而revenue是“元”混用的时候换算错了结果非常离谱。我在项目里统一做一个单位换算工具函数把所有金额统一转为“万元”或者“亿元”保证后续计算口径一致。第二是报告期的对齐。做多因子分析时你需要把财务数据和行情数据对齐但同一财务报告期对不同的股票来说发布日期是不一致的。处理方式是用ann_date作为发布日然后“向前填充”——也就是在公告发布日之后才能使用这份财报数据而不是简单用end_date去join行情。我最初写策略时就栽在这里把当年的一季报和当年的股价直接对齐后来发现策略看起来收益漂亮回测却很难盈利排查了半天才发现前视偏差。第三是TTM计算。如果你需要滚动市盈率或者滚动净利润而接口又没有直接提供那就需要自己用近四季财报累加。具体做法是取最新报告期净利润或营收加上去年同期对应报告期之前三季度的数据再减去最新报告期之前一年同期的数据稍微绕但这是标准做法。6. 龙虎榜数据获取每日热门股票的硬核细节龙虎榜是A股市场一个特色数据源它记录了每个交易日满足一定异动条件的股票及其买卖前五席位信息。做短线情绪分析、游资行为研究时龙虎榜数据价值很大。6.1 核心接口每日清单与机构买卖Tushare Pro里跟龙虎榜相关的接口不止一个早期不少人只知道top_list这个接口但后面又发现数据明细不全找来找去才知道还有另外几个配套接口。我梳理一下最常用的三个# 1. 每日龙虎榜明细按日期获取当日上榜股票和买卖席位 top_list pro.top_list(trade_date20240603) # 2. 龙虎榜机构成交明细获取机构专用账户的买卖情况 top_inst pro.top_inst(trade_date20240603) # 3. 每日龙虎榜汇总含上榜原因等 top_flist pro.top_flist(trade_date20240603)top_list返回的是当日每个上榜股票的买卖前五营业部名称、买入额、卖出额、净买额等top_inst专门过滤出机构专用席位的数据。机构专用席位在A股通常是公募、社保、保险等机构的交易通道跟踪它能在一定程度上观察大资金的动向。不过央行的公开数据和交易所的披露规则有一定延迟你拿到的数据也是T1盘后披露做不了盘中决策做盘后分析和复盘足够用了。top_flist则偏汇总包含股票代码、上榜原因、龙虎榜净买额、龙虎榜买入额等聚合信息适合快速筛选“当天哪些票被资金重点关注”。三个接口配合使用时通常先拿到top_flist的股票列表再对每只股票去top_list里挖细节。6.2 龙虎榜数据的实战用法与常见误区用法上常见的方向有两个一是看个股上榜后次日的表现——统计上涨概率、平均涨幅二是跟踪知名游资席位——比如某些固定营业部频繁出现在龙虎榜买方前五时可能暗示它对这只股票有较强预期。我自己做过一个统计把某营业部出现的日期和标的记录下来然后计算它们在随后3日内的超额收益分布样本足够多的话能看出一点游资偏好和持续性。但这个数据有个天然问题就是“幸存者偏差”。能上龙虎榜的股票本来就波动剧烈次日的走势跟市场环境、板块联动的关系也很大你不能把龙虎榜数据当成金手指它只是众多维度之一。另一个要注意的是龙虎榜数据披露的是营业部名义买卖很多人会用多个账户协同操作你去重时也会面临挑战目前没有特别完美的识别办法。6.3 爬取历史龙虎榜数据按日期循环由于top_list等接口单次只能按trade_date请求如果你要拉整年的龙虎榜就需要循环遍历一年中所有交易日# 获取2024年上证交易日历 cal pro.trade_cal(exchangeSSE, start_date20240101, end_date20241231) trade_days cal[cal[is_open] 1][cal_date].tolist() # 循环拉取每日龙虎榜明细 all_top_list [] for day in trade_days: try: one_day pro.top_list(trade_dateday) if one_day is not None and len(one_day) 0: all_top_list.append(one_day) print(f{day} 完成共 {len(one_day)} 条) except Exception as e: print(f{day} 请求失败: {e}) time.sleep(2) # 合并保存 result pd.concat(all_top_list, ignore_indexTrue) result.to_csv(top_list_2024.csv, indexFalse, encodingutf-8-sig)这段代码里有几个处理细节值得讲一是异常捕获后不要直接pass至少要打印出来否则某天数据丢了你在后面完全无感知二是请求失败时做短暂time.sleep重试给网络和接口一点缓冲时间三是在循环体中加一个简单的进度提示年份数据多的时候跑起来心里有数。用encodingutf-8-sig保存CSV是为了Excel打开不乱码——这是很多人容易忽视的细节Windows环境尤其要注意。还有一点别一次性把全年数据都塞到内存里再存盘。如果是一整年、每天几百条DataFrame合并起来倒还好如果是5年、10年的数据建议每拉完一个月就往数据库写一次避免内存溢出。7. 数据库存储与增量更新如何构建一个可持续的本地数据库前文所有内容都是在教你怎么“取数”但取完后的存储方案直接决定了你能不能长期用这套数据。我见过很多朋友用CSV存数据跑了三个月后文件管理一团糟不同日期数据版本还互相冲突。更好的方案是使用轻量级的SQLite零配置、单文件、支持SQL查询对个人项目来说足够了。7.1 表结构设计与建表语句以股票日线行情表为例设计如下表结构CREATE TABLE IF NOT EXISTS daily_price ( ts_code VARCHAR(10) NOT NULL, trade_date VARCHAR(8) NOT NULL, open FLOAT, high FLOAT, low FLOAT, close FLOAT, pre_close FLOAT, change FLOAT, pct_chg FLOAT, vol FLOAT, amount FLOAT, PRIMARY KEY (ts_code, trade_date) );这里用ts_code trade_date做联合主键天然防止重复数据。每次拉取数据后用INSERT OR REPLACE语法写入就能做到幂等更新——同一笔数据重复执行多次最终结果不会扭曲。7.2 增量更新的核心逻辑“增量更新”是本地数据库能不能长期运转的关键词。中国有几千只股票每天都全量拉一遍所有历史数据不仅浪费接口额度而且会拖垮程序性能。正确的思路是只在本地数据缺失或者发生除权需要重算复权时去请求缺失部分。一个简单的增量更新策略如下def fetch_daily_incremental(ts_code, conn, pro): # 1. 本地库里查询该股票的最新交易日期 latest conn.execute( SELECT MAX(trade_date) FROM daily_price WHERE ts_code ?, (ts_code,) ).fetchone()[0] # 2. 如果没有数据从上市日期开始拉否则从latest的下一天开始 if latest is None: start 19900101 # 或者从股票上市日期开始 else: start str(int(latest) 1) # 3. 当前日期 end time.strftime(%Y%m%d) # 4. 请求新数据 if start end: new_df pro.daily(ts_codets_code, start_datestart, end_dateend) if new_df is not None and len(new_df) 0: new_df.to_sql(daily_price, conn, if_existsappend, indexFalse)这样做有三个优点第一每日更新所花时间极短只处理新增数据第二接口请求次数大幅减少不容易撞到频率限制第三本地库始终保持一致和完整不需要反复全量重建。7.3 何时需要重建历史数据有一些情况特例——不只是新增日期那么简单而是要“重算历史”。典型的例子是前复权价格某只股票除权除息之后它的前复权因子会变化所有历史价格都会改变。所以你的更新任务里除了每日增量拉取行情还要定期检测该股票的adj_factor是否更新一旦发现最近复权因子与本地存储的版本不一致就要从Tushare重新拉取整段复权价格。这一块我实际项目里是单独做成了一个定时任务每周末跑一次成本不高且能保证回测数据源头没问题。8. 常见报错、积分限制与避坑技巧8.1 权限不足报错最常见的报错是类似“抱歉您没有访问该接口的权限。您的积分是xxx接口需要xxx分”这样的提示。这说明你的积分没达到该接口的要求。Tushare Pro的积分体系比较复杂被很多人吐槽过但转念一想这也是它在维持服务质量的必然选择免费而且无限制的接口很难保持稳定和高质量。遇到这种报错有几个处理方向先去官网完善个人资料。真实姓名、职业、使用目的这些信息填完后会赠送一部分积分通常能覆盖更多的低频接口。做社区任务发帖、贡献文档、参与开源项目都能积累积分。权衡需求如果只是偶尔用某个高积分接口可以考虑用别人封装好的接口轮询方案或者暂时放弃。这里我得提醒一句不要用网上流传的所谓“挂机脚本刷积分”之类的偏门方法那是拿自己账号开玩笑账号一旦被封之前维护的本地数据库和代码全部白搭。8.2 单次返回行数的上限很多接口单次返回数据行数有限制常见的是单次最多返回一定行数。日线接口按trade_date拉全市场时一天几千行是可以返回的但如果按ts_code拉一只股票的多年日线由于股票交易天数超过限制就必须做时间分段循环。我的经验是// 拉取一只股票的日线数据建议按年分段例如每年一个请求for year in range(2018, 2025): start_date f{year}0101 end_date f{year}1231 df_year pro.daily(ts_code600519.SH, start_datestart_date, end_dateend_date) # 处理、存储...每段拉下来后立刻写入数据库而不是全部拼装完了再存。8.3 网络超时与重试机制Tushare Pro的接口偶尔也会响应慢尤其在你高频率循环调用时可能触发它的频率限制。我没有死磕官方文档给的具体限频数字而是选择在代码里做“请求-重试-退避”的策略import time def fetch_with_retry(func, max_retries5, wait_seconds3, **kwargs): for attempt in range(max_retries): try: df func(**kwargs) if df is not None and len(df) 0: return df else: # 返回空结果时可能遇到限流 print(f第 {attempt 1} 次返回空准备重试) except Exception as e: print(f第 {attempt 1} 次异常: {e}) time.sleep(wait_seconds * (attempt 1)) return None这里的退避策略是重试间隔倍数递增第一次失败等3秒第二次等6秒第三次等9秒……给接口留出足够的恢复时间。实测下来这种方式能显著减少偶发请求失败导致的任务中断。8.4 数据完整性验证你以为拉下来数据就没事了吗最大的坑是Tushare返回的数据偶尔会有缺失或不一致比如某一天某只股票的成交量明显为0或者pre_close跟前一天close对不上。如果你不校验后面回测时就会出现莫名其妙的“涨停”或“跌停”。我建议在数据入库前做一个基础校验脚本# 检查pre_close是否等于前一天的close df_sorted df.sort_values(trade_date) df_sorted[pre_close_check] df_sorted[close].shift(1) mismatch df_sorted[abs(df_sorted[pre_close] - df_sorted[pre_close_check]) 0.01] if len(mismatch) 0: print(发现pre_close不一致记录:) print(mismatch[[trade_date, close, pre_close, pre_close_check]])这个校验很基础但极其有效能把你从“策略回测结果看起来很好但实盘亏惨了”的困境中解救出来。我自己的团队里数据质量监控是最高优先级任何新数据源接入前必须先过这一关。9. 实战案例把行情、财务、龙虎榜组合起来做一次个股体检前面讲了很多接口和代码片段这一节用一个完整的案例把它们串起来。目标是对指定股票做一份简单的“体检报告”涵盖行情走势、估值水位和近期龙虎榜资金动向。这样即看即用代码段也可以直接改改参数用于其他股票。9.1 获取行情数据与区间统计假设我们要分析600519.SH贵州茅台在2024年上半年的表现import tushare as ts import pandas as pd ts.set_token(你的token) pro ts.pro_api() df ts.pro_bar(ts_code600519.SH, adjqfq, start_date20240101, end_date20240630) df df.sort_values(trade_date) # 区间涨幅 start_price df.iloc[0][close] end_price df.iloc[-1][close] range_return (end_price / start_price - 1) * 100 print(f区间涨幅: {range_return:.2f}%) # 最大回撤 df[cummax] df[close].cummax() df[drawdown] df[close] / df[cummax] - 1 max_drawdown df[drawdown].min() * 100 print(f最大回撤: {max_drawdown:.2f}%)这里用了ts.pro_bar并指定adjqfq确保价格是复权后的才能正确计算区间涨幅和回撤。需要说明的是茅台这种常年分红送股的股票如果不做复权半年区间涨幅会被除权缺口干扰算出来误差巨大。9.2 拉取财务数据判断估值水位再用daily_basic拉估值指标basic pro.daily_basic(ts_code600519.SH, start_date20240601, end_date20240630, fieldstrade_date,close,pe_ttm,pb,total_mv,circ_mv) print(basic.sort_values(trade_date).tail())pe_ttm和pb结合历史区间来看能大致判断当前估值处于历史什么分位。我的习惯是从上市日起拉长周期的PE-TTM序列然后计算当前值处在过去5年或10年的多少百分位。手续费、税费等成本另说单就估值维度这个分数的上下边界和变化趋势比单看某一天的绝对值更有参考价值。9.3 检查龙虎榜资金动向检查该股票在观察期内是否上过龙虎榜# 拉取2024年上半年每日龙虎榜看看茅台是否在列 cal pro.trade_cal(exchangeSSE, start_date20240101, end_date20240630) trade_days cal[cal[is_open] 1][cal_date].tolist() target_code 600519.SH appeared [] for day in trade_days: try: one_day pro.top_list(trade_dateday) if one_day is not None and len(one_day) 0: hit one_day[one_day[ts_code] target_code] if len(hit) 0: appeared.append(hit) except Exception as e: print(f{day} 请求失败: {e}) continue if len(appeared) 0: hitted pd.concat(appeared, ignore_indexTrue) print(hitted[[trade_date, close, pct_change, l_buy, l_sell, net_amount]]) else: print(该股票在上半年没有登录龙虎榜)对茅台这种大盘股来说上龙虎榜本身概率低但这套代码对热门中小盘股就非常有效了可以直观看到自己关注的股票是否被资金重点博弈过。这个案例展示的核心思想是Tushare Pro不是某一个单独接口的集合而是可以交叉组合使用的数据体系。行情、估值、资金筹码三个维度的数据拼在一起就是一份相对立体、可以用作决策参考的个股快照。10. 关于免费、频率与长远使用的一些真心话写到最后还是想聊几句实在的。Tushare Pro确实是目前我接触过的对个人用户最友好的A股数据源之一注册门槛低基础数据免费可用接口覆盖面足够广社区生态也活跃。新用户刚开始用不要急着追求把每个接口都拉一遍而是从自己的实际需求出发先确定到底要用哪些数据再按需接入。关于免费额度不同接口有不同的积分门槛日常行情、基础财务、龙虎榜这类核心数据基本都能通过初始积分或者小幅任务获得使用权。但确实有部分高级接口需要较高积分这个现实你绕不开。我的建议是如果用量大优先从自己身上找优化空间——比如做好本地缓存、增量更新、按需取字段而不是反复全量请求如果确实需要高频或更高深度数据再考虑付费方案。还有一点不管用什么数据源都不要忽略数据质量校验。拿到的数据不是直接能进策略的必须经过清洗、对齐和校验。我见过太多人兴致勃勃地跑回测、看结果、上杠杆最后却发现数据里藏着前视偏差、复权错误、单位不一致这些基础问题。数据源提供的是原料做成什么菜、会不会吃坏肚子最终取决于自己的厨房管理水平。文章里所有代码逻辑都是我实际在用的精简版。你完全可以直接搭建一个属于自己的本地数据仓库然后按需扩展。做数据分析这条路数据永远是最底层的地基地基牢了上面才能盖楼。