#134 by GitHub stars
simonlin1212/a-stock-data
当任务需要写代码实际获取A股及相关市场数据时使用——行情/K线/逐笔(腾讯日周月前后复权+分钟线+当日逐笔、通达信官网全市场盘后包、百度)、研报(东财+新浪+同花顺+iwencai)、信号(热点/北向/龙虎榜/解禁/行业/板块资金流)、资金面(融资融券/大宗/股东户数/分红/资金流/ETF份额)、新闻(财联社/东财/华尔街见闻/新闻联播)、财务三表/F10/估值历史/ST名单、公告(巨潮)、打板(涨停池/连板/炸板率/监控池/异动)、ETF期权、舆情互动(互动易/上证e互动/热榜)、筹码分布、复权因子、申万行业变迁、宏观与利率(社融/PMI/中债收益率曲线/回购定盘利率/LPR/全球宏观日历)
History
Review weekly changes to SKILL.md before updating. Dates mark the weeks in which we observed each version; checks apply to the recorded commits.
View weekly changes
SKILL.md
Week of Nov 2, 2026 · Line counts unavailable
Before Network or broad shell → After Network or broad shell
bf447c1d05fa → f21534946c42
A local comparison is unavailable. You can inspect the recorded versions on GitHub.
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Network or broad shell
First observation → bf447c1d05fa
No earlier version was observed for comparison.
Heat
7.4- Star growth, last 7 daysAhead of 92% of tracked repositories
- Star growth, last 24 hoursAhead of 90% of tracked repositories
- Rank movement, last 7 daysAhead of 67% of tracked repositories
- Commits, last 30 daysAhead of 82% of tracked repositories
- Accounts asking about it through MCP, last 7 daysNot available
- Hot votes this weekAhead of 0% of tracked repositories
Heat never changes the order by stars, and sponsorship never touches it. How heat works
Stars over time
Individual skills in this repository
How it works
a-stock-data
When your agent uses it
当任务需要写代码实际获取A股及相关市场数据时使用——行情/K线/逐笔(腾讯日周月前后复权+分钟线+当日逐笔、通达信官网全市场盘后包、百度)、研报(东财+新浪+同花顺+iwencai)、信号(热点/北向/龙虎榜/解禁/行业/板块资金流)、资金面(融资融券/大宗/股东户数/分红/资金流/ETF份额)、新闻(财联社/东财/华尔街见闻/新闻联播)、财务三表/F10/估值历史/ST名单、公告(巨潮)、打板(涨停池/连板/炸板率/监控池/异动)、ETF期权、舆情互动(互动易/上证e互动/热榜)、筹码分布、复权因子、申万行业变迁、宏观与利率(社融/PMI/中债收益率曲线/回购定盘利率/LPR/全球宏观日历)、指数成分/权重/估值/交易日历、期货与大宗商品(五家期货交易所日行情/商品与股指期权/持仓排名/期货日K含大商所/实时期货/A50/上海金)、事件驱动(业绩预告/机构调研/增减持/回购/股权质押/新股申购)、可转债等真实数据。十五层·87端点(含5备胎)·34个来源·内嵌全部可运行代码,自包含零外部文件;优先用腾讯/交易所官方等不封IP源,东财接口已内置限流防封,主源被封可查「备用源速查」降级。仅在需要调用数据接口取数时使用:A股概念解释、投资观点讨论、策略问答等无需取数的话题不要加载本skill。
What it loads into context
Frontmatter
465 tokensAlways available to the agent
SKILL.md
132,957 tokensWhen the skill is activated
Reference documents
65,125 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- 端点路由速查(按需定位,不必通读全文)
- 数据源优先级 & 东财防封(重要,先读)
- When to Activate
- Prerequisites
- Layer 1: 行情层(实时,不封IP)
- Layer 2: 研报层
- Layer 3: 信号层
- Layer 4: 资金面 / 筹码层(V3.0 新增)
- Layer 5: 新闻层
- Layer 6: 基础数据层
- Layer 7: 公告层
- Layer 8: 打板层(涨停 / 炸板 / 跌停 / 题材情绪,V3.3.0 新增)
- Layer 9: ETF 期权层(T型报价 + 希腊字母 + IV,V3.3.0 新增)
- Layer 10: 舆情互动层(互动易问答 + 热榜 + 人气榜,V3.3.0 新增)
- Layer 11: 宏观与利率层(社融 / PMI / 收益率曲线 / 回购利率 / LPR / 宏观日历)
- Layer 12: 指数与交易日历(V3.8.0)
- Layer 13: 期货与大宗商品(V3.9.0 新增 · #49)
- Layer 14: 事件驱动(V3.9.0 新增)
- Layer 15: 可转债(V3.9.0 新增)
- 估值计算公式
- 完整调研流程
- 官方两融与北交所行情备胎(V3.8.0)
- 数据源优先级
- 备用源速查 & 降级策略(东财/主源被封时用)
- FAQ
- 安装说明
Scripts executed separately
tests/fixtures/sina_adjust/sh511010-hfq.jstests/fixtures/sina_adjust/sh511010-qfq.jstests/fixtures/sina_adjust/sh513100-hfq.jstests/fixtures/sina_adjust/sh513100-qfq.jstests/fixtures/sina_adjust/sh600519-hfq.jstests/fixtures/sina_adjust/sh600519-qfq.jstests/fixtures/sina_adjust/sz159919-hfq.jstests/fixtures/sina_adjust/sz159919-qfq.jstests/fixtures/sina_adjust/sz161226-hfq.jstests/fixtures/sina_adjust/sz161226-qfq.jstests/test_official_data.pytests/test_v310_sources.pytests/test_v37_adjust_factor.pytests/test_v39_sources.pytests/test_valuation.py
Files
.gitignoreasset38 bytesCHANGELOG.mddoc91,558 bytesLICENSEasset10,760 bytesREADME.mddoc50,171 bytesREADME_en.mddoc46,130 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesSKILL.mdcore442,341 bytesassets/.gitkeepasset0 bytesassets/bmc-qr.pngasset80,325 bytesassets/bmc-sponsor.pngasset60,327 bytesdocs/source-integration-v3.8.0.mddoc7,023 bytesdocs/source-integration-v3.9.0.mddoc15,604 bytestests/fixtures/sina_adjust/checkpoints.jsonasset4,681 bytestests/fixtures/sina_adjust/sh508000-qfq.htmlasset162 bytestests/fixtures/sina_adjust/sh511010-hfq.jsruns955 bytestests/fixtures/sina_adjust/sh511010-qfq.jsruns955 bytestests/fixtures/sina_adjust/sh513100-hfq.jsruns475 bytestests/fixtures/sina_adjust/sh513100-qfq.jsruns475 bytestests/fixtures/sina_adjust/sh600519-hfq.jsruns1,801 bytestests/fixtures/sina_adjust/sh600519-qfq.jsruns1,801 bytestests/fixtures/sina_adjust/sz159919-hfq.jsruns955 bytestests/fixtures/sina_adjust/sz159919-qfq.jsruns955 bytestests/fixtures/sina_adjust/sz161226-hfq.jsruns395 bytestests/fixtures/sina_adjust/sz161226-qfq.jsruns395 bytestests/test_official_data.pyruns16,061 bytestests/test_v310_sources.pyruns27,978 bytestests/test_v37_adjust_factor.pyruns13,756 bytestests/test_v39_sources.pyruns103,228 bytestests/test_valuation.pyruns3,658 bytes
Read SKILL.md
> 📦 项目主页:https://github.com/simonlin1212/a-stock-data — 更新、反馈、支持作者
>
> 作者:Simon 林 · X [@linsizhen](https://x.com/linsizhen) · 邮箱:simonlin0423@gmail.com
# A股全栈数据工具包 V3.10.4
十五层数据架构,87 个能力端点(82 主端点 + 5 备胎)、34 个来源。V3.10 新增的 2 个入口于 2026-09-22 实测,V3.9 新增的 25 个入口于 2026-09-20 实测;旧端点的验证日期见各章节。覆盖主板/创业板/科创板/ST,北交所覆盖依端点而异;已有备胎的数据可按「备用源速查」降级。
> **V3.10.4(基金复权修复,2026-11-04 · #64):** 入口数、来源数不变,个股的返回值不变。§1.6 `sina_adjust_factor()` / `apply_adjust()`:
> 基金(ETF / LOF)原来只读新浪的 `f`(基金恒为 1),复权等于没做;现在补读 `s`(累计份额折算比例)和 `u`(累计每份分红),
> 前复权 `raw / s - u`、后复权 `(raw + u) * s`,因子多出 `split` / `dividend`,结果多出 `adj_split` / `adj_dividend`。
> **V3.10.3(上证e互动时间列修复,2026-10-23):** 入口数、来源数不变,返回的数据也不变。§10.3 `sse_e_interaction()`:
> 站点 1 天内的回复时间写成「昨天 18:22」,原来只认绝对时间,遇到就整页抛 `RuntimeError`;现在相对 / 绝对写法都换算成View the complete source on GitHubSkills included
- a-stock-data
Repository facts
- License
- Apache-2.0
- Created
- May 11, 2026
- Last pushed
- Nov 3, 2026
- Forks
- 2,089
- Open issues
- 0
- Project activity
- Active
Rank over the last 12 weeks
Now #134 · best #127 · down 2 in 30 days
- #132 on Oct 29
- #133 from Oct 30 to Oct 31
- #132 on Nov 1
- #133 on Nov 2
- #135 from Nov 3 to Nov 5
- #134 since Nov 6
43 earlier periods
- #135 on Aug 2
- #133 on Aug 7
- #132 from Aug 8 to Aug 9
- #134 on Aug 10
- #133 from Aug 11 to Aug 13
- #132 from Aug 14 to Aug 15
- #131 on Aug 16
- #132 from Aug 17 to Aug 19
- #133 on Aug 20
- #132 on Aug 21
- #130 from Aug 22 to Aug 23
- #131 on Aug 24
- #130 from Aug 25 to Aug 27
- #129 from Aug 28 to Aug 29
- #128 on Aug 30
- #127 on Aug 31
- #128 on Sep 1
- #127 on Sep 2
- #128 on Sep 3
- #127 on Sep 4
- #128 on Sep 5
- #127 from Sep 6 to Sep 7
- #128 from Sep 8 to Sep 11
- #129 from Sep 12 to Sep 15
- #128 on Sep 16
- #129 on Sep 17
- #130 on Sep 18
- #129 on Sep 19
- #131 from Sep 20 to Sep 22
- #129 from Sep 23 to Sep 25
- #127 on Sep 26
- #130 on Sep 27
- #131 from Sep 28 to Sep 29
- #130 on Sep 30
- #131 from Oct 1 to Oct 3
- #129 on Oct 4
- #131 on Oct 5
- #129 on Oct 6
- #132 from Oct 7 to Oct 14
- #131 from Oct 15 to Oct 17
- #132 from Oct 18 to Oct 24
- #133 on Oct 25
- #131 on Oct 28
Before you install
Network or broad shellAutomated signals, not a guarantee
Checked Nov 6, 2026
Not fully analyzed: some files were too long, unreadable or missing. This never lowers the level.
Show 103 notes
SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzed
- No broad tool permissions
- 5 dangerous shell commandsin 5 files: tests/test_official_data.py:27 tests/test_v310_sources.py:38 tests/test_v37_adjust_factor.py:29 and 2 more
- 548 network referencesin 11 files: SKILL.md:8 tests/test_v39_sources.py:111 README.md:14 and 8 more
- 3 obfuscation signalsin 3 files: tests/fixtures/sina_adjust/sh600519-hfq.js:1 tests/fixtures/sina_adjust/sh600519-qfq.js:1 tests/test_v39_sources.py:517
- No instruction overrides
- 15 executable scriptsin 15 files: tests/fixtures/sina_adjust/sh511010-hfq.js:1 tests/fixtures/sina_adjust/sh511010-qfq.js:1 tests/fixtures/sina_adjust/sh513100-hfq.js:1 and 12 more
- 8 references to secretsin 4 files: SKILL.md:456 tests/test_official_data.py:290 tests/test_v310_sources.py:436 and 1 more
- No requests to vote in Hot
Show all 579 signals by file
CHANGELOG.md
- Network accessline 455
**#46 东财资金流将沪市 ETF 510300 错误路由为深市**(感谢 [@zmcmcc](https://github.com/zmcmcc))— **已修** - Network accessline 476
**#47 datacenter filter 的 `>` `<` 未 URL 编码**([@alicessr](https://github.com/alicessr))— **不适用于本项目,不改** - Network accessline 478
issue 的前提是「`requests.get(url)` 不会自动编码 `>` `<`」。但本项目的 `eastmoney_datacenter()` - Network accessline 619
感谢 [@tongflau-dongzhu](https://github.com/tongflau-dongzhu) 的报告——根因、复现和 - Network accessline 795
- **备用源速查 K线行补腾讯分钟 K 线(#43)**:同花顺 K 线备胎只有 30/60 分,mootdx 一挂就无 5 分钟源。补腾讯 `ifzq.gtimg.cn/appstock/app/kline/mkline`(`m1/m5/m15/m30/m60`,≤320 根,零鉴权不封 IP,需 `Referer: https://gu.qq.com/`)。⚠<U+FE0F> 文档标注字段坑:返回数组第 7 个字段是**换手率基点**不是成交额(当成交额读会小三个数量级),成交额需自
LICENSE
README.md
- Network accessline 14
<p align="center"> <a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache_2.0-blue.svg" alt="License"></a> - Network accessline 15
<a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache_2.0-blue.svg" alt="License"></a> - Network accessline 16
<img src="https://img.shields.io/badge/Python-3.9+-3776AB?logo=python&logoColor=white" alt="Python"> - Network accessline 17
<a href="https://github.com/simonlin1212/a-stock-data/stargazers"><img src="https://img.shields.io/github/stars/simonlin1212/a-stock-data?style=social" alt="Stars"></a> - Network accessline 18
<br> <img src="https://img.shields.io/badge/layers-15-2ea44f.svg" alt="Layers"> <img src="https://img.shields.io/badge/endpoints-87-2ea44f.svg" alt="Endpoints"> - Network accessline 19
<img src="https://img.shields.io/badge/layers-15-2ea44f.svg" alt="Layers"> - Network accessline 20
<img src="https://img.shields.io/badge/endpoints-87-2ea44f.svg" alt="Endpoints"> - Network accessline 21
<img src="https://img.shields.io/badge/sources-34-2ea44f.svg" alt="Sources"> - Network accessline 22
<img src="https://img.shields.io/badge/auth-zero-success.svg" alt="Zero Auth"> - Network accessline 39
> 兼容 [Claude Code](https://github.com/anthropics/claude-code) · [Codex](https://github.com/openai/codex) · [OpenClaw](https://github.com/openclaw/openclaw) · [WorkBuddy](https://www.workbuddy.cn/) · [Muse](https://muse.ai/) · [Grok Bot](htt - Network accessline 133
# 2. 把 SKILL.md 放进去 curl -o ~/.claude/skills/a-stock-data/SKILL.md \ - Network accessline 134
curl -o ~/.claude/skills/a-stock-data/SKILL.md \ - Network accessline 135
https://raw.githubusercontent.com/simonlin1212/a-stock-data/main/SKILL.md - Network accessline 352
除 iwencai 外,其余已接入数据源无需用户注册或 API Key;V3.8 的中证、国证和北交所,以及 V3.9 新增的 12 个来源(通达信官网、华尔街见闻、央视网、上证e互动、中债、中国货币网、五家期货交易所、上金所)也不需要用户凭据(北交所使用官网匿名 Cookie)。仅 iwencai 语义搜索需要 API Key([申请地址](https://www.iwencai.com/skillhub))。候选增强源不计入上述能力。 - Network accessline 629
**作者:** Simon 林 · X [@linsizhen](https://x.com/linsizhen) · 邮箱:[simonlin0423@gmail.com](mailto:simonlin0423@gmail.com)
README_en.md
- Network accessline 14
<p align="center"> <a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache_2.0-blue.svg" alt="License"></a> - Network accessline 15
<a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache_2.0-blue.svg" alt="License"></a> - Network accessline 16
<img src="https://img.shields.io/badge/Python-3.9+-3776AB?logo=python&logoColor=white" alt="Python"> - Network accessline 17
<a href="https://github.com/simonlin1212/a-stock-data/stargazers"><img src="https://img.shields.io/github/stars/simonlin1212/a-stock-data?style=social" alt="Stars"></a> - Network accessline 18
<br> <img src="https://img.shields.io/badge/layers-15-2ea44f.svg" alt="Layers"> <img src="https://img.shields.io/badge/endpoints-87-2ea44f.svg" alt="Endpoints"> - Network accessline 19
<img src="https://img.shields.io/badge/layers-15-2ea44f.svg" alt="Layers"> - Network accessline 20
<img src="https://img.shields.io/badge/endpoints-87-2ea44f.svg" alt="Endpoints"> - Network accessline 21
<img src="https://img.shields.io/badge/sources-34-2ea44f.svg" alt="Sources"> - Network accessline 22
<img src="https://img.shields.io/badge/auth-zero-success.svg" alt="Zero Auth"> - Network accessline 37
> Compatible with [Claude Code](https://github.com/anthropics/claude-code) · [Codex](https://github.com/openai/codex) · [OpenClaw](https://github.com/openclaw/openclaw) · [WorkBuddy](https://www.workbuddy.cn/) · [Muse](https://muse.ai/) · [ - Network accessline 131
# 2. Download SKILL.md curl -o ~/.claude/skills/a-stock-data/SKILL.md \ - Network accessline 132
curl -o ~/.claude/skills/a-stock-data/SKILL.md \ - Network accessline 133
https://raw.githubusercontent.com/simonlin1212/a-stock-data/main/SKILL.md - Network accessline 350
All integrated sources except iwencai require no user registration or API key. CSI, CNI and BSE (V3.8) and the 12 sources added in V3.9 (TDX official site, Wallstreetcn, CCTV, SSE e-Interaction, ChinaBond, China Money, the five futures exch - Network accessline 573
**Author:** Simon Lin · X [@linsizhen](https://x.com/linsizhen) · Email: [simonlin0423@gmail.com](mailto:simonlin0423@gmail.com)
SKILL.md
- Network accessline 8
> 📦 项目主页:https://github.com/simonlin1212/a-stock-data — 更新、反馈、支持作者 - Network accessline 10
> 作者:Simon 林 · X [@linsizhen](https://x.com/linsizhen) · 邮箱:simonlin0423@gmail.com - Network accessline 363
### ⚠<U+FE0F> 实测封禁案例(2026-06-30,一手数据,感谢 [@luodada99](https://github.com/luodada99) issue #36) - Network accessline 455
[Credential-related source omitted] - Access to secretsline 456
[Credential-related source omitted] - Network accessline 457
export IWENCAI_BASE_URL="https://openapi.iwencai.com" - Network accessline 459
# 申请地址: https://www.iwencai.com/skillhub - Network accessline 486
"""TCP 握手探测(快速粗筛)。注意:握手成功 ≠ 能取数,必须再经 _validate 验活。""" try: with socket.create_connection((ip, port), timeout=timeout): - Network accessline 487
try: with socket.create_connection((ip, port), timeout=timeout): return True - Network accessline 488
with socket.create_connection((ip, port), timeout=timeout): - Network accessline 757
UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" DATACENTER_URL = "https://datacenter-web.eastmoney.com/api/data/v1/get" - Network accessline 758
DATACENTER_URL = "https://datacenter-web.eastmoney.com/api/data/v1/get" - Network accessline 763
# 所有 eastmoney.com 请求一律走 em_get():串行限流(最小间隔 + 随机抖动)+ 复用 # Keep-Alive 会话,批量调用时自动降速,避免被封。详见「数据源优先级 & 东财防封」章节。 EM_SESSION = requests.Session() - Network accessline 764
# Keep-Alive 会话,批量调用时自动降速,避免被封。详见「数据源优先级 & 东财防封」章节。 EM_SESSION = requests.Session() EM_SESSION.headers.update({"User-Agent": UA}) - Network accessline 765
EM_SESSION = requests.Session() - Network accessline 834
# 连接失败、握手或等响应头超时、429 / 5xx 指数退避重试(写法同 EM_SESSION);读响应体中途超时不重试, # 也不按服务端给的 Retry-After 等待。 V39_RETRY_SESSION = requests.Session() - Network accessline 835
# 也不按服务端给的 Retry-After 等待。 V39_RETRY_SESSION = requests.Session() try: - Network accessline 836
V39_RETRY_SESSION = requests.Session() - Network accessline 1099
url = "https://qt.gtimg.cn/q=" + ",".join(prefixed) req = urllib.request.Request(url) - Network accessline 1100
req = urllib.request.Request(url) - Network accessline 1101
req.add_header("User-Agent", "Mozilla/5.0") resp = urllib.request.urlopen(req, timeout=10) data = resp.read().decode("gbk") - Network accessline 1102
resp = urllib.request.urlopen(req, timeout=10) - Network accessline 1230
# 三个入口是同一后端,但限流各自独立(#52 实测单域名约 600 次后返回空 JSON)。 TENCENT_KLINE_HOSTS = ["https://web.ifzq.gtimg.cn", - Network accessline 1231
TENCENT_KLINE_HOSTS = ["https://web.ifzq.gtimg.cn", - Network accessline 1232
"https://proxy.finance.qq.com/ifzqgtimg", - Network accessline 1233
"https://ifzq.gtimg.cn"] - Network accessline 1246
try: response = _v39_http(host + path, params={"param": param}, headers={"Referer": "https://gu.qq.com/"}, timeout=(8, 20)) - Network accessline 1247
response = _v39_http(host + path, params={"param": param}, headers={"Referer": "https://gu.qq.com/"}, timeout=(8, 20)) payload = _v39_json(response) if response.text.strip() else {} - Network accessline 1248
headers={"Referer": "https://gu.qq.com/"}, timeout=(8, 20)) - Network accessline 1402
通达信官网每天发布的增量数据包(HTTP 下载约 2.7MB),一次拿到**沪深北全部证券**当日的昨收、开高低收、成交量(股)、 成交额(元)。它走 HTTP,和 §1.7 失效的 TCP 行情命令是两条路。适合收盘后全市场截面筛选、每日落库。 二进制布局参考 [jing2uo/tdx2db](https://github.com/jing2uo/tdx2db)(MIT),已与腾讯收盘价对拍。 - Network accessline 1403
成交额(元)。它走 HTTP,和 §1.7 失效的 TCP 行情命令是两条路。适合收盘后全市场截面筛选、每日落库。 二进制布局参考 [jing2uo/tdx2db](https://github.com/jing2uo/tdx2db)(MIT),已与腾讯收盘价对拍。 非交易日、或当天包还没发布(通常收盘后数小时)抛 `ValueError`,不返回空表。 - Network accessline 1404
二进制布局参考 [jing2uo/tdx2db](https://github.com/jing2uo/tdx2db)(MIT),已与腾讯收盘价对拍。 - Network accessline 1416
TDX_PACKAGE_URL = "https://www.tdx.com.cn/products/data/data/g4day/{ymd}.zip" - Network accessline 1549
TENCENT_TICK_URL = "https://stock.gtimg.cn/data/index.php" - Network accessline 1550
TENCENT_QT_URL = "https://qt.gtimg.cn/q=" - Network accessline 1688
def baidu_kline_with_ma(code: str, start_time: str = "") -> dict: """百度股市通K线 — 独有能力: 返回时自带 ma5/ma10/ma20 均价""" url = "https://finance.pae.baidu.com/selfselect/getstockquotation" - Network accessline 1689
"""百度股市通K线 — 独有能力: 返回时自带 ma5/ma10/ma20 均价""" url = "https://finance.pae.baidu.com/selfselect/getstockquotation" params = { - Network accessline 1690
url = "https://finance.pae.baidu.com/selfselect/getstockquotation" - Network accessline 1698
"User-Agent": "Mozilla/5.0", "Accept": "application/vnd.finance-web.v1+json", "Origin": "https://gushitong.baidu.com", - Network accessline 1699
"Accept": "application/vnd.finance-web.v1+json", "Origin": "https://gushitong.baidu.com", "Referer": "https://gushitong.baidu.com/", - Network accessline 1700
"Origin": "https://gushitong.baidu.com", - Network accessline 1701
"Referer": "https://gushitong.baidu.com/", } r = requests.get(url, params=params, headers=headers, timeout=10) - Network accessline 1702
} r = requests.get(url, params=params, headers=headers, timeout=10) d = r.json() - Network accessline 1703
r = requests.get(url, params=params, headers=headers, timeout=10) - Network accessline 1748
prefix = {"xshg": "sh", "xshe": "sz"}.get(m.group(1).lower(), m.group(1).lower()) if m else get_prefix(digits) symbol = f"{prefix}{digits}" url = f"https://finance.sina.com.cn/realstock/company/{symbol}/{kind}.js" - Network accessline 1749
symbol = f"{prefix}{digits}" url = f"https://finance.sina.com.cn/realstock/company/{symbol}/{kind}.js" r = requests.get(url, headers={"User-Agent": "Mozilla/5.0", - Network accessline 1750
url = f"https://finance.sina.com.cn/realstock/company/{symbol}/{kind}.js" r = requests.get(url, headers={"User-Agent": "Mozilla/5.0", "Referer": "https://finance.sina.com.cn/"}, timeout=10) - Network accessline 1751
r = requests.get(url, headers={"User-Agent": "Mozilla/5.0", - Network accessline 1752
"Referer": "https://finance.sina.com.cn/"}, timeout=10) - Network accessline 1981
REPORT_API = "https://reportapi.eastmoney.com/report/list" - Network accessline 1982
PDF_TPL = "https://pdf.dfcfw.com/pdf/H3_{info_code}_1.pdf" - Network accessline 2003
} r = em_get(REPORT_API, params=params, headers={"Referer": "https://data.eastmoney.com/"}, timeout=30) # 已内置限流 - Network accessline 2004
r = em_get(REPORT_API, params=params, headers={"Referer": "https://data.eastmoney.com/"}, timeout=30) # 已内置限流 d = r.json() - Network accessline 2005
headers={"Referer": "https://data.eastmoney.com/"}, timeout=30) # 已内置限流 - Network accessline 2033
return str(target) url = PDF_TPL.format(info_code=info_code) r = em_get(url, headers={"Referer": "https://data.eastmoney.com/"}, timeout=60) - Network accessline 2034
url = PDF_TPL.format(info_code=info_code) r = em_get(url, headers={"Referer": "https://data.eastmoney.com/"}, timeout=60) if r.status_code == 200 and len(r.content) >= 1024: - Network accessline 2035
r = em_get(url, headers={"Referer": "https://data.eastmoney.com/"}, timeout=60) - Network accessline 2086
} r = em_get(REPORT_API, params=params, headers={"Referer": "https://data.eastmoney.com/"}, timeout=30) # 已内置限流 - Network accessline 2087
r = em_get(REPORT_API, params=params, headers={"Referer": "https://data.eastmoney.com/"}, timeout=30) # 已内置限流 d = r.json() - Network accessline 2088
headers={"Referer": "https://data.eastmoney.com/"}, timeout=30) # 已内置限流 - Network accessline 2138
""" code = norm_ticker(code, stock_only=True) # URL 路径只认纯 6 位,带前缀会 404 到空表 url = f"https://basic.10jqka.com.cn/new/{code}/worth.html" - Network accessline 2139
code = norm_ticker(code, stock_only=True) # URL 路径只认纯 6 位,带前缀会 404 到空表 url = f"https://basic.10jqka.com.cn/new/{code}/worth.html" headers = { - Network accessline 2140
url = f"https://basic.10jqka.com.cn/new/{code}/worth.html" - Network accessline 2141
headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36", "Referer": "https://basic.10jqka.com.cn/", - Network accessline 2142
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36", "Referer": "https://basic.10jqka.com.cn/", } - Network accessline 2143
"Referer": "https://basic.10jqka.com.cn/", } r = requests.get(url, headers=headers, timeout=15) - Network accessline 2144
} r = requests.get(url, headers=headers, timeout=15) r.encoding = "gbk" - Network accessline 2145
r = requests.get(url, headers=headers, timeout=15) - Network accessline 2172
[Credential-related source omitted] - Access to secretsline 2172
[Credential-related source omitted] - Access to secretsline 2173
[Credential-related source omitted] - Network accessline 2201
"size": size, } r = requests.post( - Network accessline 2202
} r = requests.post( f"{IWENCAI_BASE}/v1/comprehensive/search", - Network accessline 2203
r = requests.post( - Network accessline 2229
"expand_index": "true", } r = requests.post( - Network accessline 2230
} r = requests.post( f"{IWENCAI_BASE}/v1/query2data", - Network accessline 2231
r = requests.post( - Network accessline 2276
SINA_REPORT_URL = "https://vip.stock.finance.sina.com.cn/q/go.php/vReport_List/kind/{kind}/index.phtml" - Network accessline 2295
try: response = _v39_http(url, params=params, headers={"Referer": "https://finance.sina.com.cn/"}) - Network accessline 2296
response = _v39_http(url, params=params, headers={"Referer": "https://finance.sina.com.cn/"}) finally: - Network accessline 2297
headers={"Referer": "https://finance.sina.com.cn/"}) - Network accessline 2378
url = ( f"http://zx.10jqka.com.cn/event/api/getharden/" - Network accessline 2379
f"http://zx.10jqka.com.cn/event/api/getharden/" - Network accessline 2386
) } r = requests.get(url, headers=headers, timeout=10) - Network accessline 2387
} r = requests.get(url, headers=headers, timeout=10) data = r.json() - Network accessline 2388
r = requests.get(url, headers=headers, timeout=10) - Network accessline 2449
), "Host": "data.hexin.cn", "Referer": "https://data.hexin.cn/", - Network accessline 2450
"Host": "data.hexin.cn", "Referer": "https://data.hexin.cn/", } - Network accessline 2451
"Referer": "https://data.hexin.cn/", - Network accessline 2458
单位: 亿元 """ url = "https://data.hexin.cn/market/hsgtApi/method/dayChart/" - Network accessline 2459
""" url = "https://data.hexin.cn/market/hsgtApi/method/dayChart/" r = requests.get(url, headers=HSGT_HEADERS, timeout=10) - Network accessline 2460
url = "https://data.hexin.cn/market/hsgtApi/method/dayChart/" r = requests.get(url, headers=HSGT_HEADERS, timeout=10) d = r.json() - Network accessline 2461
r = requests.get(url, headers=HSGT_HEADERS, timeout=10) - Network accessline 2538
"fields": "f12,f14,f3,f128", } headers = {"User-Agent": UA, "Referer": "https://quote.eastmoney.com/"} - Network accessline 2539
} headers = {"User-Agent": UA, "Referer": "https://quote.eastmoney.com/"} try: - Network accessline 2540
headers = {"User-Agent": UA, "Referer": "https://quote.eastmoney.com/"} - Network accessline 2541
try: r = em_get("https://push2.eastmoney.com/api/qt/slist/get", params=params, headers=headers, timeout=15) - Network accessline 2542
r = em_get("https://push2.eastmoney.com/api/qt/slist/get", - Network accessline 2594
# 东财这个**个股**资金流接口本身不覆盖 ETF。ETF 资金流请另找端点。 secid = em_secid(code) url = "https://push2.eastmoney.com/api/qt/stock/fflow/kline/get" - Network accessline 2595
secid = em_secid(code) url = "https://push2.eastmoney.com/api/qt/stock/fflow/kline/get" params = { - Network accessline 2596
url = "https://push2.eastmoney.com/api/qt/stock/fflow/kline/get" - Network accessline 2602
headers = { "User-Agent": UA, "Referer": "https://quote.eastmoney.com/", - Network accessline 2603
"User-Agent": UA, "Referer": "https://quote.eastmoney.com/", "Origin": "https://quote.eastmoney.com", - Network accessline 2604
"Referer": "https://quote.eastmoney.com/", - Network accessline 2605
"Origin": "https://quote.eastmoney.com", - Network accessline 2818
返回: {top: [...], bottom: [...], total: int} """ url = "https://push2.eastmoney.com/api/qt/clist/get" - Network accessline 2819
""" url = "https://push2.eastmoney.com/api/qt/clist/get" params = { - Network accessline 2820
url = "https://push2.eastmoney.com/api/qt/clist/get" - Network accessline 2903
url = "https://push2.eastmoney.com/api/qt/clist/get" - Network accessline 3207
""" market_code = em_market_code(code) # #46 url = "https://push2his.eastmoney.com/api/qt/stock/fflow/daykline/get" - Network accessline 3208
market_code = em_market_code(code) # #46 url = "https://push2his.eastmoney.com/api/qt/stock/fflow/daykline/get" params = { - Network accessline 3209
url = "https://push2his.eastmoney.com/api/qt/stock/fflow/daykline/get" - Network accessline 3216
headers = { "User-Agent": UA, "Referer": "https://quote.eastmoney.com/", - Network accessline 3217
"User-Agent": UA, "Referer": "https://quote.eastmoney.com/", "Origin": "https://quote.eastmoney.com", - Network accessline 3218
"Referer": "https://quote.eastmoney.com/", - Network accessline 3219
"Origin": "https://quote.eastmoney.com", - Network accessline 3422
SSE_ETF_SHARES_URL = "https://query.sse.com.cn/commonQuery.do" - Network accessline 3423
SZSE_FUND_LIST_URL = "https://fund.szse.cn/api/report/ShowReport/data" - Network accessline 3429
"pageHelp.beginPage": 1, "pageHelp.cacheSize": 1, "pageHelp.endPage": 1} response = _v39_http(SSE_ETF_SHARES_URL, params=params, headers={"Referer": "https://www.sse.com.cn/"}) - Network accessline 3430
response = _v39_http(SSE_ETF_SHARES_URL, params=params, headers={"Referer": "https://www.sse.com.cn/"}) payload = _v39_json(response) - Network accessline 3431
headers={"Referer": "https://www.sse.com.cn/"}) - Network accessline 3462
params={"SHOWTYPE": "JSON", "CATALOGID": "1000_lf", "TABKEY": "tab1", "selectJjlb": "ETF", "PAGENO": page}, headers={"Referer": "https://fund.szse.cn/"}) - Network accessline 3463
"selectJjlb": "ETF", "PAGENO": page}, headers={"Referer": "https://fund.szse.cn/"}) payload = _v39_json(response) - Network accessline 3464
headers={"Referer": "https://fund.szse.cn/"}) - Network accessline 3554
# 构造 JSONP 参数 cb = "jQuery_news" url = "https://search-api-web.eastmoney.com/search/jsonp" - Network accessline 3555
cb = "jQuery_news" url = "https://search-api-web.eastmoney.com/search/jsonp" inner_params = json.dumps({ - Network accessline 3556
url = "https://search-api-web.eastmoney.com/search/jsonp" - Network accessline 3566
}, separators=(',', ':')) params = {"cb": cb, "param": inner_params} headers = {"User-Agent": UA, "Referer": "https://so.eastmoney.com/"} - Network accessline 3567
params = {"cb": cb, "param": inner_params} headers = {"User-Agent": UA, "Referer": "https://so.eastmoney.com/"} r = em_get(url, params=params, headers=headers, timeout=15) - Network accessline 3568
headers = {"User-Agent": UA, "Referer": "https://so.eastmoney.com/"} - Network accessline 3618
qs = "&".join(f"{k}={params[k]}" for k in sorted(params)) sign = hashlib.md5(hashlib.sha1(qs.encode()).hexdigest().encode()).hexdigest() url = f"https://www.cls.cn/v1/roll/get_roll_list?{qs}&sign={sign}" - Network accessline 3619
sign = hashlib.md5(hashlib.sha1(qs.encode()).hexdigest().encode()).hexdigest() url = f"https://www.cls.cn/v1/roll/get_roll_list?{qs}&sign={sign}" headers = {"User-Agent": UA, "Referer": "https://www.cls.cn/"} - Network accessline 3620
url = f"https://www.cls.cn/v1/roll/get_roll_list?{qs}&sign={sign}" headers = {"User-Agent": UA, "Referer": "https://www.cls.cn/"} r = requests.get(url, headers=headers, timeout=10) - Network accessline 3621
headers = {"User-Agent": UA, "Referer": "https://www.cls.cn/"} r = requests.get(url, headers=headers, timeout=10) d = r.json() - Network accessline 3622
r = requests.get(url, headers=headers, timeout=10) - Network accessline 3652
返回: [{title, summary, time}] """ url = "https://np-weblist.eastmoney.com/comm/web/getFastNewsList" - Network accessline 3653
""" url = "https://np-weblist.eastmoney.com/comm/web/getFastNewsList" params = { - Network accessline 3654
url = "https://np-weblist.eastmoney.com/comm/web/getFastNewsList" - Network accessline 3659
"req_trace": str(uuid.uuid4()), } headers = {"User-Agent": UA, "Referer": "https://kuaixun.eastmoney.com/"} - Network accessline 3660
} headers = {"User-Agent": UA, "Referer": "https://kuaixun.eastmoney.com/"} r = em_get(url, params=params, headers=headers, timeout=10) - Network accessline 3661
headers = {"User-Agent": UA, "Referer": "https://kuaixun.eastmoney.com/"} - Network accessline 3691
WSCN_LIVES_URL = "https://api-one-wscn.awtmt.com/apiv1/content/lives" - Network accessline 3750
CCTV_DAY_URL = "https://tv.cctv.com/lm/xwlb/day/{ymd}.shtml" - Network accessline 3865
""" market_code = em_market_code(code) # #46 url = "https://push2.eastmoney.com/api/qt/stock/get" - Network accessline 3866
market_code = em_market_code(code) # #46 url = "https://push2.eastmoney.com/api/qt/stock/get" params = { - Network accessline 3867
url = "https://push2.eastmoney.com/api/qt/stock/get" - Network accessline 3908
prefix = get_prefix(code) # #46:51x/588x/900x 也是沪市 paper_code = f"{prefix}{code}" url = "https://quotes.sina.cn/cn/api/openapi.php/CompanyFinanceService.getFinanceReport2022" - Network accessline 3909
paper_code = f"{prefix}{code}" url = "https://quotes.sina.cn/cn/api/openapi.php/CompanyFinanceService.getFinanceReport2022" params = { - Network accessline 3910
url = "https://quotes.sina.cn/cn/api/openapi.php/CompanyFinanceService.getFinanceReport2022" - Network accessline 3917
} headers = {"User-Agent": UA} r = requests.get(url, params=params, headers=headers, timeout=15) - Network accessline 3918
headers = {"User-Agent": UA} r = requests.get(url, params=params, headers=headers, timeout=15) # 新浪实际结构: result.data.report_list 是「按报告期(如 '20260331')为键」的 dict, - Network accessline 3919
r = requests.get(url, params=params, headers=headers, timeout=15) - Network accessline 4089
SW_URL = "https://www.swsresearch.com/swindex/pdf/SwClass2021/StockClassifyUse_stock.xls" - Network accessline 4093
"""申万行业归属变迁史 — 每只股票每次行业调整一行""" try: r = requests.get(SW_URL, headers={"User-Agent": "Mozilla/5.0"}, timeout=60) - Network accessline 4094
try: r = requests.get(SW_URL, headers={"User-Agent": "Mozilla/5.0"}, timeout=60) r.raise_for_status() - Network accessline 4095
r = requests.get(SW_URL, headers={"User-Agent": "Mozilla/5.0"}, timeout=60) - Network accessline 4162
EM_CLIST_HOSTS = ["https://push2.eastmoney.com", "https://push2delay.eastmoney.com"] - Network accessline 4197
raise RuntimeError(f"东财 clist 翻页后 {len(rows)} 条,与 total={total} 不符") return rows, url raise requests.ConnectionError("东财 push2 / push2delay 均不可达: " + "; ".join(errors)) - Network accessline 4199
raise requests.ConnectionError("东财 push2 / push2delay 均不可达: " + "; ".join(errors)) - Network accessline 4295
if not _CNINFO_ORGID_MAP: try: r = requests.get("http://www.cninfo.com.cn/new/data/szse_stock.json", - Network accessline 4296
try: r = requests.get("http://www.cninfo.com.cn/new/data/szse_stock.json", headers={"User-Agent": UA}, timeout=15) - Network accessline 4297
r = requests.get("http://www.cninfo.com.cn/new/data/szse_stock.json", - Network accessline 4313
返回: [{title, type, date, url}] """ url = "https://www.cninfo.com.cn/new/hisAnnouncement/query" - Network accessline 4314
""" url = "https://www.cninfo.com.cn/new/hisAnnouncement/query" org_id = _cninfo_orgid(code) # 动态查真实 orgId(#19 修复,自带硬编码 fallback) - Network accessline 4315
url = "https://www.cninfo.com.cn/new/hisAnnouncement/query" - Network accessline 4334
"User-Agent": UA, "Content-Type": "application/x-www-form-urlencoded", "Referer": "https://www.cninfo.com.cn/new/disclosure", - Network accessline 4335
"Content-Type": "application/x-www-form-urlencoded", "Referer": "https://www.cninfo.com.cn/new/disclosure", "Origin": "https://www.cninfo.com.cn", - Network accessline 4336
"Referer": "https://www.cninfo.com.cn/new/disclosure", - Network accessline 4337
"Origin": "https://www.cninfo.com.cn", } r = requests.post(url, data=payload, headers=headers, timeout=15) - Network accessline 4338
} r = requests.post(url, data=payload, headers=headers, timeout=15) d = r.json() - Network accessline 4339
r = requests.post(url, data=payload, headers=headers, timeout=15) - Network accessline 4346
"type": item.get("announcementTypeName", ""), "date": _cninfo_ts_to_date(item.get("announcementTime")), "url": f"https://www.cninfo.com.cn/new/disclosure/detail?annoId={item.get('announcementId', '')}", - Network accessline 4347
"date": _cninfo_ts_to_date(item.get("announcementTime")), "url": f"https://www.cninfo.com.cn/new/disclosure/detail?annoId={item.get('announcementId', '')}", }) - Network accessline 4348
"url": f"https://www.cninfo.com.cn/new/disclosure/detail?annoId={item.get('announcementId', '')}", - Network accessline 4387
endpoint: getTopicZTPool / getTopicZBPool / getTopicDTPool / getYesterdayZTPool 返回 data.pool 原始列表(data 为 null = 非交易日 / 参数错)。""" url = f"https://push2ex.eastmoney.com/{endpoint}" - Network accessline 4388
返回 data.pool 原始列表(data 为 null = 非交易日 / 参数错)。""" url = f"https://push2ex.eastmoney.com/{endpoint}" params = {"ut": ZTB_UT, "dpt": "wz.ztzt", "Pageindex": 0, - Network accessline 4389
url = f"https://push2ex.eastmoney.com/{endpoint}" - Network accessline 4390
params = {"ut": ZTB_UT, "dpt": "wz.ztzt", "Pageindex": 0, "pagesize": 10000, "sort": sort, "date": date} headers = {"User-Agent": UA, "Referer": "https://quote.eastmoney.com/"} - Network accessline 4391
"pagesize": 10000, "sort": sort, "date": date} headers = {"User-Agent": UA, "Referer": "https://quote.eastmoney.com/"} try: - Network accessline 4392
headers = {"User-Agent": UA, "Referer": "https://quote.eastmoney.com/"} - Network accessline 4470
seal_rate(封板成功率,0~1)/break_times(炸板次数)/seal_amount(封单额,元)/ high_days(几天几板)/first_time(首次涨停时间)/is_again(是否回封 0/1)""" url = "https://data.10jqka.com.cn/dataapi/limit_up/limit_up_pool" - Network accessline 4471
high_days(几天几板)/first_time(首次涨停时间)/is_again(是否回封 0/1)""" url = "https://data.10jqka.com.cn/dataapi/limit_up/limit_up_pool" params = {"page": 1, "limit": 200, - Network accessline 4472
url = "https://data.10jqka.com.cn/dataapi/limit_up/limit_up_pool" - Network accessline 4475
"filter": "HS,GEM2STAR", "order_field": "330324", "order_type": "0", "date": date} try: r = requests.get(url, params=params, headers={"User-Agent": UA}, timeout=10) - Network accessline 4476
try: r = requests.get(url, params=params, headers={"User-Agent": UA}, timeout=10) info = (r.json().get("data") or {}).get("info", []) - Network accessline 4477
r = requests.get(url, params=params, headers={"User-Agent": UA}, timeout=10) - Network accessline 4541
MONITOR_URL = "https://mobappconfig.securities.eastmoney.com/emcfg/stock_monitor.json" - Network accessline 4551
返回: [{code, name, market, start, end, link}] """ r = em_get(MONITOR_URL, headers={"Referer": "https://vipmoney.eastmoney.com/"}, timeout=20) - Network accessline 4552
""" r = em_get(MONITOR_URL, headers={"Referer": "https://vipmoney.eastmoney.com/"}, timeout=20) rows = r.json() or [] - Network accessline 4553
r = em_get(MONITOR_URL, headers={"Referer": "https://vipmoney.eastmoney.com/"}, timeout=20) - Network accessline 4591
ANOMALY_BASE = "https://dycalchis.eastmoney.com/price-anomaly" - Network accessline 4624
params = {**HQ_PARAMS, "pageSize": str(page_size), "pageNo": str(page_no), **extra} r = em_get(f"{ANOMALY_BASE}/{path}", params=params, headers={"Referer": "https://vipmoney.eastmoney.com/"}, timeout=20) - Network accessline 4625
r = em_get(f"{ANOMALY_BASE}/{path}", params=params, headers={"Referer": "https://vipmoney.eastmoney.com/"}, timeout=20) d = r.json() - Network accessline 4626
headers={"Referer": "https://vipmoney.eastmoney.com/"}, timeout=20) - Network accessline 4702
SINA_OPT_HDR = {"Referer": "https://stock.finance.sina.com.cn/", "User-Agent": UA} - Network accessline 4708
def _sina_opt_list(param: str) -> list: """新浪 hq.sinajs.cn 取值(GBK,逗号分隔,去 var hq_str_XXX="..." 壳)。""" r = requests.get(f"https://hq.sinajs.cn/list={param}", headers=SINA_OPT_HDR, timeout=10) - Network accessline 4709
"""新浪 hq.sinajs.cn 取值(GBK,逗号分隔,去 var hq_str_XXX="..." 壳)。""" r = requests.get(f"https://hq.sinajs.cn/list={param}", headers=SINA_OPT_HDR, timeout=10) r.encoding = "gbk" - Network accessline 4710
r = requests.get(f"https://hq.sinajs.cn/list={param}", headers=SINA_OPT_HDR, timeout=10) - Network accessline 4718
cate = {"510050": "50ETF", "510300": "300ETF", "588000": "科创50ETF", "510500": "500ETF"}.get(underlying, "50ETF") url = ("https://stock.finance.sina.com.cn/futures/api/openapi.php/" - Network accessline 4719
"588000": "科创50ETF", "510500": "500ETF"}.get(underlying, "50ETF") url = ("https://stock.finance.sina.com.cn/futures/api/openapi.php/" f"StockOptionService.getStockName?exchange=null&cate={cate}") - Network accessline 4720
url = ("https://stock.finance.sina.com.cn/futures/api/openapi.php/" - Network accessline 4721
f"StockOptionService.getStockName?exchange=null&cate={cate}") try: months = requests.get(url, headers=SINA_OPT_HDR, timeout=10).json()["result"]["data"]["contractMonth"] - Network accessline 4722
try: months = requests.get(url, headers=SINA_OPT_HDR, timeout=10).json()["result"]["data"]["contractMonth"] except Exception as e: - Network accessline 4723
months = requests.get(url, headers=SINA_OPT_HDR, timeout=10).json()["result"]["data"]["contractMonth"] - Network accessline 4771
> **坑:** ① 新浪源 **GBK 编码**、**逗号分隔**、需去 `var hq_str_XXX="..."` 壳。② 必带 `Referer: https://stock.finance.sina.com.cn/`,否则 403。③ 希腊字母解析 **`[raw[0]] + raw[4:]`**——`raw[1:4]` 是 3 个空串,不跳过则 Delta/IV 全错位。④ `iv` 是小数(0.1735 = 17.35%)。⑤ 300ETF(510300)、科创 - Network accessline 4788
answerer(回答方)/ask_time。""" try: r1 = requests.post("https://irm.cninfo.com.cn/newircs/index/queryKeyboardInfo", - Network accessline 4789
try: r1 = requests.post("https://irm.cninfo.com.cn/newircs/index/queryKeyboardInfo", data={"keyWord": code}, headers={"User-Agent": UA}, timeout=10) - Network accessline 4790
r1 = requests.post("https://irm.cninfo.com.cn/newircs/index/queryKeyboardInfo", - Network accessline 4797
params = {"_t": 1, "stockcode": code, "orgId": org_id, "pageSize": page_size, "pageNum": page_num, "keyWord": "", "startDay": "", "endDay": ""} r2 = requests.post("https://irm.cninfo.com.cn/newircs/company/question - Network accessline 4798
"pageNum": page_num, "keyWord": "", "startDay": "", "endDay": ""} r2 = requests.post("https://irm.cninfo.com.cn/newircs/company/question", params=params, headers={"User-Agent": UA}, timeout=10) - Network accessline 4799
r2 = requests.post("https://irm.cninfo.com.cn/newircs/company/question", - Network accessline 4829
返回每只: rank/code/name/heat(人气值)/pct/rank_chg(排名变化)/concepts(概念标签)/tag。""" try: r = requests.get("https://dq.10jqka.com.cn/fuyao/hot_list_data/out/hot_list/v1/stock", - Network accessline 4830
try: r = requests.get("https://dq.10jqka.com.cn/fuyao/hot_list_data/out/hot_list/v1/stock", params={"stock_type": "a", "type": period, "list_type": "normal"}, - Network accessline 4831
r = requests.get("https://dq.10jqka.com.cn/fuyao/hot_list_data/out/hot_list/v1/stock", - Network accessline 4847
"""东财人气榜(排名 + 排名变化 + 名称/价格)。返回 rank/code/name/price/pct/rank_chg。""" try: r = requests.post("https://emappdata.eastmoney.com/stockrank/getAllCurrentList", - Network accessline 4848
try: r = requests.post("https://emappdata.eastmoney.com/stockrank/getAllCurrentList", json={**EM_HOT_BODY, "marketType": "", "pageNo": 1, "pageSize": top}, - Network accessline 4849
r = requests.post("https://emappdata.eastmoney.com/stockrank/getAllCurrentList", - Network accessline 4855
# 人气榜只给带前缀代码,用 push2 ulist.np 批量补名称/价格 secids = [("0." if it["sc"].startswith("SZ") else "1.") + it["sc"][2:] for it in data] u = requests.get("https://push2.eastmoney.com/api/qt/ulist.np/get", - Network accessline 4856
secids = [("0." if it["sc"].startswith("SZ") else "1.") + it["sc"][2:] for it in data] u = requests.get("https://push2.eastmoney.com/api/qt/ulist.np/get", params={"ut": "f057cbcbce2a86e2866ab8877db1d059", "fltt": 2, "inv - Network accessline 4857
u = requests.get("https://push2.eastmoney.com/api/qt/ulist.np/get", - Network accessline 4858
params={"ut": "f057cbcbce2a86e2866ab8877db1d059", "fltt": 2, "invt": 2, "fields": "f14,f3,f12,f2", "secids": ",".join(secids)}, headers={"User-Agent": UA, "Referer": "https://quote.eastmoney.com/"}, timeout=1 - Network accessline 4859
"fields": "f14,f3,f12,f2", "secids": ",".join(secids)}, headers={"User-Agent": UA, "Referer": "https://quote.eastmoney.com/"}, timeout=10) diff = (u.json().get("data") or {}).get("diff") or [] - Network accessline 4860
headers={"User-Agent": UA, "Referer": "https://quote.eastmoney.com/"}, timeout=10) - Network accessline 4879
try: prefix = get_prefix(code).upper() # #46;emappdata 用大写 SH/SZ/BJ r = requests.post("https://emappdata.eastmoney.com/stockrank/getHotStockRankList", - Network accessline 4880
prefix = get_prefix(code).upper() # #46;emappdata 用大写 SH/SZ/BJ r = requests.post("https://emappdata.eastmoney.com/stockrank/getHotStockRankList", json={**EM_HOT_BODY, "srcSecurityCode": prefix + code}, - Network accessline 4881
r = requests.post("https://emappdata.eastmoney.com/stockrank/getHotStockRankList", - Network accessline 4916
SSE_E_BASE = "https://sns.sseinfo.com" - Network accessline 5154
_UA = {"User-Agent": "Mozilla/5.0"} PBC_BASE = "https://www.pbc.gov.cn" - Network accessline 5155
PBC_BASE = "https://www.pbc.gov.cn" - Network accessline 5159
def _macro_get(url: str, timeout: int = 30) -> str: r = requests.get(url, headers=_UA, timeout=timeout) - Network accessline 5160
r = requests.get(url, headers=_UA, timeout=timeout) - Network accessline 5191
content = requests.get(_abs_pbc(books[0]), headers=_UA, timeout=60).content - Network accessline 5268
NBS_INDEX = "https://www.stats.gov.cn/sj/zxfb/" - Network accessline 5273
"""与 §11.1 同名同实现 —— 本块按「端点路由速查」单独取用时也能独立跑, 不必先执行 §11.1。两处同时执行时后定义覆盖前者,行为一致,无副作用。""" r = requests.get(url, headers=_UA, timeout=timeout) - Network accessline 5274
不必先执行 §11.1。两处同时执行时后定义覆盖前者,行为一致,无副作用。""" r = requests.get(url, headers=_UA, timeout=timeout) r.raise_for_status() - Network accessline 5275
r = requests.get(url, headers=_UA, timeout=timeout) - Network accessline 5375
CHINABOND_HISTORY_URL = "https://yield.chinabond.com.cn/cbweb-pbc-web/pbc/historyQuery" - Network accessline 5463
CHINAMONEY_FIXING_URL = "https://www.chinamoney.com.cn/r/cms/www/chinamoney/data/currency/{name}-chrt.csv" - Network accessline 5476
raise ValueError("kind 只能是 'FR' 或 'FDR'") url = CHINAMONEY_FIXING_URL.format(name=names[kind]) response = _v39_http(url, headers={"Referer": "https://www.chinamoney.com.cn/chinese/bkfrr/"}) - Network accessline 5477
url = CHINAMONEY_FIXING_URL.format(name=names[kind]) response = _v39_http(url, headers={"Referer": "https://www.chinamoney.com.cn/chinese/bkfrr/"}) rows = [] - Network accessline 5478
response = _v39_http(url, headers={"Referer": "https://www.chinamoney.com.cn/chinese/bkfrr/"}) - Network accessline 5536
WSCN_MACRO_URL = "https://api-one-wscn.awtmt.com/apiv1/finance/macrodatas" - Network accessline 5687
def _official_get(url, params=None, referer=None): response = requests.get( - Network accessline 5688
response = requests.get( - Network accessline 5727
if provider == "csi": kind = "closeweight" if weights else "cons" url = ("https://oss-ch.csindex.com.cn/static/html/csindex/public/uploads/file/" - Network accessline 5728
kind = "closeweight" if weights else "cons" url = ("https://oss-ch.csindex.com.cn/static/html/csindex/public/uploads/file/" f"autofile/{kind}/{index_code}{kind}.xls") - Network accessline 5729
url = ("https://oss-ch.csindex.com.cn/static/html/csindex/public/uploads/file/" - Network accessline 5736
cols.append("权重(%)weight") else: url = "https://www.cnindex.com.cn/sample-detail/download-history" - Network accessline 5737
else: url = "https://www.cnindex.com.cn/sample-detail/download-history" response = _official_get(url, {"indexcode": index_code}) - Network accessline 5738
url = "https://www.cnindex.com.cn/sample-detail/download-history" - Network accessline 5790
"""中证近期 PE/股息率文件;不含 PB,两种股本口径不混用。""" index_code = _official_code(index_code) url = ("https://oss-ch.csindex.com.cn/static/html/csindex/public/uploads/file/" - Network accessline 5791
index_code = _official_code(index_code) url = ("https://oss-ch.csindex.com.cn/static/html/csindex/public/uploads/file/" f"autofile/indicator/{index_code}indicator.xls") - Network accessline 5792
url = ("https://oss-ch.csindex.com.cn/static/html/csindex/public/uploads/file/" - Network accessline 5814
last = calendar.monthrange(year, month)[1] expected = {datetime(year, month, day).date().isoformat() for day in range(1, last + 1)} url = "https://www.szse.cn/api/report/exchange/onepersistenthour/monthList" - Network accessline 5815
expected = {datetime(year, month, day).date().isoformat() for day in range(1, last + 1)} url = "https://www.szse.cn/api/report/exchange/onepersistenthour/monthList" response = _official_get(url, {"month": f"{year}-{month}"}) - Network accessline 5816
url = "https://www.szse.cn/api/report/exchange/onepersistenthour/monthList" - Network accessline 5844
原始端点的发现与交叉核对参考: [AKShare 中证成分](https://github.com/akfamily/akshare/blob/main/akshare/index/index_cons.py)、 - Network accessline 5845
[AKShare 中证成分](https://github.com/akfamily/akshare/blob/main/akshare/index/index_cons.py)、 - Network accessline 5846
[AKShare 中证估值](https://github.com/akfamily/akshare/blob/main/akshare/index/index_stock_zh_csindex.py)、 - Network accessline 5847
[AKShare 国证](https://github.com/akfamily/akshare/blob/main/akshare/index/index_cni.py)、 - Network accessline 5848
[Qlib 交易日历](https://github.com/microsoft/qlib/blob/main/scripts/data_collector/utils.py)。 - Network accessline 5885
FUTURES_EXCHANGES = ("SHFE", "INE", "CZCE", "CFFEX", "GFEX") _SHFE_HOSTS = {"SHFE": "https://www.shfe.com.cn", "INE": "https://www.ine.cn"} - Network accessline 5886
_SHFE_HOSTS = {"SHFE": "https://www.shfe.com.cn", "INE": "https://www.ine.cn"} - Network accessline 5887
CZCE_FILE_URL = "https://www.czce.com.cn/cn/DFSStaticFiles/{kind}/{year}/{ymd}/{name}.txt" - Network accessline 5888
CZCE_FIRST_DAY = "20150921" # 郑商所现行文件路径的第一天;更早是另一套无表头 CSV,未接入 CFFEX_DAILY_URL = "http://www.cffex.com.cn/fzjy/mrhq/{ym}/{dd}/{ymd}_1.csv" CFFEX_DAILY_XML = "http://www.cffex.com.cn/fzjy/mrhq/{ym}/{dd}/index.xml" - Network accessline 5889
CFFEX_DAILY_URL = "http://www.cffex.com.cn/fzjy/mrhq/{ym}/{dd}/{ymd}_1.csv" - Network accessline 5890
CFFEX_DAILY_XML = "http://www.cffex.com.cn/fzjy/mrhq/{ym}/{dd}/index.xml" - Network accessline 5891
CFFEX_RANK_URL = "http://www.cffex.com.cn/sj/ccpm/{ym}/{dd}/{product}_1.csv" - Network accessline 5893
CFFEX_RANK_FIRST_DAY = {"IF": "20100416", "IH": "20150416", "IC": "20150416", "IM": "20220722", "TS": "20180817", "TF": "20130906", "T": "20150320", "TL": "20230421"} GFEX_DAILY_URL = "http://www.gfex.com.cn/u/interf - Network accessline 5894
"TS": "20180817", "TF": "20130906", "T": "20150320", "TL": "20230421"} GFEX_DAILY_URL = "http://www.gfex.com.cn/u/interfacesWebTiDayQuotes/loadList" SINA_HQ_URL = "https://hq.sinajs.cn/list=" - Network accessline 5895
GFEX_DAILY_URL = "http://www.gfex.com.cn/u/interfacesWebTiDayQuotes/loadList" - Network accessline 5896
SINA_HQ_URL = "https://hq.sinajs.cn/list=" - Network accessline 5897
SINA_FUT_KLINE_URL = ("https://stock2.finance.sina.com.cn/futures/api/jsonp.php/var%20_{code}=" - Network accessline 5898
"/InnerFuturesNewService.getDailyKLine") SGE_DAILY_URL = "https://www.sge.com.cn/graph/Dailyhq" _CFFEX_SINA_PRODUCTS = ("IF", "IH", "IC", "IM", "TS", "TF", "T", "TL") - Network accessline 5899
SGE_DAILY_URL = "https://www.sge.com.cn/graph/Dailyhq" - Network accessline 6090
def _gfex_rows(ymd, trade_type): response = _v39_http(GFEX_DAILY_URL, method="POST", data={"trade_date": ymd, "trade_type": trade_type}, headers={"Referer": "http://www.gfex.com.cn/gfex/rihq/hqsj_tjsj.shtml"}) - Network accessline 6091
response = _v39_http(GFEX_DAILY_URL, method="POST", data={"trade_date": ymd, "trade_type": trade_type}, headers={"Referer": "http://www.gfex.com.cn/gfex/rihq/hqsj_tjsj.shtml"}) payload = _v39_json(response) - Network accessline 6092
headers={"Referer": "http://www.gfex.com.cn/gfex/rihq/hqsj_tjsj.shtml"}) - Network accessline 6436
def _sina_hq(codes): response = _v39_http(SINA_HQ_URL + ",".join(codes), headers={"Referer": "https://finance.sina.com.cn/"}) - Network accessline 6437
response = _v39_http(SINA_HQ_URL + ",".join(codes), headers={"Referer": "https://finance.sina.com.cn/"}) - Network accessline 6523
raise ValueError(f"start {lo} 晚于 end {hi}") response = _v39_http(SINA_FUT_KLINE_URL.format(code=code), params={"symbol": code}, timeout=(5, 20), headers={"Referer": "https://finance.sina.com.cn/"}, session=V39_R - Network accessline 6524
response = _v39_http(SINA_FUT_KLINE_URL.format(code=code), params={"symbol": code}, timeout=(5, 20), headers={"Referer": "https://finance.sina.com.cn/"}, session=V39_RETRY_SESSION) text = response.content.decode - Network accessline 6525
headers={"Referer": "https://finance.sina.com.cn/"}, session=V39_RETRY_SESSION) - Network accessline 6582
""" response = _v39_http(SGE_DAILY_URL, method="POST", data={"instid": instrument}, headers={"Referer": "https://www.sge.com.cn/"}) - Network accessline 6583
response = _v39_http(SGE_DAILY_URL, method="POST", data={"instid": instrument}, headers={"Referer": "https://www.sge.com.cn/"}) payload = _v39_json(response) - Network accessline 6584
headers={"Referer": "https://www.sge.com.cn/"}) - Network accessline 7132
prefix = ("bj" if code.startswith(("92", "8")) else "sh" if code.startswith(("6", "9")) else "sz") url = f"https://qt.gtimg.cn/q={prefix}{code}" - Network accessline 7133
else "sh" if code.startswith(("6", "9")) else "sz") url = f"https://qt.gtimg.cn/q={prefix}{code}" req = urllib.request.Request(url) - Network accessline 7134
url = f"https://qt.gtimg.cn/q={prefix}{code}" req = urllib.request.Request(url) req.add_header("User-Agent", "Mozilla/5.0") - Network accessline 7135
req = urllib.request.Request(url) - Network accessline 7136
req.add_header("User-Agent", "Mozilla/5.0") resp = urllib.request.urlopen(req, timeout=10) data = resp.read().decode("gbk") - Network accessline 7137
resp = urllib.request.urlopen(req, timeout=10) - Network accessline 7337
code = _official_margin_code(code, exchange) if exchange == "SH": url = "https://query.sse.com.cn/marketdata/tradedata/queryMargin.do" - Network accessline 7338
if exchange == "SH": url = "https://query.sse.com.cn/marketdata/tradedata/queryMargin.do" response = _official_get(url, { - Network accessline 7339
url = "https://query.sse.com.cn/marketdata/tradedata/queryMargin.do" - Network accessline 7342
"pageHelp.pageSize": 5000, "pageHelp.pageNo": 1, "pageHelp.beginPage": 1, "pageHelp.cacheSize": 1, "pageHelp.endPage": 1, }, "https://www.sse.com.cn/") - Network accessline 7343
"pageHelp.cacheSize": 1, "pageHelp.endPage": 1, }, "https://www.sse.com.cn/") page = response.json().get("pageHelp") or {} - Network accessline 7344
}, "https://www.sse.com.cn/") - Network accessline 7360
for src, dest in fields.items()}}) else: url = "https://www.szse.cn/api/report/ShowReport" - Network accessline 7361
else: url = "https://www.szse.cn/api/report/ShowReport" response = _official_get(url, {"SHOWTYPE": "xlsx", "CATALOGID": "1837_xxpl", - Network accessline 7362
url = "https://www.szse.cn/api/report/ShowReport" - Network accessline 7363
response = _official_get(url, {"SHOWTYPE": "xlsx", "CATALOGID": "1837_xxpl", "TABKEY": "tab2", "txtDate": trade_date}, "https://www.szse.cn/") data = _official_excel(response) - Network accessline 7364
"TABKEY": "tab2", "txtDate": trade_date}, "https://www.szse.cn/") - Network accessline 7383
if not code.startswith(("4", "8", "92")): raise ValueError("请输入北交所代码(4/8/92 开头)") page_url = "https://www.bse.cn/nq/quotation.html" - Network accessline 7384
raise ValueError("请输入北交所代码(4/8/92 开头)") page_url = "https://www.bse.cn/nq/quotation.html" url = "https://www.bse.cn/nqhqController/nqhq_en.do" - Network accessline 7385
page_url = "https://www.bse.cn/nq/quotation.html" - Network accessline 7386
url = "https://www.bse.cn/nqhqController/nqhq_en.do" - Network accessline 7387
raw_rows = [] total = None with requests.Session() as session: - Network accessline 7388
total = None with requests.Session() as session: session.headers.update({"User-Agent": "Mozilla/5.0", "Referer": page_url, - Network accessline 7389
with requests.Session() as session: - Network accessline 7449
端点与字段交叉参考 [CNEquity 两融适配](https://github.com/rootSunc/CNEquity/blob/main/src/cnequity/adapters/exchange/margin_trading.py) - Network accessline 7450
及 [北交所适配](https://github.com/rootSunc/CNEquity/blob/main/src/cnequity/adapters/bse/daily_quotes.py)。 - Network accessline 7535
"""龙虎榜官方备用源(东财被封时用):上交所+深交所官方,零鉴权权威一手,含营业部席位。""" out = {"date": trade_date, "sse_raw": "", "szse": []} su = (f"https://www.szse.cn/api/report/ShowReport/data?SHOWTYPE=JSON" - Network accessline 7536
out = {"date": trade_date, "sse_raw": "", "szse": []} su = (f"https://www.szse.cn/api/report/ShowReport/data?SHOWTYPE=JSON" f"&CATALOGID=1842_xxpl&TABKEY=tab1&txtStart={trade_date}&txtEnd={trade_date}&random=0.9") - Network accessline 7537
su = (f"https://www.szse.cn/api/report/ShowReport/data?SHOWTYPE=JSON" f"&CATALOGID=1842_xxpl&TABKEY=tab1&txtStart={trade_date}&txtEnd={trade_date}&random=0.9") req = urllib.request.Request(su, headers={"User-Agent": UA, - Network accessline 7538
f"&CATALOGID=1842_xxpl&TABKEY=tab1&txtStart={trade_date}&txtEnd={trade_date}&random=0.9") req = urllib.request.Request(su, headers={"User-Agent": UA, "Referer": "https://www.szse.cn/disclosure/supervision/dealinfo/index.html"} - Network accessline 7539
req = urllib.request.Request(su, headers={"User-Agent": UA, - Network accessline 7540
"Referer": "https://www.szse.cn/disclosure/supervision/dealinfo/index.html"}) with urllib.request.urlopen(req, timeout=15, context=_ctx) as r: d = json.loads(r.read()) - Network accessline 7541
with urllib.request.urlopen(req, timeout=15, context=_ctx) as r: - Network accessline 7544
out["szse"].append({"code": row.get("zqdm"), "name": row.get("zqjc"), "amount": row.get("cjje"), "reason": row.get("plyy")}) eu = (f"https://query.sse.com.cn/infodisplay/showTradePublicFile.do?" - Network accessline 7545
"amount": row.get("cjje"), "reason": row.get("plyy")}) eu = (f"https://query.sse.com.cn/infodisplay/showTradePublicFile.do?" f"jsonCallBack=cb&isPagination=false&dateTx={trade_date}") - Network accessline 7546
eu = (f"https://query.sse.com.cn/infodisplay/showTradePublicFile.do?" f"jsonCallBack=cb&isPagination=false&dateTx={trade_date}") req = urllib.request.Request(eu, headers={"User-Agent": UA, - Network accessline 7547
f"jsonCallBack=cb&isPagination=false&dateTx={trade_date}") req = urllib.request.Request(eu, headers={"User-Agent": UA, "Referer": "https://www.sse.com.cn/disclosure/diclosure/public/"}) - Network accessline 7548
req = urllib.request.Request(eu, headers={"User-Agent": UA, - Network accessline 7549
"Referer": "https://www.sse.com.cn/disclosure/diclosure/public/"}) with urllib.request.urlopen(req, timeout=15) as r: t = r.read().decode("utf-8", "ignore") - Network accessline 7550
with urllib.request.urlopen(req, timeout=15) as r: - Network accessline 7558
pre = ("bj" if code.startswith(("92", "8")) else "sh" if code.startswith(("6", "9")) else "sz") + code u = (f"https://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/" - Network accessline 7559
else "sh" if code.startswith(("6", "9")) else "sz") + code u = (f"https://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/" f"MoneyFlow.ssl_qsfx_zjlrqs?page=1&num={days}&sort=opendate&asc=0&daima={pre}") - Network accessline 7560
u = (f"https://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/" f"MoneyFlow.ssl_qsfx_zjlrqs?page=1&num={days}&sort=opendate&asc=0&daima={pre}") req = urllib.request.Request(u, headers={"User-Agent": UA, "Referer": - Network accessline 7561
f"MoneyFlow.ssl_qsfx_zjlrqs?page=1&num={days}&sort=opendate&asc=0&daima={pre}") req = urllib.request.Request(u, headers={"User-Agent": UA, "Referer": "https://finance.sina.com.cn/"}) with urllib.request.urlopen(req, timeout=15) as r - Network accessline 7562
req = urllib.request.Request(u, headers={"User-Agent": UA, "Referer": "https://finance.sina.com.cn/"}) - Network accessline 7563
with urllib.request.urlopen(req, timeout=15) as r: - Network accessline 7572
body = json.dumps({"channelCode": ["listedNotice_disc"], "pageSize": page_size, "pageNum": 1, "stock": [code]}).encode() req = urllib.request.Request("https://www.szse.cn/api/disc/announcement/annList", da - Network accessline 7573
"pageNum": 1, "stock": [code]}).encode() req = urllib.request.Request("https://www.szse.cn/api/disc/announcement/annList", data=body, headers={"User-Agent": UA, "Content-Type": "application/json", - Network accessline 7574
req = urllib.request.Request("https://www.szse.cn/api/disc/announcement/annList", data=body, - Network accessline 7575
headers={"User-Agent": UA, "Content-Type": "application/json", "Referer": "https://www.szse.cn/disclosure/listed/notice/index.html"}) with urllib.request.urlopen(req, timeout=15, context=_ctx) as r: - Network accessline 7576
"Referer": "https://www.szse.cn/disclosure/listed/notice/index.html"}) with urllib.request.urlopen(req, timeout=15, context=_ctx) as r: d = json.loads(r.read()) - Network accessline 7577
with urllib.request.urlopen(req, timeout=15, context=_ctx) as r: - Network accessline 7578
d = json.loads(r.read()) return [{"title": a.get("title"), "time": a.get("publishTime", "")[:10], "pdf": "https://disc.static.szse.cn/download" + a.get("attachPath", "")} - Network accessline 7579
return [{"title": a.get("title"), "time": a.get("publishTime", "")[:10], "pdf": "https://disc.static.szse.cn/download" + a.get("attachPath", "")} for a in d.get("data", [])] - Network accessline 7580
"pdf": "https://disc.static.szse.cn/download" + a.get("attachPath", "")} - Network accessline 7581
for a in d.get("data", [])] u = (f"https://np-anotice-stock.eastmoney.com/api/security/ann?sr=-1&page_size={page_size}" f"&page_index=1&ann_type=A&client_source=web&stock_list={code}&f_node=0&s_node=0") - Network accessline 7582
u = (f"https://np-anotice-stock.eastmoney.com/api/security/ann?sr=-1&page_size={page_size}" f"&page_index=1&ann_type=A&client_source=web&stock_list={code}&f_node=0&s_node=0") req = urllib.request.Request(u, headers={"User-Agent - Network accessline 7583
f"&page_index=1&ann_type=A&client_source=web&stock_list={code}&f_node=0&s_node=0") req = urllib.request.Request(u, headers={"User-Agent": UA}) with urllib.request.urlopen(req, timeout=15) as r: - Network accessline 7584
req = urllib.request.Request(u, headers={"User-Agent": UA}) - Network accessline 7585
with urllib.request.urlopen(req, timeout=15) as r: - Network accessline 7586
d = json.loads(r.read()) return [{"title": a.get("title"), "time": a.get("notice_date", "")[:10], "pdf": f"https://pdf.dfcfw.com/pdf/H2_{a.get('art_code','')}_1.pdf"} - Network accessline 7587
return [{"title": a.get("title"), "time": a.get("notice_date", "")[:10], "pdf": f"https://pdf.dfcfw.com/pdf/H2_{a.get('art_code','')}_1.pdf"} for a in (d.get("data") or {}).get("list") or []] # #46 同因 - Network accessline 7588
"pdf": f"https://pdf.dfcfw.com/pdf/H2_{a.get('art_code','')}_1.pdf"} - Network accessline 7647
### Q: 东财 PDF 下载 403 A: 必须带 `Referer: https://data.eastmoney.com/` header。 - Network accessline 7648
A: 必须带 `Referer: https://data.eastmoney.com/` header。 - Access to secretsline 7695
[Credential-related source omitted] - Network accessline 7702
> 📦 https://github.com/simonlin1212/a-stock-data — Star ⭐ 是最好的支持
docs/source-integration-v3.8.0.md
- Network accessline 23
- [AKShare:中证成分/权重](https://github.com/akfamily/akshare/blob/main/akshare/index/index_cons.py) - Network accessline 24
- [AKShare:中证估值](https://github.com/akfamily/akshare/blob/main/akshare/index/index_stock_zh_csindex.py) - Network accessline 25
- [AKShare:国证指数](https://github.com/akfamily/akshare/blob/main/akshare/index/index_cni.py) - Network accessline 26
- [Qlib:深交所交易日历](https://github.com/microsoft/qlib/blob/main/scripts/data_collector/utils.py) - Network accessline 27
- [CNEquity:沪深官方两融](https://github.com/rootSunc/CNEquity/blob/main/src/cnequity/adapters/exchange/margin_trading.py) - Network accessline 28
- [CNEquity:北交所行情](https://github.com/rootSunc/CNEquity/blob/main/src/cnequity/adapters/bse/daily_quotes.py) - Network accessline 78
| 候选 | 已核实价值 | 决定及剩余条件 | |---|---|---| | [easy_tdx](https://github.com/handsomejustin/easy_tdx) | 通达信竞价过程;2026-09-04平安银行实测63点;MIT | 同一通达信数据来源的实现备选。要求Python≥3.10,先验证可选依赖与竞价契约,不改变主包Python3.9兼容 | - Network accessline 79
|---|---|---| | [easy_tdx](https://github.com/handsomejustin/easy_tdx) | 通达信竞价过程;2026-09-04平安银行实测63点;MIT | 同一通达信数据来源的实现备选。要求Python≥3.10,先验证可选依赖与竞价契约,不改变主包Python3.9兼容 | | [eltdx](https://github.com/electkismet/eltdx) | 当日竞价82点及历史09:25快照可用;历史 - Network accessline 80
| [easy_tdx](https://github.com/handsomejustin/easy_tdx) | 通达信竞价过程;2026-09-04平安银行实测63点;MIT | 同一通达信数据来源的实现备选。要求Python≥3.10,先验证可选依赖与竞价契约,不改变主包Python3.9兼容 | - Network accessline 81
| [eltdx](https://github.com/electkismet/eltdx) | 当日竞价82点及历史09:25快照可用;历史完整过程未复现 | 当前 LICENSE 为 Research-Only,限制商业/生产用途;不纳入本Apache-2.0项目,不复制实现 | - Network accessline 82
| [同花顺官方 Financial-API](https://github.com/HiThink-Tech/Financial-API) | 文档含竞价、基金、批量数据等增强能力 | 需用户Key,未做带Key数据验收;不增加强制鉴权,不计入主源数量 | - Network accessline 83
| [TickFlow](https://github.com/tickflow-org/tickflow) | 免费日K实测沪市和北交所成功 | 观察型独立服务备选;本次未确认数据来源、再分发条件和长期服务保障 | - Network accessline 84
| [CNEquity](https://github.com/rootSunc/CNEquity) | 官方端点和日期/分页防错参考,含国证历史调样适配 | 继续作为实现参考;历史调样另需时点验证,不把当前月末文件称为历史成分 | - Network accessline 85
| [AKShare](https://github.com/akfamily/akshare)、[adata](https://github.com/1nchaos/adata)、[efinance](https://github.com/Micro-sheep/efinance)、[Ashare](https://github.com/mpquant/Ashare) | 可检索上游端点与解析经验 | 多数为已有来源的包装;不作为新独立来源,不恢复运行时依赖 | - Network accessline 86
| [free-stockdb](https://github.com/hello245m/free-stockdb) | 本地存储和同步设计 | 上游数据出处不够清楚,暂不接入 |
docs/source-integration-v3.9.0.md
- Network accessline 47
- [AKShare](https://github.com/akfamily/akshare):期货交易所日行情、持仓排名、上金所、中债、货币网等端点格式 - Network accessline 48
- [jing2uo/tdx2db](https://github.com/jing2uo/tdx2db):通达信官网盘后包地址与 `.cod` / `.md1` 布局 - Network accessline 49
- [Xiaoyuan-Liu/national-team-position](https://github.com/Xiaoyuan-Liu/national-team-position):上交所 ETF 份额归档接口 - Network accessline 93
- 新浪研报每页序号都从 1 编起;翻过末页、以及没有研报的股票,页面都写「没有找到相关内容」。上证e互动问答为空时,公司维度写「近1个月暂无回复 / 暂无提问」, 全市场翻过末页写「暂时没有问答内容」。华尔街见闻宏观日历 31 周 5976 条没有重复 id。 - 中金所、广期所的数据地址只能走 HTTP:2026-09-20 用 curl 8.7.1 与 Python requests 实测,中金所 443 握手即断(SSL_ERROR_SYSCALL), - Network accessline 94
全市场翻过末页写「暂时没有问答内容」。华尔街见闻宏观日历 31 周 5976 条没有重复 id。 - 中金所、广期所的数据地址只能走 HTTP:2026-09-20 用 curl 8.7.1 与 Python requests 实测,中金所 443 握手即断(SSL_ERROR_SYSCALL), 广期所 443 返回的是 `*.unionpayintl.com` 的证书。交易日靠来源自己核对:中金所日行情 / 期权用同目录 `index.xml`,持仓排名用行内交易日, - Network accessline 95
- 中金所、广期所的数据地址只能走 HTTP:2026-09-20 用 curl 8.7.1 与 Python requests 实测,中金所 443 握手即断(SSL_ERROR_SYSCALL),
tests/fixtures/sina_adjust/sh511010-hfq.js
- Executable scriptline 1
Executable file
tests/fixtures/sina_adjust/sh511010-qfq.js
- Executable scriptline 1
Executable file
tests/fixtures/sina_adjust/sh513100-hfq.js
- Executable scriptline 1
Executable file
tests/fixtures/sina_adjust/sh513100-qfq.js
- Executable scriptline 1
Executable file
tests/fixtures/sina_adjust/sh600519-hfq.js
- Possible obfuscationline 1
var sh600519hfq={"total":33,"data":[{"d":"2026-06-26", "f":"8.8825126710204000"},{"d":"2025-12-19", "f":"8.6771454751862000"},{"d":"2025-06-26", "f":"8.5318775687229000"},{"d":"2024-12-20", "f":"8.3678784177632990"},{"d":"2024-06-19", "f":" - Executable scriptline 1
Executable file
tests/fixtures/sina_adjust/sh600519-qfq.js
- Possible obfuscationline 1
var sh600519qfq={"total":33,"data":[{"d":"2026-06-26", "f":"1.0000000000000000"},{"d":"2025-12-19", "f":"1.0236675985693000"},{"d":"2025-06-26", "f":"1.0410970621031000"},{"d":"2024-12-20", "f":"1.0615011628473000"},{"d":"2024-06-19", "f":" - Executable scriptline 1
Executable file
tests/fixtures/sina_adjust/sz159919-hfq.js
- Executable scriptline 1
Executable file
tests/fixtures/sina_adjust/sz159919-qfq.js
- Executable scriptline 1
Executable file
tests/fixtures/sina_adjust/sz161226-hfq.js
- Executable scriptline 1
Executable file
tests/fixtures/sina_adjust/sz161226-qfq.js
- Executable scriptline 1
Executable file
tests/test_official_data.py
- Executable scriptline 1
Executable file - Dangerous shell operationline 27
exec(compile(block, f"SKILL.md:{name}", "exec"), namespace) - Network accessline 33
self.data = data self.status_code = status self.url = "https://official.example/data" - Network accessline 34
self.status_code = status self.url = "https://official.example/data" self.text = json.dumps(data) if data is not None else "" - Network accessline 35
self.url = "https://official.example/data" - Network accessline 46
def raise_for_status(self): if self.status_code >= 400: raise requests.HTTPError(str(self.status_code)) - Network accessline 48
raise requests.HTTPError(str(self.status_code)) - Access to secretsline 290
[Credential-related source omitted] - Access to secretsline 291
[Credential-related source omitted]
tests/test_v310_sources.py
- Executable scriptline 1
Executable file - Dangerous shell operationline 38
exec(compile(_marker_code("v310-tencent-ticks"), "SKILL.md:v310-tencent-ticks", "exec"), ns) - Network accessline 403
RequestException=REAL_REQUESTS.RequestException) with patch.dict(self.ns, {"requests": no_new_connection}): response = self.ns["_v39_http"]("https://example.test/x", params={"a": 1}, session=session) - Network accessline 404
with patch.dict(self.ns, {"requests": no_new_connection}): response = self.ns["_v39_http"]("https://example.test/x", params={"a": 1}, session=session) self.assertEqual(response.content, b"ok") - Network accessline 405
response = self.ns["_v39_http"]("https://example.test/x", params={"a": 1}, session=session) - Network accessline 406
self.assertEqual(response.content, b"ok") self.assertEqual(session.request.call_args[0], ("GET", "https://example.test/x")) self.assertEqual(session.request.call_args[1]["params"], {"a": 1}) - Network accessline 407
self.assertEqual(session.request.call_args[0], ("GET", "https://example.test/x")) - Network accessline 409
session.request.side_effect = REAL_REQUESTS.ConnectionError("reset") with self.assertRaises(RuntimeError): # 重试用完仍失败:照旧是「来源坏了」 self.ns["_v39_http"]("https://example.test/x", session=session) - Network accessline 411
self.ns["_v39_http"]("https://example.test/x", session=session) - Network accessline 415
if tuple(int(p) for p in urllib3.__version__.split(".")[:2]) < (1, 26): self.skipTest("urllib3 < 1.26 没有重试会话,见下一条测试") for url in ("https://stock.gtimg.cn/data/index.php", "https://qt.gtimg.cn/q=sz000001", - Network accessline 416
self.skipTest("urllib3 < 1.26 没有重试会话,见下一条测试") for url in ("https://stock.gtimg.cn/data/index.php", "https://qt.gtimg.cn/q=sz000001", "https://stock2.finance.sina.com.cn/futures/api/jsonp.php/"): - Network accessline 417
for url in ("https://stock.gtimg.cn/data/index.php", "https://qt.gtimg.cn/q=sz000001", - Network accessline 418
"https://stock2.finance.sina.com.cn/futures/api/jsonp.php/"): - Access to secretsline 436
[Credential-related source omitted] - Network accessline 442
("futures_kline M0", lambda: ns["futures_kline"]("M0", start="2026-01-01"))): with self.subTest(name=name): frame = fetch() - Network accessline 443
with self.subTest(name=name): frame = fetch() self.assertGreater(len(frame), 0) - Network accessline 444
frame = fetch()
tests/test_v37_adjust_factor.py
- Executable scriptline 1
Executable file - Dangerous shell operationline 29
exec(_defs_only(block), ns) - Network accessline 43
def factors(self, code, kind="qfq", status=200): suffix = ".html" if status == 404 else ".js" response = requests.Response() - Network accessline 44
suffix = ".html" if status == 404 else ".js" response = requests.Response() response.status_code = status - Network accessline 45
response = requests.Response() - Network accessline 46
response.status_code = status response.url = "https://example.test/" + code + "/" + kind + ".js" response.encoding = "utf-8" - Network accessline 47
response.url = "https://example.test/" + code + "/" + kind + ".js" - Network accessline 114
for kind in ("qfq", "hfq"): for row, expected in cases: response = requests.Response() - Network accessline 115
for row, expected in cases: response = requests.Response() response.status_code = 200 - Network accessline 116
response = requests.Response() - Network accessline 248
def test_malformed_fund_fields_are_runtime_errors(self): for fields in ('"s":"bad","u":"0"', '"s":"1"', '"u":"0"'): response = requests.Response() - Network accessline 249
for fields in ('"s":"bad","u":"0"', '"s":"1"', '"u":"0"'): response = requests.Response() response.status_code = 200 - Network accessline 250
response = requests.Response()
tests/test_v39_sources.py
- Executable scriptline 1
Executable file - Dangerous shell operationline 80
exec(code, namespace) - Network accessline 111
self.text = text if text is not None else content.decode("latin-1") self._payload = payload self.url = "https://example.test/response" - Network accessline 113
self.url = "https://example.test/response" - Network accessline 309
RequestException=REAL_REQUESTS.RequestException) with patch.dict(self.ns, {"requests": fake}): return self.ns["_v39_http"]("https://example.test/x", allow_status=(404,)) - Network accessline 311
return self.ns["_v39_http"]("https://example.test/x", allow_status=(404,)) - Network accessline 481
def fetch(self, response, day="2026-09-18"): - Network accessline 485
def test_parses_all_three_markets(self): out = self.fetch(Response(content=tdx_zip("20260918", ["sh", "sz", "bj"]))) - Network accessline 486
out = self.fetch(Response(content=tdx_zip("20260918", ["sh", "sz", "bj"]))) - Network accessline 493
def test_early_2022_package_without_bse_files(self): out = self.fetch(Response(content=tdx_zip("20220104", ["sh", "sz"])), "2022-01-04") - Network accessline 494
out = self.fetch(Response(content=tdx_zip("20220104", ["sh", "sz"])), "2022-01-04") - Network accessline 499
with self.assertRaises(RuntimeError): self.fetch(Response(content=tdx_zip("20260918", ["sh", "sz"]))) - Network accessline 500
self.fetch(Response(content=tdx_zip("20260918", ["sh", "sz"]))) - Network accessline 501
out = self.fetch(Response(content=tdx_zip("20220505", ["sh", "sz"])), "2022-05-05") - Network accessline 504
def test_missing_shanghai_or_shenzhen_is_an_error(self): with self.assertRaises(RuntimeError): self.fetch(Response(content=tdx_zip("20260918", ["sh", "bj"]))) - Network accessline 506
self.fetch(Response(content=tdx_zip("20260918", ["sh", "bj"]))) - Network accessline 510
with self.assertRaises(RuntimeError): self.fetch(Response(content=tdx_zip("20260918", ["sh", "sz", "bj"], empty=("bj",)))) - Network accessline 511
self.fetch(Response(content=tdx_zip("20260918", ["sh", "sz", "bj"], empty=("bj",)))) - Possible obfuscationline 517
cod[40:44] = b"\xff\xfe\xff\xfe" - Network accessline 522
for tweak in (bad_bytes, blank): with self.subTest(tweak=tweak.__name__), self.assertRaises(RuntimeError): self.fetch(Response(content=tdx_zip("20260918", ["sh", "sz", "bj"], tweak=tweak))) - Network accessline 524
self.fetch(Response(content=tdx_zip("20260918", ["sh", "sz", "bj"], tweak=tweak))) - Network accessline 528
for market in ("sh", "sz", "bj"): with self.subTest(market=market), self.assertRaises(RuntimeError): self.fetch(Response(content=tdx_zip("20260918", ["sh", "sz", "bj"], - Network accessline 529
with self.subTest(market=market), self.assertRaises(RuntimeError): self.fetch(Response(content=tdx_zip("20260918", ["sh", "sz", "bj"], counts={market: TDX_FLOOR[market] - 1 - Network accessline 530
self.fetch(Response(content=tdx_zip("20260918", ["sh", "sz", "bj"], - Network accessline 550
for tweak in (dup_code, dup_seq, blank_code, extra_block): with self.subTest(tweak=tweak.__name__), self.assertRaises(RuntimeError): self.fetch(Response(content=tdx_zip("20260918", ["sh", "sz", "bj"], - Network accessline 551
with self.subTest(tweak=tweak.__name__), self.assertRaises(RuntimeError): self.fetch(Response(content=tdx_zip("20260918", ["sh", "sz", "bj"], counts={"sh": 10001, "sz": 300 - Network accessline 552
self.fetch(Response(content=tdx_zip("20260918", ["sh", "sz", "bj"], - Network accessline 578
for tweak in (bad_byte, letter, nan_close, inf_amount, nan_in_unpriced_block): with self.subTest(tweak=tweak.__name__), self.assertRaises(RuntimeError): self.fetch(Response(content=tdx_zip("20260918", ["sh", "sz" - Network accessline 579
with self.subTest(tweak=tweak.__name__), self.assertRaises(RuntimeError): self.fetch(Response(content=tdx_zip("20260918", ["sh", "sz", "bj"], counts={"sh": 10001, "sz": 300 - Network accessline 580
self.fetch(Response(content=tdx_zip("20260918", ["sh", "sz", "bj"], - Network accessline 584
def test_404_is_value_error_and_error_page_is_runtime_error(self): with self.assertRaises(ValueError): self.fetch(Response(status=404)) - Network accessline 585
with self.assertRaises(ValueError): self.fetch(Response(status=404)) with self.assertRaises(RuntimeError): - Network accessline 586
self.fetch(Response(status=404)) - Network accessline 588
self.fetch(Response(content=b"<html>error</html>")) - Network accessline 593
for content in (b"PK\x03\x04broken", good[:len(good) // 2]): with self.subTest(size=len(content)), self.assertRaises(RuntimeError): self.fetch(Response(content=content)) - Network accessline 595
self.fetch(Response(content=content)) - Network accessline 760
ns = load_shipped_code() page = MagicMock(return_value=(MagicMock(url="https://sina.example"), - Network accessline 761
page = MagicMock(return_value=(MagicMock(url="https://sina.example"), - Network accessline 772
def reports(self, body): ns = load_shipped_code() page = MagicMock(return_value=(MagicMock(url="https://sina.example"), - Network accessline 773
ns = load_shipped_code() page = MagicMock(return_value=(MagicMock(url="https://sina.example"), f"<table class=tb_01><tr><th>研究员</th></tr>{body}</table>")) - Network accessline 774
page = MagicMock(return_value=(MagicMock(url="https://sina.example"), - Network accessline 1029
class EtfSharesSseTests(unittest.TestCase): def fetch(self, result, total, day="2026-09-18"): - Network accessline 1030
def fetch(self, result, total, day="2026-09-18"): - Network accessline 1040
rec = {"STAT_DATE": "2026-09-18", "SEC_CODE": "510300", "SEC_NAME": "样本ETF", "TOT_VOL": "1,234.5"} rows, _ = self.fetch([rec, dict(rec, SEC_CODE="510500")], 2) - Network accessline 1041
rows, _ = self.fetch([rec, dict(rec, SEC_CODE="510500")], 2) - Network accessline 1042
self.assertEqual([r["code"] for r in rows], ["510300", "510500"]) with self.assertRaises(ValueError): # 非交易日:result 空、total 0 self.fetch([], 0, "2026-09-19") - Network accessline 1043
with self.assertRaises(ValueError): # 非交易日:result 空、total 0 self.fetch([], 0, "2026-09-19") for result, total in (([rec], 912), ([rec], True), ([rec], None), ([], 3), ([rec, "x"], 2), - Network accessline 1044
self.fetch([], 0, "2026-09-19") - Network accessline 1047
([dict(rec, TOT_VOL="")], 1), ([dict(rec, TOT_VOL="-")], 1)): with self.subTest(total=total, n=len(result)), self.assertRaises(RuntimeError): self.fetch(result, total) - Network accessline 1049
self.fetch(result, total) - Network accessline 1061
def fetch(self, *pages): - Network accessline 1066
def test_complete_pages_match_record_count(self): rows, _ = self.fetch(self.page(1), self.page(1)) - Network accessline 1067
rows, _ = self.fetch(self.page(1), self.page(1)) - Network accessline 1074
broken = Response(text="x", payload=[{"metadata": meta, "data": [rec]}]) with self.assertRaises(RuntimeError): self.fetch(broken, self.page(1)) - Network accessline 1076
self.fetch(broken, self.page(1)) - Network accessline 1078
def test_empty_page_or_count_mismatch_raises(self): with self.assertRaises(RuntimeError): self.fetch(self.page(1), self.page(0)) # 第 2 页空:只返回第 1 页就是部分快照 - Network accessline 1079
with self.assertRaises(RuntimeError): self.fetch(self.page(1), self.page(0)) # 第 2 页空:只返回第 1 页就是部分快照 with self.assertRaises(RuntimeError): # 总数也跟着少报时,只有空页检查拦得住 - Network accessline 1080
self.fetch(self.page(1), self.page(0)) # 第 2 页空:只返回第 1 页就是部分快照 - Network accessline 1081
with self.assertRaises(RuntimeError): # 总数也跟着少报时,只有空页检查拦得住 self.fetch(self.page(1, recordcount=1), self.page(0, recordcount=1)) with self.assertRaises(RuntimeError): - Network accessline 1082
self.fetch(self.page(1, recordcount=1), self.page(0, recordcount=1)) - Network accessline 1084
self.fetch(self.page(1, recordcount=3), self.page(1, recordcount=3)) - Network accessline 1090
self.page(50, pagecount=2, recordcount=150, subname="2026-09-21")): with self.subTest(meta=second._payload[0]["metadata"]), self.assertRaises(RuntimeError): self.fetch(first, second) - Network accessline 1091
with self.subTest(meta=second._payload[0]["metadata"]), self.assertRaises(RuntimeError): self.fetch(first, second) with self.assertRaises(ValueError): # 第 1 页日期不符才是「深市只有当前快照」 - Network accessline 1092
self.fetch(first, second) - Network accessline 1094
self.fetch(self.page(1, subname="2026-09-17")) - Network accessline 1098
for subname in (None, "", "2026/09/18", 20260918.0, True): with self.subTest(subname=subname), self.assertRaises(RuntimeError): self.fetch(self.page(1, pagecount=1, recordcount=1, subname=subname)) - Network accessline 1099
with self.subTest(subname=subname), self.assertRaises(RuntimeError): self.fetch(self.page(1, pagecount=1, recordcount=1, subname=subname)) rows, _ = self.fetch(self.page(1, pagecount=1, recordcount=1, subname="202609 - Network accessline 1100
self.fetch(self.page(1, pagecount=1, recordcount=1, subname=subname)) - Network accessline 1101
rows, _ = self.fetch(self.page(1, pagecount=1, recordcount=1, subname="20260918")) - Network accessline 1107
{"pagecount": 1, "recordcount": "-1"}, {"pagecount": 1.0, "recordcount": 1}): with self.subTest(kwargs=kwargs), self.assertRaises(RuntimeError): self.fetch(self.page(1, **kwargs)) - Network accessline 1108
with self.subTest(kwargs=kwargs), self.assertRaises(RuntimeError): self.fetch(self.page(1, **kwargs)) rows, _ = self.fetch(self.page(1, pagecount="1", recordcount="1")) - Network accessline 1109
self.fetch(self.page(1, **kwargs)) - Network accessline 1110
rows, _ = self.fetch(self.page(1, pagecount="1", recordcount="1")) - Network accessline 1114
for payload in ([], {}, [None], [{"data": []}], [{"metadata": {}, "data": None}], [{"metadata": [], "data": []}]): with self.subTest(payload=payload), self.assertRaises(RuntimeError): self.fetch(Response(text="x" - Network accessline 1115
with self.subTest(payload=payload), self.assertRaises(RuntimeError): self.fetch(Response(text="x", payload=payload)) rec_missing = self.page(1, pagecount=1, recordcount=1) - Network accessline 1116
self.fetch(Response(text="x", payload=payload)) - Network accessline 1118
rec_missing._payload[0]["data"][0].pop("dqgm") with self.assertRaises(RuntimeError): self.fetch(rec_missing) - Network accessline 1120
self.fetch(rec_missing) - Network accessline 1205
shsz = [{"f12": "600001", "f13": 1, "f14": "*ST样本", "f2": 1.0, "f3": 0.5}] bj = [{"f12": "920001", "f13": 0, "f14": "ST北交", "f2": 2.0, "f3": 0.1}] with patch.dict(ns, {"_em_clist_all": MagicMock(side_effect=[(shsz, "https:// - Network accessline 1206
bj = [{"f12": "920001", "f13": 0, "f14": "ST北交", "f2": 2.0, "f3": 0.1}] with patch.dict(ns, {"_em_clist_all": MagicMock(side_effect=[(shsz, "https://a"), ([], "https://a")])}): with self.assertRaises(RuntimeError): - Network accessline 1207
with patch.dict(ns, {"_em_clist_all": MagicMock(side_effect=[(shsz, "https://a"), ([], "https://a")])}): - Network accessline 1208
with self.assertRaises(RuntimeError): ns["st_stock_list"]() with patch.dict(ns, {"_em_clist_all": MagicMock(side_effect=[(shsz, "https://a"), (bj, "https://b")])}): - Network accessline 1209
ns["st_stock_list"]() with patch.dict(ns, {"_em_clist_all": MagicMock(side_effect=[(shsz, "https://a"), (bj, "https://b")])}): out = ns["st_stock_list"]() - Network accessline 1210
with patch.dict(ns, {"_em_clist_all": MagicMock(side_effect=[(shsz, "https://a"), (bj, "https://b")])}): - Network accessline 1211
out = ns["st_stock_list"]() self.assertEqual(sorted(out.code), ["600001", "920001"]) self.assertEqual(set(out.source_url), {"https://a | https://b"}) - Network accessline 1213
self.assertEqual(set(out.source_url), {"https://a | https://b"}) - Network accessline 1222
rec = dict(good_sh, **bad) with self.subTest(bad=bad), patch.dict(ns, {"_em_clist_all": MagicMock( side_effect=[([rec], "https://a"), ([good_bj], "https://a")])}): - Network accessline 1223
with self.subTest(bad=bad), patch.dict(ns, {"_em_clist_all": MagicMock( side_effect=[([rec], "https://a"), ([good_bj], "https://a")])}): if bad == {"f13": 0}: # 真的是深市:照常出表,market 跟着变 - Network accessline 1224
side_effect=[([rec], "https://a"), ([good_bj], "https://a")])}): - Network accessline 1231
rec = {k: v for k, v in good_sh.items() if k != missing} with self.subTest(missing=missing), patch.dict(ns, {"_em_clist_all": MagicMock( side_effect=[([rec], "https://a"), ([good_bj], "https://a")])}), \ - Network accessline 1232
with self.subTest(missing=missing), patch.dict(ns, {"_em_clist_all": MagicMock( side_effect=[([rec], "https://a"), ([good_bj], "https://a")])}), \ self.assertRaises(RuntimeError): - Network accessline 1233
side_effect=[([rec], "https://a"), ([good_bj], "https://a")])}), \ - Network accessline 1297
shfe_json = MagicMock(return_value=(None, "https://www.ine.cn/x")) - Network accessline 1395
for sigma in ({}, "", 0, {"a": 1}, [1], [{"SIGMA": 0.2}]): payload = dict(option, o_cursigma=sigma) stub = MagicMock(return_value=(payload, "https://x")) - Network accessline 1396
payload = dict(option, o_cursigma=sigma) stub = MagicMock(return_value=(payload, "https://x")) with self.subTest(sigma=sigma), patch.dict(self.ns, {"_shfe_json": stub}), \ - Network accessline 1397
stub = MagicMock(return_value=(payload, "https://x")) - Network accessline 1412
def call(sigma_rows): stub = MagicMock(return_value=({"o_curinstrument": [inst], "o_cursigma": sigma_rows}, "https://x")) - Network accessline 1413
stub = MagicMock(return_value=({"o_curinstrument": [inst], "o_cursigma": sigma_rows}, "https://x")) - Network accessline 1431
head = "品种:{} 日期:2026-09-18" body = "\n名次|会员|成交量|增减|会员|持买单量|增减|会员|持卖单量|增减\n1|华泰|100|1|银河|200|2|国泰|300|3\n" with patch.dict(self.ns, {"_czce_text": MagicMock(return_value=(head.format("SR") + body, "https://x"))}): - Network accessline 1432
body = "\n名次|会员|成交量|增减|会员|持买单量|增减|会员|持卖单量|增减\n1|华泰|100|1|银河|200|2|国泰|300|3\n" with patch.dict(self.ns, {"_czce_text": MagicMock(return_value=(head.format("SR") + body, "https://x"))}): out = self.ns["futures_position_ran - Network accessline 1433
with patch.dict(self.ns, {"_czce_text": MagicMock(return_value=(head.format("SR") + body, "https://x"))}): - Network accessline 1434
out = self.ns["futures_position_rank"]("2026-09-18", "CZCE") self.assertEqual((out.symbol[0], out["rank"][0], out.long_member[0]), ("SR", 1, "银河")) with patch.dict(self.ns, {"_czce_text": MagicMock(return_value=(head.format( - Network accessline 1435
self.assertEqual((out.symbol[0], out["rank"][0], out.long_member[0]), ("SR", 1, "银河")) with patch.dict(self.ns, {"_czce_text": MagicMock(return_value=(head.format("2026") + body, "https://x"))}): with self.assertRaises(R - Network accessline 1436
with patch.dict(self.ns, {"_czce_text": MagicMock(return_value=(head.format("2026") + body, "https://x"))}): - Network accessline 1483
load(body) sigma = {"o_curinstrument": [], "o_cursigma": [["cu2611", 0.2]], "report_date": "20260918"} with patch.dict(self.ns, {"_shfe_json": MagicMock(return_value=(sigma, "https://www.ine.cn/x"))}): - Network accessline 1484
sigma = {"o_curinstrument": [], "o_cursigma": [["cu2611", 0.2]], "report_date": "20260918"} with patch.dict(self.ns, {"_shfe_json": MagicMock(return_value=(sigma, "https://www.ine.cn/x"))}): with self.assertRaises(Runtim - Network accessline 1485
with patch.dict(self.ns, {"_shfe_json": MagicMock(return_value=(sigma, "https://www.ine.cn/x"))}): - Network accessline 1489
def test_shfe_rank_without_rank_field_is_an_error(self): payload = {"o_cursor": [{"INSTRUMENTID": "sc2610", "RANK": ""}]} with patch.dict(self.ns, {"_shfe_json": MagicMock(return_value=(payload, "https://www.ine.cn/x"))}): - Network accessline 1490
payload = {"o_cursor": [{"INSTRUMENTID": "sc2610", "RANK": ""}]} with patch.dict(self.ns, {"_shfe_json": MagicMock(return_value=(payload, "https://www.ine.cn/x"))}): with self.assertRaises(RuntimeError): - Network accessline 1491
with patch.dict(self.ns, {"_shfe_json": MagicMock(return_value=(payload, "https://www.ine.cn/x"))}): - Access to secretsline 1703
[Credential-related source omitted] - Network accessline 1744
for name, fetch in calls: with self.subTest(name=name): frame = fetch() - Network accessline 1745
with self.subTest(name=name): frame = fetch() self.assertGreater(len(frame), 0) - Network accessline 1746
frame = fetch()
How the signals fit together
Facts from a static read of the files at the pinned commit. They describe what the code does, not why.
Some files could not be read; the facts below still hold.
Signal confidence: 500 facts
- Network access in prose of documentationCHANGELOG.md:455Low confidence
- Network access in prose of documentationCHANGELOG.md:476Low confidence
- Network access in prose of documentationCHANGELOG.md:478Low confidence
- Network access in prose of documentationCHANGELOG.md:619Low confidence
- Network access in prose of documentationCHANGELOG.md:795Low confidence
- Network access in prose of documentationREADME.md:14Low confidence
- Network access in prose of documentationREADME.md:15Low confidence
- Network access in prose of documentationREADME.md:16Low confidence
- Network access in prose of documentationREADME.md:17Low confidence
- Network access in prose of documentationREADME.md:18Low confidence
- Network access in prose of documentationREADME.md:19Low confidence
- Network access in prose of documentationREADME.md:20Low confidence
- Network access in prose of documentationREADME.md:21Low confidence
- Network access in prose of documentationREADME.md:22Low confidence
- Network access in prose of documentationREADME.md:39Low confidence
- Network access in code of documentationREADME.md:133Low confidence
- Network access in code of documentationREADME.md:134Low confidence
- Network access in code of documentationREADME.md:135Low confidence
- Network access in prose of documentationREADME.md:352Low confidence
- Network access in prose of documentationREADME.md:629Low confidence
- Network access in prose of documentationREADME_en.md:14Low confidence
- Network access in prose of documentationREADME_en.md:15Low confidence
- Network access in prose of documentationREADME_en.md:16Low confidence
- Network access in prose of documentationREADME_en.md:17Low confidence
- Network access in prose of documentationREADME_en.md:18Low confidence
- Network access in prose of documentationREADME_en.md:19Low confidence
- Network access in prose of documentationREADME_en.md:20Low confidence
- Network access in prose of documentationREADME_en.md:21Low confidence
- Network access in prose of documentationREADME_en.md:22Low confidence
- Network access in prose of documentationREADME_en.md:37Low confidence
- Network access in code of documentationREADME_en.md:131Low confidence
- Network access in code of documentationREADME_en.md:132Low confidence
- Network access in code of documentationREADME_en.md:133Low confidence
- Network access in prose of documentationREADME_en.md:350Low confidence
- Network access in prose of documentationREADME_en.md:573Low confidence
- Network access in prose of the SKILL.mdSKILL.md:8Low confidence
- Network access in prose of the SKILL.mdSKILL.md:10Low confidence
- Network access in prose of the SKILL.mdSKILL.md:363Low confidence
- Network access in code of the SKILL.mdSKILL.md:455High confidence
- Access to secrets in code of the SKILL.mdSKILL.md:456High confidence
- Network access in code of the SKILL.mdSKILL.md:457High confidence
- Network access in code of the SKILL.mdSKILL.md:459High confidence
- Network access in code of the SKILL.mdSKILL.md:486High confidence
- Network access in code of the SKILL.mdSKILL.md:487High confidence
- Network access in code of the SKILL.mdSKILL.md:488High confidence
- Network access in code of the SKILL.mdSKILL.md:757High confidence
- Network access in code of the SKILL.mdSKILL.md:758High confidence
- Network access in code of the SKILL.mdSKILL.md:763High confidence
- Network access in code of the SKILL.mdSKILL.md:764High confidence
- Network access in code of the SKILL.mdSKILL.md:765High confidence
and 450 more
Only the first 500 facts are listed.
Works with
| Agent | Status | Evidence | Install to |
|---|---|---|---|
| Claude Code | Compatible | Standard SKILL.md SKILL.md | .claude/skills/<skill-name>/ |
| Codex | Compatible | Standard SKILL.md SKILL.md | .agents/skills/<skill-name>/ |
| Cursor | Compatible | Standard SKILL.md SKILL.md | .cursor/skills/<skill-name>/ |
| Gemini CLI | Compatible | Standard SKILL.md SKILL.md | .gemini/skills/<skill-name>/ |
| GitHub Copilot | Compatible | Standard SKILL.md SKILL.md | .github/skills/<skill-name>/ |
| OpenCode | Compatible | Standard SKILL.md SKILL.md | .opencode/skills/<skill-name>/ |
- Native The repository ships a manifest, folder or frontmatter field for this agent.
- Compatible A standard SKILL.md that this agent can read.
- Unknown No evidence either way.
Derived automatically from paths, manifests and frontmatter. Not tested on each agent.
Explore alternatives and comparisons
Add this badge to your README
It updates every night and links to this page.
[](https://hotskills.dev/skill/simonlin1212-a-stock-data/)