ashareapi-pi 0.2.6 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,127 +1,128 @@
1
- # 端点清单(32 个)
2
-
3
- - **统一前缀**:`https://api.ashareapi.com/v1`
4
- - **统一信封**:`{ ok, endpoint, tier, elapsed_ms, source, data }` —— 只有这 6 个键
5
- - ⚠️ **`structured` / `tables` 是【条件字段】,不是每个端点都有**:**只有 `data` 是 Markdown 文本时才附**
6
- (`market-overview` · `changedist` · `lhb` · `sector` · `sector-valuation` · `bond` · `etf` · `screen` · `macro`)。
7
- **其余端点没有这两个键** → `body["structured"]` 会 **KeyError**,**一律用 `body.get("structured")`**。
8
- - ⚠️ **3 个端点信封不同**(都**没有 `data`**):`/v1/health` = `{ok, uptime_s, data_ready, tiers}` ·
9
- `/v1/challenge` = `{challenge, difficulty, expires_in, how_to}` · `/v1/usage` = `{ok, day, calls_today, tier, total_calls, total_quota, total_left, daily_quota, per_min}`
10
- - **参数带 `*` = 必填**
11
- - **实时规格**:`GET https://api.ashareapi.com/openapi.json`(本文件据其生成)
12
-
13
- ---
14
-
15
- ## 一、免费端点(无需 Key,5 个数据端点 + 2 个工具端点)
16
-
17
- | 端点 | 参数 | 返回要点 |
18
- |---|---|---|
19
- | `/v1/quote` | `code*` | 实时行情:`last` 现价 / `open/high/low` / `volume`(手)/ `amount`(元)/ `turnover` 换手率% / `date`。**最新一根 = 当日实时** |
20
- | `/v1/kline` | `code*` · `period`(day/week/month) · `count`(默认 30,最大 **1212**;**匿名最多 250**)| OHLCV 历史 K 线。**只有日/周/月,无分钟级**。价格口径**固定为前复权**(除权除息日不跳空;无 `adjust` 参数)—— **不要再自己复权**(会二次复权)|
21
- | `/v1/hot` | `limit`(默认 30,**上限 50**)| 全市场热搜榜(A股/美股/ETF):关注度排名 + 涨跌幅 |
22
- | `/v1/market-overview` | `type`(summary/trade/interval/technical/margin/**valuation**/**rotation**) | 大盘画像。`valuation` = 中证全指 PE/PB/PS **历史百分位**;`rotation` = 风格轮动(大小盘/成长价值)。⚠️ `type=updown` 是 **T-1 口径**,涨跌家数请用 `/v1/changedist` |
23
- | `/v1/changedist` | 无 | **当期**涨跌家数 / 涨跌停家数 / 停牌 / 成交额 / 区间分布 —— **市场广度推荐入口** |
24
- | `/v1/health` | 无 | `data_ready=true` 表示数据通道可用(不含内部实现细节)|
25
- | `/v1/challenge` | `difficulty` | PoW 挑战(匿名提额用)。解 nonce 后带 `X-PoW: <challenge>.<nonce>`,匿名配额 5 → 60 次/分(**只提每分钟次数,每日条数上限不变**)|
26
-
27
- ---
28
-
29
- ## 二、行情与技术(需 Key)
30
-
31
- | 端点 | 参数 | 返回要点 |
32
- |---|---|---|
33
- | `/v1/technical` | `code*` | MA / MACD / KDJ / RSI / BOLL 全家桶 |
34
- | `/v1/chip` | `code*` | 筹码分布与持仓成本(获利盘 / 套牢盘比例)|
35
- | `/v1/orderbook` | `code*` | **五档盘口(order book)**:买一~买五 / 卖一~卖五的**价 + 挂单量(手)**。字段:`b1_p`/`b1_v`~`b5_p`/`b5_v`(买档)、`a1_p`/`a1_v`~`a5_p`/`a5_v`(卖档)。⚠️ **秒级快照(10 秒缓存)· 盘中才有意义**;量单位是**手**(×100 = 股);**跌停买档全 0 / 涨停卖档全 0**(正常)|
36
- | `/v1/snapshot` | `code*` | **全字段行情画像(35 字段)**:`code/name/sec_type/currency/status` + 价格(`price/prev_close/open/high/low/avg_price/change/change_pct/amplitude/speed`)+ 量(`volume/amount/turnover/outer_vol/inner_vol/volume_ratio`)+ 估值(`pe_ttm/pe_dynamic/pe_static/pb`)+ 市值股本(`float_market_cap/total_market_cap/float_shares/total_shares`)+ 涨跌停(`limit_up/limit_down`)+ 盘口(`bid/ask/bid_ask_diff`)+ `time`。⚠️ **与 quote 分工**:quote 轻(8 字段)免费 / snapshot 全(**35 字段**)付费,**只要现价用 quote 更轻**;✅ **计费=次数**:要估值+市值+股本+涨停价**多项**时,本端点 1 次搞定——比分别调 quote/valuation/orderbook **更省次数**。⚠️ **仅 A 股**(港股/美股字段布局不同,用 quote)——**传其他市场返回空,不返回错数据**|
37
- | `/v1/search` | `q*` | 按名称/代码搜股票、基金、板块 —— **用户只给名称时先搜代码** |
38
- | `/v1/profile` | `code*` | 公司简况:上市日期 / 主营业务 / 所属行业 |
39
-
40
- ## 三、财务
41
-
42
- | 端点 | 参数 | 返回要点 |
43
- |---|---|---|
44
- | `/v1/finance` | `code*` · `num`(期数)| 利润表 / 资产负债表 / 现金流量表(多期)。营收 / 净利 / 毛利率 / 负债。⚠️ **`data` 是【表列表】`[[行...], [行...], ...]`**(外层=表,内层=行)→ **先按表索引再按行**:`data[0][0]["..."]` |
45
- | `/v1/dividend` | `code*` · `years` | 分红送转历史:每股分红 / 送股 / 除权日 |
46
- | `/v1/shareholder` | `code*` | 十大股东 / **股东户数(筹码集中度)** / 机构持仓。⚠️ **`data` 是【多段结构】**:`{code, market, tables: [{title, slug, rows}], data: {slug: rows}}`,slug = `top10_holders` / `top10_float_holders` / `holder_count` |
47
-
48
- ## 四、资金与交易(核心)
49
-
50
- | 端点 | 参数 | 返回要点 |
51
- |---|---|---|
52
- | **`/v1/fund`** | `code*` | ⭐ **一接口拿全交易面**:主力资金(当日/5/10/20 日净流入 + 全市场排名)+ 龙虎榜(上榜原因 / 买卖总额 / **营业部明细**)+ 大宗交易 + 融资融券。**问"主力资金/资金流/龙虎榜"优先用它**。⚠️ `data` 是**扁平 dict**(不是多段):`{date, close, main_net, main_net_5d/10d/20d, main_rank, lhb, lhb_details, block_trades, margin, industry_rank}` |
53
- | `/v1/lhb` | `type`(institution/hotmoney/activeseat) · `date` | 龙虎榜**分榜**:机构榜(机构数 / 机构买入 / 净买)· 游资榜 · 活跃席位榜 |
54
- | `/v1/margin-trade` | `code`(**必填**,支持 `sh600667,sz000651` 批量)· `date` | 融资余额 / 买入 / 偿还 / 融券。未披露日上游会给出原因 |
55
- | `/v1/block-trade` | `code` · `date` | 大宗交易:成交价 / 折溢价 / 量 / 买卖方营业部 |
56
- | `/v1/events` | `code*` | 个股事件总览:**42 类**(大宗 / 龙虎榜 / 回购 / 定增 / 分红 / 业绩 / 解禁 …)|
57
- | `/v1/calendar` | `date` · `limit` | **个股**事件日历(分红派息 / 解禁 / 财报披露排期)。**不是宏观日历**(宏观用 `/v1/macro`)。⚠️ **`data` 是【多段结构】**:`{tables: [{title, slug, rows}], data: {slug: rows}}`,**按事件类型分段保序**;slug 取值 = `financial_report` / `dividend` / `ipo` / `meeting` / `lockup_release` / `rights_issue` |
58
-
59
- ## 五、板块与产业链
60
-
61
- | 端点 | 参数 | 返回要点 |
62
- |---|---|---|
63
- | `/v1/sector` | 无 | 行业 / 概念 / 地域板块涨幅榜 + 领涨股 |
64
- | `/v1/sector-valuation` | `code*`(`pt01801780` 形式)| 申万板块 PE/PB/PS/PCF + 股息率 + **历史百分位** |
65
- | `/v1/industry-chain` | `mode`(list/graph/stock) · `topic` · `code` | `list` = **183 个主题** · `graph&topic=X` = 图谱(关联个股 + 节点 + 上中下游)· `stock&code=X` = 该股所属链(主题/节点/位置/**关联度**/业务描述)|
66
-
67
- ## 六、可转债 / ETF / 新股
68
-
69
- | 端点 | 参数 | 返回要点 |
70
- |---|---|---|
71
- | `/v1/bond` | `code*`(`sh113052`)| 转债完整条款:溢价率 / 转股价值 / **双低值** / **强赎触发价** / 回售触发价 / 转股价 / 正股 / 到期日 / 信用评级 |
72
- | `/v1/etf` | `code*`(`sh510300`)| ETF 行情 / 规模 / 溢折率 / 资金流 |
73
- | `/v1/ipo` | `days` | 新股发行 / 申购 / 中签 / 上市日历 |
74
-
75
- ## 七、选股与宏观
76
-
77
- | 端点 | 参数 | 返回要点 |
78
- |---|---|---|
79
- | `/v1/screen` | `expr` 或 `preset` · `limit` · `orderby` · `desc` · `market` | **因子选股**。`expr` 多因子交集:`intersect([PE_TTM > 0, PE_TTM < 20, ROETTM > 15])`;`preset` 22 个官方预设(**大小写/下划线不敏感**:`low_pe` = `LowPE`)。常用因子:PE_TTM / PB / PS_TTM / TotalMV / DividendRatioTTM(估值)· ROE / ROETTM / ROIC / GrossIncomeRatioTTM(盈利)· OperatingRevenueGrowRate / NPParentCompanyYOY(成长)· CurrentRatio / DebtAssetsRatio(负债)· NetOperateCashFlowTTM(现金流)|
80
- | `/v1/macro` | `region`(cn/us/jp/eu/hk) · `names` | 宏观:GDP / CPI / PMI / LPR / 国债收益率 / 财政 |
81
- | `/v1/dehydrated` | `mode`(list/detail) · `symbol` · `limit` | 券商研报脱水摘要 |
82
- | `/v1/usage` | 无 | 当前 Key 的今日调用次数 / 剩余总量 / 到期时间 / 限流额度 |
83
-
84
- ---
85
-
86
- ## 返回形态:`data` 有四种形状(32 端点全量)
87
-
88
- **程序化处理前必须先判形状** —— `data` **不是**永远同一个类型,写死 `data[0]["x"]` 会在 `finance` / `calendar` 上炸。
89
-
90
- | 形状 | 长这样 | 哪些端点 | 怎么读 |
91
- |---|---|---|---|
92
- | **① 对象数组** | `[{"col": val}, ...]` | 多数:`quote` `kline` `hot` `technical` `chip` `orderbook` `snapshot` `profile` `dividend` `margin-trade` `ipo` | `for row in data: row["field"]` |
93
- | **② 表列表** | `[[行...], [行...]]`(外层=表,内层=行)| `finance`(利润表 / 资产负债表 / 现金流量表)| `data[表号][行号]["字段"]` —— **先按表索引** |
94
- | **③ 多段结构** | `{"tables": [{"title","slug","rows"}], "data": {"<slug>": rows}}` | `shareholder`(另带 `code`/`market`)· `calendar` | `data["tables"]` 保序分段;`data["data"]["<slug>"]` 便捷索引 |
95
- | **④ Markdown 字符串** | `"\| 列 \| 列 \|\n..."` | 9 个(见信封说明)+ `events` · `dehydrated` | 优先读同响应的 `structured` / `tables`(**若存在**);不存在才正则解析 |
96
-
97
- **特殊 dict(不属于上面四类)**:`fund` = 扁平 `{date, close, main_net, main_net_5d/10d/20d, main_rank, lhb, lhb_details, block_trades, margin, industry_rank}` ·
98
- `industry-chain?mode=list` = `{mode, topics}`。
99
-
100
- **空结果的三种表现**(都**不是**故障,`ok:true`):`data = []`(如 `block-trade` 当天无成交)· `data` 是含"数据为空"的 Markdown(`events`)· 多段结构里 `tables = []`。
101
-
102
- **推荐写法(四种形状通吃)**:
103
-
104
- ```python
105
- def rows_of(body):
106
- d = body.get("data")
107
- if isinstance(d, dict) and "tables" in d: # ③ 多段结构
108
- return [r for t in d["tables"] for r in (t.get("rows") or [])]
109
- if isinstance(d, list) and d and isinstance(d[0], list): # ② 表列表
110
- return d[0] # 或按表号取
111
- return body.get("structured") or d # ① / ④(④ 优先用 structured)
112
- ```
113
-
114
- ---
115
-
116
- ## 代码格式(`code` 参数)
117
-
118
- | 写法 | 说明 |
119
- |---|---|
120
- | `sh600667` | 沪市(sh)· 深市(sz)· 北交所(bj)· 港股(hk)· 美股(us)|
121
- | `600667.SH` | 后缀写法 |
122
- | `600667` | 纯 6 位(按首位推断:5/6→sh · 0/3→sz · 4/8→bj)|
123
- | `pt01801780` | **板块**代码(申万板块,用于 `sector-valuation`)|
124
- | `sh113052` | **可转债**代码 |
125
- | `sh510300` | **ETF** 代码 |
126
-
127
- **官方 SDK 会自动归一化三种股票写法**;直接调 HTTP 时建议统一用 `sh600667` 形式。
1
+ # 端点清单(33 个)
2
+
3
+ - **统一前缀**:`https://api.ashareapi.com/v1`
4
+ - **统一信封**:`{ ok, endpoint, tier, elapsed_ms, source, data }` —— 只有这 6 个键
5
+ - ⚠️ **`structured` / `tables` 是【条件字段】,不是每个端点都有**:**只有 `data` 是 Markdown 文本时才附**
6
+ (`market-overview` · `changedist` · `lhb` · `sector` · `sector-valuation` · `bond` · `etf` · `screen` · `macro`)。
7
+ **其余端点没有这两个键** → `body["structured"]` 会 **KeyError**,**一律用 `body.get("structured")`**。
8
+ - ⚠️ **3 个端点信封不同**(都**没有 `data`**):`/v1/health` = `{ok, uptime_s, data_ready, tiers}` ·
9
+ `/v1/challenge` = `{challenge, difficulty, expires_in, how_to}` · `/v1/usage` = `{ok, day, calls_today, tier, total_calls, total_quota, total_left, daily_quota, per_min}`
10
+ - **参数带 `*` = 必填**
11
+ - **实时规格**:`GET https://api.ashareapi.com/openapi.json`(本文件据其生成)
12
+
13
+ ---
14
+
15
+ ## 一、免费端点(无需 Key,5 个数据端点 + 2 个工具端点)
16
+
17
+ | 端点 | 参数 | 返回要点 |
18
+ |---|---|---|
19
+ | `/v1/quote` | `code*` | 实时行情:`last` 现价 / `open/high/low` / `volume`(手)/ `amount`(元)/ `turnover` 换手率% / `date`。**最新一根 = 当日实时** |
20
+ | `/v1/kline` | `code*` · `period`(day/week/month/season/year/**m1/m5/m15/m30/m60/m120**) · `count`(默认 30,最大 **1212**;**匿名最多 250**)· `start`/`end`(仅 day 与分钟线,须配对)| OHLCV 历史 K 线。⚠️ **分钟线属付费层**(日/周/月/季/年免费),窗口近 1 个月,不支持 北交所/期货/外汇。复权口径**由服务端固定**(无 `adjust` 参数):日线及以上前复权(除权除息日不跳空),分钟线不复权 —— **不要再自己复权**(会二次复权)|
21
+ | `/v1/minute` | `code*` · `days`(`1` 当日 · `5` 近 5 个交易日,**只有这两档**)| **分时**:盘中每分钟的价格与累计成交量。⚠️ 与 `/v1/kline` 的**分钟 K 线不是一回事**(前者分时、后者 OHLC 蜡烛)。⚠️ **付费端点** |
22
+ | `/v1/hot` | `limit`(默认 30,**上限 50**)| 全市场热搜榜(A股/美股/ETF):关注度排名 + 涨跌幅 |
23
+ | `/v1/market-overview` | `type`(summary/trade/interval/technical/margin/**valuation**/**rotation**) | 大盘画像。`valuation` = 中证全指 PE/PB/PS **历史百分位**;`rotation` = 风格轮动(大小盘/成长价值)。⚠️ `type=updown` 是 **T-1 口径**,涨跌家数请用 `/v1/changedist` |
24
+ | `/v1/changedist` | 无 | **当期**涨跌家数 / 涨跌停家数 / 停牌 / 成交额 / 区间分布 —— **市场广度推荐入口** |
25
+ | `/v1/health` | 无 | `data_ready=true` 表示数据通道可用(不含内部实现细节)|
26
+ | `/v1/challenge` | `difficulty` | PoW 挑战(匿名提额用)。解 nonce 后带 `X-PoW: <challenge>.<nonce>`,匿名配额 5 → 15 次/分(**只提每分钟次数,每日条数上限不变**)|
27
+
28
+ ---
29
+
30
+ ## 二、行情与技术(需 Key)
31
+
32
+ | 端点 | 参数 | 返回要点 |
33
+ |---|---|---|
34
+ | `/v1/technical` | `code*` | MA / MACD / KDJ / RSI / BOLL 全家桶 |
35
+ | `/v1/chip` | `code*` | 筹码分布与持仓成本(获利盘 / 套牢盘比例)|
36
+ | `/v1/orderbook` | `code*` | **五档盘口(order book)**:买一~买五 / 卖一~卖五的**价 + 挂单量(手)**。字段:`b1_p`/`b1_v`~`b5_p`/`b5_v`(买档)、`a1_p`/`a1_v`~`a5_p`/`a5_v`(卖档)。⚠️ **秒级快照(10 秒缓存)· 盘中才有意义**;量单位是**手**(×100 = 股);**跌停买档全 0 / 涨停卖档全 0**(正常)|
37
+ | `/v1/snapshot` | `code*` | **全字段行情画像(35 字段)**:`code/name/sec_type/currency/status` + 价格(`price/prev_close/open/high/low/avg_price/change/change_pct/amplitude/speed`)+ 量(`volume/amount/turnover/outer_vol/inner_vol/volume_ratio`)+ 估值(`pe_ttm/pe_dynamic/pe_static/pb`)+ 市值股本(`float_market_cap/total_market_cap/float_shares/total_shares`)+ 涨跌停(`limit_up/limit_down`)+ 盘口(`bid/ask/bid_ask_diff`)+ `time`。⚠️ **与 quote 分工**:quote 轻(8 字段)免费 / snapshot 全(**35 字段**)付费,**只要现价用 quote 更轻**;✅ **计费=次数**:要估值+市值+股本+涨停价**多项**时,本端点 1 次搞定——比分别调 quote/valuation/orderbook **更省次数**。⚠️ **仅 A 股**(港股/美股字段布局不同,用 quote)——**传其他市场返回空,不返回错数据**|
38
+ | `/v1/search` | `q*` | 按名称/代码搜股票、基金、板块 —— **用户只给名称时先搜代码** |
39
+ | `/v1/profile` | `code*` | 公司简况:上市日期 / 主营业务 / 所属行业 |
40
+
41
+ ## 三、财务
42
+
43
+ | 端点 | 参数 | 返回要点 |
44
+ |---|---|---|
45
+ | `/v1/finance` | `code*` · `num`(期数)| 利润表 / 资产负债表 / 现金流量表(多期)。营收 / 净利 / 毛利率 / 负债。⚠️ **`data` 是【表列表】`[[行...], [行...], ...]`**(外层=表,内层=行)→ **先按表索引再按行**:`data[0][0]["..."]` |
46
+ | `/v1/dividend` | `code*` · `years` | 分红送转历史:每股分红 / 送股 / 除权日 |
47
+ | `/v1/shareholder` | `code*` | 十大股东 / **股东户数(筹码集中度)** / 机构持仓。⚠️ **`data` 是【多段结构】**:`{code, market, tables: [{title, slug, rows}], data: {slug: rows}}`,slug = `top10_holders` / `top10_float_holders` / `holder_count` |
48
+
49
+ ## 四、资金与交易(核心)
50
+
51
+ | 端点 | 参数 | 返回要点 |
52
+ |---|---|---|
53
+ | **`/v1/fund`** | `code*` | ⭐ **一接口拿全交易面**:主力资金(当日/5/10/20 日净流入 + 全市场排名)+ 龙虎榜(上榜原因 / 买卖总额 / **营业部明细**)+ 大宗交易 + 融资融券。**问"主力资金/资金流/龙虎榜"优先用它**。⚠️ `data` 是**扁平 dict**(不是多段):`{date, close, main_net, main_net_5d/10d/20d, main_rank, lhb, lhb_details, block_trades, margin, industry_rank}` |
54
+ | `/v1/lhb` | `type`(institution/hotmoney/activeseat) · `date` | 龙虎榜**分榜**:机构榜(机构数 / 机构买入 / 净买)· 游资榜 · 活跃席位榜 |
55
+ | `/v1/margin-trade` | `code`(**必填**,支持 `sh600667,sz000651` 批量)· `date` | 融资余额 / 买入 / 偿还 / 融券。未披露日上游会给出原因 |
56
+ | `/v1/block-trade` | `code` · `date` | 大宗交易:成交价 / 折溢价 / 量 / 买卖方营业部 |
57
+ | `/v1/events` | `code*` | 个股事件总览:**42 类**(大宗 / 龙虎榜 / 回购 / 定增 / 分红 / 业绩 / 解禁 …)|
58
+ | `/v1/calendar` | `date` · `limit` | **个股**事件日历(分红派息 / 解禁 / 财报披露排期)。**不是宏观日历**(宏观用 `/v1/macro`)。⚠️ **`data` 是【多段结构】**:`{tables: [{title, slug, rows}], data: {slug: rows}}`,**按事件类型分段保序**;slug 取值 = `financial_report` / `dividend` / `ipo` / `meeting` / `lockup_release` / `rights_issue` |
59
+
60
+ ## 五、板块与产业链
61
+
62
+ | 端点 | 参数 | 返回要点 |
63
+ |---|---|---|
64
+ | `/v1/sector` | 无 | 行业 / 概念 / 地域板块涨幅榜 + 领涨股 |
65
+ | `/v1/sector-valuation` | `code*`(`pt01801780` 形式)| 申万板块 PE/PB/PS/PCF + 股息率 + **历史百分位** |
66
+ | `/v1/industry-chain` | `mode`(list/graph/stock) · `topic` · `code` | `list` = **183 个主题** · `graph&topic=X` = 图谱(关联个股 + 节点 + 上中下游)· `stock&code=X` = 该股所属链(主题/节点/位置/**关联度**/业务描述)|
67
+
68
+ ## 六、可转债 / ETF / 新股
69
+
70
+ | 端点 | 参数 | 返回要点 |
71
+ |---|---|---|
72
+ | `/v1/bond` | `code*`(`sh113052`)| 转债完整条款:溢价率 / 转股价值 / **双低值** / **强赎触发价** / 回售触发价 / 转股价 / 正股 / 到期日 / 信用评级 |
73
+ | `/v1/etf` | `code*`(`sh510300`)| ETF 行情 / 规模 / 溢折率 / 资金流 |
74
+ | `/v1/ipo` | `days` | 新股发行 / 申购 / 中签 / 上市日历 |
75
+
76
+ ## 七、选股与宏观
77
+
78
+ | 端点 | 参数 | 返回要点 |
79
+ |---|---|---|
80
+ | `/v1/screen` | `expr` 或 `preset` · `limit` · `orderby` · `desc` · `market` | **因子选股**。`expr` 多因子交集:`intersect([PE_TTM > 0, PE_TTM < 20, ROETTM > 15])`;`preset` 22 个官方预设(**大小写/下划线不敏感**:`low_pe` = `LowPE`)。常用因子:PE_TTM / PB / PS_TTM / TotalMV / DividendRatioTTM(估值)· ROE / ROETTM / ROIC / GrossIncomeRatioTTM(盈利)· OperatingRevenueGrowRate / NPParentCompanyYOY(成长)· CurrentRatio / DebtAssetsRatio(负债)· NetOperateCashFlowTTM(现金流)|
81
+ | `/v1/macro` | `region`(cn/us/jp/eu/hk) · `names` | 宏观:GDP / CPI / PMI / LPR / 国债收益率 / 财政 |
82
+ | `/v1/dehydrated` | `mode`(list/detail) · `symbol` · `limit` | 券商研报脱水摘要 |
83
+ | `/v1/usage` | 无 | 当前 Key 的今日调用次数 / 剩余总量 / 到期时间 / 限流额度 |
84
+
85
+ ---
86
+
87
+ ## 返回形态:`data` 有四种形状(33 端点全量)
88
+
89
+ **程序化处理前必须先判形状** —— `data` **不是**永远同一个类型,写死 `data[0]["x"]` 会在 `finance` / `calendar` 上炸。
90
+
91
+ | 形状 | 长这样 | 哪些端点 | 怎么读 |
92
+ |---|---|---|---|
93
+ | **① 对象数组** | `[{"col": val}, ...]` | 多数:`quote` `kline` `hot` `technical` `chip` `orderbook` `snapshot` `profile` `dividend` `margin-trade` `ipo` | `for row in data: row["field"]` |
94
+ | **② 表列表** | `[[行...], [行...]]`(外层=表,内层=行)| `finance`(利润表 / 资产负债表 / 现金流量表)| `data[表号][行号]["字段"]` —— **先按表索引** |
95
+ | **③ 多段结构** | `{"tables": [{"title","slug","rows"}], "data": {"<slug>": rows}}` | `shareholder`(另带 `code`/`market`)· `calendar` | `data["tables"]` 保序分段;`data["data"]["<slug>"]` 便捷索引 |
96
+ | **④ Markdown 字符串** | `"\| 列 \| 列 \|\n..."` | 9 个(见信封说明)+ `events` · `dehydrated` | 优先读同响应的 `structured` / `tables`(**若存在**);不存在才正则解析 |
97
+
98
+ **特殊 dict(不属于上面四类)**:`fund` = 扁平 `{date, close, main_net, main_net_5d/10d/20d, main_rank, lhb, lhb_details, block_trades, margin, industry_rank}` ·
99
+ `industry-chain?mode=list` = `{mode, topics}`。
100
+
101
+ **空结果的三种表现**(都**不是**故障,`ok:true`):`data = []`(如 `block-trade` 当天无成交)· `data` 是含"数据为空"的 Markdown(`events`)· 多段结构里 `tables = []`。
102
+
103
+ **推荐写法(四种形状通吃)**:
104
+
105
+ ```python
106
+ def rows_of(body):
107
+ d = body.get("data")
108
+ if isinstance(d, dict) and "tables" in d: # ③ 多段结构
109
+ return [r for t in d["tables"] for r in (t.get("rows") or [])]
110
+ if isinstance(d, list) and d and isinstance(d[0], list): # ② 表列表
111
+ return d[0] # 或按表号取
112
+ return body.get("structured") or d # ① / ④(④ 优先用 structured)
113
+ ```
114
+
115
+ ---
116
+
117
+ ## 代码格式(`code` 参数)
118
+
119
+ | 写法 | 说明 |
120
+ |---|---|
121
+ | `sh600667` | 沪市(sh)· 深市(sz)· 北交所(bj)· 港股(hk)· 美股(us)|
122
+ | `600667.SH` | 后缀写法 |
123
+ | `600667` | 纯 6 位(按首位推断:5/6→sh · 0/3→sz · 4/8→bj)|
124
+ | `pt01801780` | **板块**代码(申万板块,用于 `sector-valuation`)|
125
+ | `sh113052` | **可转债**代码 |
126
+ | `sh510300` | **ETF** 代码 |
127
+
128
+ **官方 SDK 会自动归一化三种股票写法**;直接调 HTTP 时建议统一用 `sh600667` 形式。
@@ -1,117 +1,117 @@
1
- # 错误、限流与"无数据"
2
-
3
- **核心区分**(先记住这条):**"取数失败" ≠ "当前没有这类数据"**。两者都有明确信号,不要混为一谈。
4
-
5
- ---
6
-
7
- ## 一、HTTP 状态码
8
-
9
- | 状态 | 含义 | 处理 |
10
- |---|---|---|
11
- | **200** | 成功(但要看 `ok` 字段,见下)| 读 `data` / `structured` |
12
- | **401** | 未授权 —— **没带 Key 调了付费端点**(或 Key 无效/已停用)| 拿 Key(https://ashareapi.com/pricing),或改用 5 个免费端点 |
13
- | **403** | 禁止 —— 常见于 **IP 维度限制**(一个 Key 被多个 IP 共用,超出该档位允许的 IP 数)| 别把 Key 共享给多人;升级档位 |
14
- | **404** | 路径不存在 | 核对端点名(见 `endpoints.md`)|
15
- | **422** | 参数错误(缺必填 / 值非法)| 看返回里的说明;常见是缺 `code` |
16
- | **429** | **超出限流**(两种:每分钟**次数**超 · 当天**条数**超)| 次数超 → 降频 · 解 PoW 提额 · 升级档位;**条数超 → 解 PoW 无效**,次日恢复,或用 Key / 升级档位(见下)|
17
- | **5xx** | 服务端/上游异常 | 稍后重试 |
18
-
19
- ## 二、`ok` 字段(HTTP 200 也要看它)
20
-
21
- ```json
22
- { "ok": false, "endpoint": "block-trade", "data": [] }
23
- ```
24
-
25
- - **`ok:true`** = 取数成功
26
- - **`ok:false`** = **上游取数失败**(我们**已自动换源**,且 **不扣调用次数**)→ **重试一次通常就好**
27
-
28
- ⚠️ **`ok:false` 不是"你写错了"** —— 是数据源那一侧的问题。所以**不要**因为 `ok:false` 就改代码逻辑。
29
-
30
- ## 三、空结果(≠ 失败)
31
-
32
- **`ok:false` + `data: []`** 或 **`ok:true` 但列表为空** → 可能是"**当前确实没有这类数据**":
33
-
34
- - 今天没有大宗交易
35
- - 这个时间段没有解禁事件
36
- - 该股今日不在龙虎榜
37
-
38
- **处理**:换条件 / 换日期 / 稍后再试 —— **不是故障,不会计费**。
39
- **不要**把它当成"上游挂了"去重试到超时。
40
-
41
- ## 四、限流(匿名很紧,这是设计)
42
-
43
- | 档位 | 额度 |
44
- |---|---|
45
- | **匿名**(无 Key)| **5 次/分钟** · 单次最多 **250 条** · 每天最多 **10 万条** |
46
- | **匿名 + PoW** | **60 次/分钟**(**每日条数上限不变**,仍 10 万条)|
47
- | 各付费档 | 见 https://ashareapi.com/pricing(含每分钟与总量限制)|
48
-
49
- ⚠️ 匿名有**两种**上限 —— **每分钟次数** 与 **每天条数**,429 可能是其中任意一种触发;先看返回里的提示是哪种。
50
-
51
- **触发时**:返回 **429**。
52
-
53
- ### 匿名提额:解一次 PoW 挑战
54
-
55
- ```bash
56
- # 1) 取挑战
57
- curl "https://api.ashareapi.com/v1/challenge"
58
- # → { "challenge": "...", "difficulty": 18, "expires_in": 600, "how_to": "..." }
59
-
60
- # 2) 算 nonce:要求 sha256("<challenge>.<nonce>") 的十六进制前 difficulty 位为 '0'
61
- # (普通电脑毫秒~秒级;难度由服务端定,只允许调高不允许调低)
62
-
63
- # 3) 带上去请求
64
- curl -H "X-PoW: <challenge>.<nonce>" \
65
- "https://api.ashareapi.com/v1/quote?code=sh600667"
66
- ```
67
-
68
- **要点**:
69
- - 挑战**有有效期**(`expires_in`,通常 600 秒),过期重新取
70
- - 挑战可以**预取 + 预解算 + 延后使用**(流水线化,不必每次现解)
71
- - **付费 Key 用户不需要 PoW**(额度已够)
72
- - ⚠️ PoW 只提升**每分钟次数**,**不提升每日条数** —— 匿名每天仍最多 10 万条
73
-
74
- ### 降频建议(比死磕 429 更实际)
75
-
76
- - 批量取数时**加 `time.sleep()`**(匿名至少 12 秒/次;PoW 后 1 秒/次)
77
- - ⚠️ 匿名**每天最多 10 万条** —— 批量补历史/回测请用 Key(一次 1212 条、无日上限)
78
- - **本地缓存**:同一标的一天内的行情/财务不必重复取
79
- - 需要**高频**就升级档位 —— 比反复解 PoW 省事
80
-
81
- ## 五、官方 Python SDK 的 5 类异常(不用自己判状态码)
82
-
83
- ```python
84
- from ashareapi import (AShareAPI, AuthError, RateLimitError,
85
- UpstreamError, EmptyResultError, APIError)
86
-
87
- try:
88
- df = cli.fund("sh600667")
89
- except AuthError: # 401 / 缺 Key
90
- ...
91
- except RateLimitError: # 429(含提额提示)
92
- ...
93
- except UpstreamError: # ok:false —— 上游失败,已换源,不扣次数 → 重试一次
94
- ...
95
- except EmptyResultError: # 当前无数据(如当天无大宗交易)→ 不计费,换条件
96
- ...
97
- except APIError: # 其他(网络 / 5xx 重试耗尽)
98
- ...
99
- ```
100
-
101
- | SDK 异常 | 对应上面的情况 |
102
- |---|---|
103
- | `AuthError` | 401 / 403(鉴权与 IP 维度)|
104
- | `RateLimitError` | 429 |
105
- | `UpstreamError` | `ok:false` 且 `data` 非空(真失败)|
106
- | **`EmptyResultError`** | `ok:false` 且 `data` 为空(**无数据 ≠ 失败**)|
107
- | `APIError` | 网络异常 / 5xx 重试耗尽 |
108
-
109
- **这正是 SDK 的价值**:把"该重试"和"该换条件"分开,不用自己猜。
110
-
111
- ## 六、排错顺序(省时间)
112
-
113
- 1. **401 还是 429?** → 缺 Key 还是超频(两者处理完全不同)
114
- 2. **HTTP 200 但没数据?** → 看 `ok` 与 `data`:`ok:false`+空 = 无数据(换条件);`ok:false`+有内容 = 上游失败(重试)
115
- 3. **403?** → 是不是把 Key 给多人用了(IP 维度)
116
- 4. **422?** → 看返回说明,多半少传了必填参数(如 `code`)
117
- 5. **数据看着不对?** → 先查单位与日期(见 `fields.md`),90% 是单位/日期问题,不是接口问题
1
+ # 错误、限流与"无数据"
2
+
3
+ **核心区分**(先记住这条):**"取数失败" ≠ "当前没有这类数据"**。两者都有明确信号,不要混为一谈。
4
+
5
+ ---
6
+
7
+ ## 一、HTTP 状态码
8
+
9
+ | 状态 | 含义 | 处理 |
10
+ |---|---|---|
11
+ | **200** | 成功(但要看 `ok` 字段,见下)| 读 `data` / `structured` |
12
+ | **401** | 未授权 —— **没带 Key 调了付费端点**(或 Key 无效/已停用)| 拿 Key(https://ashareapi.com/pricing),或改用 5 个免费端点 |
13
+ | **403** | 禁止 —— 常见于 **IP 维度限制**(一个 Key 被多个 IP 共用,超出该档位允许的 IP 数)| 别把 Key 共享给多人;升级档位 |
14
+ | **404** | 路径不存在 | 核对端点名(见 `endpoints.md`)|
15
+ | **422** | 参数错误(缺必填 / 值非法)| 看返回里的说明;常见是缺 `code` |
16
+ | **429** | **超出限流**(两种:每分钟**次数**超 · 当天**条数**超)| 次数超 → 降频 · 解 PoW 提额 · 升级档位;**条数超 → 解 PoW 无效**,次日恢复,或用 Key / 升级档位(见下)|
17
+ | **5xx** | 服务端/上游异常 | 稍后重试 |
18
+
19
+ ## 二、`ok` 字段(HTTP 200 也要看它)
20
+
21
+ ```json
22
+ { "ok": false, "endpoint": "block-trade", "data": [] }
23
+ ```
24
+
25
+ - **`ok:true`** = 取数成功
26
+ - **`ok:false`** = **上游取数失败**(我们**已自动换源**,且 **不扣调用次数**)→ **重试一次通常就好**
27
+
28
+ ⚠️ **`ok:false` 不是"你写错了"** —— 是数据源那一侧的问题。所以**不要**因为 `ok:false` 就改代码逻辑。
29
+
30
+ ## 三、空结果(≠ 失败)
31
+
32
+ **`ok:false` + `data: []`** 或 **`ok:true` 但列表为空** → 可能是"**当前确实没有这类数据**":
33
+
34
+ - 今天没有大宗交易
35
+ - 这个时间段没有解禁事件
36
+ - 该股今日不在龙虎榜
37
+
38
+ **处理**:换条件 / 换日期 / 稍后再试 —— **不是故障,不会计费**。
39
+ **不要**把它当成"上游挂了"去重试到超时。
40
+
41
+ ## 四、限流(匿名很紧,这是设计)
42
+
43
+ | 档位 | 额度 |
44
+ |---|---|
45
+ | **匿名**(无 Key)| **5 次/分钟** · 单次最多 **250 条** · 每天最多 **10 万条** |
46
+ | **匿名 + PoW** | **15 次/分钟**(**每日条数上限不变**,仍 10 万条)|
47
+ | 各付费档 | 见 https://ashareapi.com/pricing(含每分钟与总量限制)|
48
+
49
+ ⚠️ 匿名有**两种**上限 —— **每分钟次数** 与 **每天条数**,429 可能是其中任意一种触发;先看返回里的提示是哪种。
50
+
51
+ **触发时**:返回 **429**。
52
+
53
+ ### 匿名提额:解一次 PoW 挑战
54
+
55
+ ```bash
56
+ # 1) 取挑战
57
+ curl "https://api.ashareapi.com/v1/challenge"
58
+ # → { "challenge": "...", "difficulty": 18, "expires_in": 600, "how_to": "..." }
59
+
60
+ # 2) 算 nonce:要求 sha256("<challenge>.<nonce>") 的十六进制前 difficulty 位为 '0'
61
+ # (普通电脑毫秒~秒级;难度由服务端定,只允许调高不允许调低)
62
+
63
+ # 3) 带上去请求
64
+ curl -H "X-PoW: <challenge>.<nonce>" \
65
+ "https://api.ashareapi.com/v1/quote?code=sh600667"
66
+ ```
67
+
68
+ **要点**:
69
+ - 挑战**有有效期**(`expires_in`,通常 600 秒),过期重新取
70
+ - 挑战可以**预取 + 预解算 + 延后使用**(流水线化,不必每次现解)
71
+ - **付费 Key 用户不需要 PoW**(额度已够)
72
+ - ⚠️ PoW 只提升**每分钟次数**,**不提升每日条数** —— 匿名每天仍最多 10 万条
73
+
74
+ ### 降频建议(比死磕 429 更实际)
75
+
76
+ - 批量取数时**加 `time.sleep()`**(匿名至少 12 秒/次;PoW 后 1 秒/次)
77
+ - ⚠️ 匿名**每天最多 10 万条** —— 批量补历史/回测请用 Key(一次 1212 条、无日上限)
78
+ - **本地缓存**:同一标的一天内的行情/财务不必重复取
79
+ - 需要**高频**就升级档位 —— 比反复解 PoW 省事
80
+
81
+ ## 五、官方 Python SDK 的 5 类异常(不用自己判状态码)
82
+
83
+ ```python
84
+ from ashareapi import (AShareAPI, AuthError, RateLimitError,
85
+ UpstreamError, EmptyResultError, APIError)
86
+
87
+ try:
88
+ df = cli.fund("sh600667")
89
+ except AuthError: # 401 / 缺 Key
90
+ ...
91
+ except RateLimitError: # 429(含提额提示)
92
+ ...
93
+ except UpstreamError: # ok:false —— 上游失败,已换源,不扣次数 → 重试一次
94
+ ...
95
+ except EmptyResultError: # 当前无数据(如当天无大宗交易)→ 不计费,换条件
96
+ ...
97
+ except APIError: # 其他(网络 / 5xx 重试耗尽)
98
+ ...
99
+ ```
100
+
101
+ | SDK 异常 | 对应上面的情况 |
102
+ |---|---|
103
+ | `AuthError` | 401 / 403(鉴权与 IP 维度)|
104
+ | `RateLimitError` | 429 |
105
+ | `UpstreamError` | `ok:false` 且 `data` 非空(真失败)|
106
+ | **`EmptyResultError`** | `ok:false` 且 `data` 为空(**无数据 ≠ 失败**)|
107
+ | `APIError` | 网络异常 / 5xx 重试耗尽 |
108
+
109
+ **这正是 SDK 的价值**:把"该重试"和"该换条件"分开,不用自己猜。
110
+
111
+ ## 六、排错顺序(省时间)
112
+
113
+ 1. **401 还是 429?** → 缺 Key 还是超频(两者处理完全不同)
114
+ 2. **HTTP 200 但没数据?** → 看 `ok` 与 `data`:`ok:false`+空 = 无数据(换条件);`ok:false`+有内容 = 上游失败(重试)
115
+ 3. **403?** → 是不是把 Key 给多人用了(IP 维度)
116
+ 4. **422?** → 看返回说明,多半少传了必填参数(如 `code`)
117
+ 5. **数据看着不对?** → 先查单位与日期(见 `fields.md`),90% 是单位/日期问题,不是接口问题