dragon_tiger_board() 的 buy_data / sell_data 只在 if records: 分支内赋值,
而第 3 步「机构买卖统计」无条件遍历这两个变量。回看窗口内没有上榜记录时分支不
执行,变量从未绑定:
dragon_tiger_board("600519", "2026-08-05", 30)
# UnboundLocalError: local variable 'buy_data' referenced before assignment危害不只是报错:大市值 / 低换手率标的常态无上榜(贵州茅台即是),等于这类票调用 即崩;而且调用方无法区分「这段时间没上榜」和「接口出问题了」,容易误判。
修复为在条件分支前初始化空列表,空窗口返回语义一致的空结构:
{"records": [], "seats": {"buy": [], "sell": []}, "institution": {...0}}。
已用 AST 扫描全文件同类模式(只在条件分支赋值、却在分支外读取),确认无其他实例。
感谢 @tongflau-dongzhu 的报告——根因、复现和 修复方案都写得很清楚。
2026-07-31 实测东财北交所在市 342 只中 336 只已迁至 920xxx 号段,仅剩 3 只老码且全部停牌。
存量公司代码整体变更(锦波生物 832982→920982、贝特瑞 835185→920185)。
老码的危险不在于失败,而在于失败得像成功:
| 接口 | 老码 832982 |
新码 920982 |
|---|---|---|
| 腾讯行情 | 112.60、成交量 0(定格在迁移日) | 131.74,正常成交 |
| 腾讯行情(贝特瑞) | 835185 → 45.91、成交量 0 |
920185 → 21.05 |
| 东财研报 | 0 篇(静默空) | 79 篇 |
价差达 17%~100%+,全部 HTTP 200 无异常。拿去算估值会得出完全错误的结论。
三处修复:
- 新增「北交所老号段」全局警告章节(含判定方法与反查新码的办法)。
tencent_quote()新增is_stale/stale_reason:成交量==0 且 最新价==昨收判定为僵尸报价, 老号段额外给出迁移提示。实测老码 2/2 命中、正常票 4/4 无误报。eastmoney_reports()遇 43/87/83 老码且查无结果时抛ValueError,不再返回空列表。get_prefix()的4x/8x注释标注为老号段。
eastmoney_reports("SH600519") / "600519.SH" / "sh600519" 全部返回 0 篇,
纯 "600519" 返回 100 篇——reportapi 只认纯 6 位数字。
问题在于文档「Ticker 格式归一化」章节明文承诺所有接口统一支持带前缀写法,并列了
SH688017→688017 的对照表,但从未有过实现(全仓搜不到归一化函数)。
承诺与实现不符,且失败方式是静默返回空,调用方会把「代码格式写错」误读成「该标的无研报覆盖」。
- 新增
norm_ticker():整串锚定匹配受支持写法;解析失败抛ValueError,绝不返回空串。 eastmoney_reports()/ths_eps_forecast()接入。实测四种写法结果一致(100 篇)。- 研报层导入改用
from datetime import date, timedelta风格, 避免与本文件多处from datetime import datetime互相遮蔽(模块名会被类名顶掉)。
代码审计中又发现同一函数的四个静默误路由缺口,一并堵上(每条都有回归用例):
- 不能用
re.search(r"\d{6})从任意串里"捞"代码——6005190/foo600519bar会被截成600519,返回的是另一只股票的真实数据,比报错危险得多。改为整串锚定。 - 前缀与后缀不能同时可选——
SH000001.SZ这种自相矛盾的写法会被照单全收, 而000001恰是歧义码(沪=上证指数 / 深=平安银行)。改为二选一。 - 个股接口必须拒绝显式沪市指数码(新增
stock_only=True)。实测不拦的话:sh000001→平安银行研报 100 篇、sh000016→深康佳A、sh000039→中集集团 84 篇。 判定按号段而非白名单:沪市个股只有 600/601/603/605/688/689(B 股 900), 不存在000xxx沪市个股,故「显式 sh + 000 段」整段拒掉才完备。 前缀式与后缀式(SH000001与000001.SH)都要认。 - 显式市场标识与号段矛盾时报错——
SZ600519/SH300750/BJ600519一律拒。 例外:000xxx是沪指数与深个股共用的歧义段,该段的显式标识是消歧不是矛盾,sz000016(深康佳A)等文档承诺的写法照常放行。
- 重点监控池
MARKET是三值且含字母:"1"=沪 /"0"=深 /"B"=北交所。 按"SH" if MARKET=="1" else "SZ"写会把北交所标的整片错标为 SZ—— 实测 2026-07-31 全量 16 只里就有 3 只MARKET="B"(*ST康乐 920575 / *ST同辉 920090 / *ST田野 920023)。 改为显式映射表,未知取值原样带出?<原值>而不猜市场。 - 异动接口不能只看
m:东财体系里北交所与深市同为m=0(拉北交所清单用的就是m:0+t:81), 只按m==1 else "SZ"会把北交所错标成 SZ,而异动规则码 8 正是北交所专用。 新增_anomaly_market()按代码号段判定(920/43/83/87 → BJ)。
only_active=True 原先用 date.today(),在比北京时间早的时区(如新西兰早 4~5 小时)
会在北京傍晚就跨到次日,导致监控窗口首日提前纳入、末日提前剔除。
新增 cn_today()(固定 UTC+8,不依赖 tzdata)。
「Ticker 格式归一化」章节原文写「所有接口统一支持多种输入格式」,但归一化只在本版接入了
研报层两个函数。其余端点(tencent_quote() 等走 get_prefix() 路由的)只认纯 6 位与显式
sh/sz/bj 前缀,不认后缀式:实测 tencent_quote(["600519.SH"]) 会拼成
sh600519.SH 并返回空载荷(又一处静默失败)。
改为如实说明哪些端点内置归一化、其余端点接受什么格式,并建议「拿到用户输入先过一遍
norm_ticker() 再传给任何端点」。没有为了让文档成立而去批量改 25 个端点——
那超出本次改动范围、回归面过大;把虚假承诺改成准确描述才是正确的修法。
(后续可考虑逐层接入,届时再放开这句话。)
交易所风险警示 / 重点监控名单 + 生效时间窗,零鉴权静态 JSON(mobappconfig.securities.eastmoney.com),
全量返回不分页。only_active=True 按今日日期过滤有效窗口。实测 16 只在管标的。
交易所「严重异常波动」口径的异动明细与按标的聚合统计(dycalchis.eastmoney.com/price-anomaly)。
- 必须带
team=h5等 6 个固定公共参数,否则返回{"result":1001,"msg":"unknow team"}。 已按「正向识别」原则做result != 0→ 抛RuntimeError冒泡,不静默当成「今天没异动」。 - 内置 12 条异动规则码全解释(含
s==6时按e*10取更严阈值那档的分支)。 p(最新价)/a(涨跌幅)已与腾讯行情逐条核对,3/3 完全一致;其余字段语义取自东财前端字段映射。⚠️ 两端点同名字母含义不同:list的t是涨跌幅目标值(浮点),count的t是异动次数(整数)。
eastmoney_industry_reports() 的 begin 默认值由固定的 "2024-01-01" 改为留空时
按「相对今天往前两年」计算,避免时间窗随版本老化越拉越旧。
改后代码逐字抽出实跑真实接口,60/60 通过:norm_ticker 正例 6 + 负例 9、
个股接口拒绝显式指数码 9 项(前缀式/后缀式)、市场标识矛盾 6 拒 6 放行、
研报前缀四种写法结果一致、北交所老号段拦截、920 新码正常、行业码过滤、
同花顺一致预期归一化、两个新端点真数据、北交所标 BJ 不标 SZ、
异动接口缺参时正确冒泡、监控池×异动交叉。
经 9 轮独立代码审计至无回归(前 8 轮共提出 8 条,逐条实测复现后修复,无一误报放行)。
端点 44 → 47(44 主端点 + 3 官方备胎);数据源仍为 15(新端点同属东财,不重复计数)。
board_fund_flow() 写死 pz=200 且不翻页。实测东财行业板块 496 个、概念板块 495 个,
两类都被截断:total 恒为 200,top_n > 200 时静默丢掉有效板块。
改为先取第一页拿真实 total,仅当 top_n 超过已取数量时才继续翻页
(多数调用 top_n ≤ 20,仍只发一次请求,不给东财增加压力);
API 提前返空时跳出,避免死循环。total 改用接口真实值。
接口不返 total 时,按「取到不足一页即末页」收敛,不再退化成只取首页。
上一版只修了估值函数与新浪资金流两处,get_prefix() 和 tencent_quote() 的内联判断
用的是 startswith(("5","6","9")),同一个 bug 还在这两处(北交所 920xxx 落到 sh,
腾讯返回空载荷)。两处均改为先判 92 → bj。
结果字典一律用裸 6 位码做键,导致同批传入 sh000001(上证指数) 与 sz000001(平安银行)
时后者静默覆盖前者——显式前缀这个特性因此形同虚设。改为按调用方入参原样做键
(传裸码返回裸码,传带前缀返回带前缀),行为向后兼容。
_validate() 用 A 股代码 000001 拉 K 线验活,这只对 market='std' 有意义。
传 'ext' 等其它市场时必然取不到数,会把所有正常服务器判死、误报「全部不可达」。
非 std 市场跳过验活(仍保留 factory 连接异常的跳过逻辑)。
仓库内所有调用点均用默认 std,故此前未暴露。
板块资金流向(#37 收口)。端点 43 → 44,数据源 15 / 层数 10 不变(新端点与行业排名同源)。
- §3.8
board_fund_flow()板块资金流向:补上此前缺失的板块级资金流——board_type支持行业(industry)/概念(concept)/地域(region) 三类,period支持今日(today)/5日(5d)/10日(10d) 三周期,按主力净流入降序返回:主力净额 + 主力净占比 + 涨跌幅 + 领涨股,今日周期额外含超大/大/中/小单四档明细。- 与 §3.7
industry_comparison()同源同接口(东财 push2clist,fs=m:90+t:2/t:3/t:1)——此前只请求了价格/涨跌家数字段(f2,f3,f104,f105...),本版补请求资金流字段(今日f62/f184/f66/f72/f78/f84、5日f164/f165/f257、10日f174/f175)即覆盖。正如 #37 报告者 + trae 的诊断:「同一个接口,只查了几列没查全」。 - 走
em_get()限流防封(东财源);非法board_type/period抛ValueError。 - 坑记录:板块级只有今日/5日/10日(无 3日,个股级才有);东财
clist返回的total字段不可信(行业板块报 496 实际 100 个),代码用len(items);10日领涨股名称字段(f267/f268 均为数字)未干净识别,故 10日省略领涨名。
- 与 §3.7
- 行业·今日:100 个板块主力净额降序,电力设备 64.66亿(= 超大 43.55亿 + 大 21.11亿,主力=超大+大校验通过)+ 四档明细 + 领涨股。
- 概念·5日(黄金概念 81.71亿)、地域·10日(宁夏板块)均真实返回;
f109(5日涨跌)/f160(10日涨跌) 字段验证正确。 - 参数校验:非法 board_type='x' / period='3d' 均被
ValueError拒绝。 - 全文件 48 个 Python 代码块
py_compile零语法错误。
前缀路由 + mootdx 验活 bug 修复(社区实测反馈收口)。端点 43 · 数据源 15 · 层数 10 均不变,纯质量修复。
- §1.2
tencent_quote()/ §市场前缀规则get_prefix()前缀路由错判(#40 #41):5开头沪市 ETF(510300/510050/588200)、沪深指数(000300/000016/000905等)此前落到else → sz,腾讯qt.gtimg.cn对sz510300/sz000300返回空 —— *更危险的是000016被拼成sz000016(ST康佳A),静默返回完全不相干标的的数据。§1.2 docstring 自带的 ETF / 指数示例本身因此跑不通。修复:两处同步改为5x → sh+ 沪指数白名单SH_INDEX{000300,000905,000016,000688,000852,000010}+ 支持显式前缀sh/sz/bj透传(解决000001上证指数 vs 平安银行歧义)。 - §1.1
tdx_client()探测通过 ≠ 能取数,静默返回空表(#43):原_probe()只做socket.create_connectionTCP 握手,坏服务器可握手通过却对真实取数请求回 2 字节空 body(tdxpy按 header 声称的根数解析越界 →struct.error被raise_exception=False吞掉 → mootdx 包成空 DataFrame),或直接ConnectionReset使tdx_client()崩溃且走不到 fallback。新增_validate():每个候选 server 必须真实拉一根 K 线(bars('000001', frequency=9, offset=1))非空才采用;factory()连接异常改 try/except 跳过下一台;bestip / 裸 factory fallback 同样验活;全部失败才抛明确RuntimeError。把「静默空表 / 崩溃」变成「自动切到可用源,或明确报错」。
- 备用源速查 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/)。⚠️ 文档标注字段坑:返回数组第 7 个字段是换手率基点不是成交额(当成交额读会小三个数量级),成交额需自算量(手) × 100 × 均价。
get_prefix()11 例路由全对:510300/588200 → sh、000300/000016 → sh、159915/399006 → sz、600519 → sh、000001 → sz、830799 → bj、显式sh000001 → sh/sz000016 → sz。tencent_quote()真实拉数:沪深300ETF华泰柏瑞 / 上证50ETF华夏 / 沪深300指数 / 上证50指数 / 创业板ETF易方达 / 贵州茅台 / 平安银行 —— 名称与现价全部命中(修复前 ETF/指数全部 NO DATA 或返错票)。- 新
tdx_client():本机 10 台 pin 服全部_probe假阳性(握手通、取数 reset),正确跳过 → fallback bestip 验活通过 → 返回 600519 真实日线;修复前会崩溃 / 返空表。 - 腾讯 m5:
603986返回 10 根、8 字段、第 7 字段确为换手率基点,验证通过。
接口质量修复 + 备用源韧性层。端点 40 → 43(新增 3 个官方备胎函数),数据源 13 → 15(新增沪深交易所官方),层数 10 不变。
- §5.2 财联社快讯复活(#14 收口):2026-05 下线的是旧
nodeapi系接口;官方新版cls.cn/v1/roll/get_roll_list一直可用,只是强制sign校验——sign 纯本地可算(md5(sha1(按 key 字典序拼接的 query 串))),零 key。cls_telegraph()重写接入新版,V3.2 移除的全市场电报能力恢复,与 §5.3 东财 7×24 互为独立备份(不同源、不同风控面)。 - §3.6
lockup_expiry字段名 bug:东财RPT_LIFT_STAGE报表改列名,旧LIMITED_STOCK_TYPE/FREE_SHARES_NUM恒空 → 改FREE_SHARES_TYPE/FREE_SHARES,并新增able_shares(ABLE_FREE_SHARES,实际可流通股数,更贴近真实抛压)。 - §3.7
industry_comparison排序 bug:clist 请求缺排序字段,top/bottom切片并非按涨幅排序 → 补fid=f3,现按涨跌幅真实降序。 - §3.2 深股通标注:北向盘中实时披露 2024-08 起收紧,沪股通(hgt)分钟序列完整、深股通(sgt)常只回零星几个点且末值量级异常(上游问题非代码 bug)→ 加显著警示:hgt 可用于当日情绪、sgt 仅供参考,权威北向用 HKEX 官方日统计。
- 十层主源 → 独立备胎速查表:每类数据一条不同域名、不同风控面的备胎(交易所官方 / 新浪 / 同花顺 / HKEX / 巨潮 webapi / 金十),东财 IP 被封成片失联时可即时降级。附「已死透别用」名单(网易 / 和讯 / 凤凰 / 腾讯资金流 / 雪球免登录深度数据)。
- 3 个官方备胎函数(全部实测):
dragon_tiger_backup()(上交所showTradePublicFile.do+ 深交所1842_xxpl,零鉴权权威一手,含营业部席位)、fund_flow_backup()(新浪MoneyFlow.ssl_qsfx_zjlrqs,日度四档单净额)、announcements_backup()(深市走深交所官方annList、沪市走东财,均带 PDF 直链)。 - 新增数据源:上交所官方(query.sse.com.cn / yunhq.sse.com.cn)、深交所官方(szse.cn)。
- 顶部新增「端点路由速查」总表(§ → 函数 → 用途 → 源):60+ 内嵌函数首次有一页总览,agent 可按表定位章节局部读取,不必通读全文。
- FAQ 新增 3 条:东财 403/连接重置三步处理(等待/降频/查备胎)、财联社为何复活、mootdx 库烂尾但通达信协议照常(含 easy_tdx 预案)。
- 数据源优先级章节补「降级」原则;架构树新闻层同步财联社复活状态。
- 财联社 v1+sign:HTTP 200 / errno=0,真实电报直出。
- 解禁(600519):
type/shares/able_shares三字段非空。 - 行业排名:
top按涨跌幅降序(当日 TOP1 航天装备 +10.36%)。 - 3 个备胎函数:深交所龙虎榜 JSON 直出、上交所全文(含营业部五强)、新浪 60 日资金流、深市公告含
disc.static.szse.cnPDF 直链——全部跑通。 - 全文件 Python 代码块逐块
py_compile,零语法错误。
元数据与文档变更,端点与代码零改动(40 端点 · 10 层 · 13 数据源不变)。
- frontmatter
description重写:明确「仅在需要写代码实际获取 A 股数据时使用」,并显式排除 A 股概念解释 / 投资观点讨论 / 策略问答等无需取数的话题——此前过宽的 description 会让 agent 在任何 A 股相关对话中误加载整个 SKILL.md(约 50K token),误触发才是最大的 token 浪费。
- 产品决策:单文件自包含(拷一个文件就能用、离线可携、便于分发)是本项目的有意选择,长期保持,不做目录化拆分。README FAQ 新增说明与两条降耗建议(收窄触发 + token 敏感用户按需局部读取的用法)。
- 感谢 @Arkzf2 的渐进式披露完整实现(PR #22)与 @iOSleep @taicilang-lcy @ywxkdz 的推动讨论——方案已存档,若未来端点规模翻倍导致单文件不可持续,将重新评估。
Layer 8 打板层(#23 / #15)
- 东财涨停板四池(
push2ex.eastmoney.com,与现有 push2 同源、走em_get限流):em_zt_pool(涨停池:连板数 / 几天几板 / 封板资金 / 炸板次数 / 首末封板时间 / 行业)、em_zb_pool(炸板池:振幅 / 涨速)、em_dt_pool(跌停池:封单资金 / 连续跌停 / 开板次数)、em_yzt_pool(昨日涨停池:自算晋级率 / 赚钱效应)。 - 同花顺涨停揭秘
ths_limit_up_pool:涨停原因题材 / 封板成功率 / 一字·换手·T字板 / 封单额 / 几天几板。 - 打板情绪速算
limit_up_sentiment:炸板率 / 连板高度 / 连板梯队分布。
Layer 9 ETF 期权层(#13)
- 新浪源:
sina_option_codes(50ETF / 300ETF / 科创50ETF / 500ETF 合约清单)、sina_option_tquote(T型报价:买卖五档 / 持仓量 / 行权价)、sina_option_greeks(希腊字母 Delta / Gamma / Theta / Vega + 隐含波动率 + 理论价值)。交易所预算好,无需本地算 BSM。
Layer 10 舆情互动层
cninfo_irm(互动易问答:投资者提问 + 公司官方回复,AI 问答独家信源)、ths_hot_list(同花顺热榜:人气值 / 概念标签 / 排名变化)、em_hot_rank(东财人气榜 + 名称转换)、em_hot_concept(个股概念命中)。
- ETF 显式说明:ETF 行情 / K线一直支持(腾讯 + mootdx,代码直接当股票查),README 使用示例表显式补上 ETF 例子,避免被看漏。
- README(中英)架构图、端点清单、使用示例、亮点区,SKILL.md 触发场景 + 关键词,全部同步到 10 层 40 端点。
- 三层全部本机实测真实数据(数据日 20260626):涨停池 60 只 / 炸板 35 / 跌停 30 / 昨涨停 86 / 同花顺涨停揭秘 60,字段映射 +
price÷1000+ 时间格式化全对;ETF 期权 50ETF/300ETF 合约清单 + T型报价 + 希腊字母(Delta 0.535 平值校验对齐、IV 17.35%);互动易(比亚迪 50 条中 12 条有公司回复)+ 同花顺热榜 100 条 + 东财人气榜(名称转换)+ 个股概念命中全通。 - 实测纠正的 3 个坑:东财四池价格字段 ÷1000(非 ÷10000);互动易第二步参数放 query string(否则 400);期权希腊字母解析
[raw[0]] + raw[4:](跳 3 个空位)。
- 数据源数(13)不变——三个新层用的 push2ex / 新浪 / 巨潮 / 同花顺 / 东财均为已有数据源品牌。
- §1.1 mootdx K线参数名写错,分钟数据恒退化为日线(#31,CRITICAL):旧代码
client.bars(symbol=..., category=4, ...)用了不存在的参数名category。mootdxbars()真实签名是bars(symbol, frequency=9, start=0, offset=800, **kwargs)——category被**kwargs静默吞掉,frequency永远取默认值 9(日线)。后果:任何 agent 想取分钟/周/月 K 线全部静默退化成日线、且不报错(用户只能自行 fallback 到新浪 API)。修复:参数名改frequency,并按 mootdx 0.11.7 源码重写频率值表(旧表7=1分钟…11=60分钟整段错误)。补 1 分钟(frequency=8)/ 5 分钟(frequency=0)示例。 - §1.1 复权口径未说明(#28):mootdx
bars返回不复权原始价(通达信原始数据,签名无adjust参数),跨除权除息日做估值/回测会失真。文档此前零说明 → 补明确警示:跨除权日需自行复权或改用带前复权的日 K 数据源(腾讯财经)。 - §full_valuation 机构一致预期 EPS 取错列(HIGH):旧代码
row.iloc[2]按位置取,而同花顺ths_eps_forecast表列序为年度/预测机构数/最小值/均值/最大值——iloc[2]实为「最小值」,并非文档声明的「均值=机构一致预期EPS」。导致pe_forward/PEG/估值摘要系统性偏差(取值偏低)。修复:改按列名均值/预测机构数取,抗列序漂移;解析失败由静默except: pass改为打印[WARN]。
- §东财
em_get()增加连接级自动重试(glm review P1.3):挂载HTTPAdapter + urllib3.Retry(total=3、指数退避、status_forcelist=[429,500,502,503,504]、仅 GET)。403 不重试(东财风控信号,靠EM_MIN_INTERVAL降频应对)。老版本 urllib3 缺参数时降级为无重试,不影响主流程。 - §download_pdf 文件名加固:
org(机构简称)与title一致做re.sub路径字符清洗 + 截断,避免机构名含/等字符拼坏保存路径。
- 本机实跑 mootdx 0.11.7 坐实 #31:
bars(category=8)索引全为15:00(日线,复现退化);bars(frequency=8)索引14:59/15:00(真 1 分钟)、frequency=0为 5 分钟间隔;bars签名确认无category/adjust。 - 实跑同花顺
worth.html(600519)坐实 EPS 取列错误:iloc[2]=最小值=66.27vs均值=68.82;修复后按列名取到68.82。 em_getRetry 挂载 smoke test 通过(HTTPAdapter正常 mount)。
- 端点数(28)、数据源数不变;本版为 bugfix + 文档修正。感谢 @hhsacsb(#31)、#28 提问者,及社区 glm review(@taicilang-lcy,#27)。
- mootdx 0.11.x 全新安装 BESTIP 空串崩溃:干净环境下
Quotes.factory(market='std')裸调用会抛ValueError: not enough values to unpack (expected 2, got 0)。根因:~/.mootdx/config.json的BESTIP.HQ初始为空字符串""(非缺失键),mootdx 内部dict.get(key, default)取不到 default,拆包失败。老用户(config 曾填充过 IP)不触发,故此前多次实测漏掉。 - 解法:新增
tdx_client()helper(Prerequisites 章节),所有 4 处 mootdx 调用统一改走它。 顺序探测内置可用服务器列表_TDX_SERVERS(TCP 握手),用第一个可达的显式server=(ip,port)绕过 BESTIP;三级 fallback(bestip 测速 → 裸 factory → 明确 RuntimeError)保证 IP 列表老化/换网/老用户场景都能工作。 - 明确不锁版本:锁
mootdx==0.10.12在部分环境(干净 Python 3.9)下import mootdx因 numpy/pandas 二进制不兼容直接崩,比 0.11.x 更糟。helper 对 0.10 / 0.11 通用,故依赖仍保持mootdx>=0.10。
- helper 探测逻辑实测(2026-06-20,本机网络):
_TDX_SERVERS10/10 TCP 可达;语法py_compile通过。 - 早前隔离实测(临时 venv,mootdx 0.11.7):强制
BESTIP.HQ=""稳定复现 ValueError;改用server=(ip,port)显式传参后bars()正常取回 5 根。
- 端点数(28)、数据源数不变;纯兼容性补丁。致谢 PR #7(@ericheroster)提供 helper 思路,本版在其基础上加了三级 fallback 防 IP 老化。
- §2.1 东财行业研报
eastmoney_industry_reports():研报层补上行业研报端点(此前只有个股研报)。与个股研报同一端点reportapi.eastmoney.com/report/list,仅qType不同(0=个股 /1=行业)。industry_code="*"拉全行业(实测约 47928 篇 / 4793 页),传东财行业码(如1238=IT服务Ⅱ,实测 1863 篇)精确过滤;返回 record 复用 §2.1 的download_pdf()下载 PDF(模板通用),走em_get限流。新增字段说明:industryName/industryCode/emRatingName/reportType/attachPages/attachSize。 - 同步架构树研报层一行:「东财 reportapi → 个股研报 + 行业研报 + PDF下载 + 评级 + 三年EPS」。
- 实测(2026-06-20,真实公开 API,零 key):全行业
qType=1返回hits=47928、TotalPage=4793,字段含industryName/industryCode;按行业码1238过滤hits=1863;首篇 PDF(AP202606181823678972)H3_{infoCode}_1.pdf模板下载成功(2512829 bytes,%PDF头)。 - 行业码表端点(
bxpa等)实测 404 不存在 → 文档注明用industry_code="*"拉取后从结果反查行业码,无独立码表。
- 端点数 27 → 28(新增东财行业研报);数据源数不变(仍走东财 reportapi)。
- §3.3 概念板块归属(#18):百度 PAE
getrelatedblock接口失效(实测返回ResultCode 10003+ 空数组)→ 替换为东财slist(spt=3)个股所属板块接口eastmoney_concept_blocks(),一次请求拿全行业/概念/地域混合板块列表(板块名 + BK码 + 涨跌幅 + 龙头股),零鉴权、走em_get限流。函数名baidu_concept_blocks→eastmoney_concept_blocks。 - §7.1 巨潮公告 orgId 硬编码(#19):旧代码用
gssx0{code}规则硬编码 orgId,但巨潮 orgId 并非统一格式(601318→9900002221、601398→jjxt0000019、688017→9900041602),导致大量股票(尤其 601xxx 段)totalAnnouncement=0查不到公告 → 新增_cninfo_orgid(),动态查官方映射表szse_stock.json(模块级缓存,6198 只股),硬编码规则降为 fallback。 - 综合用法示例隐藏崩溃:示例第 6 步仍调用 v3.1 已删除的
baidu_fund_flow_history()(recent['mainIn'])→ 改为eastmoney_fund_flow_minute();第 5 步baidu_concept_blocks→eastmoney_concept_blocks。
- §4.5 120日资金流 / §5.1 个股新闻:实测代码本身正常(多网络/时段返回完整数据),但部分大陆住宅 IP 会被东财 push2/search-api 连接级间歇风控(表现
HTTP 000或只返回passportWeb)→ 两节各加⚠️ 说明:隔几分钟重试 / 换网络 / 调大EM_MIN_INTERVAL。这是 IP 级风控,非代码问题(#18 报告者环境复现,作者多环境实测正常)。
- 新代码原样 exec smoke test(含
em_get助手)实测:eastmoney_concept_blocks茅台 27 / 五粮液 28 / 绿的谐波 21 个板块均非空、分类正确;cninfo_announcements平安 601318(2454条)/ 工行 601398(2483条)原失效股恢复,茅台 600519 老规则 fallback 兼容。 - §1.3 百度 K线(同 PAE 主机)实测仍正常(
ResultCode 0,2001 根),百度作为数据源保留。
- 端点数(27)、数据源数不变(百度因 K线 保留,东财 slist 已在册);本次为失效接口替换 + orgId 动态化 + 示例修复。
- §5.1 东财个股新闻
eastmoney_stock_news:东财实际返回里result.cmsArticleWebOld直接就是文章列表(非{list:[...]}嵌套),旧写法.get("cmsArticleWebOld", {}).get("list", [])对 list 调用.get触发AttributeError/ 返回空 → 改为遍历d.get("result", {}).get("cmsArticleWebOld", []) or []。 - §6.4 新浪财报三表
sina_financial_report:新浪实际结构是result.data.report_list(按报告期如'20260331'为键的 dict,每期对象的data字段才是行项列表[{item_title, item_value, item_tongbi}]),旧写法取result.data.{report_type}永久返回空 → 改为遍历report_list期次(倒序),每期从data按item_title提取,返回「按报告期记录列表」({"报告期": ..., "<科目>": <值>, "<科目>_同比": <同比>})。新增num参数(默认 8 期)。
- 两函数用真实公开 API(茅台 600519,零 key)实测:个股新闻返回 20 条、字段(date/title/content/mediaName/url)齐全;财报三表 lrb/fzb/llb 各返回 8 期、净利润+同比可取。
- 验证方式:exec SKILL.md 代码块本身(含
em_get助手)直连真实 API 断言非空。
- 端点数(27)、数据源数不变;修复来自姊妹项目 astock-peg 移植时实测发现并验证的正确修法。
- 数据源优先级原则:新增「数据源优先级 & 东财防封」章节,明确「能用通达信(mootdx)/腾讯(不封 IP)就别用东财,东财仅用于其独有数据」
- 统一节流入口
em_get():所有东财端点(datacenter / push2 / push2his / reportapi / search-api / np-weblist 共 9 处调用)改用em_get(),内置:- 串行限流(
EM_MIN_INTERVAL=1.0s最小间隔 + 0.1~0.5s 随机抖动) - 复用
EM_SESSION(Keep-Alive)+ 默认 UA - 批量任务调大
EM_MIN_INTERVAL即进一步降速
- 串行限流(
- 东财风控阈值文档化:列出触发封禁的实测阈值(每秒>5 / 并发≥10 / 1分≥200 / 5分≥300)与 5 条防封铁律
- 财联社快讯下线(#14):
cls.cn/nodeapi/telegraphList等旧接口全面 404(网站迁 Next.js + 新 API 需签名)→ §5.2 标注弃用,全市场快讯改用 §5.3 东财全球资讯(np-weblist)
- 端点数 28 → 27(财联社快讯下线)
- README 数据源优先级表重排:mootdx/腾讯置顶(标注「不封 IP」),东财降至末位(标注「中—有风控会封 IP」)
- 用真实东财 API(datacenter 股东户数 + np-weblist 全球资讯)实测
em_get功能与限流间隔(间隔 ≥1s 通过)
- 百度 PAE 资金流
fundflow+fundsortlist已下线(返回 null)→ 替换为东财 push2 分钟级资金流eastmoney_fund_flow_minute() - 大宗交易
RPT_DATA_OCCURTRADE报表配置已下线 → 替换为RPT_DATA_BLOCKTRADE(字段兼容) - 龙虎榜机构买卖
RPT_ORGANIZATION_BUSSINESS报表配置已下线 → 改用 BUY/SELL 席位明细筛选OPERATEDEPT_CODE="0" - 东财全球资讯 新增必填参数
req_trace(UUID),否则返回 403 - 巨潮公告
stock参数格式变更:旧"{code},{plate}"→ 新"{code},{orgId}"(如600519,gssh0600519),column改为空字符串
- 信号层资金流数据源从百度切换到东财 push2,与 Layer 4 资金面统一为东财体系
- 数据源优先级表更新:百度股市通降级为概念板块+K线,资金流功能归入东财 push2
- 28 端点全量实测(2026-05-19),所有端点均通过贵州茅台 600519 验证
- push2 系列 5 个端点在阿里云服务器直连验证通过(本地 Clash 代理可能干扰)
- 彻底移除 akshare 依赖:所有 13 个 akshare 调用替换为直连 HTTP API(东财/新浪/同花顺/财联社源头接口)
pip install不再需要akshare,依赖缩减为mootdx requests pandas stockstats- 行业板块数据源从同花顺(401 反爬)切换至东财 push2(
m:90+t:2,零鉴权)
- 融资融券明细
margin_trading()— 日级融资余额/买入/偿还 + 融券余额/卖出/偿还 - 大宗交易
block_trade()— 成交价/量 + 买卖方营业部 + 溢价率 - 股东户数变化
holder_num_change()— 季度股东数 + 环比变化 + 户均持股 - 分红送转历史
dividend_history()— 每股派息/送股/转增 + 进度状态 - 个股资金流120日
stock_fund_flow_120d()— 主力/大单/中单/小单日级净流入
- 百度K线(带MA5/10/20)
baidu_kline()— 返回时直接含均价,无需自行计算 - 指数/ETF 实时行情 — 腾讯 API 扩展支持指数代码和 ETF 代码
- 架构从六层升级为七层,端点从 20 个增至 28 个
- 数据源从 8 个增至 13 个(东财 datacenter/push2his/search-api/np-weblist + 新浪 + 财联社 独立计数)
- 新增
eastmoney_datacenter()统一 helper — 龙虎榜/解禁/融资融券/大宗/股东/分红共用 - FAQ 新增 5 条常见问题(akshare 移除原因、行业板块切换、海外部署等)
- 28 端点全量实测(2026-05-17),覆盖主板/中小板/科创板/ST
- 所有新增 Tier 1 端点均通过贵州茅台 600519 验证
- 龙虎榜席位:
get_dragon_tiger_board— 上榜记录 + 买卖席位 TOP5 + 机构动向(akshare 三函数聚合) - 限售解禁日历:
get_lockup_expiry— 历史解禁记录 + 未来 90 天待解禁事件 - 行业横向对比:
get_industry_comparison— 同花顺 90 行业涨跌幅排名 + 成交额 + 净流入 + 领涨股 - 百度股市通概念板块:
get_concept_blocks— 行业/概念/地域三维板块归属 + 当日涨跌幅 - 百度股市通资金流向:
get_fund_flow— 主力/散户/超大单/大单分钟级流向 + 20 日历史 - 架构端点从 15 个增至 20 个,数据源从 7 个增至 8 个
- 北向资金自缓存:eastmoney 全系北向数据 2024-08 起断供,改为本地 CSV 自缓存模式(每次调用自动积累)
- F10 股东研究截断:【4.股东变化】只保留最新一期,19969→5906 chars(-70% token 消耗)
- 百度 PAE ResultCode 修复:返回类型 int/string 不稳定,统一
str()比较
- 17 接口全量实测,覆盖主板/中小板/科创板/ST 四类股票
- 50 OK / 1 预期 WARN(ST 无机构覆盖)/ 0 FAIL
首次开源发布。
- 信号层:同花顺热点(当日强势股 + 题材归因 reason tags)
- 信号层:同花顺北向资金(hsgtApi 实时分钟 + 历史日级)
- 架构从五层升级为六层,端点从 13 个增至 15 个
- 行情层:mootdx K 线 + 盘口 + 逐笔 / 腾讯财经 PE·PB·市值
- 研报层:东财 reportapi + PDF / akshare 一致预期 / iwencai NL 搜索
- 新闻层:个股新闻 / 财联社快讯 / 全球资讯
- 基础数据:季报 37 字段 / F10 九大类 / 个股基本面
- 公告层:巨潮全量公告 / F10 最新提示
- 4 套调研流程:单票估值 / 批量对比 / 主题研报 / 新标的调研
- 估值框架:前向 PE / PE 消化 / PEG / 30x 锚点
内部版本(未开源)。
- 五层架构 · 13 端点
- 行情 / 研报 / 新闻 / 基础数据 / 公告