Develop #14
@@ -0,0 +1,7 @@
|
||||
{"file":"CONTEXT.md","reason":"检查两份报告对历史可复现、选股信号、数据时点和投资建议边界的措辞是否一致。"}
|
||||
{"file":"docs/adr/0003-postgresql-as-market-data-store.md","reason":"检查复现建议是否清楚区分外部页面数据与本仓库已有市场数据事实源。"}
|
||||
{"file":"docs/adr/0004-tushare-six-year-snapshot-sync.md","reason":"检查时间窗口、数据修订和前视风险说明是否足以支持历史复现。"}
|
||||
{"file":"docs/adr/0005-selection-formula-semantics-and-independent-subsignals.md","reason":"检查报告是否区分规则语义、实现证据、作者自述和推断。"}
|
||||
{"file":".trellis/tasks/08-27-onechartlab-research/prd.md","reason":"逐条核对两份独立报告、复现深度、证据定位和范围边界的验收条件。"}
|
||||
{"file":".trellis/tasks/08-27-onechartlab-research/research/sector-capital-radar-evidence.md","reason":"核对板块报告的已确认事实、推断边界和排名复算结果。"}
|
||||
{"file":".trellis/tasks/08-27-onechartlab-research/research/macro-timing-evidence.md","reason":"核对宏观报告的阈值、状态、贡献恒等式和核心公式缺口。"}
|
||||
@@ -0,0 +1,34 @@
|
||||
# OneChartLab 技术调研设计
|
||||
|
||||
## 边界与交付
|
||||
|
||||
本任务分析公开可访问的 OneChartLab 页面、前端资源和浏览器请求,不修改产品代码,也不绕过任何访问控制。最终产出两份独立报告:`docs/research/onechartlab-sector-capital-radar.md` 与 `docs/research/onechartlab-macro-timing.md`。原始观察、接口样本和推断过程写入 `.trellis/tasks/08-27-onechartlab-research/research/`,作为报告的工作底稿。作者视频证据待用户提供可访问环境后补充。
|
||||
|
||||
## 调研分流
|
||||
|
||||
本轮调研拆成两个可并行证据流:板块资金雷达页面和宏观择时页面。每个证据流由一次性研究子代理形成一份 Markdown 底稿;主会话负责浏览器交互核验、关键出处抽查、跨来源冲突处理、技术判断和两份最终报告写作。子代理只做探索,不负责最终结论。作者视频作为后续独立证据流,待用户提供可访问环境后再执行。
|
||||
|
||||
## 证据模型
|
||||
|
||||
每条关键结论按以下状态标注:
|
||||
|
||||
1. `已确认`:可由页面文本、公开脚本、接口响应或可重复交互直接验证。
|
||||
2. `作者自述`:来自作者视频或其他第一方表达,但未必等同于当前实现。
|
||||
3. `合理推断`:由多个公开事实推导,必须写出推断链并给出高、中、低置信度。
|
||||
4. `无法确认`:公开证据不足,说明缺口与最小验证办法,不补造参数。
|
||||
|
||||
页面当前行为优先于视频中的历史描述;公开实现证据优先于营销文案;不同来源冲突时并列呈现,不强行合并。
|
||||
|
||||
## 数据与分析链路
|
||||
|
||||
对每个模块沿同一条复现链路分析:用户问题与输出语义、页面状态与交互、数据来源与请求结构、字段和时间粒度、预处理与派生指标、排序/打分/阈值或状态机、信号刷新与历史切换、异常和缺失数据处理。能确认公式时给出公式或等价伪代码;只能确认输入输出时给出候选机制、排除依据和验证实验。
|
||||
|
||||
板块资金雷达重点检查板块分类口径、资金/价格/成交活跃度输入、横截面归一化与象限或雷达映射、排名变化和时间窗口。宏观择时重点检查宏观/市场输入、风险状态定义、信号切换阈值、滞后与确认机制、资产映射和发布日期前视风险。
|
||||
|
||||
## 取证方式与兼容边界
|
||||
|
||||
优先使用真实浏览器观察 DOM、交互和网络请求,再检查公开静态资源及必要的只读 HTTP 响应。作者视频当前明确暂缓,本轮不继续尝试访问或转述。不得提交 cookie、token、个人账号信息或大体积媒体文件。
|
||||
|
||||
## 验证与回滚
|
||||
|
||||
最终检查逐条核对 PRD 验收标准、报告内引用的可访问性、事实/推断分级、两模块的一致术语和复现说明完整性。报告是新增 Markdown 文件,回滚只需移除新增报告和任务底稿,不影响运行时系统。
|
||||
@@ -0,0 +1,7 @@
|
||||
{"file":"CONTEXT.md","reason":"保持历史可复现分析、信号解释和非收益承诺等现有领域语义,并识别潜在前视偏差。"}
|
||||
{"file":"docs/adr/0003-postgresql-as-market-data-store.md","reason":"理解本仓库日线数据、qfq 口径和当前股票池边界,避免把外部模块假设直接当成本项目事实。"}
|
||||
{"file":"docs/adr/0004-tushare-six-year-snapshot-sync.md","reason":"核对日频数据、历史修订、覆盖率和时间窗口对后续复现的约束。"}
|
||||
{"file":"docs/adr/0005-selection-formula-semantics-and-independent-subsignals.md","reason":"报告应区分公式语义、实现证据和独立信号,不把旧输出或作者表述当作当前算法。"}
|
||||
{"file":".trellis/tasks/08-27-onechartlab-research/design.md","reason":"提供证据等级、两路页面调研分工、视频暂缓边界、复现链路和访问限制。"}
|
||||
{"file":".trellis/tasks/08-27-onechartlab-research/research/sector-capital-radar-evidence.md","reason":"提供板块页面、公开分片、排名算法、失败边界和主会话复算证据。"}
|
||||
{"file":".trellis/tasks/08-27-onechartlab-research/research/macro-timing-evidence.md","reason":"提供宏观页面、状态/贡献协议、阈值、证据缺口和主会话复算证据。"}
|
||||
@@ -0,0 +1,32 @@
|
||||
# OneChartLab 技术调研执行计划
|
||||
|
||||
## 执行清单
|
||||
|
||||
- [x] 建立 `research/` 工作底稿目录,分别派发板块资金雷达和宏观择时两个一次性研究子代理;每个子代理只写自己的证据文件,并返回 URL、资源名、字段或关键原文。
|
||||
- [x] 尝试使用真实浏览器核验两个页面;连接被目标站点关闭后,按风险边界改用公开 HTML、脚本和 JSON 响应核验可见控件、图表逻辑、时间切换与加载/错误行为,并在报告中记录限制。
|
||||
- [x] 只读检查页面 HTML、公开 JavaScript、静态资源和网络请求,识别接口、字段、数据粒度、更新频率以及前后端计算边界;保存最小必要样本,不保存凭据或无关个人数据。
|
||||
- [x] 在两份报告中记录作者视频证据暂缓及其影响,不在用户提供可访问环境前继续尝试该路径。
|
||||
- [x] 对两路页面底稿进行出处抽查和交叉验证,建立事实、作者自述、合理推断、无法确认四级证据表,并显式记录冲突。
|
||||
- [x] 编写 `docs/research/onechartlab-sector-capital-radar.md`,覆盖输入、加工链路、排序/打分/映射、输出信号、更新和异常边界、复现伪代码及证据置信度。
|
||||
- [x] 编写 `docs/research/onechartlab-macro-timing.md`,覆盖输入、状态定义、阈值/状态机、滞后与前视风险、资产解释、复现伪代码及证据置信度。
|
||||
- [x] 执行最终内容检查,确认每条关键技术结论有出处或推断标签,两份报告可以独立阅读且不包含收益承诺或未经确认的精确参数。
|
||||
|
||||
## 验证命令与人工检查
|
||||
|
||||
```bash
|
||||
test -s docs/research/onechartlab-sector-capital-radar.md
|
||||
test -s docs/research/onechartlab-macro-timing.md
|
||||
rg -n "已确认|作者自述|合理推断|无法确认" docs/research/onechartlab-*.md
|
||||
rg -n "https?://|时间点|接口|字段|伪代码|局限" docs/research/onechartlab-*.md
|
||||
git diff --check
|
||||
```
|
||||
|
||||
人工核对报告中的关键 URL 和公开请求字段,检查证据等级是否与正文措辞一致,并确认视频暂缓状态及其影响已写清楚。
|
||||
|
||||
## 风险与停止条件
|
||||
|
||||
如果网站需要绕过登录、付费、验证码、地域限制或反爬机制才能继续,停止该取证路径并记录缺口。若压缩/混淆脚本只能支持候选实现而不能证明算法,降级为推断。若公开数据只给出最终分值,报告提供可实施的验证实验,而不虚构原始公式。
|
||||
|
||||
## 回滚点
|
||||
|
||||
本任务不改产品代码。任何过程性抓取文件都限制在任务 `research/` 下;最终报告写入 `docs/research/`。出现敏感信息或无关个人数据时立即停止使用并从交付物中剔除。
|
||||
@@ -0,0 +1,44 @@
|
||||
# OneChartLab 板块资金雷达与宏观择时技术调研
|
||||
|
||||
## Goal
|
||||
|
||||
基于公开可访问的页面、网络请求、前端资源及作者公开视频,分别还原 OneChartLab「板块资金雷达」和「宏观择时」模块的产品逻辑与可验证技术机制,并进一步整理复现所需的 Tushare 数据采购与采集契约,形成三份证据可追溯、能够指导后续复现实现的中文技术调研报告。
|
||||
|
||||
调研的用户价值是区分页面明确展示的事实、可由公开证据推导的实现逻辑和仍无法确认的假设,避免把界面观感或作者观点误写成已证实的算法细节。
|
||||
|
||||
## Background
|
||||
|
||||
- 调研对象为 `https://onechartlab.com/`(板块资金雷达)和 `https://onechartlab.com/macro/`(宏观择时)。
|
||||
- 补充材料为作者发布在 `https://b23.tv/IJRk8y2` 的视频;页面与公开音视频流现已可访问,视频没有公开字幕,本轮使用音轨转写与画面抽帧补充作者自述证据。
|
||||
- 交付物为两份模块技术调研报告和一份 Tushare 数据需求研究文档,而不是产品代码、投资策略实现或投资建议。
|
||||
|
||||
## Requirements
|
||||
|
||||
- 分别描述每个模块的目标用户问题、界面信息架构、指标或信号含义、状态变化、交互流程和结果解读方式。
|
||||
- 检查公开页面的 HTML、脚本、静态资源和浏览器网络请求,在不绕过登录、付费、验证码或访问控制的前提下,识别前端数据结构、接口、更新频率及计算发生位置。
|
||||
- 分析指标构造、分层/排序/打分、阈值、择时状态机、信号确认与切换等核心逻辑;无法从公开证据确认时,明确标注为推测并给出推断链和置信度。
|
||||
- 补充作者对设计目标、市场假设、指标选择、使用方法和限制的观点,并把视频自述与页面代码、公开数据复算结果分开标注和交叉验证。
|
||||
- 每份报告独立成篇,包含结论摘要、模块拆解、数据与计算链路、信号逻辑、证据与置信度、局限及可复现建议。
|
||||
- 复现说明应尽量覆盖输入字段、数据粒度、时间窗口、指标公式或伪代码、归一化/排序/打分、阈值、状态机、更新时点和异常边界;证据不足时不得伪造精确参数。
|
||||
- 引用可定位到 URL、资源名、请求字段、页面文本、视频时间点或仓库文件的证据;不得将未验证信息陈述为事实。
|
||||
- 报告使用简体中文,代码标识符、字段名、接口和路径保持原样。
|
||||
- 新增 Tushare 数据需求文档,按模块列出必需、推荐和可选接口,覆盖用途、调用粒度、输入参数、输出字段、业务主键、更新频率、历史深度、积分/权限、落库与 point-in-time 要求,并把作者/页面暴露的接口事实与官方文档能力分开标注。
|
||||
- 最终交付路径为 `docs/research/onechartlab-sector-capital-radar.md`、`docs/research/onechartlab-macro-timing.md` 和 `docs/research/onechartlab-tushare-data-requirements.md`;过程证据保存在本任务的 `research/` 目录。
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [x] 生成两份独立的 Markdown 技术调研报告,分别覆盖「板块资金雷达」和「宏观择时」。
|
||||
- [x] 每份报告都明确回答模块解决什么问题、输入数据是什么、如何加工、输出信号是什么、用户如何解释以及有哪些已知限制。
|
||||
- [x] 关键结论附有可追溯证据,并区分“页面/代码/请求已确认”“作者自述”“合理推断”“无法确认”四类来源状态。
|
||||
- [x] 对公开可见的接口、数据字段、前端算法或状态机给出足以指导后续复现验证的技术说明;若无法获得,则记录尝试路径和证据缺口。
|
||||
- [x] 视频观点已按时间点补充,并明确区分作者自述、页面实现和仍无法确认的算法细节。
|
||||
- [x] 两份报告不存在投资收益承诺,并明确其用途是技术与产品逻辑研究,不构成投资建议。
|
||||
- [x] 生成一份 Tushare 数据需求研究文档,能够作为后续采集、落库和独立重算的接口清单与实施边界。
|
||||
- [x] Tushare 文档明确区分页面已暴露的确定接口、为复现建议补充的接口和仍需实测/开通权限确认的接口;关键字段及权限信息引用官方来源。
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- 绕过登录、会员、验证码、地域限制、反爬机制或其他访问控制。
|
||||
- 对未公开的后端源码、私有数据源或专有算法作确定性归因。
|
||||
- 开发、回测或上线等价策略,评估真实交易收益,或提供个性化投资建议。
|
||||
- 修改 OneChartLab 网站或向其作者、用户发送消息。
|
||||
@@ -0,0 +1,39 @@
|
||||
# 作者视频证据:OneChartLab 四个网页工具
|
||||
|
||||
## 视频身份与取证方式
|
||||
|
||||
- 标题:《我把自己的交易系统,做成了4个网页工具》
|
||||
- 作者:知行图表交易
|
||||
- Bilibili:`BV16Hur6rEq2`,`aid=117077738265338`,`cid=40820081505`
|
||||
- 页面发布时间:2026-08-12 00:13:10;时长:14:32
|
||||
- 页面地址:<https://www.bilibili.com/video/BV16Hur6rEq2/>
|
||||
- 页面简介:网站数据每日下午约 17:10—17:40 更新,受 Tushare 数据同步节奏限制。
|
||||
|
||||
视频没有公开字幕。本记录使用公开音轨经 `faster-whisper small` 中文模型转写,并用每 10 秒画面抽帧校对模块切换和页面位置。以下内容是按语义整理的作者自述,不把自动转写中的同音字当作精确原话;涉及关键公式时仍以页面代码和公开数据复算为最高证据。
|
||||
|
||||
## 板块资金雷达
|
||||
|
||||
- `00:00—01:15`:作者说明视频用于概览四个网页及近期更新;两个域名都可访问同一网站,新域名 `onechartlab.com` 主要改善国内连接性。四个页面统一了视觉外观,新增深色模式并调大字体。
|
||||
- `01:17—01:36`:板块资金雷达不仅展示概念/行业的单日主力净流入,也展示单日流入率和多日波段流入率。
|
||||
- `01:36—01:58`:作者把单日流入率解释为“主力流入相对当天成交额的比例”。比例越高,主力资金占比越高;但成分股过少、交易不活跃或成交量过低的板块可能出现失真的高比例。
|
||||
- `01:58—02:23`:作者把波段流入率解释为“统计 3—10 天加权的单日流入率并排名”。在三百多个行业和概念中排名越靠前,表示主力资金在板块内“留存下来的比例”越高,后续行情的延续性可能相对更好。作者使用了概率性表述,没有承诺必然延续。
|
||||
- `02:23—02:56`:作者以仪器仪表、元件、PCB/印刷电路板等为例,说明相近板块若波段流入率同时靠前,可辅助识别同一主题的资金持续性。
|
||||
- `02:56—03:49`:页面新增板块成分股解释层,可查看涨跌幅、主力净额和主买净额的前后标的。作者认为它既能解释陌生行业包含哪些股票,也能帮助理解板块排名由哪些成分驱动。
|
||||
- `03:49—04:13`:成分股支持复制、单板块导出和多板块勾选批量导出。作者明确说网页数据已公开,用户也可以让 Agent 工具每日定时抓取并分析。
|
||||
|
||||
## 宏观择时 / 高切低指标
|
||||
|
||||
- `04:13—04:27`:宏观择时页目前只放入一个“高切低指标”,未来可能继续加入作者认为有价值的指标。
|
||||
- `04:27—04:42`:作者说明该指标参考国投证券的同名指标,并建议查看相关研报。视频没有声称复刻原版公式;页面同时明确标注“非原版算法”。
|
||||
- `04:42—05:13`:作者把指标输入解释为申万一百多个二级行业近 90 天涨跌幅的横截面分布。行业涨跌幅差异越大,指标数值越大;高值意味着少数行业显著跑赢,甚至后排行业反向运行,形成结构性上涨或抱团行情。
|
||||
- `05:23—05:39`:作者给出的状态解释是:`30—70` 为正常区间,`70—120` 代表结构性抱团,超过 `120` 代表极致化抱团,可视为拥挤或过热。视频没有补充滞回、连续确认或仓位规则。
|
||||
- `05:41—06:27`:作者以 2007、2015、2021 年及近期行情为例说明极值。视频称近期六月底一度达到 `119.19`,抱团瓦解后指标快速回落;高位板块回调、低位板块均值回归会共同降低横截面离散度。
|
||||
- `06:29—06:40`:第一种用途是宏观层面的择时/风险识别,通过是否超过 `70` 或 `120` 判断市场是否处于极致抱团甚至过热环境。
|
||||
- `06:40—07:27`:第二种用途是判断市场风格是普涨还是结构化。作者以“924”行情为例:初期指数上涨但离散度没有同步大升,代表普涨;后期离散度上升,代表只有少数行业上涨。作者进一步把它解释为主线识别,希望持仓行业处于主线、贡献正向离散度,而非位于主线对立面。
|
||||
- `07:27—07:58`:第三种用途是观察由高离散度转向低离散度时可能出现的“高切低”,即资金从高风险/高位板块切向低风险/低位板块。作者强调低位板块出现小行情不等于它一定会成为新主线,只能说明资金存在高切低趋势。
|
||||
|
||||
## 与页面证据的交叉结论
|
||||
|
||||
视频补足了两项设计语义。其一,单日流入率的概念分母是当日成交额,并明确提示小样本与低流动性会造成比例失真;但视频仍未公开精确字段、聚合顺序、异常值处理和 score 标准化。其二,高切低指标明确基于申万二级行业近 90 日涨跌幅差异,阈值用于解释拥挤与市场结构;但视频仍未公开离散度统计量、行业相对基准、历史校准、贡献 `C/O` 的上游公式或任何可执行仓位规则。
|
||||
|
||||
因此,视频适合用来确认产品意图、指标语义、使用边界和风险提示,不能替代页面代码与公开数据对精确公式的验证。
|
||||
@@ -0,0 +1,48 @@
|
||||
# OneChartLab「宏观择时」公开实现证据
|
||||
|
||||
核验日期:2026-08-27(只读请求;未使用登录、验证码、cookie/token,也未分析视频)。主页面:<https://onechartlab.com/macro/>。
|
||||
|
||||
## 已确认
|
||||
|
||||
1. **产品目标和公开界面。** 页面标题为“宏观择时”,副标题是“观察市场趋势与拥挤程度,判断中长期多空方向”;唯一指标页签为“高切低指标”,并明确写“参考国投证券同名指标,非原版算法”(HTML 原文及出处:`https://onechartlab.com/macro/`,抓取 HTML `51-66` 行)。页面显示今日离散度、十年历史百分位、较昨日、近5日,并叠加行情离散度与指数累计表现图(HTML `70-114`)。
|
||||
|
||||
2. **算法公开到什么程度。** 页面原文是“以申万二级行业的相对收益分布衡量行情分化程度,并通过平滑处理形成离散度序列”,且声明“仅供历史研究学习使用,不构成投资建议”(HTML `121-126`)。因此行业层级和“相对收益分布”是确认事实,但分布统计量、归一化方式、平滑窗口及权重没有在公开页面说明;不能把它复现为某个特定公式。
|
||||
|
||||
3. **阈值/状态机。** 前端 `assets/app.js?v=a4a0a7155f44` 的 `dispersionZone(value)` 明确实现:`value<30` → `低位趋同`;`30<=value<70` → `正常区间范围内`;`70<=value<120` → `中高位 · 潜在高切低动力`;否则 → `极致化抱团 · 谨慎`(该 JS 为单行压缩资源,函数位置可按符号检索;等价源码行号见本底稿 `file:line` 说明)。页面可见的数值区间文案为“30—70 趋同发展 | 70—120 结构抱团 | 120+ 极致化”(HTML `83-87`)。
|
||||
|
||||
4. **百分位、变化量和发布日期。** 同一 JS 的 `tenYearPercentile(values,last)` 取 `last` 日期往前十年的样本,只保留当前日期以前且为有限值的观测,百分位为 `100 * count(value <= current) / sample.length`;`updateStats()` 使用最后一个有限值,计算当日值、百分位、1日差和 `last-5` 差,并把对应日期写入 `#as-of`(`assets/app.js` 函数 `tenYearPercentile` / `updateStats`)。这意味着百分位包含当前观测(并非严格“之前”的样本),页面的“数据日期”是序列最后一个有效交易日。
|
||||
|
||||
5. **实际公开数据接口和当前快照。** `assets/app.js` 的 `init()` 请求 `state.json`,读取 `state.current.manifest.series_path`,再请求该路径;当前公开响应 `https://onechartlab.com/macro/state.json` 为 `schema_version: onechart_macro_daily_bundle_v3`、`release_status: production`、`revision_watermark: 21`,`current.as_of_date: 20260826`、`current.batch_id: batch-20260826-r21-c8768898f3`,系列路径为 `batches/batch-20260826-r21-c8768898f3/series.json`。该系列响应的 schema 为 `onechart_macro_v1`,日期从 `20000601` 到 `20260826`,字段包括 `dates`、`precise`、`smooth`、`indices`;当前摘要中 `precise=42.1781`、`value(smooth)=42.551`、`change_1d=-1.7363`、`change_5d=-15.5529`、`precise_percentile_10y=38.4`、`smooth_percentile_10y=38.6`。出处:`https://onechartlab.com/macro/state.json`、`https://onechartlab.com/macro/batches/batch-20260826-r21-c8768898f3/series.json`。
|
||||
|
||||
6. **指数输入和图表交互。** JS 的 `TAG_ORDER` 固定包含 `000001.SH`、`399006.SZ`、`000688.SH`、`000016.SH`、`000300.SH`、`000852.SH`、`932000.CSI`,标签分别为上证、创业、科创、50、300、1000、2000;指数曲线以选定时间范围起点价格做 `100*log(price/base)` 的累计表现,tooltip 再将其转成 `100*(price/base-1)` 的区间涨跌幅。默认展示平滑序列和上证曲线;可切换精准、显示/隐藏曲线、拖动时间范围、双击恢复、选择曲线后上下拖动改变显示缩放(`assets/app.js`:`normalized`、`tooltip`、`setupSeriesTags`、`setupVerticalScaleInteraction`)。页面操作提示原文在 HTML `116-119`。
|
||||
|
||||
7. **离散度贡献模块的数据契约。** 页面嵌入“离散度贡献”区块,文案写“正贡献表示相对状态增强,负贡献表示相对状态减弱”,并称行业贡献按公开归一化数据构建、支持固定90日窗口(HTML `131-135`)。`assets/dispersion-store.js` 的 `DataStore` 公开校验:schema `dispersion-public-v2`;manifest 要求 `industry_count===124`、`index_count===7`、日期序列严格递增且至少91个;每行字段严格为 `date,D,MA3,K,K_MA5,industries,indices`;行业字段为 `code,name,normalized,return90,C,O`,指数字段为 `code,name,normalized`。`view(end)` 明确返回所选结束日及其前90个交易日共91行的 C/O/normalized 序列。出处:`https://onechartlab.com/macro/assets/dispersion-store.js`,函数 `validManifest`、`validBlock`、`view`。
|
||||
|
||||
8. **贡献模块的窗口、排序和状态映射。** `assets/dispersion-contribution.js` 以 `DATA.values`(行业 C)做逐行业前缀和;1/3/5/10/90 日贡献分别是截至日最近 N 个交易日的累计和,正负两侧各取10个行业排序。页面/脚本显示“固定90日窗口(虚线为MA5)”,每日柱状贡献正值代表扩大分化、负值代表缩小分化;后续 V31 逻辑使用 `O` 计算“方向性”、使用 C 判断结构扩大/缩小,状态函数 `state18` / `effect18` 的完整阈值未在可读页面文案中公开。该资源为压缩单行,出处 URL:`https://onechartlab.com/macro/assets/dispersion-contribution.js?v=05aeb6c74aaf`,符号 `sum`、`metric`、`pool`、`curve18`、`state18`、`effect18`。
|
||||
|
||||
9. **更新、缓存和异常边界。** `DataStore.bytes` 所有请求都用 `cache:'no-store'`,若 manifest 给出 hash 则 SHA-256 校验;`choose` 对 current 构建超过 `maxAgeDays=30` 视为 `stale-current`,失败后回退 `last_good`;若回退构建也失败,状态为 `unavailable`。`ensureWindow` 要求窗口正好91个交易日,缺块时按年份文件懒加载,缺行/范围不匹配/字段形状错误都会失败。贡献模块失败时页面明确显示“离散度贡献暂不可用,高切低指标保持正常”(HTML `134`,JS 主 IIFE catch)。
|
||||
|
||||
10. **成分股详情接口(补充模块)。** 贡献排行点击行业后,脚本懒加载 `../sector_rankings/manifest.json`,按 `systems.macro.current.date_files[date]` 读取日期文件;字段契约声明宏观输入来自 Tushare:`daily.pct_chg`、`moneyflow.net_mf_amount`、`moneyflow_dc.net_amount`、`index_member_all`、`suspend_d`、`suspend`、`stock_basic`。公开 payload 只给 top/bottom 派生排名;主买净额单位从万元转展示亿元,且明确“不等同主力净额”。出处:`https://onechartlab.com/sector_rankings/manifest.json` 及 `dispersion-contribution.js` 的 lazy-detail `open()`。
|
||||
|
||||
## 合理推断(注明链条与置信度)
|
||||
|
||||
- **前端只消费预计算序列,核心算法在后端/构建流程。** 证据链:`init()` 仅 fetch `series.json` 并直接使用 `precise`/`smooth`;页面和 JS 没有根据行业原始收益计算离散度的代码,而贡献模块消费 `D/MA3/K/K_MA5/C/O`。置信度高;但构建端未公开,无法确认具体服务/脚本。
|
||||
- **存在至少一个“平滑确认”层。** 证据链:接口同时提供 `precise` 和 `smooth`,UI 默认 smooth,贡献数据行又提供 `MA3`;可以合理推断平滑用于减少日噪声或确认,但不能确认平滑是3日移动平均、是否居中、是否有信号滞后。置信度中。
|
||||
- **历史数据可能发生修订,且当前页面存在版本/口径并行。** `state.json` 记录 `accepted_input_hash`、`bundle_id`、`revision_watermark` 和 `last_good`;dispersion manifest 的 `identity.daily_contract` 为 `macro-bundle-v10-public-0644-private-0600-round4-percentile-closure-round10-seed-latest-names`,说明构建链会版本化并接受输入链。由此可推断历史序列不是不可变真值;但公开接口没有修订日志或逐日版本对照,无法量化修订频率。
|
||||
- **回测前视偏差风险主要来自发布日期/可见时点未公开。** 数据有交易日 `as_of=20260826`,但没有公开生成时间、Tushare 各输入实际返回时间或“次日可用”规则。因而使用当日收盘构建的指标去解释当日盘中/收盘前决策会有潜在前视;这是复现时必须保守处理的风险,不是已证实的泄漏。
|
||||
|
||||
## 无法确认 / 失败尝试与证据缺口
|
||||
|
||||
- 未找到公开的核心公式:没有确认相对收益分布采用标准差、分位距、极差、熵或其他统计量,也没有确认 `K`、`K_MA5` 的定义;不能据此声称原版“高切低”算法。
|
||||
- 未确认资产/风险状态映射:页面只把阈值文案映射为“趋同/抱团/极致化”和“潜在高切低动力/谨慎”,没有公开仓位比例、具体资产切换或风险预算映射。
|
||||
- 未确认发布日期/交易时点和历史修订策略:只有 `as_of_date`、bundle/hash/watermark,没有公开 release timestamp、修订差分、输入快照或 point-in-time 数据协议。
|
||||
- 只读尝试 `https://onechartlab.com/macro/dispersion/state.json` 返回板块资金雷达 HTML(非 JSON,HTTP 200);页面脚本仍以相对路径 `dispersion/state.json` 请求。这是当前公开部署路径异常的证据,不能据此判断后端接口不存在,且不要用主页 fallback 内容当作数据。
|
||||
- `latest180.json`(manifest 路径 `https://onechartlab.com/macro/dispersion/builds/dispersion-20260826-6186c256680b/latest180.json`)响应体较大,当前 curl 超时/截断,未将不完整响应当作数据证据;manifest 本身成功核验到 `date_index` 2326 个、124 行业、7 指数、V31 renderer、`as_of=20260826`。
|
||||
|
||||
## 供抽查的定位
|
||||
|
||||
外部 HTML(下载后 `nl -ba`):`/tmp/oc_macro.html:51-66,70-87,90-119,121-145`;外部 JS 原文件均为压缩单行,应用资源名和关键符号可直接用 `rg`:`/tmp/oc_app.js:1`(`dispersionZone`、`tenYearPercentile`、`updateStats`、`init`)、`/tmp/oc_store.js:7-21`(`DataStore`)、`/tmp/oc_contrib.js:1-124`(`sum`、`pool`、`curve18`、`state18`、`open`)。数据响应:`https://onechartlab.com/macro/state.json`、`https://onechartlab.com/macro/batches/batch-20260826-r21-c8768898f3/series.json`、`https://onechartlab.com/macro/dispersion/builds/dispersion-20260826-6186c256680b/manifest.json`、`https://onechartlab.com/sector_rankings/manifest.json`。
|
||||
|
||||
## 主会话复核补充
|
||||
|
||||
主会话随后成功完整读取 `latest180.json`,SHA-256 为 `b0f2821c9f72f9d7b583f748b0759b5c0a1cc72f92edc66162418d2bc9b3add3`,与 manifest 一致。对 180 行、22320 个行业观测复算确认:`MA3=mean(D_t..D_{t-2})`、`D_t-D_{t-1}=ΣC_i,t`、`K_t=ΣO_i,t`、`K_MA5=mean(K_t..K_{t-4})`,并且所有观测满足 `abs(O)=abs(C)`。当前 V31 脚本最终使用窗口内 `ΣO` 排贡献方向、`ΣC` 判结构扩大/收敛,再映射进攻/走弱/回落/修复四象限。
|
||||
@@ -0,0 +1,43 @@
|
||||
# OneChartLab「板块资金雷达」公开实现证据
|
||||
|
||||
核查日期:2026-08-27。范围是无需登录的 `https://onechartlab.com/` HTML、其公开 JSON 静态资源和前端内嵌 JavaScript;没有绕过访问控制,也未保存 cookie/token/个人数据。
|
||||
|
||||
## 已确认
|
||||
|
||||
1. **用户目标与主界面。** 页面 title/description 是“板块资金雷达”和“观察板块资金流向、强弱变化与市场主线”;正文副标题为“识别主线资金流向与趋势,对比板块强弱”。页面可选数据日期、概念/行业类型、搜索板块名称或代码,并支持“波段流入率、单日流入率、单日净额、排名变化”四种排序指标(`https://onechartlab.com/`,HTML `file:line`:`:6-7`, `:641-671`)。
|
||||
|
||||
2. **公开数据协议与粒度。** 首页首先只读请求 `radar_manifest.json`,校验 `schema_version===1`、`AVAILABLE_DATES`、日期 shard 路径,再请求 `radar_data/dates/2026-08-26.f49c721846fb.json`(manifest 当前文件名来自 `https://onechartlab.com/radar_manifest.json`)。manifest 给出 `LATEST_DATE=2026-08-26`,可用日期为 2026-07-16 至 2026-08-26 的 30 个交易日;最新 shard 实测为 JSON 数组 791 条,概念板块 414、行业板块 377。实现证据:HTML `:1894-1972`;响应字段/路径证据:`https://onechartlab.com/radar_manifest.json` 的 `AVAILABLE_DATES`、`LATEST_DATE`、`files.dates`,最新 shard URL 上述路径。
|
||||
|
||||
3. **单条板块字段。** 最新 shard 的记录含 `trade_date`, `type`, `index_name`, `ts_code`, `lead_stock`, `pct_change`, `pct_change_stock`,以及 `Swing/Ratio/Amount` 三类的 raw 值、分数、排名位置、排名百分位、近 30 日在榜计数和 1/2/3 日排名变化字段:如 `Swing_Ratio_Val`, `Swing_Amount_Val`, `Swing_Score`, `Swing_RankPos`, `Swing_RankPct`, `Swing_Top30d`, `Swing_Bot30d`,对应 `Ratio_*`、`Amount_*`。实测示例 `2026一季报扭亏 (概念)`(ts_code `BK1682.DC`)在 2026-08-26 的 `Amount_Raw_BN=-5.59969136`, `Amount_RankPos=353`, `Ratio_Raw_Pct=-0.06896072719626979`, `Swing_Ratio_Val=-0.03308411781204722`。来源:`https://onechartlab.com/radar_data/dates/2026-08-26.f49c721846fb.json`,响应记录键集合。
|
||||
|
||||
4. **榜单筛选和排名。** 非“排名变化”时,前榜取 `activeTab_RankPct >= 90`,后榜取 `<= 10`;默认前榜按 `Amount_Raw_BN`(单日净额)或相应 `*_Score` 降序,后榜升序。“排名变化”时按所选基准 `Swing/Ratio/Amount` 的 `*_Rank_Chg` 排序,各取 `ceil(板块数*0.1)` 且至少 1 条。代码还明确页面文案为 `TOP 10%` / `BOTTOM 10%`。HTML `:1292-1314`, `:695-718`。
|
||||
|
||||
5. **排名变化的时间窗口。** 排名变化基准可选波段率、单日率、单日额;统计天数 UI 提供近 1 至近 5 天。1–3 天直接读取记录中的 `Swing/Ratio/Amount_Rank_Chg_1d/2d/3d`;超过 3 天时读取 rank-history,并以 `pastRank - currRank` 计算变化,过去日期超出范围时钳制到最早可用日期。HTML `:676-691`, `:1260-1289`。
|
||||
|
||||
6. **数值显示与单位映射。** `Swing_Ratio_Val` 和 `Ratio_Raw_Pct` 在显示时乘 100 并格式化为百分比;`Amount_Raw_BN` 直接按亿元显示;分数显示 1 位小数,净额显示 1 位小数,排名变化显示整数。HTML `:1453-1467`, `:1482-1500`;详情文字也明确“波段均值”“占比”“主力净流入 … 亿”,`:1072-1092`。
|
||||
|
||||
7. **历史轨迹和详情交互。** 榜单的“在榜”按钮读取公开 `radar_data/rank_history.3674d0a1cecf.json`,结构为 `Amount`, `Ratio`, `Swing` 三个 map,每个包含约 799 个板块名到日期→排名的映射;详情图使用可用日期反转后的 30 个点,缺失历史排名以总池大小代替,并把排名限制到 `[1,maxRank]`。HTML `:1522-1539`, `:1564-1571`, `:1794-1815`;资源 URL:`https://onechartlab.com/radar_data/rank_history.3674d0a1cecf.json`。
|
||||
|
||||
8. **成分股数据、字段和异常边界。** 详情通过 `sector_rankings/manifest.json`(schema `onechart_sector_stock_rankings_v2`)定位日期文档 `sector_rankings/radar/dates/20260826.bacc5d9e1581.json`,再按 `sectors[ts_code]['1']` 读取 `metrics.pct_change/main_net_amount/active_buy_net_amount` 的 `top`、`bottom`、`sample_size`、`status` 和 `value`。实测日期文档含 `date=20260826`, `system=radar`, `sectors` 791 个板块;示例 `BK0420.DC` 的三指标均为 `status=available`, `sample_size=13`。HTML `:1667-1704`;资源 URL:`https://onechartlab.com/sector_rankings/manifest.json`、`https://onechartlab.com/sector_rankings/radar/dates/20260826.bacc5d9e1581.json`。
|
||||
|
||||
9. **数据源、口径和更新时点(页面公开原文)。** 页脚写明“数据源: Tushare + 东财板块日线资金流数据”“更新频率: 交易日 17:00 ~ 17:30 自动同步”“参数说明: 波段周期取 3-10 个交易日多周期协同加权”。页面也提示“本日板块数据由个股本地聚合计算,涨跌幅暂不显示(\"-\")”。HTML `:636-639`, `:1028-1035`。`radar_manifest.json` 当前 `DATA_SOURCE` 为空,因此“本地聚合”提示在当前公开 payload 不会因该字段自动出现;提示逻辑为 HTML `:1187`。
|
||||
|
||||
10. **前后端计算边界和失败处理。** 公开 JSON 已提供 raw、score、rank 等派生字段,浏览器端只做筛选、排序、格式化、排名变化(超过 3 日)、Jaccard 近似板块计算和 SVG 轨迹绘制;manifest/日期 shard/rank-history 请求失败会回退到 `radar_data_latest.json`,仍失败则显示“数据加载失败”和“重新加载”按钮。HTML `:1905-1972`, `:1771-1792`。旧接口是 `https://onechartlab.com/radar_data_latest.json`,实测可公开读取但约 20 MB,含 `RADAR_DATA`, `AVAILABLE_DATES`, `LATEST_DATE`, `RANK_HISTORY_MAP`, `CONSTITUENT_MAP`。
|
||||
|
||||
## 合理推断
|
||||
|
||||
- **“波段”口径是服务端预计算的多周期指标。** 依据:页脚原文称“3-10 个交易日多周期协同加权”,记录同时暴露 `Swing_Ratio_Val`、`Swing_Amount_Val` 与 `Swing_Score`,但前端没有生成这些字段的公式。置信度:高(页面口径明确),具体权重未知。
|
||||
- **榜单主数据主要在服务端生成。** 依据:前端直接消费 `*_Score`, `*_RankPct`, `*_RankPos`, `*_Rank_Chg_1d..3d`,只在 4/5 日排名变化时用公开历史 map 做差;因此原始资金聚合、打分、排名应已在静态数据发布前完成。置信度:高;无法据此确定后端具体语言或作业实现。
|
||||
- **排名池是东财板块宇宙,当前 791 个板块。** 依据:`sector_rankings/manifest.json` 的 radar `universe_id="eastmoney-dc-v1"`, `sector_count=791`,与最新日期 shard 数量一致。置信度:高。
|
||||
- **近似板块“重合度”是 Jaccard。** 依据:浏览器端计算 `intersection / (setA.size + codes.length - intersection)`,排序取前 4(HTML `:1781-1792`);不是后端评分。置信度:高。
|
||||
|
||||
## 无法确认 / 证据缺口
|
||||
|
||||
- 未在公开 HTML/JS/JSON 找到 `Swing_Score`、`Ratio_Score`、`Amount_Score` 的具体公式、权重、标准化方式、并列排名规则,也无法从响应反推出“TOP 10%”之外的完整排序 universe 计算细节。
|
||||
- 页脚只给出 Tushare 与东财来源名;未公开 API token、抓取 SQL、任务代码、实际同步失败重试策略或时区说明。`sector_rankings/manifest.json` 的 contract 能确认 radar 输入字段映射:`tushare.moneyflow.net_mf_amount`, `tushare.moneyflow_dc.net_amount`, `tushare.dc_member`, `tushare.daily.pct_chg` 等,但不能证明上游响应在本次发布中的每一行具体值。
|
||||
- “本日板块数据由个股本地聚合计算”是页面条件提示文本;当前 `radar_manifest.json` 的 `DATA_SOURCE` 为空,实际页面是否显示该提示取决于运行时 payload/旧回退数据,未用交互浏览器截图确认。
|
||||
- 未分析视频;未访问需要登录、验证码、付费或绕过反爬的资源。对不存在的后端 API,实际仅检索 HTML 中 `fetch(`/api`/axios` 等关键词和内嵌请求路径;发现的公开请求路径限于 `radar_manifest.json`、日期 shard、`radar_data/rank_history...json`、`radar_data_latest.json` 和 `sector_rankings/...`,未发现 XHR API。
|
||||
|
||||
## 主会话复核补充
|
||||
|
||||
主会话对 2026-08-26 全部 791 条记录复算确认:概念和行业两个排名池内,`Swing_RankPos` 与 `Swing_Score` 降序、`Ratio_RankPos` 与 `Ratio_Score` 降序、`Amount_RankPos` 与 `Amount_Raw_BN` 降序均为零不匹配;三个 `RankPct` 字段均满足 `100 * (N - RankPos + 1) / N`,最大浮点误差约 `1.42e-14`。这使排名外层逻辑可以精确复现,但不能反推出三个 score 的服务端构造公式。
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"id": "onechartlab-research",
|
||||
"name": "onechartlab-research",
|
||||
"title": "OneChartLab 板块资金雷达与宏观择时技术调研",
|
||||
"description": "",
|
||||
"status": "in_progress",
|
||||
"dev_type": null,
|
||||
"scope": null,
|
||||
"package": null,
|
||||
"priority": "P2",
|
||||
"creator": "yuxuanhui",
|
||||
"assignee": "yuxuanhui",
|
||||
"createdAt": "2026-08-27",
|
||||
"completedAt": null,
|
||||
"branch": null,
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
"commit": null,
|
||||
"pr_url": null,
|
||||
"subtasks": [],
|
||||
"children": [],
|
||||
"parent": null,
|
||||
"relatedFiles": [],
|
||||
"notes": "",
|
||||
"meta": {}
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
# OneChartLab「宏观择时」技术调研报告
|
||||
|
||||
> 调研日期:2026-08-27;视频补充:2026-08-28;页面:<https://onechartlab.com/macro/>;当前公开数据日期:2026-08-26。
|
||||
> 目标:还原能够由公开证据支持的指标、状态和贡献逻辑,为后续复现提供技术边界。
|
||||
|
||||
## 结论摘要
|
||||
|
||||
OneChartLab 的“宏观择时”公开页面、脚本和数据协议中**没有披露**利率、信用、通胀、PMI 等传统宏观输入;已公开部分更准确地说是一个 **A 股行业横截面离散度与拥挤结构指标**。它以 124 个申万二级行业的相对收益分布生成精确离散度 `D`,使用 3 日均值作为默认平滑序列,再把当前值映射到“低位趋同—正常—潜在高切低—极致化抱团”四个区间。由于构建端源码未公开,不能排除其内部还使用了未披露变量。
|
||||
|
||||
页面公开了状态阈值、平滑方式、十年百分位、行业贡献恒等关系、方向/结构四象限和数据发布协议,但没有公开最核心的 `D` 构造公式。作者在视频 `04:42—05:13` 进一步说明其设计输入是申万一百多个二级行业近 90 天涨跌幅的横截面差异;这确认了指标语义,仍不能确定它使用标准差、分位距、极差、熵还是其他统计量。作者也把“高切低”限定为资金趋势和风险环境观察,不能把页面区间直接解释成仓位或资产切换指令。所谓“择时”目前是风险环境解释层,而不是一套可直接交易的完整状态机。
|
||||
|
||||
本报告把证据分为四类:“已确认”表示页面、公开脚本或响应可直接验证;“作者自述”表示视频中可定位的设计与使用说明;“合理推断”表示有清楚推断链但没有构建端源码证明;“无法确认”表示公开证据不足。视频观点只用于解释设计意图和使用边界,不覆盖页面代码和公开数据已经确认的公式。
|
||||
|
||||
## 产品逻辑
|
||||
|
||||
页面的目标文案是“观察市场趋势与拥挤程度,判断中长期多空方向”,唯一指标页签叫“高切低指标”,并明确注明“参考国投证券同名指标,非原版算法”。公开方法说明是:使用申万二级行业的相对收益分布衡量行情分化程度,再通过平滑形成离散度序列。作者视频 `04:27—04:42` 同样只称“参考”国投证券同名指标,没有声称复刻原版;`04:42—05:13` 则把观察窗口解释为行业近 90 天涨跌幅差异,未说明“90 天”是自然日还是交易日。
|
||||
|
||||
这一产品逻辑可以拆成三层:
|
||||
|
||||
1. 主指标层用离散度判断市场处于趋同还是抱团;
|
||||
2. 对照层把离散度与上证、创业、科创、50、300、1000、2000 七条指数累计表现叠加;
|
||||
3. 贡献层把离散度变化拆给 124 个行业,解释哪些行业正在推动分化或收敛,以及行业相对方向是向上还是向下。
|
||||
|
||||
它没有公开“买入什么、卖出什么、仓位多少”的规则。因此复现时应把输出定义为市场结构状态和行业贡献,不应擅自增加交易信号。
|
||||
|
||||
## 公开数据架构
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[macro/state.json] --> B[current / last_good]
|
||||
B --> C[series.json]
|
||||
C --> D[D=precise / MA3=smooth / 7个指数]
|
||||
B --> E[dispersion manifest]
|
||||
E --> F[latest180 + 年度数据块]
|
||||
F --> G[124行业 C/O/normalized + D/MA3/K/K_MA5]
|
||||
H[sector_rankings/manifest.json] --> I[行业成分排行分片]
|
||||
I --> J[1/3/5/10/90日个股解释]
|
||||
```
|
||||
|
||||
主入口 [`macro/state.json`](https://onechartlab.com/macro/state.json) 使用 `onechart_macro_daily_bundle_v3`,同时提供 `current` 和 `last_good`。2026-08-27 本轮复核时,两者都指向同一份 2026-08-26 快照:发布状态为 `production`,`revision_watermark=21`,批次是 `batch-20260826-r21-c8768898f3`。主序列位于 [`series.json`](https://onechartlab.com/macro/batches/batch-20260826-r21-c8768898f3/series.json),schema 为 `onechart_macro_v1`。这是动态入口,后续复现必须记录实际响应和观测时间,不能假设 `current` 永远存在或永远与 `last_good` 相同。
|
||||
|
||||
主序列含 6365 个日期,从 2000-06-01 到 2026-08-26;前端会裁掉 2002-11-12 以前的数据,默认显示最近 7 年。字段包括 `dates`、`precise`、`smooth` 和七个指数的收盘序列。当前摘要是:
|
||||
|
||||
| 指标 | 2026-08-26 值 |
|
||||
| --- | ---: |
|
||||
| `precise` | 42.1781 |
|
||||
| `smooth` | 42.5510 |
|
||||
| 1 日变化 | -1.7363 |
|
||||
| 5 日变化 | -15.5529 |
|
||||
| 精确值十年百分位 | 38.4% |
|
||||
| 平滑值十年百分位 | 38.6% |
|
||||
|
||||
贡献模块使用 `dispersion-public-v2`。公开 manifest 是 [`macro/dispersion/builds/dispersion-20260826-6186c256680b/manifest.json`](https://onechartlab.com/macro/dispersion/builds/dispersion-20260826-6186c256680b/manifest.json),包含 2017-01-25 至 2026-08-26 共 2326 个交易日、124 个申万二级行业和 7 个指数。前端先加载 `latest180.json`,拖动到更早日期时再按年份懒加载数据块。
|
||||
|
||||
## 主指标的可确认公式
|
||||
|
||||
### 1. 精确值与平滑值
|
||||
|
||||
贡献数据把主指标写成 `D`,把平滑值写成 `MA3`。公开 180 日数据逐日验证:
|
||||
|
||||
```text
|
||||
precise_t = D_t
|
||||
smooth_t = MA3_t
|
||||
= mean(D_t, D_{t-1}, D_{t-2})
|
||||
```
|
||||
|
||||
180 日窗口内 `MA3` 与 3 日简单移动平均的最大误差约为 `6.67e-11`,可以视为同一公式。前端默认 `mode="smooth"`,用户可以切换到 `precise`。
|
||||
|
||||
### 2. 十年百分位
|
||||
|
||||
对当前模式的最后一个有效值,前端取当前日期向前十年的所有有限样本,并计算:
|
||||
|
||||
```text
|
||||
percentile_10y = 100 × count(sample <= current) / len(sample)
|
||||
```
|
||||
|
||||
样本包含当前观测,因此百分位不是严格的历史外样本百分位。页面显示的 1 日变化是 `value_t - value_{t-1}`,5 日变化是 `value_t - value_{t-5}`。
|
||||
|
||||
### 3. 区间状态
|
||||
|
||||
`dispersionZone(value)` 是无记忆的阈值映射,没有滞回、连续多日确认或跨区间冷却:
|
||||
|
||||
| 条件 | 页面状态 | 技术含义 |
|
||||
| --- | --- | --- |
|
||||
| `value < 30` | 低位趋同 | 行业相对收益分化较低 |
|
||||
| `30 <= value < 70` | 正常区间范围内 | 常态分化 |
|
||||
| `70 <= value < 120` | 中高位 · 潜在高切低动力 | 结构抱团较强,存在切换风险 |
|
||||
| `value >= 120` | 极致化抱团 · 谨慎 | 极端分化环境 |
|
||||
|
||||
状态使用当前选择的 `smooth` 或 `precise` 序列。默认平滑值降低了日噪声,但这只是 3 日均值,不是另一个有持续性约束的状态机。
|
||||
|
||||
视频 `05:23—05:39` 对区间的口头解释与页面文案一致:30—70 为正常,70—120 为结构性抱团,120 以上是极致化抱团、拥挤或过热。边界实现仍以代码为准:页面在 `value >= 120` 时进入极致区间,而视频口头说的是“超过 120”,不能用口述改变恰好等于 120 的实现行为。
|
||||
|
||||
## 指数对照不是择时信号
|
||||
|
||||
七个对照指数是 `000001.SH`、`399006.SZ`、`000688.SH`、`000016.SH`、`000300.SH`、`000852.SH`、`932000.CSI`。图中曲线以当前可视时间范围起点为基准,绘制:
|
||||
|
||||
```text
|
||||
chart_value_t = 100 × log(close_t / close_base)
|
||||
```
|
||||
|
||||
tooltip 则显示普通区间收益 `100 × (close_t / close_base - 1)`。这两者是可视化变换,不参与离散度和阈值计算。默认只选择上证指数;选择、缩放或隐藏指数不会改变主指标状态。
|
||||
|
||||
## 行业贡献的可确认公式
|
||||
|
||||
贡献数据每个交易日包含:
|
||||
|
||||
- 主指标 `D`、`MA3`、`K`、`K_MA5`;
|
||||
- 每个行业的 `normalized`、`return90`、`C`、`O`;
|
||||
- 七个指数的 `normalized`。
|
||||
|
||||
公开 180 日、22320 个行业观测可以验证以下恒等关系:
|
||||
|
||||
```text
|
||||
D_t - D_{t-1} = Σ_i C_{i,t}
|
||||
K_t = Σ_i O_{i,t}
|
||||
K_MA5_t = mean(K_t ... K_{t-4})
|
||||
abs(O_{i,t}) = abs(C_{i,t})
|
||||
```
|
||||
|
||||
其中第一条的最大误差约为 `1.1e-9`,后两条移动平均/求和关系误差约为 `1e-10`。因此:
|
||||
|
||||
- `C` 是每个行业对离散度日变化的结构贡献,正数扩大分化,负数缩小分化;
|
||||
- `O` 保留 `C` 的绝对贡献大小,但把符号重新定向为行业相对向上或向下迁移;
|
||||
- `K` 是所有定向贡献的合计,`K_MA5` 是其 5 日均值。
|
||||
|
||||
公开数据没有说明 `O` 的定向符号如何从行业相对收益生成。`return90`、`normalized` 与方向之间也不存在可以从字段名直接确定的单一规则,所以只能复现消费逻辑,不能复现 `O` 的上游构造。
|
||||
|
||||
### 复算说明
|
||||
|
||||
上述关系使用 manifest 指向的完整 `latest180.json` 复算。响应 SHA-256 是 `b0f2821c9f72f9d7b583f748b0759b5c0a1cc72f92edc66162418d2bc9b3add3`,与 manifest 一致。以下最小脚本从标准输入检查四个恒等关系:
|
||||
|
||||
```python
|
||||
import json
|
||||
import sys
|
||||
from statistics import fmean
|
||||
|
||||
rows = json.load(sys.stdin)["rows"]
|
||||
|
||||
ma3_error = max(
|
||||
abs(rows[t]["MA3"] - fmean(row["D"] for row in rows[t - 2 : t + 1]))
|
||||
for t in range(2, len(rows))
|
||||
)
|
||||
delta_error = max(
|
||||
abs(
|
||||
(rows[t]["D"] - rows[t - 1]["D"])
|
||||
- sum(item["C"] for item in rows[t]["industries"])
|
||||
)
|
||||
for t in range(1, len(rows))
|
||||
)
|
||||
k_error = max(
|
||||
abs(row["K"] - sum(item["O"] for item in row["industries"]))
|
||||
for row in rows
|
||||
)
|
||||
k_ma5_error = max(
|
||||
abs(rows[t]["K_MA5"] - fmean(row["K"] for row in rows[t - 4 : t + 1]))
|
||||
for t in range(4, len(rows))
|
||||
)
|
||||
|
||||
print(ma3_error, delta_error, k_error, k_ma5_error)
|
||||
```
|
||||
|
||||
## 当前 V31 贡献视图
|
||||
|
||||
页面允许选择 1、3、5、10、90 个交易日,或在固定 91 点窗口内自定义框选区间。对行业 `i` 和窗口 `(a,b]`,当前脚本使用:
|
||||
|
||||
```text
|
||||
direction_i = Σ O_i,t
|
||||
structure_i = Σ C_i,t
|
||||
relative_return_i = normalized_i,b / normalized_i,a - 1
|
||||
```
|
||||
|
||||
贡献榜按 `direction_i` 排序,正向和负向各取 10 个行业。行业状态是方向与结构的四象限:
|
||||
|
||||
| `direction` | `structure` | 状态 |
|
||||
| ---: | ---: | --- |
|
||||
| `>= 0` | `>= 0` | 进攻 |
|
||||
| `< 0` | `>= 0` | 走弱 |
|
||||
| `< 0` | `< 0` | 回落 |
|
||||
| `>= 0` | `< 0` | 修复 |
|
||||
|
||||
主曲线累计 `O`,虚线是累计曲线的 5 日均值;每日柱子的方向由 `O` 决定,颜色由 `C` 决定。因此“向上/向下迁移”和“扩大/缩小分化”是两个不同维度,不能只看柱子正负或颜色之一。
|
||||
|
||||
详情层可以读取 1/3/5/10/90 日窗口对应的行业成分股排行。输入契约来自 Tushare:行业成员 `index_member_all`、涨跌幅 `daily.pct_chg`、主力净额 `moneyflow_dc.net_amount`、主买净额 `moneyflow.net_mf_amount`,并使用停牌和上市生命周期数据筛选有效样本。
|
||||
|
||||
## 核心离散度 `D` 为什么仍不能复现
|
||||
|
||||
页面公开“申万二级行业的相对收益分布”和平滑说明,视频又确认作者意图是衡量一百多个二级行业近 90 天涨跌幅的差异;公开贡献数据同时含有 `return90`。这些证据仍不能把 `D` 推导成某个标准统计量。`D` 并不等于公开 `normalized` 的横截面标准差:2026-08-26 的 `D=42.1781`,而 124 个 `normalized` 的总体标准差约为 104.8181。公开 payload 也没有给出生成 `D` 所用的原始相对收益向量、相对基准、截尾、标准化和历史校准参数。
|
||||
|
||||
以下候选都无法由现有证据确定:标准差、分位距、分位数间距组合、极差、熵、MAD、横截面分布拟合或多步归一化。因此只能确认 `D` 的**下游代数关系**,不能确认它的**上游统计定义**。
|
||||
|
||||
`state.json` 中的 `accepted_input_hash`、`bundle_id`、`revision_watermark` 和 `last_good`,以及 dispersion manifest 的版本化 `daily_contract`,说明构建链会接受版本化输入并可能修订历史结果。公开页面没有发布修订差分或 point-in-time 输入快照。
|
||||
|
||||
## 推荐的复现设计
|
||||
|
||||
建议把系统分成两个兼容层:外层完全复现已确认的消费逻辑,内层把核心离散度公式作为明确的可替换接口。
|
||||
|
||||
```python
|
||||
def derive_public_state(dates, precise, industry_contrib):
|
||||
smooth = sma(precise, window=3)
|
||||
|
||||
c = industry_contrib.structure_contribution
|
||||
o = industry_contrib.oriented_contribution
|
||||
assert_close(diff(precise), sum_by_day(c))
|
||||
|
||||
k = sum_by_day(o)
|
||||
k_ma5 = sma(k, window=5)
|
||||
|
||||
current = smooth[-1] # 页面默认模式
|
||||
zone = (
|
||||
"low" if current < 30 else
|
||||
"normal" if current < 70 else
|
||||
"elevated" if current < 120 else
|
||||
"extreme"
|
||||
)
|
||||
return smooth, k, k_ma5, zone
|
||||
```
|
||||
|
||||
核心接口可以定义为:
|
||||
|
||||
```python
|
||||
def dispersion_formula(
|
||||
trade_date,
|
||||
point_in_time_sw2_membership,
|
||||
industry_relative_returns,
|
||||
versioned_parameters,
|
||||
) -> tuple[float, list[IndustryContribution]]:
|
||||
"""返回 D_t,以及能够严格加总到 ΔD_t 的 C/O 行业贡献。"""
|
||||
```
|
||||
|
||||
如果目标是先复刻页面而不是复刻专有算法,可以直接消费公开 `series.json` 和 dispersion 分片;如果目标是独立重算,就必须先获得 `D`、`C`、`O` 的构建定义或建立与公开历史序列的校准实验。不能只通过调整标准差倍率宣称等价。
|
||||
|
||||
## 发布、缓存与异常边界
|
||||
|
||||
贡献数据加载器执行以下保护:所有请求使用 `cache: no-store`;manifest 带 hash 时执行 SHA-256 校验;`current` 超过 30 天视为 stale 并尝试 `last_good`;年度块必须满足 schema、日期范围、严格递增、124 行业、7 指数和固定字段集合。贡献模块失败时只显示“离散度贡献暂不可用”,主高切低指标继续工作。
|
||||
|
||||
这些保护说明主指标和解释层是松耦合的。复现时应保持同样边界:贡献数据失败不能把主指标错误清空,使用 `last_good` 时必须显式标注,而不是伪装为最新数据。
|
||||
|
||||
## 回测和使用风险
|
||||
|
||||
公开数据只有 `as_of_date`,没有 release timestamp、输入实际到达时间或“次日可用”契约。指标明显依赖当日行业收盘及资金数据,因此历史验证应保守地把 `T` 日结果视为 `T+1` 可用。用 `T` 日指标指导 `T` 日盘中或收盘前交易存在潜在前视偏差。
|
||||
|
||||
申万二级行业当前 universe 是 124 个,但公开协议没有提供完整的历史成分版本。若用当前行业成员回填历史,会引入成员变更和幸存者偏差。主序列也可能随输入修订;不保存批次和 hash 就无法重建某次页面发布时的历史曲线。
|
||||
|
||||
阈值只是数值分区,不包含收益保证。`70—120` 的“潜在高切低动力”不能直接推导为卖出高位行业或买入低位行业;贡献四象限也只是结构解释,缺少交易成本、持有期、风控和退出规则。作者在视频 `07:27—07:58` 也明确提醒:低位板块出现小行情不等于它会成为新主线,只能说明资金存在高切低趋势。因此“主线识别”与“资金留存、行情延续”都应保留启发式和概率性限定,不能写成经过验证的预测能力。
|
||||
|
||||
## 复现置信度
|
||||
|
||||
| 能力 | 置信度 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 页面目标、输入行业层级和数据协议 | 高 | HTML、JS、state、manifest 可重复核验 |
|
||||
| `smooth=MA3(D)`、十年百分位和 30/70/120 阈值 | 高 | 代码与公开序列交叉验证 |
|
||||
| `ΔD=ΣC`、`K=ΣO`、`K_MA5=MA5(K)` | 高 | 180 日公开数据逐日验证 |
|
||||
| 贡献窗口、正负各 10、方向/结构四象限 | 高 | 当前 V31 前端代码明确 |
|
||||
| `D` 的核心统计公式 | 低 | 没有构建端源码或足够原始输入 |
|
||||
| `O` 的符号定向规则 | 低 | 只能确认 `abs(O)=abs(C)` |
|
||||
| 仓位、资产切换和交易状态机 | 无 | 页面没有公开这类输出 |
|
||||
| 历史 point-in-time 可复现性 | 低 | 没有发布日期、完整历史成员和修订快照 |
|
||||
|
||||
## 视频与本轮限制
|
||||
|
||||
浏览器交互连接在本轮核验时被目标站点关闭,因此没有把截图作为证据;页面 DOM、公开脚本、state、manifest 和 JSON 响应均通过只读 HTTP 重复核对。图表拖拽和响应式视觉行为没有做完整端到端测试,但公式、阈值和数据契约不依赖截图判断。
|
||||
|
||||
作者视频现已完成 `04:13—08:00` 的音轨转写和画面抽帧核对。视频没有公开字幕,自动转写可能存在同音字误差,因此本报告只引用语义清楚且能与画面模块位置对齐的片段。视频补强了指标输入、阈值解释和三类使用场景:宏观风险识别、普涨/结构行情判断,以及高离散度回落时的高切低趋势观察;它没有披露 `D/C/O` 的精确公式、滞回或连续确认、仓位与买卖规则。
|
||||
|
||||
本报告只用于技术与产品逻辑研究,不构成投资建议,也不代表能够复制原作者未公开的专有算法。
|
||||
|
||||
## 主要证据
|
||||
|
||||
- [宏观择时首页](https://onechartlab.com/macro/):产品目标、非原版声明、方法摘要、阈值文案和贡献模块说明。
|
||||
- [作者视频《我把自己的交易系统,做成了4个网页工具》](https://www.bilibili.com/video/BV16Hur6rEq2/):`04:13—07:58` 的指标来源、近 90 天行业涨跌幅语义、阈值解释和使用边界。
|
||||
- [`assets/app.js`](https://onechartlab.com/macro/assets/app.js?v=a4a0a7155f44):默认模式、MA 序列消费、十年百分位、阈值、指数归一化和 state 加载。
|
||||
- [`macro/state.json`](https://onechartlab.com/macro/state.json):当前/最近有效构建、日期、批次、hash、水位和摘要。
|
||||
- [当前 `series.json`](https://onechartlab.com/macro/batches/batch-20260826-r21-c8768898f3/series.json):`precise`、`smooth`、日期和七个指数序列。
|
||||
- [`dispersion-store.js`](https://onechartlab.com/macro/assets/dispersion-store.js):schema、hash、current/last_good、30 日过期、91 点窗口和数据块校验。
|
||||
- [dispersion manifest](https://onechartlab.com/macro/dispersion/builds/dispersion-20260826-6186c256680b/manifest.json):124 行业、7 指数、2326 个日期、构建身份和数据块。
|
||||
- [当前 `latest180.json`](https://onechartlab.com/macro/dispersion/builds/dispersion-20260826-6186c256680b/latest180.json):`D/MA3/K/K_MA5` 与行业 `C/O/normalized/return90`。
|
||||
- [`dispersion-contribution.js`](https://onechartlab.com/macro/assets/dispersion-contribution.js?v=05aeb6c74aaf):贡献窗口、O/C 消费、四象限、图形与成分详情逻辑。
|
||||
- [成分排行 manifest](https://onechartlab.com/sector_rankings/manifest.json):Tushare 输入字段、聚合单位、124 行业 universe 和窗口契约。
|
||||
@@ -0,0 +1,186 @@
|
||||
# OneChartLab「板块资金雷达」技术调研报告
|
||||
|
||||
> 调研日期:2026-08-27;视频补充:2026-08-28;页面:<https://onechartlab.com/>;当前公开数据日期:2026-08-26。
|
||||
> 目标:还原能够由公开证据支持的产品、数据和计算逻辑,为后续复现提供技术边界。
|
||||
|
||||
## 结论摘要
|
||||
|
||||
OneChartLab 的“板块资金雷达”本质上不是实时雷达,而是一个**交易日收盘后的板块横截面排名系统**。它每天把东财概念板块和行业板块分开排序,从单日主力净流入金额、单日资金流入率、3—10 个交易日的多周期波段流入三个角度展示资金强弱,并用前后 10% 镜像榜、近 30 日排名轨迹和成分股强弱解释结果。
|
||||
|
||||
公开页面已经足以精确复现展示层、数据协议、三套排名键、排名百分位、前后榜筛选和排名变化算法。作者在视频 `01:36—01:58` 将单日流入率解释为“主力流入相对当天成交额的比例”,并提示小样本、低活跃度和低成交量会造成比例失真;这补足了指标的概念口径,但没有证明页面使用的精确字段、聚合顺序和异常值处理。仍无法精确复现的是 `Amount_Score`、`Ratio_Score`、`Swing_Score` 的构造方式,以及 3—10 日加权的窗口权重。后续实现应把这些部分设计成可替换的计算策略,不应根据字段名或口头说明虚构生产公式。
|
||||
|
||||
本报告把证据分为四类:“已确认”表示页面、公开脚本或响应可直接验证;“作者自述”表示视频中可定位的设计与使用说明;“合理推断”表示有清楚推断链但没有源码证明;“无法确认”表示公开证据不足。视频观点只用于解释产品意图,不覆盖页面代码和公开数据已经确认的事实。
|
||||
|
||||
## 产品逻辑
|
||||
|
||||
页面解决的问题是:在数百个板块中,快速识别资金正在集中进入、集中撤离或排名快速变化的方向,并下钻到板块内个股检查涨跌幅、主力净额和主买净额。它把“方向”与“持续性”分开呈现:当前排名回答今天谁强,近 30 日在榜次数和排名轨迹回答这种强弱是否持续,排名变化则回答强弱是否正在加速切换。
|
||||
|
||||
页面先选择概念或行业板块,再选择四个视角之一:
|
||||
|
||||
| 视角 | 默认排名依据 | 页面含义 | 证据状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| 波段流入率 `Swing` | `Swing_Score` 降序 | 作者所述的 3—10 日加权单日流入率 | 已确认排名键;窗口权重、聚合与 score 公式无法确认 |
|
||||
| 单日流入率 `Ratio` | `Ratio_Score` 降序 | 作者称为主力流入相对当日成交额的比例 | 已确认排名键;精确字段、异常值处理与 score 公式无法确认 |
|
||||
| 单日净额 `Amount` | `Amount_Raw_BN` 降序 | 当日主力净流入亿元值 | 已确认 |
|
||||
| 排名变化 `RankChange` | 指定指标的 `Rank_Chg` | 近 1—5 个交易日排名升降 | 已确认 |
|
||||
|
||||
概念板块与行业板块是两个独立排名池。2026-08-26 的公开日期分片共有 791 条记录,其中概念板块 414 个、行业板块 377 个。搜索、榜单和详情都在当前类型的数据子集内工作。
|
||||
|
||||
## 公开数据架构
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[radar_manifest.json] --> B[当日日期分片]
|
||||
B --> C[前端按类型筛选、排序和展示]
|
||||
A --> D[rank_history 分片]
|
||||
D --> E[近30日排名轨迹与4/5日排名变化]
|
||||
F[sector_rankings/manifest.json] --> G[当日板块成分排行分片]
|
||||
G --> H[涨跌幅 / 主力净额 / 主买净额详情]
|
||||
A -.协议失败.-> I[radar_data_latest.json 旧版整包回退]
|
||||
```
|
||||
|
||||
首页首先以 `cache: no-store` 请求 [`radar_manifest.json`](https://onechartlab.com/radar_manifest.json),要求 `schema_version === 1`,再通过 `files.dates[LATEST_DATE]` 加载当日分片。当前 manifest 提供 2026-07-16 至 2026-08-26 共 30 个交易日,最新文件是 [`radar_data/dates/2026-08-26.f49c721846fb.json`](https://onechartlab.com/radar_data/dates/2026-08-26.f49c721846fb.json)。
|
||||
|
||||
排名历史通过 [`radar_data/rank_history.3674d0a1cecf.json`](https://onechartlab.com/radar_data/rank_history.3674d0a1cecf.json) 懒加载。成分股详情先读取 [`sector_rankings/manifest.json`](https://onechartlab.com/sector_rankings/manifest.json),再定位到当日 radar 分片;2026-08-26 的公开文件是 [`sector_rankings/radar/dates/20260826.bacc5d9e1581.json`](https://onechartlab.com/sector_rankings/radar/dates/20260826.bacc5d9e1581.json)。
|
||||
|
||||
如果 manifest、日期分片或 schema 校验失败,前端回退到约 20 MB 的 [`radar_data_latest.json`](https://onechartlab.com/radar_data_latest.json)。该旧整包同时包含日期数据、排名历史和成分映射;再次失败时才显示“数据加载失败”和“重新加载”。这说明当前站点是**静态构建发布 + 浏览器只读消费**,不是浏览器实时请求计算接口。
|
||||
|
||||
## 日期分片字段
|
||||
|
||||
每条记录的身份字段是 `trade_date`、`type`、`index_name` 和 `ts_code`,并携带 `lead_stock`、`pct_change`、`pct_change_stock`。三套排名指标使用同构字段:
|
||||
|
||||
| 字段组 | 作用 |
|
||||
| --- | --- |
|
||||
| `*_Raw_*` / `*_Val` | 可解释的原始金额、比例或波段值 |
|
||||
| `*_Score` | 用于 `Swing`、`Ratio` 排名的服务端预计算分数 |
|
||||
| `*_RankPos` | 当前类型排名池内的 1 基排名 |
|
||||
| `*_RankPct` | 由排名位置换算的百分位,越大越强 |
|
||||
| `*_Rank_Chg_1d/2d/3d` | 过去排名减当前排名,正数表示排名上升 |
|
||||
| `*_Top30d` / `*_Bot30d` | 近 30 日进入强榜或弱榜的累计次数 |
|
||||
|
||||
金额以 `Amount_Raw_BN` 表示亿元,单日比率 `Ratio_Raw_Pct` 和波段比率 `Swing_Ratio_Val` 在页面显示时乘 100。页面保留完整浮点值,展示时金额取 1—2 位小数、比率取 2 位小数、score 取 1 位小数。
|
||||
|
||||
## 可精确复现的排名算法
|
||||
|
||||
### 1. 排名池与排名键
|
||||
|
||||
对同一交易日,先按 `type` 分为概念和行业两个池。公开的 791 条记录逐条校验结果是:
|
||||
|
||||
- `Swing_RankPos` 与 `Swing_Score` 降序完全一致;
|
||||
- `Ratio_RankPos` 与 `Ratio_Score` 降序完全一致;
|
||||
- `Amount_RankPos` 与 `Amount_Raw_BN` 降序完全一致。
|
||||
|
||||
两个类型、三个指标的排名位置均为零不匹配。`Amount_Score` 存在于 payload 中,但不决定 `Amount_RankPos`,也不是单日净额榜的默认排序键。
|
||||
|
||||
### 2. 排名百分位
|
||||
|
||||
对排名池大小 `N`、1 基排名 `rank`,公开数据严格满足:
|
||||
|
||||
```text
|
||||
RankPct = 100 × (N - rank + 1) / N
|
||||
```
|
||||
|
||||
在 791 条记录、三个指标上的最大浮点误差约为 `1.42e-14`。因此第一名恒为 100,最后一名仍为 `100 / N`,而不是 0。
|
||||
|
||||
### 3. 前后 10% 榜单
|
||||
|
||||
普通指标不重新截取固定条数,而是直接使用百分位阈值:
|
||||
|
||||
```text
|
||||
TOP: RankPct >= 90
|
||||
BOTTOM: RankPct <= 10
|
||||
```
|
||||
|
||||
随后 TOP 按默认排名键降序,BOTTOM 按默认排名键升序。由于百分位包含当前样本,实际条数会按池大小取整,不保证恰好是 `N × 10%`。
|
||||
|
||||
### 4. 排名变化
|
||||
|
||||
排名变化的基准可选 `Swing`、`Ratio` 或 `Amount`,窗口可选 1—5 个交易日。1—3 日直接读取服务端字段;4—5 日由浏览器使用排名历史计算:
|
||||
|
||||
```text
|
||||
RankChange = PastRank - CurrentRank
|
||||
```
|
||||
|
||||
所以正值表示排名上升,负值表示排名下降。若所选过去日期早于 30 日公开历史,前端钳制到最早可用日期;缺失任一排名时变化记为 0。排名变化榜不使用 `RankPct` 阈值,而是排序后各取 `ceil(N × 0.1)` 且至少 1 条。
|
||||
|
||||
## 原始数据和 score 的已知边界
|
||||
|
||||
页面页脚明确写明数据源为“Tushare + 东财板块日线资金流数据”,交易日 17:00—17:30 自动同步;视频简介写的是约 17:10—17:40,并注明受 Tushare 同步节奏限制。两者存在十分钟口径差,应视为预计发布窗口而非严格 SLA。成分排行 manifest 进一步公开了输入契约:板块成员来自 `tushare.dc_member`,主力净额来自 `tushare.moneyflow_dc.net_amount`,主买净额来自 `tushare.moneyflow.net_mf_amount`,涨跌幅来自 `tushare.daily.pct_chg`;金额从万元聚合后转换为亿元。
|
||||
|
||||
据此可以高置信度推断,`Amount_Raw_BN` 是板块有效成分股 `moneyflow_dc.net_amount` 的日内求和并转换为亿元。但主雷达日期分片没有逐股计算明细,所以该关系仍应通过同日抽样重算验证后再写成生产公式。
|
||||
|
||||
作者视频为原始字段提供了概念解释,但没有公开构建端实现。`01:36—01:58` 将单日流入率的分母描述为当天成交额,同时提示成分股过少、交易不活跃或成交量过低会导致高比例失真;`01:58—02:23` 将波段流入率描述为 3—10 日加权的单日流入率并在三百多个行业/概念中排名。两段都属于作者自述,而不是可由响应重算的生产公式。
|
||||
|
||||
以下内容仍没有公开证据支持精确公式:
|
||||
|
||||
- `Ratio_Raw_Pct` 使用哪一套主力资金与成交额字段、先逐股求比还是先板块聚合、分母为零和低流动性如何处理;
|
||||
- `Ratio_Score` 如何联合或标准化流入比例、净额、板块规模和流动性等变量;
|
||||
- `Swing_Ratio_Val` 与 `Swing_Amount_Val` 如何在 3—10 个交易日间加权;
|
||||
- `Swing_Score` 的组合、截尾、标准化和缺失值规则;
|
||||
- 并列值的服务端排序稳定键。
|
||||
|
||||
横截面线性拟合不能精确解释 score,且同一 raw 值附近的 score 会受到其他变量影响。因此不应把 score 简化成 raw 值的线性缩放或排名百分位。
|
||||
|
||||
## 成分股解释层
|
||||
|
||||
成分排行 manifest 的 schema 是 `onechart_sector_stock_rankings_v2`,radar 当前 universe 是 `eastmoney-dc-v1`,板块数与主分片同为 791。每个板块按窗口 `1` 提供三个指标:`pct_change`、`main_net_amount`、`active_buy_net_amount`,并包含 `top`、`bottom`、`sample_size`、`status` 和 `value`。
|
||||
|
||||
其契约明确区分“主力净额”和“主买净额”:后者是个股 L2 主动买卖净额 `moneyflow.net_mf_amount`,不能用大小单相减自行构造。样本不足时返回 `available_limited_sample`,页面改为展示全部有效标的而不宣称“前 5 / 后 5”。这是复现时必须保留的数据质量语义。
|
||||
|
||||
## 推荐的复现设计
|
||||
|
||||
建议把复现拆成“数据事实、指标策略、横截面排名、静态发布、展示”五层。只有横截面排名和展示层能够按当前证据一比一实现;指标策略层必须可配置并保留版本号。
|
||||
|
||||
```python
|
||||
def publish_radar(trade_date, sector_type, rows):
|
||||
# raw_amount、ratio_score、swing_score 由可替换且版本化的指标策略产生。
|
||||
ranking_keys = {
|
||||
"Amount": "Amount_Raw_BN",
|
||||
"Ratio": "Ratio_Score",
|
||||
"Swing": "Swing_Score",
|
||||
}
|
||||
|
||||
for metric, key in ranking_keys.items():
|
||||
ranked = stable_sort(rows, key=key, descending=True)
|
||||
n = len(ranked)
|
||||
for rank, row in enumerate(ranked, start=1):
|
||||
row[f"{metric}_RankPos"] = rank
|
||||
row[f"{metric}_RankPct"] = 100 * (n - rank + 1) / n
|
||||
row[f"{metric}_Rank_Chg"] = historical_rank(row, metric) - rank
|
||||
|
||||
return rows
|
||||
```
|
||||
|
||||
为了避免历史不可复现,生产版本还应保存 `trade_date` 当日有效板块成员、输入源版本、指标参数版本、发布日期时间和原始输入 hash。当前公开站点只提供当日结果及有限历史,没有提供完整 point-in-time 输入快照和修订日志。
|
||||
|
||||
## 复现置信度
|
||||
|
||||
| 能力 | 置信度 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 页面信息架构和交互 | 高 | HTML/Vue 模板直接公开 |
|
||||
| manifest、日期分片、历史与成分详情协议 | 高 | 公开 JSON 和校验代码可重复请求 |
|
||||
| 三个排名键、排名百分位、前后榜和排名变化 | 高 | 前端代码与 791 条公开记录交叉验证 |
|
||||
| 单日净额的上游来源和聚合方向 | 中高 | manifest 契约明确,但主雷达逐股明细未公开 |
|
||||
| 单日流入率概念口径 | 中 | 作者称分母为当日成交额;生产字段、聚合和异常值规则未公开 |
|
||||
| `Ratio_Score` / `Amount_Score` 公式 | 低 | 只有输出,没有构建代码 |
|
||||
| 3—10 日波段权重与 `Swing_Score` | 低 | 只公开周期范围和结果字段 |
|
||||
|
||||
## 风险与局限
|
||||
|
||||
当前公开页面的最新数据恰好是调研前一交易日,但 manifest 没有明确时区和实际发布时间戳。若用于回测,应保守地把交易日 `T` 的资金雷达视为 `T` 收盘后、最早 `T+1` 可用,不能用它解释 `T` 日盘中决策。
|
||||
|
||||
浏览器交互连接在本轮核验时被目标站点关闭,因此没有把截图作为证据;页面 DOM、公开脚本、manifest 和 JSON 响应均通过只读 HTTP 重复核对。视觉细节不影响本报告的算法结论,但鼠标拖动、弹层焦点和响应式行为没有做完整端到端测试。
|
||||
|
||||
作者视频现已完成 `00:00—04:13` 的音轨转写和画面抽帧核对。视频没有公开字幕,自动转写可能存在同音字误差,因此本报告只引用语义清楚且能与画面模块位置对齐的片段。视频确认了单日流入率的概念分母、3—10 日加权的设计语义、低流动性失真风险和成分导出用途,但仍未披露窗口权重、score 设计、精确字段和异常值规则。
|
||||
|
||||
本报告只用于技术与产品逻辑研究,不构成投资建议,也不代表能够复制原作者未公开的专有算法。
|
||||
|
||||
## 主要证据
|
||||
|
||||
- [板块资金雷达首页](https://onechartlab.com/):页面文案、Vue 模板、排序、排名变化、加载与回退代码。
|
||||
- [作者视频《我把自己的交易系统,做成了4个网页工具》](https://www.bilibili.com/video/BV16Hur6rEq2/):`01:17—04:13` 的指标口径、风险提示、成分解释和数据导出说明。
|
||||
- [`radar_manifest.json`](https://onechartlab.com/radar_manifest.json):schema、30 个交易日、日期分片和历史资源定位。
|
||||
- [2026-08-26 日期分片](https://onechartlab.com/radar_data/dates/2026-08-26.f49c721846fb.json):791 条板块记录、raw/score/rank 字段。
|
||||
- [排名历史](https://onechartlab.com/radar_data/rank_history.3674d0a1cecf.json):近 30 日排名映射。
|
||||
- [成分排行 manifest](https://onechartlab.com/sector_rankings/manifest.json):数据源、单位、聚合、universe 和日期文件契约。
|
||||
- [2026-08-26 radar 成分排行](https://onechartlab.com/sector_rankings/radar/dates/20260826.bacc5d9e1581.json):板块内个股 top/bottom 数据结构。
|
||||
@@ -0,0 +1,376 @@
|
||||
# OneChartLab 复现的 Tushare 数据需求研究
|
||||
|
||||
> 调研日期:2026-08-28。范围:OneChartLab「板块资金雷达」与「宏观择时」的数据采集、落库、历史回填和独立重算边界。本文只讨论技术复现,不构成投资建议。
|
||||
|
||||
## 结论摘要与目标边界
|
||||
|
||||
复现工作必须先区分两个不同目标。
|
||||
|
||||
**目标 A:完全复刻页面消费层。** 最可靠的输入不是重新从 Tushare 推导,而是直接保存 OneChartLab 已公开的 manifest、日期分片、排名历史、宏观 `state.json`、`series.json` 和 dispersion 数据块。页面已经公开 `Ratio_Score`、`Swing_Score`、`D/C/O` 等结果,却没有公开这些结果的完整构建公式。只要保留公开 payload、schema、hash、批次和修订水位,就能精确复刻页面已经确认的排序、百分位、阈值、MA 和贡献消费逻辑。[页面/manifest 已确认:[`radar_manifest.json`](https://onechartlab.com/radar_manifest.json)、[`sector_rankings/manifest.json`](https://onechartlab.com/sector_rankings/manifest.json)、[`macro/state.json`](https://onechartlab.com/macro/state.json)]
|
||||
|
||||
**目标 B:独立重算未公开指标。** Tushare 能提供板块成员、个股资金流、日行情、申万分类、申万成员和指数行情等底层事实,但不能直接提供或确认 OneChartLab 的 `Ratio_Score`、3—10 日权重、`Swing_Score`、核心离散度 `D`、行业贡献 `C/O`、修订水位生成规则或原站私有版本参数。因此可以独立构造“同语义替代指标”,也可以复算公开的下游恒等式,但在获得构建公式和 point-in-time 输入快照前,不能宣称独立结果与原站等价。[页面/manifest 已确认;需实测/缺公式]
|
||||
|
||||
当前最小可执行策略是“双轨落库”:一轨原样保存 OneChartLab 公开发布物以保证消费层可复现,另一轨按本文接口清单保存 Tushare 原始事实,以便做抽样对账、替代公式实验和未来独立重算。两轨通过 `trade_date`、稳定代码、`source_version`、`observed_at`、响应 hash 和计算参数版本关联,不用网页展示名称作为主键。
|
||||
|
||||
## 证据标记
|
||||
|
||||
本文使用四种状态:`页面/manifest 已确认` 表示 OneChartLab 第一方公开文件明确给出;`Tushare 官方文档已确认` 表示接口名、字段、单位或限制来自 Tushare 官方接口页;`复现建议` 表示本文为采集和落库提出的工程方案;`需实测` 表示官方页没有稳定说明、实际账号权限/频次/历史覆盖或边界语义需要用已授权账号验证。官方页面上的积分和限量是 2026-08-28 的页面快照,可能调整;上线前仍应以目标账号调用结果和权限中心为准。
|
||||
|
||||
## 第一方公开契约
|
||||
|
||||
OneChartLab 的 [`sector_rankings/manifest.json`](https://onechartlab.com/sector_rankings/manifest.json) 当前明确声明以下来源和单位:
|
||||
|
||||
| 页面事实 | Radar | Macro | 证据状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| 板块/行业成员 | `tushare.dc_member` | `tushare.index_member_all` | 页面/manifest 已确认 |
|
||||
| 主力净额 | `tushare.moneyflow_dc.net_amount` | 同左 | 页面/manifest 已确认;输入单位万元,聚合求和后输出亿元 |
|
||||
| 主买净额 | `tushare.moneyflow.net_mf_amount` | 同左 | 页面/manifest 已确认;输入单位万元,禁止由大小单金额自行相减 |
|
||||
| 个股涨跌幅 | `tushare.daily.pct_chg` | 同左 | 页面/manifest 已确认;多日窗口使用 `compound_return` |
|
||||
| 上市生命周期 | `tushare.stock_basic` | 同左 | 页面/manifest 已确认;有效区间为 `list_date <= trade_date <= delist_date_or_open` |
|
||||
| 日停复牌 | `tushare.suspend_d` | 同左 | 页面/manifest 已确认 |
|
||||
| 停牌区间 | `tushare.suspend` | 同左 | 页面/manifest 已确认其字符串;当前官方接口目录未找到对应公开页,需实测,不能替代 `suspend_d` 的官方事实 |
|
||||
| 股票池 | 沪深上市 A 股,排除北交所与沪深 B 股 | 同左 | 页面/manifest 已确认 |
|
||||
|
||||
该 manifest 的 `public_payload` 是 `derived_top_bottom_only`,说明公开成分文件只给派生后的前后榜,不是完整逐股输入明细。2026-08-28 观测到的当前批次日期为 2026-08-27,Radar 是 `eastmoney-dc-v1`、707 个板块、窗口 `[1]`,Macro 是 `sw2021_l2_current124_*`、124 个申万二级行业、窗口 `[1,3,5,10,90]`。既有 2026-08-26 Radar 报告记录的是 791 个板块;数量变化证明 universe 必须随交易日快照保存,不得硬编码。[页面/manifest 已确认]
|
||||
|
||||
宏观 [`state.json`](https://onechartlab.com/macro/state.json) 在同次观测中已从既有报告的 `revision_watermark=21` 更新到 `22`。这说明相同或相邻日期的数据可被重新构建,所有公开输入都应保存 `batch_id`、`bundle_id`、`accepted_input_hash`、`revision_watermark`、响应 hash 和 `observed_at`,不能只覆盖一张“最新值”表。[页面/manifest 已确认;复现建议]
|
||||
|
||||
## 模块数据血缘与分级
|
||||
|
||||
### 板块资金雷达
|
||||
|
||||
| 分级 | 数据 | 用途与边界 |
|
||||
| --- | --- | --- |
|
||||
| 必需 | `dc_index`、`dc_member`、`moneyflow_dc`、`daily`、`trade_cal`、`stock_basic`、`suspend_d` | 建立每日东财概念/行业板块 universe、point-in-time 成员、主力净额、涨跌幅、交易日和有效样本。`moneyflow_dc.net_amount` 是公开成分 manifest 明确的主力净额来源。 |
|
||||
| 必需(完整成分解释层) | `moneyflow` | 提供 `net_mf_amount` 主买净额;这是 L2 主动买卖净额,不能由大中小单简单相减。只复刻主雷达榜单而不实现成分详情时可暂缓。 |
|
||||
| 推荐 | `daily_basic`、`moneyflow_ind_dc`、`namechange` | `daily_basic` 提供换手率、市值等低流动性质量特征;`moneyflow_ind_dc` 是官方“东财概念及行业板块资金流向”接口,可与逐股聚合做交叉对账;`namechange` 保留历史展示名和名称区间。三者均不是公开 manifest 对主指标公式的确认。 |
|
||||
| 可选 | `adj_factor` | 用于股票复权和公司行动质检,不是单日 `daily.pct_chg` 或 `moneyflow_dc` 的必需输入,也不能单独生成前复权价格。 |
|
||||
|
||||
可高置信度实施的链路是 `dc_index/dc_member + stock_basic/suspend_d` 确定当日有效成员,再关联 `moneyflow_dc`、`moneyflow` 和 `daily` 生成完整逐股事实与成分前后榜。`Amount_Raw_BN` 可用 `sum(moneyflow_dc.net_amount) / 10_000` 作为待对账候选,因为万元除以 10,000 得亿元;但主雷达构建端逐股明细未公开,必须逐日逐板块与公开 raw 值抽样核对后才能固化。[页面/manifest 已确认来源与单位;复现建议聚合;需实测等价性]
|
||||
|
||||
`Ratio_Raw_Pct` 的概念分母由作者在[公开视频](https://www.bilibili.com/video/BV16Hur6rEq2/)中解释为当日成交额,但 Tushare 和公开页面没有确认生产公式是板块级 `moneyflow_ind_dc.net_amount_rate`、`sum(net_amount)/sum(daily.amount)`、逐股比例再聚合,还是包含截尾和低流动性过滤。`daily.amount` 可作为成交额候选,`moneyflow_dc.net_amount_rate` 和 `moneyflow_ind_dc.net_amount_rate` 可用于对照实验,不能直接指定为原站公式。[作者自述;Tushare 官方字段已确认;需实测]
|
||||
|
||||
### 宏观择时
|
||||
|
||||
| 分级 | 数据 | 用途与边界 |
|
||||
| --- | --- | --- |
|
||||
| 必需(独立构造主序列) | `index_classify`、`index_member_all`、`sw_daily`、`trade_cal` | 取得申万 2021 分类、二级行业及成员区间、申万行业日线和统一交易日。作者在[公开视频](https://www.bilibili.com/video/BV16Hur6rEq2/)中称核心输入为申万二级行业近 90 日涨跌幅横截面分布,但 `D` 的统计量仍未公开。 |
|
||||
| 必需(七指数对照) | `index_daily` | 提供 `000001.SH`、`399006.SZ`、`000688.SH`、`000016.SH`、`000300.SH`、`000852.SH`、`932000.CSI` 的收盘序列。`index_daily` 官方明确不含申万行业,不能代替 `sw_daily`。 |
|
||||
| 必需(完整成分解释层) | `daily`、`moneyflow_dc`、`moneyflow`、`stock_basic`、`suspend_d` | 复算 1/3/5/10/90 日行业成分股涨跌幅、主力净额和主买净额榜。仅研究 `D` 主序列时可以与主序列采集拆开。 |
|
||||
| 推荐 | `index_basic`、`daily_basic`、`namechange` | 校验七指数代码、发布方和终止日期;提供流动性/规模质量特征和历史名称。 |
|
||||
| 可选 | `adj_factor` | 用股票级复权价格复核多日个股收益;行业主序列优先用 `sw_daily`,页面公开的成分窗口已明确使用 `daily.pct_chg` 复合。 |
|
||||
|
||||
`index_member_all` 的输出含 `in_date`、`out_date` 和 `is_new`,适合保存成员区间;但官方页没有说明剔除日是否仍算有效,也没有证明返回历史覆盖能够重建 OneChartLab 的全部历史 universe。Macro 当前公开 universe 名称含 `current124`,现有页面报告也指出完整历史 point-in-time 成员未公开。因此历史计算不得把当前 124 行业及当前成员回填到过去。[Tushare 官方字段已确认;页面/manifest 已确认当前 universe;需实测边界与完整性]
|
||||
|
||||
## 接口字典:调用与落库
|
||||
|
||||
下表的“必要字段”是本任务最小字段集,不代表应丢弃供应商原始响应。生产中建议同时保存原始 JSON/Parquet、请求参数和响应 hash,以便接口字段调整或历史修订后重放。
|
||||
|
||||
Tushare 多个接口不会默认返回全部字段,尤其是 `daily_basic.limit_status`、`stock_basic.exchange/list_status/delist_date`、`index_classify.src` 和 `index_basic.exp_date`。生产调用必须显式传入本表列出的 `fields`,并把请求参数中的分类版本等维度一并落库;不能假设默认响应足以构造生命周期过滤或自然业务主键。[Tushare 官方文档已确认;复现建议]
|
||||
|
||||
| 接口 | 模块用途/级别 | 主要调用参数 | 必要输出字段 | 粒度与自然业务主键 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| [`dc_index`](https://tushare.pro/document/2?doc_id=362) | Radar 必需:每日东财概念、行业、地域板块身份与类型 | `trade_date`;回填用 `start_date/end_date`;`idx_type` 必填,也可按 `ts_code/name` | `ts_code,trade_date,name,idx_type,level,pct_change,leading_code` | 板块×交易日;`(trade_date,ts_code)` |
|
||||
| [`dc_member`](https://tushare.pro/document/2?doc_id=363) | Radar 必需:每日板块成员 | 优先按 `trade_date`,必要时按 `ts_code` 分片;支持 `con_code,start_date,end_date` | `trade_date,ts_code,con_code,name` | 板块×股票×交易日;`(trade_date,ts_code,con_code)` |
|
||||
| [`moneyflow_dc`](https://tushare.pro/document/2?doc_id=349) | 两模块必需:个股东财口径主力净额 | 日增量按 `trade_date`;回填按股票或日期窗口 | `trade_date,ts_code,name,net_amount,net_amount_rate,pct_change,close`,建议保留四档净流入字段 | 股票×交易日;`(ts_code,trade_date)` |
|
||||
| [`moneyflow`](https://tushare.pro/document/2?doc_id=170) | 完整成分解释层必需:L2 主买净额 | 日增量按 `trade_date`;回填按 `ts_code` 或日期窗口 | `ts_code,trade_date,net_mf_amount,net_mf_vol`,建议保留各档买卖金额/量 | 股票×交易日;`(ts_code,trade_date)` |
|
||||
| [`moneyflow_ind_dc`](https://tushare.pro/document/2?doc_id=344) | Radar 推荐:官方东财板块资金流,供 raw/ratio 对账 | `trade_date` 或日期窗口;`content_type` 区分行业/概念/地域 | `trade_date,content_type,ts_code,name,net_amount,net_amount_rate,pct_change,rank` | 板块类型×板块×交易日;`(trade_date,content_type,ts_code)` |
|
||||
| [`daily`](https://tushare.pro/document/2?doc_id=27) | 两模块必需:个股涨跌幅、成交额与行情可用性 | 日增量按 `trade_date`;官方建议按日期循环全市场,避免逐股回填 | `ts_code,trade_date,close,pre_close,pct_chg,vol,amount` | 股票×交易日;`(ts_code,trade_date)` |
|
||||
| [`daily_basic`](https://tushare.pro/document/2?doc_id=32) | 推荐:换手率、市值、量比和低流动性质量规则 | 日增量按 `trade_date`;单股历史用 `ts_code,start_date,end_date` | `ts_code,trade_date,turnover_rate,turnover_rate_f,volume_ratio,total_mv,circ_mv,limit_status` | 股票×交易日;`(ts_code,trade_date)` |
|
||||
| [`trade_cal`](https://tushare.pro/document/2?doc_id=26) | 两模块必需:交易日序列、窗口和前序日 | `exchange,start_date,end_date`;A 股至少保存 SSE,建议同时校验 SZSE | `exchange,cal_date,is_open,pretrade_date` | 交易所×日历日;`(exchange,cal_date)` |
|
||||
| [`stock_basic`](https://tushare.pro/document/2?doc_id=25) | 两模块必需:上市/退市生命周期和市场过滤 | 必须分别拉 `list_status=L,D,P,G,UN`,不可只用默认 `L`;可按 `exchange/market` | `ts_code,symbol,name,market,exchange,list_status,list_date,delist_date` | 当前证券主记录;`ts_code`,另存带 `observed_at` 的快照版本 |
|
||||
| [`namechange`](https://tushare.pro/document/2?doc_id=100) | 推荐:历史名称、展示标签和 ST 名称审计 | 增量按公告区间 `start_date/end_date`,也可按 `ts_code` 回填 | `ts_code,name,start_date,end_date,ann_date,change_reason` | 股票×名称有效期;建议 `(ts_code,start_date,name)`,将其余字段视为可修订 |
|
||||
| [`suspend_d`](https://tushare.pro/document/2?doc_id=214) | 两模块必需:区分停牌、复牌与数据缺失 | 日增量按 `trade_date`;回填用 `start_date/end_date`;可按 `suspend_type` | `ts_code,trade_date,suspend_timing,suspend_type` | 股票×停复牌事件日;建议 `(ts_code,trade_date,suspend_type,suspend_timing)` |
|
||||
| [`adj_factor`](https://tushare.pro/document/2?doc_id=28) | 可选/推荐质检:复权和公司行动 | 日增量按 `trade_date`;回填可按 `ts_code` 全历史 | `ts_code,trade_date,adj_factor` | 股票×交易日;`(ts_code,trade_date)` |
|
||||
| [`index_classify`](https://tushare.pro/document/2?doc_id=181) | Macro 必需:申万 2014/2021 分类与 L2 universe | `src=SW2021,level=L2`;可按 `index_code,parent_code` | `index_code,industry_name,parent_code,level,industry_code,is_pub,src` | 分类版本×行业;`(src,index_code)` |
|
||||
| [`index_member_all`](https://tushare.pro/document/2?doc_id=335) | Macro 必需:申万 L1/L2/L3 成员区间 | 按 `l2_code` 分片;为历史回填分别核对 `is_new=Y/N`;也可按 `ts_code` | `l1_code,l1_name,l2_code,l2_name,l3_code,l3_name,ts_code,name,in_date,out_date,is_new` | 行业层级路径×股票×纳入区间;建议 `(l1_code,l2_code,l3_code,ts_code,in_date)` |
|
||||
| [`sw_daily`](https://tushare.pro/document/2?doc_id=327) | Macro 必需:申万行业日线 | 日增量按 `trade_date`;回填按 `ts_code,start_date,end_date` | `ts_code,trade_date,name,close,pct_change,vol,amount`,需要时保留 OHLC/估值/市值 | 申万指数×交易日;`(ts_code,trade_date)` |
|
||||
| [`index_basic`](https://tushare.pro/document/2?doc_id=94) | Macro 推荐:七指数代码和生命周期校验 | 按 `ts_code/symbol`,或分市场 `SSE/SZSE/CSI` 拉取 | `ts_code,name,market,publisher,category,list_date,exp_date` | 指数;`ts_code`,另存观察快照 |
|
||||
| [`index_daily`](https://tushare.pro/document/2?doc_id=95) | Macro 必需:七个市场对照指数;不含申万行业 | 必须给 `ts_code`,按 `start_date/end_date` 回填或按日增量 | `ts_code,trade_date,close,pre_close,pct_chg`,建议保留 OHLC/量额 | 指数×交易日;`(ts_code,trade_date)` |
|
||||
|
||||
## 接口字典:拉取策略、时效与权限
|
||||
|
||||
| 接口 | 建议拉取方式、更新时点与历史深度 | 官方限量/权限页面快照 | 证据状态与待测项 |
|
||||
| --- | --- | --- | --- |
|
||||
| `dc_index` | 每个开市日按 `idx_type` 分三类拉取并保存完整日快照;回填按日期循环。官方称支持每日板块数据,未给稳定入库时点。 | 单次 5,000 行;页面写 6,000 积分 | 字段/限量/积分为 Tushare 官方确认;实际到达时点和账号频次需实测 |
|
||||
| `dc_member` | 每个开市日按日期拉完整成员;超过上限时再按板块代码分片。历史成员按日期回填,绝不拿最新成员覆盖历史。 | 单次 5,000 行;页面写 6,000 积分 | 官方确认可按板块代码和日期取历史;最早历史、当日到达时点、频次需实测 |
|
||||
| `moneyflow_dc` | 每日盘后按 `trade_date` 拉全市场;回填先按日期,失败再按股票分段。官方明确历史始于 2023-09-11。 | 单次 6,000 行;页面写至少 5,000 积分 | Tushare 官方确认;盘后具体完成时刻和账号频次需实测。2023-09-11 以前不能由本接口补齐 |
|
||||
| `moneyflow` | 每日按 `trade_date` 拉全市场;长历史按日期或股票分片。官方写数据始于 2010 年。 | 单次 6,000 行、总量不限;页面写至少 2,000 积分且基础积分有流控 | Tushare 官方确认;每日到达时点和账号实际流控需实测 |
|
||||
| `moneyflow_ind_dc` | 每日盘后按日期和 `content_type` 拉取,用于与逐股聚合和公开 Radar raw 做三方对账。 | 单次 5,000 行;页面写 6,000 积分 | Tushare 官方确认接口,但 OneChartLab manifest 未声明其为主雷达构建输入;实际等价性需实测 |
|
||||
| `daily` | 交易日按日期全市场增量;官方建议按日期循环。15:00—16:00 入库,停牌期间不返回。 | 单次 6,000 行;官方页写基础积分每分钟 500 次 | Tushare 官方确认;目标账号仍需做限流和完整性实测 |
|
||||
| `daily_basic` | 交易日按日期拉全市场;15:00—17:00 入库。历史可按日循环。 | 单次 6,000 行;至少 2,000 积分,官方称 5,000 积分无总量限制 | Tushare 官方确认;实际频次需账号实测 |
|
||||
| `trade_cal` | 初始化拉完整日历,之后按年滚动刷新;不应每天全量重拉。历史起点和远期日历发布范围以响应为准。 | 页面写 2,000 积分;未给稳定行数/频次 | 字段/积分为官方确认;覆盖范围与账号频次需实测 |
|
||||
| `stock_basic` | 初始化分别拉所有 `list_status`,每日或每周做小成本快照对比;事件发生后更新生命周期。 | 单次 6,000 行;2,000 积分起、每分钟 50 次 | Tushare 官方确认;接口默认仅 `L`,必须显式补 D/P/G/UN |
|
||||
| `namechange` | 初始化按股票或公告日期回填,之后按最近公告窗口重叠拉取,允许旧记录修订。 | 官方页未给稳定积分、限量或频次 | 字段为 Tushare 官方确认;权限、频次、最早历史与日期边界需实测 |
|
||||
| `suspend_d` | 每个开市日按日期拉,连续重叠回拉最近若干日以接纳“不定期”修订;历史按日期窗口。 | 官方页未给稳定积分、限量或频次 | Tushare 官方确认“不定期更新”;权限、频次、覆盖和同日多事件需实测 |
|
||||
| `adj_factor` | 盘前 09:15—09:20 后按日期增量;回填按股票或日期。 | 2,000 积分起;5,000 以上可高频,未给精确频次 | Tushare 官方确认;实际频次需实测 |
|
||||
| `index_classify` | 初始化按 `SW2014/SW2021 × L1/L2/L3` 保存版本快照;低频刷新并对比代码、名称、父级和 `is_pub`。 | 页面写 2,000 积分,未给稳定行数/频次 | Tushare 官方确认;版本修订时点和账号频次需实测 |
|
||||
| `index_member_all` | 按 L2 行业分片回填 `is_new=Y/N`,原样保存 `in_date/out_date`;每日或每周检查新增/剔除,不覆盖区间历史。 | 单次 2,000 行、总量不限;页面写 2,000 积分 | Tushare 官方确认字段;`is_new=N` 的完整语义、剔除日边界、历史完整性和频次需实测 |
|
||||
| `sw_daily` | 每日按日期拉全部发布行业,回填按行业代码分段;默认是申万 2021 版。 | 单次 4,000 行;页面写 5,000 积分 | Tushare 官方确认;最早历史、到达时点和实际频次需实测 |
|
||||
| `index_basic` | 初始化按市场拉取,低频刷新;官方页写每天 18:00 更新、数据起始 1990-01-01。 | 单次 8,000 行;2,000 积分起 | Tushare 官方确认;账号频次需实测 |
|
||||
| `index_daily` | 七个代码逐个按时间段回填,每日收盘后增量;指数自身上市前为空。 | 页面写 2,000 积分,5,000 以上频次相对较高,未给精确频次 | Tushare 官方确认;到达时点和实际频次需实测 |
|
||||
|
||||
### 接口名与口径更正
|
||||
|
||||
1. `moneyflow_dc` 是“个股资金流向(DC)”,其 `net_amount` 单位为万元;东财概念/行业板块的直接资金流接口是 `moneyflow_ind_dc`,其 `net_amount` 单位为元。两者不可因名称相近混用。[Tushare 官方文档已确认]
|
||||
2. `moneyflow.net_mf_amount` 是基于 L2 主动买卖单统计的净流入,官方明确说不能简单由大小单总和相减;这与 OneChartLab manifest 的“主买净额”定义一致。[页面/manifest 与 Tushare 官方文档均确认]
|
||||
3. `daily` 是未复权行情,`adj_factor` 只是复权因子;若需要 qfq 价格,应使用官方 [`pro_bar`](https://tushare.pro/document/2?doc_id=146) 的 `adj="qfq"` 或基于版本化规则计算,不能把 `adj_factor` 当价格。[Tushare 官方文档已确认]
|
||||
4. `index_daily` 官方明确“不包含申万行业指数行情数据”;申万行业必须用 `sw_daily`。`index_classify(src="SW2021", level="L2")` 提供分类,`index_member_all` 提供带纳入/剔除日期的成员关系。[Tushare 官方文档已确认]
|
||||
5. 当前官方页面确认的东财板块目录接口是 `dc_index`,成员接口是 `dc_member`。不存在用一个静态 `dc_member` 当前表安全回填全部历史的做法;必须按交易日保存成员快照。[Tushare 官方文档已确认;复现建议]
|
||||
6. OneChartLab manifest 出现 `tushare.suspend`,但当前 Tushare 官方接口目录只找到 `suspend_d` 的公开页。实施清单中只把 `suspend_d` 视为已确认接口;`suspend` 作为历史/兼容调用名单独实测,未成功前不得建立生产依赖。[页面/manifest 已确认字符串;需实测]
|
||||
|
||||
## 最小采集集与增强采集集
|
||||
|
||||
### 目标 A:页面消费层最小集
|
||||
|
||||
无需 Tushare token,按发布物原样保存:Radar 的 `radar_manifest.json`、30 日日期分片、`rank_history`、成分排行 manifest 和日期文件;Macro 的 `state.json`、`current/last_good` 指向的 `series.json`、dispersion manifest、`latest180` 与所需年度块。保存 URL、HTTP 观测时间、内容 hash、schema 和所有批次身份。这个集合能复现页面已经公开的结果和消费公式,但不能生成缺失日期或重建私有指标。[页面/manifest 已确认]
|
||||
|
||||
### 目标 B:独立上游最小集
|
||||
|
||||
Radar 主榜最小集为 `trade_cal + dc_index + dc_member + stock_basic + suspend_d + daily + moneyflow_dc`;若要完整复现成分解释,再加入 `moneyflow`。Macro 主序列实验最小集为 `trade_cal + index_classify + index_member_all + sw_daily + index_daily`;若要完整成分解释,再复用 `stock_basic + suspend_d + daily + moneyflow_dc + moneyflow`。该集合只保证输入事实充分,不保证 `Ratio/Swing/D/C/O` 与原站一致。[复现建议;缺公式]
|
||||
|
||||
### 增强采集集
|
||||
|
||||
加入 `daily_basic` 做换手率、量比、市值和低流动性质量控制;加入 `moneyflow_ind_dc` 对账官方板块级净额/净占比;加入 `namechange` 保留历史名称区间;加入 `adj_factor` 做复权和公司行动质检;加入 `index_basic` 校验七指数代码、发布方和终止日期。增强字段参与计算时必须写入参数版本,不能静默改变历史结果。[复现建议]
|
||||
|
||||
## 历史回填、每日增量与幂等
|
||||
|
||||
### 历史回填顺序
|
||||
|
||||
1. 先回填 `trade_cal`、`stock_basic` 全状态、`namechange`、`index_basic`、`index_classify`,建立代码、生命周期、版本和交易日维表。
|
||||
2. 再回填 `dc_member` 每日快照和 `index_member_all` 成员区间;先完成成员事实,避免用当前成员污染历史。
|
||||
3. 回填 `daily`、`daily_basic`、`sw_daily`、`index_daily` 和 `adj_factor`,先形成价格与成交事实。
|
||||
4. 最后回填 `moneyflow_dc`、`moneyflow` 和 `moneyflow_ind_dc`。`moneyflow_dc` 只能从 2023-09-11 开始,早期缺口必须显式标记,不能用 0 填充。
|
||||
5. 在原始层通过覆盖率、重复键、单位和生命周期检查后,再生成成员有效日、窗口收益、资金聚合、替代指标和公开页面对账结果。
|
||||
|
||||
### 每日增量 DAG
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[trade_cal 确认开市日 T] --> B[盘前 stock_basic / adj_factor / 分类变更]
|
||||
B --> C[盘后轮询 daily / daily_basic / index_daily / sw_daily]
|
||||
C --> D[拉 moneyflow_dc / moneyflow / moneyflow_ind_dc]
|
||||
C --> E[拉 dc_index / dc_member / suspend_d]
|
||||
D --> F[完整性与单位校验屏障]
|
||||
E --> F
|
||||
F --> G[生成 T 日 point-in-time 有效成员]
|
||||
G --> H[逐股事实与板块/行业窗口聚合]
|
||||
H --> I[公开发布物对账与版本化指标计算]
|
||||
I --> J[原子发布 manifest + hash + last_good]
|
||||
```
|
||||
|
||||
不能只按固定钟点启动一次。`daily`、`daily_basic`、资金流和成员数据的到达时间不同,应分别轮询到“日期正确、行数/覆盖率达标、关键字段非空”,再通过校验屏障;超时则保留上一个 `last_good` 并标记 stale/partial,不发布假完整结果。OneChartLab 页脚的约 17:00—17:30/视频简介的约 17:10—17:40 只应作为观察窗口,不是 Tushare SLA。[页面与作者自述;复现建议]
|
||||
|
||||
### 幂等与修订
|
||||
|
||||
所有事实表按上文自然业务主键 upsert。先对同一请求参数和规范化响应计算 hash:相同则记 `unchanged`,不同则在原始版本表新增 `observed_at/source_revision`,再更新当前投影。成员、名称和生命周期表不得做破坏性覆盖;派生结果主键至少包含 `(metric_version, universe_version, trade_date, entity_code)`。公开 OneChartLab 发布物还应把 `batch_id/bundle_id/revision_watermark/content_sha256` 放入唯一约束或发布身份,允许同一 `as_of_date` 多修订共存。[复现建议]
|
||||
|
||||
## Point-in-time 与证券状态处理
|
||||
|
||||
`dc_member` 已直接提供交易日粒度,某日成员只来自该日快照。缺少某日快照时应标记 `membership_unknown`,不能向前或向后填充,除非经过单独验证并记录填充策略版本。[Tushare 官方字段已确认;复现建议]
|
||||
|
||||
`index_member_all` 应原样保存 Y/N 两类响应和 `in_date/out_date`。候选有效规则是 `in_date <= T < out_date`,空 `out_date` 表示仍有效;但剔除日是否排除、`is_new=N` 是否返回全部历史、同股多次纳入如何表达,都需账号样本验证。验证前不要把这个候选规则写成供应商保证。[复现建议;需实测]
|
||||
|
||||
`stock_basic` 默认只返回上市状态 `L`,历史回填必须显式拉取 `D/P/G/UN`。证券只有在 `list_date <= T` 且 `delist_date` 为空或 `T <= delist_date` 时才进入生命周期候选;再按 OneChartLab manifest 排除 B 股和北交所。停牌日 `daily` 不返回数据,必须联合 `suspend_d` 判断:无行情既可能是停牌,也可能是未上市、已退市、成员无效或供应商延迟,不能把缺行自动变成收益 0。[Tushare 官方与页面/manifest 已确认;复现建议]
|
||||
|
||||
`namechange` 用代码和有效日期恢复历史展示名,不作为稳定身份。ST/风险警示状态若会影响自建 universe,应单独定义并验证数据源;OneChartLab 当前公开 ranking universe 契约没有声明排除 ST,不应根据本项目其他模块的“非 ST”规则擅自改变复现口径。[页面/manifest 已确认;复现建议]
|
||||
|
||||
## 单位、空值与质量规则
|
||||
|
||||
必须在原始层保留供应商单位,在规范层显式换算:
|
||||
|
||||
| 来源字段 | 原始单位 | 规范换算/注意事项 |
|
||||
| --- | --- | --- |
|
||||
| `moneyflow_dc.net_amount`、`moneyflow.net_mf_amount` | 万元 | 亿元值为 `/ 10_000`;元值为 `× 10_000` |
|
||||
| `moneyflow_ind_dc.net_amount` | 元 | 亿元值为 `/ 100_000_000`;不能沿用个股资金流换算 |
|
||||
| `daily.amount`、`index_daily.amount` | 千元 | 亿元值为 `/ 100_000` |
|
||||
| `sw_daily.amount` | 万元 | 亿元值为 `/ 10_000` |
|
||||
| `daily.vol`、`index_daily.vol` | 手 | 与 `sw_daily.vol` 的万股单位分开保存 |
|
||||
| `sw_daily.vol` | 万股 | 不得与“手”直接相加或比较 |
|
||||
| `daily.pct_chg`、`index_daily.pct_chg`、`sw_daily.pct_change` | 百分数 | `1.5` 表示 1.5%;做复合收益时先除以 100 |
|
||||
| OneChart `Ratio_Raw_Pct/Swing_Ratio_Val` | 公开 payload 的小数比例 | 既有前端展示时乘 100;不要与 Tushare 的百分数字段直接混算 |
|
||||
|
||||
建议执行以下质量门槛,但阈值必须由数据分布和公开样本校准后版本化:
|
||||
|
||||
- 主键重复、代码格式错误、非有限数、日期不在交易日历、生命周期外观测属于硬错误;空字符串、`None`、`NaN` 统一规范为 NULL,不能转成 0。[复现建议]
|
||||
- 对每个交易日分别计算 `daily`、`moneyflow_dc`、`moneyflow`、成员和指数覆盖率;缺失资金流不代表净流入为 0。只有在生命周期有效、非停牌且源接口应有数据时才进入缺失率分母。[复现建议]
|
||||
- 板块有效样本数、总成交额、换手率和成员覆盖率必须随派生结果输出。小样本、低成交额、低换手率或分母接近 0 时标记 `available_limited_sample/low_liquidity`,禁止仅因比例高就视为强信号。具体阈值公开资料未披露,需校准。[作者自述与公开页面质量语义;需实测]
|
||||
- 计算资金占比候选时,先把 `moneyflow_dc.net_amount` 和 `daily.amount` 统一到元,再做 `sum(net_amount)/sum(amount)`;分母为 0 或缺失则返回 NULL。该公式只是对账候选,不是已确认的 `Ratio_Raw_Pct`。[复现建议;需实测]
|
||||
- 同日 `daily.pct_chg` 与 `moneyflow_dc.pct_change`、板块逐股聚合与 `moneyflow_ind_dc` 只用于差异告警,不应无版本地互相覆盖。不同数据源可能有到达时间、复权和成分口径差异。[Tushare 官方字段已确认;复现建议]
|
||||
- `index_classify` 的 `is_pub=0` 行业和成分少于 5 的指数可能不发布行情;构造 Macro universe 时应记录剔除原因,不能用 0 收益补齐。[Tushare 官方文档已确认]
|
||||
|
||||
## 仍无法由 Tushare 直接提供或确认的内容
|
||||
|
||||
Tushare 数据补齐后,下列内容仍是明确缺口:
|
||||
|
||||
- `Amount_Score` 和 `Ratio_Score` 的标准化、截尾、规模/流动性调整及并列排序稳定键;
|
||||
- `Ratio_Raw_Pct` 的精确分子、分母、先聚合后求比或先求比后聚合、异常值处理;
|
||||
- 3—10 个交易日的具体权重、`Swing_Ratio_Val`、`Swing_Amount_Val` 和 `Swing_Score` 的组合公式;
|
||||
- Macro 核心 `D` 使用的横截面统计量、相对收益基准、90 日自然日/交易日口径、截尾和历史校准;
|
||||
- 行业贡献 `C` 的上游分解和 `O` 的定向符号规则。公开数据只能确认 `ΔD=ΣC`、`K=ΣO`、`abs(O)=abs(C)` 等下游恒等式;
|
||||
- 原站如何生成 `accepted_input_hash`、`revision_watermark`、历史修订和 `last_good`,以及未公开的参数版本、输入快照和发布时间戳。
|
||||
|
||||
因此,独立实现必须给自建公式新的名称和 `metric_version`,并同时输出与 OneChartLab 公开序列的误差、覆盖率和样本状态。不能通过拟合一个倍率或选择最接近的 Tushare 字段来宣称“完全复刻”。[页面/公开数据复算已确认缺口;复现建议]
|
||||
|
||||
## Python 调用骨架
|
||||
|
||||
以下骨架只展示调用和幂等批次形状,token 从环境注入,不写入代码、日志或请求清单。Tushare 官方客户端的 [`DataApi.query`](https://github.com/waditu/tushare/blob/master/tushare/pro/client.py) 会把动态方法名映射为 `api_name`,因此 `pro.dc_member(...)` 与 `pro.query("dc_member", ...)` 属于同一调用模型。[Tushare 官方 GitHub 源码已确认]
|
||||
|
||||
```python
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from collections.abc import Callable
|
||||
|
||||
import pandas as pd
|
||||
import tushare as ts
|
||||
|
||||
|
||||
FIELDS = {
|
||||
"daily": "ts_code,trade_date,close,pre_close,pct_chg,vol,amount",
|
||||
"daily_basic": (
|
||||
"ts_code,trade_date,turnover_rate,turnover_rate_f,volume_ratio,"
|
||||
"total_mv,circ_mv,limit_status"
|
||||
),
|
||||
"moneyflow_dc": (
|
||||
"trade_date,ts_code,name,net_amount,net_amount_rate,pct_change,close"
|
||||
),
|
||||
"moneyflow": "ts_code,trade_date,net_mf_amount,net_mf_vol",
|
||||
"suspend_d": "ts_code,trade_date,suspend_timing,suspend_type",
|
||||
"dc_index": "ts_code,trade_date,name,idx_type,level,pct_change,leading_code",
|
||||
"dc_member": "trade_date,ts_code,con_code,name",
|
||||
"sw_daily": "ts_code,trade_date,name,close,pct_change,vol,amount",
|
||||
"stock_basic": (
|
||||
"ts_code,symbol,name,market,exchange,list_status,list_date,delist_date"
|
||||
),
|
||||
"index_classify": (
|
||||
"index_code,industry_name,parent_code,level,industry_code,is_pub,src"
|
||||
),
|
||||
"index_member_all": (
|
||||
"l1_code,l1_name,l2_code,l2_name,l3_code,l3_name,ts_code,name,"
|
||||
"in_date,out_date,is_new"
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def build_client():
|
||||
"""从运行环境创建 Tushare Pro 客户端,不泄露或持久化 token。"""
|
||||
return ts.pro_api(os.environ["TUSHARE_TOKEN"])
|
||||
|
||||
|
||||
def fetch_trade_date(pro, trade_date: str) -> dict[str, pd.DataFrame]:
|
||||
"""拉取一个交易日的原始事实;重试、限流和落库由外层批次协调器负责。"""
|
||||
return {
|
||||
"daily": pro.daily(trade_date=trade_date, fields=FIELDS["daily"]),
|
||||
"daily_basic": pro.daily_basic(
|
||||
trade_date=trade_date, fields=FIELDS["daily_basic"]
|
||||
),
|
||||
"moneyflow_dc": pro.moneyflow_dc(
|
||||
trade_date=trade_date, fields=FIELDS["moneyflow_dc"]
|
||||
),
|
||||
"moneyflow": pro.moneyflow(
|
||||
trade_date=trade_date, fields=FIELDS["moneyflow"]
|
||||
),
|
||||
"suspend_d": pro.suspend_d(
|
||||
trade_date=trade_date, fields=FIELDS["suspend_d"]
|
||||
),
|
||||
"dc_index_concept": pro.dc_index(
|
||||
trade_date=trade_date,
|
||||
idx_type="概念板块",
|
||||
fields=FIELDS["dc_index"],
|
||||
),
|
||||
"dc_index_industry": pro.dc_index(
|
||||
trade_date=trade_date,
|
||||
idx_type="行业板块",
|
||||
fields=FIELDS["dc_index"],
|
||||
),
|
||||
"dc_member": pro.dc_member(
|
||||
trade_date=trade_date, fields=FIELDS["dc_member"]
|
||||
),
|
||||
"sw_daily": pro.sw_daily(
|
||||
trade_date=trade_date, fields=FIELDS["sw_daily"]
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def fetch_security_dimensions(pro) -> pd.DataFrame:
|
||||
"""显式拉取全部上市状态及非默认生命周期字段。"""
|
||||
parts = [
|
||||
pro.stock_basic(list_status=status, fields=FIELDS["stock_basic"])
|
||||
for status in ("L", "D", "P", "G", "UN")
|
||||
]
|
||||
return pd.concat(parts, ignore_index=True)
|
||||
|
||||
|
||||
def fetch_macro_dimensions(pro) -> dict[str, pd.DataFrame]:
|
||||
"""拉取申万 2021 二级分类及成员响应;历史/当前响应必须分开保存。"""
|
||||
classification_version = "SW2021"
|
||||
industries = pro.index_classify(
|
||||
src=classification_version,
|
||||
level="L2",
|
||||
fields=FIELDS["index_classify"],
|
||||
)
|
||||
industries["classification_version"] = classification_version
|
||||
current_parts = []
|
||||
historical_parts = []
|
||||
for l2_code in industries["index_code"].dropna().unique():
|
||||
current = pro.index_member_all(
|
||||
l2_code=l2_code,
|
||||
is_new="Y",
|
||||
fields=FIELDS["index_member_all"],
|
||||
)
|
||||
historical = pro.index_member_all(
|
||||
l2_code=l2_code,
|
||||
is_new="N",
|
||||
fields=FIELDS["index_member_all"],
|
||||
)
|
||||
current["classification_version"] = classification_version
|
||||
historical["classification_version"] = classification_version
|
||||
current_parts.append(current)
|
||||
historical_parts.append(historical)
|
||||
return {
|
||||
"index_classify": industries,
|
||||
"index_member_current": pd.concat(current_parts, ignore_index=True),
|
||||
"index_member_history": pd.concat(historical_parts, ignore_index=True),
|
||||
}
|
||||
|
||||
|
||||
def ingest(
|
||||
api_name: str,
|
||||
params: dict[str, str],
|
||||
fetch: Callable[[], pd.DataFrame],
|
||||
) -> None:
|
||||
"""保存请求身份、原始响应 hash,再按自然业务主键幂等 upsert。"""
|
||||
frame = fetch()
|
||||
normalized = normalize_nulls_units_and_dates(
|
||||
api_name,
|
||||
frame,
|
||||
request_params=params,
|
||||
)
|
||||
assert_unique_business_keys(api_name, normalized)
|
||||
raw_version = persist_raw_response(api_name, params, frame)
|
||||
upsert_current_projection(api_name, normalized, source_version=raw_version)
|
||||
```
|
||||
|
||||
`dc_member` 全市场单日若超过 5,000 行,必须按 `ts_code` 或其他可验证分片重拉;不能接受被截断的“成功”响应。所有接口同理以官方单次上限、返回行数和预期覆盖率判断是否需要分片。[Tushare 官方限量;复现建议]
|
||||
|
||||
## 实施前账号实测清单
|
||||
|
||||
1. 用目标账号逐一调用 17 个接口,记录成功/失败、错误码、单次行数、分钟级限流和字段集合;尤其验证官方页未写稳定权限的 `namechange`、`suspend_d`,以及 manifest 中未找到当前官方页的 `suspend`。
|
||||
2. 在连续至少 5 个交易日记录每个接口首次完整到达时间、后续修订时间和行数,以确定每日 DAG 的轮询、超时与 `last_good` 策略。
|
||||
3. 验证 `dc_member` 的最早历史和按日完整性;验证 `index_member_all(is_new=Y/N)` 是否覆盖全部历史、重复纳入、空 `out_date` 和剔除日边界。
|
||||
4. 对同一交易日抽取至少一个概念板块、一个东财行业和一个申万二级行业,比较逐股 `sum(moneyflow_dc.net_amount)`、`moneyflow_ind_dc.net_amount` 与 OneChartLab 公开 raw/成分榜,记录成员覆盖和单位差异。
|
||||
5. 验证停牌日、上市首日、退市前后、更名日、B 股/北交所和当日无资金流的样本,确认“无行、NULL、0、无效成员”四种状态不会混淆。
|
||||
|
||||
## 主要第一方来源
|
||||
|
||||
- OneChartLab [`sector_rankings/manifest.json`](https://onechartlab.com/sector_rankings/manifest.json):成员、资金流、涨跌幅、停牌、生命周期、单位、聚合与股票池契约。
|
||||
- OneChartLab [`radar_manifest.json`](https://onechartlab.com/radar_manifest.json):Radar 日期分片和排名历史入口。
|
||||
- OneChartLab [`macro/state.json`](https://onechartlab.com/macro/state.json):Macro 当前/最近有效批次、hash 与修订水位。
|
||||
- 作者视频[《我把自己的交易系统,做成了4个网页工具》](https://www.bilibili.com/video/BV16Hur6rEq2/):单日流入率的成交额分母语义、3—10 日窗口和 Macro 近 90 日申万二级行业输入语义;未披露精确公式。
|
||||
- Tushare 官方接口页:[`dc_index`](https://tushare.pro/document/2?doc_id=362)、[`dc_member`](https://tushare.pro/document/2?doc_id=363)、[`moneyflow_dc`](https://tushare.pro/document/2?doc_id=349)、[`moneyflow`](https://tushare.pro/document/2?doc_id=170)、[`moneyflow_ind_dc`](https://tushare.pro/document/2?doc_id=344)、[`daily`](https://tushare.pro/document/2?doc_id=27)、[`daily_basic`](https://tushare.pro/document/2?doc_id=32)。
|
||||
- Tushare 官方接口页:[`trade_cal`](https://tushare.pro/document/2?doc_id=26)、[`stock_basic`](https://tushare.pro/document/2?doc_id=25)、[`namechange`](https://tushare.pro/document/2?doc_id=100)、[`suspend_d`](https://tushare.pro/document/2?doc_id=214)、[`adj_factor`](https://tushare.pro/document/2?doc_id=28)。
|
||||
- Tushare 官方接口页:[`index_classify`](https://tushare.pro/document/2?doc_id=181)、[`index_member_all`](https://tushare.pro/document/2?doc_id=335)、[`sw_daily`](https://tushare.pro/document/2?doc_id=327)、[`index_basic`](https://tushare.pro/document/2?doc_id=94)、[`index_daily`](https://tushare.pro/document/2?doc_id=95)。
|
||||
- Tushare 官方 GitHub [`tushare/pro/client.py`](https://github.com/waditu/tushare/blob/master/tushare/pro/client.py):Pro 请求结构和动态接口方法实现。
|
||||
|
||||
本文结论用于数据工程与公开机制复现,不评价指标的投资有效性,也不代表能够复制原作者未公开的专有算法。
|
||||
Reference in New Issue
Block a user