From e95d6608e95332c87cfd774fd70239a697210bc3 Mon Sep 17 00:00:00 2001 From: xiaowu Date: Sat, 15 Aug 2026 10:46:55 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=96=B0=E5=A2=9E=20Tushare=20?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=8F=82=E8=80=83=E6=96=87=E6=A1=A3=20+=20?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E8=87=AA=E6=A3=80=E8=84=9A=E6=9C=AC=EF=BC=88?= =?UTF-8?q?=E5=AE=9E=E6=B5=8B=E7=89=88=EF=BC=8C=E9=98=B2=E5=86=8D=E8=B8=A9?= =?UTF-8?q?=20daily=5Fvip=20=E4=B8=8D=E5=AD=98=E5=9C=A8=E7=9A=84=E5=9D=91?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- quantitative_data/tushare_api_check.py | 107 +++++++++++++++++ quantitative_data/tushare_api_reference.md | 128 +++++++++++++++++++++ 2 files changed, 235 insertions(+) create mode 100644 quantitative_data/tushare_api_check.py create mode 100644 quantitative_data/tushare_api_reference.md diff --git a/quantitative_data/tushare_api_check.py b/quantitative_data/tushare_api_check.py new file mode 100644 index 0000000..863d702 --- /dev/null +++ b/quantitative_data/tushare_api_check.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Tushare Pro 接口自检脚本 +========================= +检查当前 token 对常用接口的可用性,避免改代码时用到不存在的接口名/无权限接口。 + +用法(在 quantitative_data/ 目录下运行,自动读取 .env 中的 token): + /opt/quant-venv/bin/python tushare_api_check.py + /opt/quant-venv/bin/python tushare_api_check.py --token 你的token + +输出说明: + ✅ 可用 — 接口存在且有权限 + ❌ 40101 — 接口名不存在(如 daily_vip),别用这个接口名 + ❌ 40203 — 接口存在但当前 token 无权限(积分不够) + ❌ 其他 — 见错误码提示 +""" +import argparse +import json +import sys +import urllib.request + +API_URL = "http://api.tushare.pro" + +# 自检清单:接口名 -> 测试参数(用最小代价的参数) +CHECK_LIST = { + "stock_basic": {}, + "trade_cal": {"exchange": "SSE", "start_date": "20260101", "end_date": "20260131"}, + "daily": {"trade_date": "20260105"}, + "daily_vip": {"trade_date": "20260105"}, + "daily_basic": {"trade_date": "20260105"}, + "daily_basic_vip": {"trade_date": "20260105"}, + "adj_factor": {"trade_date": "20260105"}, + "adj_factor_vip": {"trade_date": "20260105"}, + "moneyflow": {"trade_date": "20260105"}, + "index_daily": {"ts_code": "000001.SH", "start_date": "20260105", "end_date": "20260105"}, + "income": {"ts_code": "000001.SZ", "period": "20251231"}, + "income_vip": {"ts_code": "000001.SZ", "period": "20251231"}, + "balancesheet": {"ts_code": "000001.SZ", "period": "20251231"}, + "balancesheet_vip": {"ts_code": "000001.SZ", "period": "20251231"}, + "cashflow": {"ts_code": "000001.SZ", "period": "20251231"}, + "cashflow_vip": {"ts_code": "000001.SZ", "period": "20251231"}, + "fina_indicator": {"ts_code": "000001.SZ", "period": "20251231"}, + "fina_indicator_vip": {"ts_code": "000001.SZ", "period": "20251231"}, +} + + +def get_token(args_token): + if args_token: + return args_token.strip() + try: + from config import TUSHARE_TOKEN + if TUSHARE_TOKEN: + return TUSHARE_TOKEN.strip() + except Exception: + pass + print("未找到 token:请加 --token 参数,或确认 .env 里 TUSHARE_TOKEN 已配置") + sys.exit(1) + + +def call_api(token, api_name, params): + body = json.dumps({ + "api_name": api_name, + "token": token, + "params": params, + "fields": "", + }).encode("utf-8") + req = urllib.request.Request(API_URL, data=body, headers={"Content-Type": "application/json"}) + with urllib.request.urlopen(req, timeout=30) as resp: + return json.loads(resp.read().decode("utf-8")) + + +def main(): + parser = argparse.ArgumentParser(description="Tushare 接口自检") + parser.add_argument("--token", default=None, help="Tushare token(默认读 .env)") + args = parser.parse_args() + + token = get_token(args.token) + print("=" * 64) + print(f"Tushare 接口自检 token前8位: {token[:8]}") + print("=" * 64) + + ok, fail = 0, 0 + for api_name, params in CHECK_LIST.items(): + try: + result = call_api(token, api_name, params) + code = result.get("code", -1) + msg = result.get("msg", "") + if code == 0: + print(f" ✅ {api_name:24s} 可用") + ok += 1 + else: + print(f" ❌ {api_name:24s} code={code} {msg}") + fail += 1 + except Exception as e: + print(f" ❌ {api_name:24s} 请求异常: {e}") + fail += 1 + + print("=" * 64) + print(f"结果: {ok} 可用, {fail} 不可用") + if fail: + print("提示: 40101=接口名不存在(别用这个名) 40203=无权限(积分不够)") + sys.exit(1 if fail else 0) + + +if __name__ == "__main__": + main() diff --git a/quantitative_data/tushare_api_reference.md b/quantitative_data/tushare_api_reference.md new file mode 100644 index 0000000..5912f6f --- /dev/null +++ b/quantitative_data/tushare_api_reference.md @@ -0,0 +1,128 @@ +# Tushare Pro 接口参考(实测版) + +> 更新时间:2026-08-15 +> 账号积分:5120(爸爸账号实测) +> 官方文档:https://tushare.pro/document/2 (积分说明 doc_id=108) + +## 一、速查表(当前账号实测结果) + +| 接口名 | 用途 | 实测结果 | 说明 | +|---|---|---|---| +| `stock_basic` | 股票列表 | ✅ 可用 | 低权限,120积分即可 | +| `trade_cal` | 交易日历 | ✅ 可用 | 按交易所拉取 | +| `daily` | 日线行情 | ✅ 可用 | 按 trade_date 全市场需2000积分 | +| `daily_basic` | 每日指标(估值) | ✅ 可用 | 同上 | +| `adj_factor` | 复权因子 | ✅ 可用 | 同上 | +| `moneyflow` | 资金流向 | ✅ 可用 | 按 trade_date 全市场 | +| `index_daily` | 指数日线 | ✅ 可用 | | +| `income` | 利润表 | ✅ 可用 | | +| `income_vip` | 利润表(VIP) | ✅ 可用 | 5000积分档可用 | +| `balancesheet` | 资产负债表 | ✅ 可用 | | +| `balancesheet_vip` | 资产负债表(VIP) | ✅ 可用 | | +| `cashflow` | 现金流量表 | ✅ 可用 | | +| `cashflow_vip` | 现金流量表(VIP) | ✅ 可用 | | +| `fina_indicator` | 财务指标 | ✅ 可用 | | +| `fina_indicator_vip` | 财务指标(VIP) | ✅ 可用 | | +| `daily_vip` | — | ❌ 40101 接口名不存在 | **Tushare 无此接口,别用!** | +| `adj_factor_vip` | — | ❌ 40101 接口名不存在 | **Tushare 无此接口,别用!** | +| `daily_basic_vip` | — | ❌ 40203 无访问权限 | 存在但当前账号不可用 | + +⚠️ 重要教训:**不是所有接口都有 _vip 版本**。写代码前先用 +`tushare_api_check.py` 自检,别想当然加 `_vip` 后缀。 + +## 二、常用接口详解 + 示例 + +统一用法(示例在 quantitative_data/ 目录下运行,自动加载 .env): + +```python +import tushare as ts +from config import TUSHARE_TOKEN # 从 .env 读取 + +ts.set_token(TUSHARE_TOKEN) +pro = ts.pro_api() +``` + +### 1. daily 日线行情 +```python +# 按交易日拉全市场(推荐,一次调用全市场,需2000积分) +df = pro.daily(trade_date='20260814') # 返回当天所有股票 + +# 按单只股票拉区间(120积分即可) +df = pro.daily(ts_code='000001.SZ', start_date='20260801', end_date='20260814') +``` +返回字段:ts_code, trade_date, open, high, low, close, pre_close, +change, pct_chg, vol, amount + +### 2. trade_cal 交易日历 +```python +df = pro.trade_cal(exchange='SSE', start_date='20260101', end_date='20260814') +# exchange: SSE上交所 / SZSE深交所 +# 返回 is_open(1开市/0休市), pretrade_date(上一交易日) +``` + +### 3. stock_basic 股票列表 +```python +df = pro.stock_basic(exchange='', list_status='L', # L上市/D退市/P暂停 + fields='ts_code,symbol,name,industry,list_date') +``` + +### 4. daily_basic 每日指标(估值/换手) +```python +df = pro.daily_basic(trade_date='20260814') # 全市场单日 +df = pro.daily_basic(ts_code='000001.SZ', start_date='20260101', end_date='20260814') +``` + +### 5. adj_factor 复权因子 +```python +df = pro.adj_factor(trade_date='20260814') # 全市场单日 +df = pro.adj_factor(ts_code='000001.SZ', start_date='20260101', end_date='20260814') +``` + +### 6. moneyflow 资金流向 +```python +df = pro.moneyflow(trade_date='20260814') # 全市场单日 +df = pro.moneyflow(ts_code='000001.SZ', start_date='20260101', end_date='20260814') +``` + +### 7. index_daily 指数日线 +```python +df = pro.index_daily(ts_code='000001.SH', start_date='20260101', end_date='20260814') +# 常用指数:000001.SH上证 / 399001.SZ深成 / 000300.SH沪深300 / 000905.SH中证500 +``` + +### 8. 财务三表 + 指标(income / balancesheet / cashflow / fina_indicator) +```python +# 按股票拉区间(start_date/end_date 为报告期,格式YYYYMMDD) +df = pro.income(ts_code='000001.SZ', start_date='20250101', end_date='20260814') +df = pro.balancesheet(ts_code='000001.SZ', start_date='20250101', end_date='20260814') +df = pro.cashflow(ts_code='000001.SZ', start_date='20250101', end_date='20260814') +df = pro.fina_indicator(ts_code='000001.SZ', start_date='20250101', end_date='20260814') + +# VIP 版按报告期拉全市场(一次一个季度,最高效) +df = pro.income_vip(period='20260331') +df = pro.cashflow_vip(period='20260331') +# period 格式:0331/0630/0930/1231 + 年份,如 20260331 +``` +返回关键字段:ann_date(公告日), f_ann_date(实际公告日), end_date(报告期) + +## 三、错误码速查 + +| 错误码 | 含义 | 处理 | +|---|---|---| +| `40101` | 请指定正确的接口名 | **接口名不存在**(如 daily_vip)→ 查官方文档/自检脚本 | +| `40203` | 没有接口访问权限 | 接口存在但积分不够 → 升级积分或换普通接口 | +| `40001` | token 无效 | 检查 .env 里 token 是否正确/被重置 | +| `40002` | 积分不足 | 需要更多积分 | +| `20002` | 请求频率超限 | 加 sleep 间隔重试 | + +## 四、自检脚本 + +```bash +# 在 quantitative_data/ 目录下运行(自动读 .env 的 token) +/opt/quant-venv/bin/python tushare_api_check.py + +# 或指定 token +/opt/quant-venv/bin/python tushare_api_check.py --token 你的token +``` + +输出每个接口的可用状态,改 importer 代码前后各跑一次最保险。