Files
shy3130 b6c35a9b64 feat(ext-data): 扩展序列粒度 auto/intraday/daily — 日级近N日序列
扩展表此前只有日内多盘一种时序形态; 无时间列的每日快照表 (板块成员/评分等)
无法画趋势。新增序列粒度:

- PullConfig.granularity 三态 (auto/intraday/daily, 默认 auto): auto 按时间列
  值形态判定 — 含非零 HH:MM:SS 判 intraday, 日期形态/00:00:00/无 time_field
  判 daily; 显式声明优先于判定。schema/list 透出 granularity_effective。
- series 端点日级分支: 无需 time_field, 取近 N 日分区按日聚合 (末次非空),
  支持标的过滤与 chartDays; 日内分支响应带 granularity 标识。
- 前端拉取配置加「序列粒度」选择 (auto 显示判定结果), 列自定义器按 effective
  粒度分流: 日内保持现状, 日级提供近N日柱/线/文本与图宽高配置。
- ExtSparkChart 修全等值退化: min===max 时归一化柱形无意义 (全负值画满格、
  全正值画 1px 线), 改回退文本直显。

auto 默认与旧行为完全一致 (向后兼容); 无 time_field 不再 400 而按日级处理。
验证: test_ext_granularity 16 条 + 快照/时间列契约适配; 前端 build + 321 测试。

Signed-off-by: shy3130 <shy3130@qq.com>
2026-10-28 12:46:51 +08:00

355 lines
35 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 功能手册
各功能模块的详细说明。配置见 [configuration.md](./configuration.md),部署见 [deployment.md](./deployment.md),策略相关见 [strategy.md](./strategy.md)。
> 首次使用建议顺序:**设置 → 凭据与能力**(重新检测) → **立即跑盘后管道**(拉日 K + 算指标) → **自选页**加标的 → **策略页**扫描 → **回测页**验证 → **监控中心**配规则。
---
## 🔍 策略引擎(Screener)
**策略全部为用户自定义文件**(`data/strategies/custom/`,可编辑可删除;新装环境策略库为空,旧版本升级用户自动补回 25 个原内置策略)。挖掘用的研究模板保留在 `backend/app/strategy/research/`(research_only,不进策略列表),见 [strategy.md → 示例策略](./strategy.md#示例策略):
| 类型 | 代表策略 |
| :---------- | :------------------------------------------------------- |
| 趋势 / 形态 | 趋势突破 · 均线多头 · MA 金叉 · MACD 金叉放量 · 布林突破 · 均线粘合突破 · 平台整理突破 · 放量创60日新高 |
| 量价 / 涨停 | 量价齐升 · 高换手强势 · 连板股 · 断板反包 · 涨停动量 · 接近涨停 · 涨停基因活跃股 |
| 反转 / 波动 | 超跌反弹 · 超卖反转 · 新低反转 · 低波动龙头 · 回踩 MA20 · 回踩支撑 · 强势开盘 · MACD 零下回升 · 长下影反击 · RSI 中轴回踩 |
全 A 股一次扫表,Polars 毫秒级返回。策略页点策略卡片即可扫描,结果支持导出。**分钟策略**与日线策略共用同一个标的池,按策略声明的周期自动路由执行(分钟策略依赖数据页开启分钟数据落盘)。
**策略包导出/导入**:策略设置可一键「导出策略包」(.zip)——除策略源码外,自动打包其引用的自定义信号/因子定义与用户调参(依赖闭包,含叠加策略子策略);策略池的「导入策略」同时接受单个 `.py` 与 `.zip` 策略包,导入前预览清单与冲突,缺失依赖黄色预警,复用配置备份的安全校验与导入即冒烟。
**ETF 支持**:策略页顶部可切换 `股票 / ETF`。ETF 复用已算好的 `kline_etf_enriched` 技术指标,仅开放**技术类策略**(趋势/量价/反转/波动);依赖涨停信号的策略(连板股、断板反包)为股票专有,ETF 模式下不显示。需先在数据页开启 ETF 拉取(`pipeline_pull_etf`)并跑一次盘后管道。
扩展策略的三种方式见 [strategy.md → 扩展策略](./strategy.md#扩展策略的三种方式)。
---
## 📊 指标流水线(Indicators)
原生 Polars 向量化,全 A 股一次扫表落盘 enriched Parquet(基础行情列),指标在读取时现算并带进程内快照缓存:
- **均线 / 趋势**:MA(5-60) · EMA · MACD · 动量 · 布林带
- **震荡 / 波动**:RSI · KDJ · ATR · 年化波动率 · 振幅
- **量能 / 涨跌停**:量比 · 量均线 · 涨跌停判定价 · 连板数
- **信号布尔列**:全部由信号库定义驱动(`data/user_data/custom_signals/*.json`,读取时注入;迁移定义可携带显式 `column` 沿用 `signal_*` 原列名)——管线不硬编码任何信号表达式
- **复权**:基于除权因子自动前复权,回测与指标口径一致
盘后管道(默认 15:35 CST 自动触发; 盘后固定价 15:30 终止 + 供应商日线定稿缓冲)会重新拉日 K + 重算 enriched 表。
---
## 🧪 回测引擎(Backtest)
基于 vectorbt(**三种模式**):
| 模式 | 说明 |
| :--- | :--- |
| 个股回测 | 单标的 + 策略,看个股历史表现 |
| 策略组合 | 一个策略扫描全市场,按组合约束回测 |
| 自由信号组合 | 多个自定义信号组合,自定义权重 |
**真实约束**:T+1 · 手续费 · 滑点 · 止损 · 最大持仓天数。
**组合管理**:最大持仓数 · 敞口控制 · 等权 / 评分加权 / 自定义仓位策略(用户规则 + 模板, 建仓日动态分配)。
输出净值曲线 · 夏普 · 最大回撤 · 胜率 · 盈亏比(平均盈利单/平均亏损单,≥1 红 <1 绿) · 蒙卡回撤(中位/95% 边界,按成交顺序重抽样估计回撤分布)。SSE 流式进度支持切页重连,不会丢失回测任务。
**因子归因**:策略评分(scoring)引用了因子的回测,结果区提供「因子归因」tab——对比盈利单与亏损单在入场信号日的因子均值(胜单均值/败单均值/差值/样本数),判断每个因子在本轮交易中贡献了正筛选力还是在拖后腿。数据来自入场候选快照,零额外计算;因子名显示「英文 id + 中文标签」。覆盖 `meta.scoring` 非空的 polars 策略,矩阵单因子排名类策略暂不产出归因。
**分钟策略回测**:分钟级策略逐交易日回放信号、以分钟收盘价入场,输出分钟级成交明细,与日线回测同一套 T+1 / 费用约束。
**结果沉淀**:回测结果可**导出 CSV**(概要 / 净值曲线 / 交易明细 / 分标的统计四段),并可**保存候选**(完整参数与指标快照);候选在回测页「候选方案」中查看,支持**一键载入复测**,回填全部参数继续研究。
**稳健参数筛选(验证 tab)**:参数不再按单窗样本内得分排名——每组参数在 K 个互不重叠验证段上独立回测,按稳健分 R = 0.6×中位 + 0.4×最差 排名,只有在多段行情上都好的参数才能当冠军。配套:主目标白名单(排除胜率/持仓天数等退化目标)、K 段合计最小交易数门槛(fail-closed,不足者降序垫底不静默剔除)、Top-20 全窗 IS 细化(样本内乐观偏差/退化率)、冠军收敛度诊断(各段冠军是否收敛于同一组)、高原判据(冠军网格邻域得分衰减,孤峰=过拟合警报)、运行前验证窗预览。冠军参数可一键应用(走策略配置 override,策略页可还原)。旧单窗样本内排名路径已移除。
**滚动样本外检验(验证 tab)**:每折在训练区间网格优化选参、紧邻测试区间做样本外(OOS)验证,滚动前移;核心产出是 OOS 拼接复利净值与 IS→OOS 退化(过拟合信号)。补强:每折 OOS 最小交易数门槛(不足标记跳过不混入复利)、运行前折预览(<3 折告警)、参数漂移轨迹(逐折最优值 + 稳定/漂移徽章)、「采用最新折参数」(确认框注明来源折,走策略配置 override)。
**策略守护(验证 tab)**:挖掘发布的策略在发布时自动建立守护基线(晋升门槛指标,天然 OOS);此后每天收盘数据更新后自动在新数据上切 K 段做真实回测复验,按稳健分对比基线判定三态——健康(退化≤阈值)/观察(20%-50% 或击穿软底线,连续 2 次告警)/退役(退化>50% 或交易数枯竭)。退役只标记与置灰,不自动删策略文件;已退役策略不再自动复验(重新守护=移除后重新入护)。任意策略也可手动入护(尾随参考基线,非 OOS,判定只针对入护后新数据)。数据纪律:守护层结果绝不反馈进取参加权(逐层 OOS);段落回测失败时只降级到观察不直接退役;新数据不足 30 个交易日跳过本轮。守护页还提供**实验室战报**(守护/挖掘/名额聚合总览,`/api/backtest/lab/report`)与**组合建议**:扫描健康守护冠军间近 126 个交易日的日收益 Pearson 相关性,≤0.7 的对列出,人工确认后生成等权 composite 策略并自动以尾随参考基线入护(幂等,不在最新建议中的对拒绝生成);**挖掘策略名额上限**(偏好项,默认 10,0=不限)在发布门槛通过后校验,名额满时新冠军停在 pending 候选等位。设计见 [自动策略实验室设计](./auto-strategy-lab-plan.md)。
**因子与策略挖掘**:复用已有日频因子和 matrix-native 策略,通过 T-1 市场环境、相关去重和嵌套样本外验证生成研究候选。冠军排序按稳健分(0.6×中位+0.4×最差外层折),strict 档要求最差折 Sharpe>0;对冠军组合再做权重精调({0.5,1.0,1.5,2.0} 网格,消耗 run 剩余预算,退化>20% 放弃),精调结果作为独立候选行追加。任务在 spawn worker 中运行,支持持久 run ID、取消、刷新重连和显式发布;自动周度任务默认关闭且永不自动发布,周度挖掘与每日守护由调度单入口(`lab_schedule`)编排、失败互不阻断。挖掘锁被其他进程占用时后端**降级启动**(挖掘入口 409、其余功能不受影响),挖掘页显示持有者横幅,满足陈旧判定(无进行中运行 + 存储静默 + pid 未复用,fail-closed)可一键强制停止并接管。完整口径见 [因子与策略挖掘](./mining.md)。
**策略设置统一**:回测页「高级策略设置」抽屉与策略页设置弹窗采用同一信息架构(策略条件 / 策略权重 / 风控触发 / 回测范围)。风控与持仓纪律(止损 · 止盈 · 移动止损 · 回撤止盈 · 最长持仓)以策略设置保存的值为默认,回测抽屉内可临时覆盖,也可「应用到策略」持久化;策略页保存的叠加条件随回测请求继承,与扫描 / 监控同一口径;回测范围(资产类型 / 股票池)为回测专属概念。
**市场阶段与主线**:市场环境页在原 5 档状态之外新增情绪周期阶段(冰点/启动/主升/高潮/退潮/修复,由连板梯队的高度、宽度、晋级率、梯队完整度判定,平均段长约 10 天)与主线识别(概念/行业维度的涨停梯队聚合排名,可配置宽基标签过滤)。完整口径见 [市场阶段与主线识别](./market-phase.md)。
**ETF 支持**:三种模式的后端与 API 均支持 `asset_type=etf`,回测面板改从 `kline_etf_enriched` 读取(单次回测为单一资产类型,不混合股票与 ETF)。策略组合与因子回测页均有 `股票 / ETF` 切换,ETF 模式下策略列表与标的搜索跟随资产。需先开启 ETF 拉取并跑盘后管道。
---
## 🔬 因子平台(Factors)
`/factors` 一级页,检验 / 因子库 / 编辑器 / 组合四个 tab,与策略线双向联动。设计与阶段规划见 [factor-platform-plan.md](./factor-platform-plan.md)。
**因子编辑器**:写 DSL 公式(如 `rank(-ts_sum(change_pct, 5))`)→ 校验语法(错误点击定位到字符)→ 试算 40 日 IC → 保存草稿。辅助输入:全部 25 个算子按「时序/截面/工具」分组点击插入(悬停显示签名与参数约束)、79 个可用字段双语 chip 点击插入、「从模板开始」下拉含经典模板与**我的因子**(导入已保存公式作为起点,非初始公式替换前有确认)。保存为草稿态,完整检验通过后在因子库激活。
**检验与组合**:服务端 IC/IR、Newey-West t 值、BH-FDR q 值、分层收益与多空对比;组合 tab 管理多因子权重。自定义/复合因子与策略评分共用同一条物化路径。
**因子 ↔ 策略联动**(四条桥):
| 方向 | 入口 | 说明 |
| :--- | :--- | :--- |
| 因子 → 策略 | 因子库「生成策略」 | 一键生成单因子排名策略(matrix_native,entry/exit 评分阈值 + top_rank 参数),保存为自定义策略可直接回测 |
| 策略 → 因子 | 策略触发器编辑的 Zap 按钮 | 从因子快速创建条件信号(阈值给建议值),自动挂接到当前策略的入场/卖出触发器 |
| AI → 因子 | 自定义信号的 AI 生成 | 提示词包含全部因子分组与 id,可直接写「因子·动量: momentum_20d > 0.8」类条件 |
| 回测 → 因子 | 策略回测「因子归因」tab | 见上文回测引擎章节 |
**版本与生命周期**:公式修改保存为新版本并回草稿态(需重新检验);状态机 active / watch / retired / draft。
---
## 🚦 盘中信号(分钟K)
信号库支持 `timeframe=intraday` 的盘中信号:基于当日**已完成**的一分钟 K 计算特征——分时均价、相对昨收/开盘涨跌幅、1/3/5 分钟放量比(今日基准,滚动窗口、每分钟刷新)、距当日与开盘 30 分钟高低点。条件支持数值比较与 `cross_up / cross_down`(上穿/下穿另一特征或阈值);信号输出为**当日条件上升沿**(条件 false→true 的那一根 bar 才为真,首根不触发;窗口不足、基准为零、缺昨收时特征为 null,判 false 绝不误报)。
- **口径单源**:监控评估、分钟策略执行、分钟回测、历史回放共用同一特征构造器(`app/strategy/intraday_features.py`),四条路径对同一段分钟数据产出完全一致(含防未来函数:只用已收盘 bar,滚动窗口不跨午休/跨日);
- **消费入口**:监控规则字段引用 `csgi_*` 列(与内置 4 个分时穿越信号并列,旧信号列名不变、存量规则零迁移);分钟策略(`timeframes=['1m']`)在 `filter_minute_history` 帧上直接引用 `csgi_*` 列(引擎单点注入);日线策略引用盘中信号会显式报错,不支持;
- **回放验证**:`POST /api/custom-signals/intraday/replay` 用本地历史分钟 K 重放信号触发时点(区间 ≤60 天、标的 ≤200),先验证再配置监控,不消耗盘中数据能力;
- **能力门槛**:盘中评估复用分时信号监控门控——分钟 K 能力(订阅池,单轮标的上限默认 100)或全量分钟能力(落盘服务健康时读本地分区,覆盖全市场);回放与分钟回测只需本地已有分钟 K 历史。
## 📡 监控中心(Monitor)
统一规则引擎,一个页面管理**四类监控**:
| 类型 | 场景 |
| :--- | :--- |
| 策略监控 | 策略扫描结果有变化时触发(如新增符合标的) |
| 个股信号监控 | 特定个股的指标条件(如 `RSI > 80`) |
| 价格涨跌监控 | 涨跌幅 / 价格突破阈值 |
| 全市场异动 | 全市场异动(如快速拉升/跌停) |
**ETF 支持**:规则可选资产类型 `股票 / ETF`。监控引擎按规则 `asset_type` 分轮评估——ETF 规则用 ETF enriched 快照评估(`engine.evaluate(..., asset_type="etf")`),策略型规则走 ETF 历史加载器(读 `kline_etf_enriched`)。盘中触发需开启 ETF 实时行情(`realtime_pull_etf`),使 ETF 报价进入 enriched 快照。
**特性:**
- 多条件 AND/OR + 冷却期去重 + 严重级别(info / warn / critical)
- 多入口配置:监控中心新建 / 个股详情页「加监控」/ 策略卡片一键开启
- 命中后右下角弹窗(可配声效)+ 持久化到 `alerts.jsonl`,菜单未读徽标
- **触发记录详情**:每条记录展示命中的具体条件(如 `RSI>80`)与当前价位,一眼看清为何触发
- **与模拟盘的关系**:模拟盘账户绑定策略即自动进入实时评估产生跟单信号(无需另建监控规则);监控引擎是全局唯一的实时评估器,同一策略每轮只评估一次、事件扇出给全部订阅账户。监控中心的规则只负责**告警推送**——模拟盘的自动评估不产生告警,反之未绑定的监控策略不影响模拟盘。
### 外部推送渠道
全局配置飞书群 Webhook、企业微信群 Webhook、通用第三方 JSON Webhook 或 SMTP 邮件。每条监控规则可独立多选渠道,每日复盘也共用同一套渠道配置。第三方 Webhook 使用稳定 JSON 信封,并支持可选 HMAC-SHA256 签名;邮件支持 SSL、STARTTLS 和无加密 SMTP。设置页可选择新建规则的默认渠道并对各渠道发送测试消息。
---
## 🚨 异动监控(Abnormal Moves)
独立的异动页,按交易时间线组织为三个 tab,覆盖盘前到多日:
| Tab | 口径 |
| :--- | :--- |
| 竞价异动(盘前) | fuyao 同花顺盘前风向标:当日竞价强势榜(5-6 只/日,含竞价涨幅与概念标签),附带**当日 / 次日真实收益对照**与**追高风险标记**(高开 ≥5% 追高当日均值显著为负,来自 60 日回测) |
| 盘中异动 | 涨停 / 炸板 / 翘板 / 跌停 / 新高 / 新低 / 放量等当日信号聚合,按信号优先级 + 涨跌幅排序,复用 enriched 信号列,零新增采集 |
| 偏移异动(多日累计) | 交易所异动偏离值口径(按板块分档:主板 3 日 ±20% · 创业板/科创板 ±30% · 北交所 ±40%;10 日 +100%/−50%,30 日 +200%/−70%),实时计算接近度(≥100% 已触发 · ≥70% 边缘 · ≥50% 观察) |
竞价数据来自 fuyao 数据源(历史按日缓存,当日不缓存);未配置 fuyao key 时竞价 tab 显示引导提示。
---
## 📈 个股分析(Beta)
以「行情 + 关键价位」为主体的单标的决策页:
- **专用日 K 图表**:主图 + 成交量 + 滑块,默认近 6 个月
- **9 类关键价位**(纯函数实时计算,毫秒级):压力支撑 · 成交密集区 · 枢轴点 · 前高前低 · Keltner 通道 · ATR 波动通道 · 缺口位 · 斐波那契 · 整数关口
- **AI 四维分析**:技术 / 基本面 / 财务 / 消息面流式生成,客观技术分析视角(不输出买卖建议)
---
## 🏆 连板梯队 & 概念分析
- **连板梯队**:实时统计各连板层级(首板 / 2 连板 / 3 连板...)的标的与封单,捕捉市场情绪与题材热度
- **概念涨幅轮动**:基于 ths 概念 / 行业,统计概念板块涨幅与 RPS 轮动,AI 分析资金主线
- **盘后 AI 复盘**:盘后自动生成市场复盘,注入**龙虎榜资金动向**(席位净买/机构与游资 Top5)与**盘前风向标**对照,可定时执行、推送飞书群、下载 Markdown;复盘页内亦有龙虎榜卡片(可排序席位明细)
---
## 🧰 数据与扩展
### 页面管理(菜单 / 扩展页面 / 页面插件)
「设置 → 页面管理」统一管理三类页面能力, 内部三个区块: **菜单与页面**(侧栏排序/显示隐藏、源码扩展页删除)、**扩展页面**(声明式分析页 CRUD)、**页面插件**(上传/启停/删除)。原「菜单设置 / 扩展页面 / 页面插件」三个设置 tab 已并入, 旧链接 `?tab=menus|ext-pages|page-packs` 自动重定向。
**扩展页面**支持四种模板: 维度热度榜 / 指标排名榜 / 明细表(基于扩展数据源), 以及 **URL 嵌入**(只填菜单名 + http(s) 网址, 生成以安全 iframe 内嵌外部页面的侧栏页面 — 复用看板外链的安全约定: 仅 http(s)、拒嵌本站、sandbox 白名单、X-Frame-Options 拒嵌时提供新窗口兜底)。注意 https 面板嵌入 http 地址会被浏览器拦截。
**源码扩展页删除**: 菜单与页面区块中, 源码扩展(`frontend/src/custom/<ns>/`)行可物理删除 — 后端先自动打包备份 zip 到 `data/backups/pages/`(界面提供下载), 再删除目录, 刷新/重新构建后该页面从菜单与路由消失; 误删可解压备份或 `git checkout -- frontend/src/custom/<ns>` 恢复。仅源码部署可用, Docker/桌面产物部署(容器内无前端源码树)返回 409 明确拒绝。
**源码导入**: 页面插件区块支持直接导入 `.tsx` 源码扩展 — 上传单文件或从本项目 `frontend/src/custom/` 清单选择, 后端用项目自带的 esbuild 自动编译并适配契约(组件路由→命令式挂载、图标→白名单), 产物即标准页面插件, 免重新构建。已知边界: 源码注册的插槽被跳过、页面内路由参数读到空值、数据缓存独立于宿主、包内捆绑的是导入时的宿主库副本(面板升级后重新导入即可刷新); 仅源码/桌面部署可发起导入(需 Node 工具链), 已导入的包全部署形态可用。
### 页面插件(运行时扩展页面)
页面可以打包成**单文件 ES 模块产物**(`frontend/page-pack-template` 一键构建),在「设置 → 页面管理 → 页面插件」上传即挂载为完整页面 — 路由、侧栏入口、菜单管理自动注册,**宿主无需重新构建**;本地 dev / 生产 / 桌面端一致生效。上传时即时试载校验契约(清单格式、路由冲突),坏包停用并显示原因;启停删除随时管理,刷新后生效。源码级扩展(`frontend/src/custom/`)与声明式分析页面仍是随构建的另外两条扩展路径。契约与安全边界见 [page-sdk.md](./page-sdk.md)。
### 数据源插件化
内置 [TickFlow](https://tickflow.org) 官方 SDK(日 K / 分钟 K / 指数 / 财务 / 实时行情),同时支持接入第三方数据源:YAML 声明自有 HTTP 接口,或开发插件源。多个数据集(日K / 除权因子 / 实时行情 / 分钟K / 五档盘口 / 财务,注册表持续扩展)按源声明自由组合,在「设置 → 数据源」切换。
详见 [custom-data-source.md](./custom-data-source.md) 与 [plugin-development.md](./plugin-development.md)。
### 扩展数据进回测
数值型**时序模式**扩展字段(人气排名等)可在回测中使用:叠加条件 / 策略评分引用 `ext_*` 字段时,引擎在矩阵加载后按 (日期, 标的) 对齐现场注入(与策略页帧路径同一台 PIT 安全 join,缺失补空值=条件不命中)。快照模式扩展字段与字符串扩展字段不进回测(快照回看历史即未来函数);引用时回测前置校验直接拒绝并说明原因。
### 全量分钟(盘中增量落盘)
「全量分钟」是独立能力(`full_minute`),**与其他能力同样可路由**:盘中将全市场当日 1 分钟 K 持续增量落盘 `data/kline_minute/`,分钟策略与分时视图即取即用。接入方式:TickFlow Expert,或声明 `full_minute` 数据集的插件/自定义源(设置 → 数据源 → 全量分钟 路由);配好能力后开启实时行情即自动运行(冷启动全天修复轮 + 稳态增量轮)。
详见 [configuration.md → 全量分钟](./configuration.md#全量分钟-full_minute)。
### 🔌 第三方数据接入(重点)
支持将自有量化项目的数据并入,与内置数据同台分析:
| 方式 | 说明 |
| :--- | :--- |
| HTTP 定时拉取 | Tushare 等 API,定时拉取并入库 |
| CSV / Excel 上传 | 页面直接上传文件 |
| JSON 写入 | 程序化写入 |
接入后自动 schema 发现 + 符号归一,页面可视化配置,最终并入 DuckDB 同台分析。HTTP 拉取的出站请求默认携带标识头 (`User-Agent: tsp/<版本>` 与 `X-TSP-Client: tick-stock-panel`),服务端可据此识别本项目来源;拉取配置里的自定义同名请求头优先。
##### 时序表历史回补
timeseries 模式的表 (如人气排行) 默认只能从开启拉取之日起逐日累积。拉取配置新增**日期参数名**(`date_param`): 接口支持按日查询时填参数名 (如 `date`), 即可在拉取面板使用**历史回补** —— 按本地交易日逐日请求 `?date=YYYY-MM-DD` 写入对应分区,已有分区自动跳过 (幂等,可重复执行; 单次上限 120 天,单日失败不中断并逐项列出原因)。回补落盘的历史数据立即进入信号/因子/回测的按日对齐通道。
防污染契约: 若接口忽略日期参数返回当日数据 (以响应行 `date` 字段为准校验), 该日**拒绝写入**并计入失败清单 —— 否则当日值会静默污染整个历史时序。接口侧需提供: 传日期参数返回该日数据、无数据返回空数组或 404 (均视为该日无数据, 计入 empty 跳过)、每行带 `date` 字段;不传参数保持当日 (向后兼容)。
##### 日内多盘表增量续传
盘中多盘表 (配置**时间字段**`time_field` 后同标的允许多行, 按标的+时刻去重) 若每次全量重拉, 越到收盘越重。拉取配置可声明**增量参数名**(`since_param`, 如 `since`): 每次拉取自动带上本地目标日分区时间列的最大值 `?since=<值>`, 源只返回其后数据 —— 缺口感知天然成立, 本地缺多少源补多少。本地无该日数据 (首拉/新交易日/分区被删修复) 时不带参数即整日全量, 回退方向永远安全; 分页拉取下 `since` 作为过滤器与页码参数一起每页携带; 两级拉取 (fanout) 不适用。接口侧契约: 传参数返回该值之后的行、无新数据返回空数组。
##### 快照表多盘化 (拉取时刻注入)
源数据没有时间列的每日快照表 (人气榜、资金流等) 同样可以多盘: **时间字段**填保留名 `__pull_ts__`, 写入时自动注入拉取时刻 (北京时间 ISO), 去重键变为 [标的, 拉取时刻] —— 盘中每次拉取各存一盘, 读取侧 `@时刻` 选盘与末盘收敛语义和真实时间列完全一致。注入列是本地时刻, `since_param` 对它自动失效 (源无法按我们的拉取时刻过滤); 历史回补一天一拉, 注入回补时刻后每标的恰一行, 与单盘行为等价; 同一秒内重复写入按末次覆盖不追加盘。
扩展数据页源卡片为多盘表显示「多盘」徽章与最新分区盘次概览 (盘数 · 时刻范围); 列表扩展列可按 折线/柱状/文字@时刻 三种形态展示盘次序列 (见选股列配置)。
##### 序列粒度 (日内多盘 / 日级别)
列表迷你图列与 `/api/ext-data/{id}/series` 按生效粒度取数: **日内多盘** (`intraday` — 每标的当日逐盘 `[HH:MM:SS, 值]` 点列) | **日级别** (`daily` — 每标的近 N 日每日一值 `[YYYY-MM-DD, 值]`, 同日多行取末个非空值; 分区日期即 x 轴, 无需时间字段)。拉取配置可显式声明 (`granularity`: `auto`/`intraday`/`daily`, 默认 `auto`); `auto` 按时间列数据形态判断 —— 存在非零时刻 → 日内多盘, 日期形态 / `00:00:00` / 未配时间字段 → 日级别, 判断结果显示在拉取设置的粒度下拉里, 判错可手动钉死。`schema-all` 与配置列表透出 `granularity_effective` 供前端分流选形态 (日内: 分时折线/逐盘柱状/文字@时刻; 日级: 近 N 日折线/柱状/最新值文字)。全等值序列 (同值多行) 的迷你图回退为数值文本, 不画伪趋势。
##### 分页拉取协议
数据量大的接口 (全市场排行、批量快照) 单次响应装不下时, 拉取配置可声明分页 (仅 GET): **页码参数名**(`page_param`, 如 `page`)、**每页条数参数名**(`page_size_param`, 如 `pageSize`)与**每页条数**(`page_size`)。配置后单次拉取按页循环请求并合并结果, 空页/不足一页自动判停; **最多页数**(`max_pages`, 默认 20, 上限 200)防止接口永远返回数据拖死循环。POST body 分页不支持 (请求体是固定模板)。
##### 两级拉取协议 (目录 → 逐条目)
有些数据源只提供「类别清单」+「单类别成员」两个端点 (同花顺概念/行业、多数板块类 API), 没有一次返回「标的 → 所属类别」全量映射的接口。这类源在拉取配置里声明 `fanout` 配方即可, 无需任何按表硬编码: 先请求 `pull.url` 拿第一级目录, 再按 `fanout.param` 并发拉每个条目的成员, 最后**反转为「标的 → 类别清单」**并与普通单请求路径产出同构的行。
配方字段 (除注明外均为字符串): `url` 第二级地址、`param` 第二级查询参数名、`id_field` 第一级条目中作为该参数值的字段、`label_field` 展示名字段 (可选, 仅用于告警)、`items_path` 第二级响应的成员数组 dot-path、`member_id_field` / `member_label_field` 成员里的代码与名称字段、`symbol_col` / `name_col` / `value_col` 输出列名、`separator` 多类别拼接符 (概念用 `;`, 行业层级用 `-`)、`concurrency` 并发上限 (默认 8)、`retries` 单条目失败重试次数 (默认 1, 用尽则跳过该条目并记 warning; 全部条目失败才报错)。鉴权与标识头沿用 `pull.auth` / 通用出站口径。
概念/行业两张内置表出厂即带完整配方, 在「数据」页展开本表 → **拉取** 可查看全部字段, 接入自有板块类源时照抄即可。
##### `/rows` 查询接口 (面向二次开发)
每张扩展表天然是标准 HTTP 接口 `GET /api/ext-data/{id}/rows`, 供页面之外的任意消费方调用:
- `date=YYYY-MM-DD` 单日; `start_date`/`end_date` 日期范围 (可只给一端, 时序全分区合并, 快照模式不支持范围) —— 范围合并自动补行级 `date` 列 (表自带 date 列时补 `data_date`), 消费方能区分每行归属日期;
- `filter=字段:值1|值2` 等值过滤 (值间 OR、多条件 AND, 可重复参数), 免拉全量自行筛;
- `sort=字段` / `sort=字段:desc` 排序; `offset`+`limit` 分页 (响应含 `total` 总数);
- `columns=a,b` 字段裁剪; 响应自带 `fields` schema 与当前数据日期。
配套枚举端点 `GET /api/ext-data/{id}/values?field=X`: 字段去重取值 + 出现次数 (降序), 日期语义与 `/rows` 相同 —— 二开方先取候选值做筛选下拉, 再带 `filter` 查明细。
上传/回补/删除等写端点属于管理操作, 不对外; 读端点即数据出口。
##### 市场级扩展表 (无标的列)
创建时勾选**市场级数据** (`market_level`): 行 = 全市场每日一条, 无 symbol/code 列 —— 适用于市场环境状态、情绪指数、择时信号等序列。上传/JSON 写入/接口拉取均跳过标的关联强制, 去重按首列; 通过 `/rows` (范围查询 + 自动 date 列) 消费完整时序。这是把"市场环境类数据发布为扩展数据"的数据底座, 策略侧的市场级过滤契约按需在此之上建设。
#### 扩展字段接入信号/因子
扩展表的数值字段(int/float)可直接用作**自定义信号条件**与**因子**——无需任何额外配置:
- **自动注册**:扩展表保存后,数值字段(int/float)以 `ext_{表ID}_{字段}` 为列名注册进因子注册表(kind=base,分组「扩展数据」),出现在自定义信号的字段下拉、因子库列表、策略评分与检验的可用因子、AI 生成提示词中;列名保留中文(如 `ext_ths_concepts_所属概念`),非 ASCII 名的数值字段只进信号通道不注册因子(DSL 公式标识符为 ASCII);
- **string 字段进信号(概念/行业归属筛选)**:字符串字段不注册为因子(数值口径),但可作为信号条件字段,运算符为 **包含(contains)/等于/不等于**,右值为字符串字面量(如「所属概念 包含 AI」);contains 按字面量匹配而非正则,空值不误报;可与数值条件混合(归属强势板块 AND 情绪/热度阈值),用于强势板块内筛选;
- **时序模式按日对齐**:按 (symbol, 交易日) 精确匹配扩展分区,缺分区为 null(不前视填充),历史帧与回测无未来函数;策略结果表展示的扩展列(如人气)同取结果日分区,与叠加条件过滤口径一致(该日期无分区时回退最新值展示);
- **快照模式仅当日**:快照代表"最新值",只在当日/盘中单日帧注入;多日历史帧跳过,防止回看历史引入未来数据(引用快照字段的信号在历史帧按缺列优雅降级);
- **写入即失效**:上传/定时拉取/配置变更后自动清扩展帧缓存、策略结果缓存与 enriched 内存缓存,下一次计算立即生效;
- **边界**:bool 字段不参与;string 字段仅进信号条件通道(不作因子);内置预设的概念/行业表为快照模式,其归属条件在当日/盘中筛选生效、历史回测不注入(防未来函数),需要历史回看请用时序模式按日写入。
### 盘后定时管道
APScheduler 默认 15:35 CST 自动:拉日 K → 重算 enriched 表 → 跑监控规则。
### 令牌桶限流
适配各档位 rpm / batch 限制,批量合并 + 增量拉取,避免触发数据源限流。
## 🌐 开放接口(Open API · Tier A)
外部程序(自己的看板/脚本/量化服务)无需面板密码,凭 **API Token** 直接调用核心读取、写入与任务接口 —— 「核心能力开放」的出口层。总体设计与后续 Tier 见 [open-platform-plan.md](./open-platform-plan.md),可运行示例见 [examples/open-api](../examples/open-api/README.md)。
### Token 管理
**设置 → 开放接口**: 新建 Token(名称 + 权限勾选),明文 `tsp_` 前缀只显示一次;可随时吊销,吊销立即生效。服务端只存 SHA-256 哈希(`data/user_data/api_tokens.json`,权限 0600)。Token 通道默认**仅接受本机/内网调用**(公网 403,`API_TOKEN_LOCAL_ONLY=0` 显式放开,远程推荐 SSH 隧道)——开放接口面向本部署的二次开发与个人工具集成,不作为数据对外分发通道,详见 [configuration.md → 开放接口网络门禁](./configuration.md#开放接口网络门禁默认仅本机内网)。
### 六个权限(scope)
| scope | 能力 |
| :--- | :--- |
| `read:market` | 标的搜索 / 日K / 分时 / 指数 / 市场快照 (默认勾选) |
| `read:ext` | 扩展表 rows / values / schema 查询 |
| `write:ext` | 向**已配置的**扩展表程序化写入行数据 (`POST /api/ext-data/{id}/ingest`) |
| `read:analysis` | 策略清单与结果 / 回测报告 / 市场环境 / 告警 |
| `run:backtest` | 提交回测 / 策略 / 因子检验任务 |
| `paper:trade` | 模拟盘读取与下单/撤单 (最高敏感) |
管理面**永不开放给 Token**: 数据同步、扩展表的**结构**配置(建表/字段/拉取/上传)、设置等只能通过面板密码会话。`write:ext` 只写行数据 —— 外部程序能把数据喂进来,但不能改写表结构;写入的数据会进入策略/回测数据面,谨慎授予。
### 调用方式
```bash
curl -H "Authorization: Bearer tsp_xxxx" \
"http://localhost:8398/api/kline/daily?symbol=600519.SH&start_date=2026-01-01"
```
- **认证通道与面板密码并行**: 带 `Authorization: Bearer` 走 Token 网关(scope 校验 + 限流),不带则走原有密码会话 —— 面板与外部调用互不影响;
- **限流**: 每 Token 默认 120 次/分钟(滑动窗口,`OPEN_API_RATE_LIMIT_PER_MIN` 环境变量可调 1–10000),响应带 `X-RateLimit-Remaining` / `X-RateLimit-Limit` 头,超限返回 429 + `Retry-After`;
- **错误语义**: 401 Token 无效或已吊销 / 403 权限不足或该接口未开放 / 429 超限;
- **CORS 全开**(自托管场景),浏览器直连亦可。
### 事件流(SSE,实时推送)
EventSource 无法携带 Authorization 头,外部程序走**短期票据**两步接入:
```bash
# ① Bearer 换一次性票据 (60 秒, 任意 scope 的 Token 皆可)
curl -X POST -H "Authorization: Bearer tsp_xxxx" http://localhost:8398/api/events/ticket
# → {"ticket":"tse_xxx","expires_in":60,"stream":"/api/events?ticket=tse_xxx"}
# ② 订阅事件流 (浏览器: new EventStream(stream); 脚本: 逐行读)
curl -N "http://localhost:8398/api/events?ticket=tse_xxx"
```
- 当前事件源:**告警触发**(`event: alert`,需票据含 `read:analysis`);心跳 15s;
- 票据**一次性**且短时效 —— 泄漏最多损失一次事件订阅,不能调任何 REST 端点;断线重连需重新换票;
- 事件总线是进程内广播(`app/services/events.py`),新的核心事件源在域模块里 `bus.publish(...)` 即可挂上。
### 契约文档(机器可读)
```bash
curl "http://localhost:8398/api/openapi.json?tier=a"
```
返回按网关规则表过滤后的 OpenAPI 3 规范(`x-tier: a`)—— 哪些路径对外开放、需要什么 scope,**规则表是唯一契约源**,生成代码 / Postman 导入即用。开放面有**契约快照测试**守护(`test_openapi_contract.py`):增删开放端点必须显式更新快照,CI 会拦下无意识的契约变更。
### MCP 接入(AI 客户端)
`mcp-server/` 提供 **MCP (Model Context Protocol)** 服务器,把开放接口包装成 AI 可调用工具 — Claude / ZCode / Cursor 等客户端可直接查行情、看市场环境、读策略与告警、触发回测:
```
AI 客户端 ⇄ MCP stdio (薄桥) ⇄ HTTP + Bearer Token ⇄ 开放网关
```
- 工具按 Token 的 scope 暴露(12 个:搜索/日K/指数/总览/环境/策略/告警/扩展表读/写/回测),**权限裁决仍在网关** — 桥不持有业务逻辑,面板升级自动受益;
- 模拟盘交易类端点刻意未包装(不建议把下单交给 AI);
- 配置方法与工具清单见 [mcp-server/README](../mcp-server/README.md),可运行冒烟测试 `smoke_test.py` 验证连通。
### 桌面客户端版本清单
发布流水线会在每个 Release 附带 `latest.json`(版本号、三平台下载地址、sha256),设置 → 关于 → 检查更新即基于它(优先 GitHub API)提示新版本。