Tushare Pro 这名字做量化的人应该都不陌生,但我发现很多新手在 pip install tushare 装好库、拿到 token 之后,第一行代码就栽在“抱歉,您没有访问该接口的权限”这个报错上。这个提示特别误导人,乍一看像是代码写错了,实际上是账号权限和积分体系的问题。这篇文章我就是想把这些年的踩坑经验一次性说清楚,从安装、token 配置,到这个权限问题到底怎么解决,以及后面怎么判断自己能用哪些接口、数据落地怎么安排,都走一遍。
先说结论,这个报错基本上不是因为你的代码有问题,而是 Tushare Pro 把数据接口拆成了不同的权限等级,你的账号积分不够,或者这个接口需要单独申请,你还没申请。搞懂这套规则比多写几行代码有用得多。
1. 项目背景与整体思路
1.1 Tushare Pro 是什么
Tushare Pro 是一个开源的金融数据接口平台,严格来说是 Tushare 的升级版。老版本 Tushare 用起来很简单,一个接口全搞定,但后来数据源合规压力变大,再加上高频调用的成本问题,Tushare Pro 改成了按接口、按积分控制权限的模式。
它的数据覆盖面非常广,股票日线、分钟线、财务数据、宏观经济、期货、基金、数字货币,甚至另类数据都有。对做量化研究的人来说,它是目前国内最容易接入、数据质量还算稳定的免费数据源之一。只要你注册账号、完成实名认证,就能拿到一个 token,靠这个 token 调接口拉数据。
需要注意,它跟直接用爬虫抓股票数据不一样,Tushare Pro 本质上是别人维护好的数据服务,你只是通过 API 去查,数据经过了清洗和格式化,省掉了很多预处理麻烦。比如日线数据它会自动处理复权因子,你可以直接拿到前复权或后复权价格,这个对回测来说非常重要。
1.2 为什么会出现“接口权限”问题
这个问题的根源在于 Tushare Pro 的权限体系。它不像普通 API 那样,你注册了就能调所有接口,而是用“积分”来决定你能用哪些接口,以及每分钟能调多少次。
“抱歉,您没有访问该接口的权限”这个报错,我见过的大致分三种情况:第一,你的账号积分低于该接口要求的最低分值;第二,这个接口需要单独申请,比如某些高频或特殊数据;第三,接口权限已经开通,但你的 token 初始化位置不对,或者用了旧版 API 的调用方式。前两种情况最常见。
很多新手不理解为什么一个数据接口还要搞这么多限制,其实它的逻辑很直白——数据库查询是有成本的,免费开放意味着服务器得承受大量请求,高分用户和付费用户理应获得更多资源。这套机制虽然用起来不爽,但确实保证了数据更新的持续性。
1.3 内容适配人群
这篇文章适合以下几类人:刚接触 Tushare Pro,照着网上的老教程写代码却发现报权限错误的;因为积分不够被卡在某个接口上,想知道有没有别的办法绕过去或者快速提分的;已经在用 Tushare Pro,但想更系统地管理自己的调用频率和数据落地方案的。
如果你是纯新手,建议先把安装和 token 配置部分看明白,再去研究积分问题。如果你已经能正常拉数据,只是偶尔碰到某个接口提示无权限,那可以直接跳到第 3 节和第 5 节,我列了完整的排查思路。
2. 安装准备与环境配置
2.1 环境要求和安装命令
Tushare Pro 的 Python 库叫tushare,支持 Python 3.6 以上版本,我建议直接上 Python 3.9 或 3.10,太老的版本有些依赖可能装不上。它本身不重,核心依赖是pandas和requests,所以如果你已经在做数据分析,基本不会引入额外麻烦。
安装命令很简单:
pip install tushare如果你用国内镜像源,可以这样装,速度会快很多:
pip install tushare -i https://pypi.tuna.tsinghua.edu.cn/simple装完之后验证一下:
import tushare as ts print(ts.__version__)能打印出版本号就说明环境没问题。我遇到过装完直接 import 报错的情况,基本都是 pandas 版本冲突,先把 pandas 升级一下就行。
2.2 Token 的获取与初始化
拿到 token 的前提是注册 Tushare Pro 账号并完成实名认证。注册之后,登录网页,在“个人主页”里能看到一个 token 字符串,通常是一串很长的字母加数字。
拿到 token 之后,初始化方式有两种:
方式一,直接在代码里赋值:
import tushare as ts ts.set_token('你的token字符串') pro = ts.pro_api()方式二,用配置文件方式,把 token 写到本地文件:
tushare set_token '你的token字符串'然后每次在代码里直接调ts.pro_api()就行。我建议用方式二,因为 token 不用硬编码进代码里,方便后续代码分享或上版本管理。
初始化完成之后,可以先用最简单的接口试一下:
df = pro.trade_cal(exchange='SSE', start_date='20240101', end_date='20240110') print(df)这个接口是交易日历,对积分要求很低,一般注册了就能用。如果它能正常返回数据,说明你的 token 配置没问题。
2.3 验证安装是否成功
很多人在ts.pro_api()这步就卡住了,报错信息往往是Authentication failed或者抱歉,您没有访问该接口的权限。注意,这两个报错含义完全不同:前者是 token 本身有问题,后者是权限不够。
验证 token 是否有效有个小技巧,直接访问 Tushare Pro 网页端的 API 调试页面,选一个自己确定有权限的接口测试。如果网页端能返回数据,代码端不行,那问题大概率出在ts.set_token()是否在ts.pro_api()之前执行。这个顺序错了,你用的就是默认 token,肯定没权限。
3. 权限问题的核心细节解析
3.1 权限错误的实际含义
那句“抱歉,您没有访问该接口的权限”来自 Tushare Pro 服务端的统一拦截逻辑。当你向服务端发请求时,服务端会先校验 token 是否合法,然后校验积分是否满足这个接口的最低要求,然后再校验这个接口是否对你单独开放。
拿它文档里提到的 doc_id=108 来说,这页专门讲的是接口权限和积分的关系,里面有一张列表,每个接口对应不同积分档位。比如有些基础行情接口只要 120 积分就能用,有些分钟线数据要 2000 积分,有些特别详细的财务数据可能要求更高。
这个报错就像一个门禁系统,你的工牌(token)能进公司大门,但有些机房(高积分接口)需要额外的门禁卡。你要么升级门禁卡(充积分),要么换一个自己能进的机房(用低分接口)。
3.2 积分体系与权限申请
Tushare Pro 的积分获取方式有几种:注册初始积分、完成实名认证加积分、每日签到加积分、充值购买会员。说实话,它的积分体系有点复杂,不同时期规则还会微调,但核心逻辑是一样的:积分越高,能用的接口越多,每分钟调用次数也越多。
我这里有一个大概的对应关系,具体数值请以 Tushare Pro 官方文档为准:
| 数据类别 | 常见接口 | 大致最低积分要求 |
|---|---|---|
| 交易日历 | trade_cal | 120 积分 |
| 股票基础信息 | stock_basic | 120 积分 |
| 日线行情 | daily | 120 积分 |
| 周线月线 | weekly / monthly | 120 积分 |
| 分钟线 | stk_mins | 2000 积分以上 |
| 财务数据 | income / balancesheet | 2000 积分开始 |
| 资金流向 | moneyflow | 5000 积分以上 |
| 龙虎榜 | top_list | 5000 积分以上 |
如果你想申请某个接口的权限,在网页端“数据权限”页面能找到申请入口,有些接口直接点击申请即可,有些需要满足积分条件之后自动开放。注意,极少有接口是“永远无法开放”的,只要你积分到了,基本都能用。
3.3 接口权限的正确使用方式
解决了是否能用的问题,还得搞清楚怎么用。我见过很多人拿着一个接口文档就开始写代码,结果字段不对、参数不对,又反过来以为是权限问题。实际上 Tushare Pro 的接口参数是强校验的,少传一个参数或者传错格式都会报错。
以日线行情为例,标准的调用格式是:
df = pro.daily(ts_code='000001.SZ', start_date='20240101', end_date='20240131')它要求ts_code必须是带后缀的股票代码,比如000001.SZ是平安银行,600000.SH是浦发银行。不带后缀或者后缀写错,服务端会直接拒绝,有时候报的就是参数缺失。
所以当你看到权限错误时,先别急着充积分,检查一下是不是接口本身的参数问题。正确的做法是去官方文档把接口定义、参数列表、输出字段全部看一遍,再在网页端的调试工具里实际跑一次,确保自己的请求格式没问题。
4. 实操过程:从请求到数据落地
4.1 调用基础行情接口
我建议新手第一个实战接口直接用daily,它的权限门槛低、返回字段丰富、和后续计算指标关联紧密。
完整的演示代码如下:
import tushare as ts import pandas as pd ts.set_token('你的token字符串') pro = ts.pro_api() df = pro.daily(ts_code='000001.SZ', start_date='20240101', end_date='20240131') print(df.head()) print(df.columns)返回的结果是一个 DataFrame,包含以下几个常用字段:ts_code、trade_date、open、high、low、close、pre_close、change、pct_chg、vol、amount。
这里的vol单位是手,amount单位是千元,很多人在计算量能指标时会搞错,我建议拿到数据后先做单位换算再存库。
4.2 处理权限异常的完整代码方案
考虑到很多人的积分确实不够,我写一段容错代码,至少让你知道问题出在哪个环节:
import tushare as ts import time ts.set_token('你的token字符串') pro = ts.pro_api() def fetch_data_with_retry(func, **kwargs): max_retry = 3 for i in range(max_retry): try: df = func(**kwargs) return df except Exception as e: print(f"第{i+1}次调用失败: {e}") if "没有访问该接口的权限" in str(e): print("当前账号积分不足或接口未开通,建议去Tushare Pro网页端查看具体权限") return None elif "每分钟" in str(e): print("触发频率限制,等待60秒后重试") time.sleep(60) else: time.sleep(5) return None df = fetch_data_with_retry(pro.daily, ts_code='000001.SZ', start_date='20240101', end_date='20240131')这里用了一个简单重试机制,核心思想是区分错误类型。没有访问该接口的权限这个错误重试多少次都没用,直接提示用户去网页端处理。如果是频率限制,就等一段时间再重新拉。
4.3 参数选择与数据落地
数据拉下来之后,你大概率不会只用一次,所以我建议把数据落成本地文件或者数据库,避免反复调用占用积分和频率。
最省事的方法是存成 CSV:
df.to_csv('daily_000001.csv', index=False)如果数据量比较大,我推荐存 SQLite,或者直接上 MySQL。我自己项目的模式是每天增量拉取当日数据,追加到数据库里,然后做定时任务。Tushare Pro 的接口很适合增量更新,因为每条数据都有交易日字段,按日期去重比较容易。
有一部分人会用 pandas 的to_sql直接写入 MySQL,这需要装sqlalchemy和pymysql:
from sqlalchemy import create_engine engine = create_engine('mysql+pymysql://root:password@localhost:3306/quantdata') df.to_sql('daily', engine, if_exists='append', index=False)这里有个注意点:to_sql如果第一次写入,会自动建表,但字段类型可能需要手动调整,特别是日期字段最好转成datetime类型,否则后面做查询筛选会麻烦。
5. 常见问题与排查技巧实录
5.1 权限报错排查清单
我根据自己的经验,整理了一个排错顺序,按照这个顺序检查,基本能解决 90% 的权限报错问题:
| 排查步骤 | 操作 | 说明 |
|---|---|---|
| 1. Token 是否有效 | 网页端调试工具测试 | 排除 token 本身失效 |
| 2. Token 初始化顺序 | 确认set_token()在pro_api()之前 | 顺序反了等于没设置 |
| 3. 接口积分要求 | 看文档确认最低积分 | 积分不够就是权限错误 |
| 4. 接口是否单独申请 | 网页端查数据权限页面 | 部分接口需要手动开通 |
| 5. 参数是否完整 | 核对 ts_code 格式和日期参数 | 参数错误有时也提示无权限 |
我强烈建议先做第 3 步和第 4 步。积分不够的情况,去个人主页看自己的积分,对照文档要求就能确认;接口需要单独申请的,在数据权限页面直接点申请,一般几分钟到一天内会批复。
5.2 积分与频率限制的避坑指南
很多人以为积分够了一切就顺畅了,其实还有一个隐藏限制:每分钟调用次数。即使你有权限,短期内疯狂调接口,也会触发流量限制,报错信息同样会带有“权限”或“频率”相关字眼。
我实测下来,普通 120 积分档位的日线接口,一分钟大概能调几十次,看起来不少,但如果你写循环拉几千只股票的日线,很快就会被限流。
我的经验是做好三重防护:第一,单次循环里加time.sleep(0.2)之类的延时;第二,做好失败重试和退避机制;第三,批量拉数据时先拉列表,再按日期范围分桶去请求,避免一次性 pull 太多数据。这样既能稳定拉数据,也不会把服务器打爆。
另外一个常见误区是重复拉历史数据。如果你只是做日线级别的回测,最好把历史数据全量拉一次存本地,之后每天增量更新,不要每次跑脚本都全量拉一遍,既浪费积分又容易触发限流。
5.3 其他实用经验
最后说几个网上很少提到的细节:
第一,Tushare Pro 返回的日期字段是字符串格式,不是 datetime。做回测前建议统一转一下:
df['trade_date'] = pd.to_datetime(df['trade_date'])第二,ts_code的股票代码后缀不是随便写的,SH和SZ分别代表上交所和深交所,但创业板和科创板要用SZ和SH区分,这本身没毛病。不过北交所的代码后缀是BJ,千万别搞混。
第三,Tushare Pro 的pro_bar接口可以方便地获取复权数据,但它的参数和pro.daily不完全一样。使用复权数据时,建议直接调用ts.pro_bar(),它会自动处理复权因子,省得你自己计算:
df = ts.pro_bar(ts_code='000001.SZ', adj='qfq', start_date='20240101', end_date='20240131')第四,如果你要拉全市场股票列表,用stock_basic接口,但记得加list_status='L'参数,只获取上市状态的股票,避免退市的股票混进你的股票池。
第五,关于积分提升,如果你是个人学习用,每天签到加完善个人资料也能慢慢攒积分,但如果你要高频使用分钟线和财务数据,我建议直接考虑付费服务,省下的时间比积分值钱得多。
就我个人的感受来说,Tushare Pro 的数据质量和稳定性在免费数据源里算是良心了,它唯一让人头疼的就是这层权限门槛。不过换个角度想,正是因为有这套机制,它才能长期稳定地提供服务,而不是被少数人刷爆。你只要花一次时间搞懂积分和权限规则,后面所有接口都是一个套路,调 token、看权限、写代码、落地数据,流程非常成熟。