Commit Graph
633 Commits
Author SHA1 Message Date
shy3130 7ac0456c53 feat(mining): 实时行情与挖掘的冲突确认弹窗
盘中实时开启时 enriched 每轮落盘推进数据世代, 排队中的挖掘任务
开跑会因首轮世代校验失败而报错 (mining data generation changed
after the run was queued, 用户反馈)。两个方向加确认弹窗:

- 挖掘页: 实时开启时点「开始挖掘」→ 三按钮确认 (取消 / 仍要开始 /
  关闭实时并开始 — 后者一键关实时并提交任务)
- 侧边栏实时开关: 存在 queued 挖掘任务时开启 → 确认弹窗;
  运行中任务自动跟随新世代, 不拦截

验证: tsc 零错误 + build 通过 + 浏览器验收 7/7 (弹窗出现/取消
无副作用/关实时并启动任务链路/无排队任务不拦截/环境恢复)。
2026-09-02 15:20:48 +08:00
wshy 7619fbcf7a Merge pull request #210 from thinkbuf/feat/kline-preview-nav
feat(kline): 弹窗切股导航 + 邻股预取 + 悬停「至今」+ 外部链接
2026-09-02 13:52:38 +08:00
richardandClaude 0a11bb870e fix(kline): align intraday prefetch with rendering (live & effective days)
Rebase 到最新 main 后,按 review 提的两点把邻股预取与真实渲染路径对齐:

- 邻股预取当日最新分时补 live=true: 与 StockMultiDayIntradayChart 的 latest 同读
  实时源,盘中切股不回落分钟增量落盘的旧本地分区 (历史日期后端自行忽略 live)
- StockPanel 两处预取 days 改用 effectiveIntradayDays, 与多日图实际渲染周期一致,
  range 预取 queryKey 命中, 切换分时 tab 即时有数据
- 附带清理 rebase 冲突解析产生的残留右括号与冗余注释

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-02 13:25:06 +08:00
richardandClaude 6964e1b5c9 fix(kline): two regressions found in PR review
- EChartsCandlestick: 悬停重置 effect 依赖补上 symbol(_symbol) ——
  预取切股到同长度邻股时 data.length 不变, 原 [data.length] 不触发,
  hoverActiveRef 残留导致切股后「至今/周期」无悬停仍显示 (自愈于下次 mousemove)
- Watchlist: DimensionMembersDialog 的 onStockClick 补第三参 navList ——
  从成分弹窗打开个股时用成分列表作切股导航 (成员可能不在自选列表,
  原实现退回自选列表, 成员不在自选则导航按钮不显示)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-02 13:15:30 +08:00
richardandClaude 341b80e7ab refactor(kline): simplify round 2 — scope flex ratio, single-source guard and default
审查后清理, 无行为变更 (除下述作用域修正):

- StockPanel: 日K/分时并排的占宽从硬编码 flex-[1.4] 改为 dailyKlineFlex prop
  (默认 flex-1) —— 避免静默改变 TradeKlineModal 等其他消费方的并排布局;
  仅 StockPreviewDialog 显式传入 flex-[1.4]
- lib/kline.ts: klineMinuteRangeQueryOptions 内嵌「仅同 symbol」placeholderData 守卫,
  与 klineDailyQueryOptions 同源, 删除 StockMultiDayIntradayChart 的内联副本
- DEFAULT_INTRADAY_DAYS 单源化: StockPanel 默认值与弹窗 loadIntradayDays 回退共用
- StockPreviewDialog: prevSymbolRef 初始值改 null (首次挂载 view 本就是 daily);
  blur 复用 keydown 的 e.target(t) 替代重复 document.activeElement 查询

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-02 13:15:30 +08:00
richardandClaude 4d36a5ff20 fix(kline): blur focused control after arrow-key switching to drop stray focus ring
点过分时tab/外链等控件后方向键切股, 浏览器会给该已聚焦控件显示
focus-visible 默认蓝色 outline(应用未自定义 focus 样式, 即浏览器默认环)。
切股成功后 blur 掉当前聚焦元素, 一次覆盖弹窗内所有控件。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-02 13:14:14 +08:00
richardandClaude f3b916c049 feat(kline): prefetch multi-day intraday so switching keeps intraday tab instant
之前邻股只预取了日K/财务/单日分时(日K视图旁的分时图), 分时 tab 用的
多日分时(klineMinuteRange)没预取 → 分时 tab 切股仍要重新加载。

- lib/kline.ts: 新增 klineMinuteRangeQueryOptions, StockMultiDayIntradayChart 与预取共用
- StockPanel: 新增 intradayDays prop, 邻股预取补充 klineMinuteRange(days) + 最新分时
- StockPreviewDialog: 把当前 intradayDays 传给两个分支的 StockPanel, 保证 queryKey 命中

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-02 13:14:14 +08:00
richardandClaude 41a97888b6 fix(kline): widen dialog, balance chart split, keep intraday view on switching
- 弹窗 max-w 1100→1200, 日K/分时并排改 1.4:1 (日K为主视图),
  图表信息栏(悬停含「至今/周期」)有足够宽度单行容纳, 不再换行
- 修复: 分时 tab 下弹窗内切股会跳回日K —
  视图重置仅在弹窗首次打开(symbol 从 null 变非空)时发生, 切股保留当前视图

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-02 13:14:14 +08:00
richardandClaude 7038c7d627 refactor(kline): simplify after review — single-source queries, sort, and nav lists
审查后清理, 无行为变更:

- lib/kline.ts: 新增 klineMinuteQueryOptions, StockIntradayChart/StockMultiDayIntradayChart/
  StockPanel 邻股预取共用 (与 klineDailyQueryOptions 同风格单源)
- LimitUpLadder: sortLadderStocks 每 tick 只跑一次 (sortedTiers memo 供 TierGroup 与
  ladderNavItems 共用), resolveExtFields 提升为 memo (原来算 4 次)
- Dashboard: rankNav 复用 toNavItems 去掉 ! 断言; onNavigate 死条件简化为 alert: undefined
- Screener: 消费 ScreenerTable 传入的 navList (成员弹窗导航不再被丢弃), 移除重复 memo
- Watchlist: nav 列表仅在弹窗打开时构建 (sortedRows 随行情 tick 重建)
- ConceptAnalysis/IndustryAnalysis: 重复的 onStockClick 内联 lambda 抽为 handleStockClick
- StockPreviewDialog: 方向键与 ESC 同层级守卫 priceAlertDraft (点位弹窗打开时不切股)
- StockPanel: 去掉冗余 tick 别名; Monitor: 去掉冗余 as NavItem 断言

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-02 13:14:14 +08:00
richardandClaude 3258325daa feat(kline): add configurable external stock link
设置页新增「个股详情外链」: 可填 URL 模板(占位符 {code}/{market}/{symbol}),
信息条第一行右侧显示外链图标(新标签打开)。留空关闭。

- 新建 lib/stock-external-link.ts: load/save/build + scheme 白名单(http/https) + symbol 形状守卫
- storage.ts 新增 stockExternalTemplate kv

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-02 13:12:42 +08:00
richardandClaude 0f7c1dfe39 feat(kline): show since-prev-close change and period count on hover
悬停某根K线时, 图表自带信息栏额外显示「至今」(该K线昨收到最新收盘的涨跌幅)
与「周期 N」(到最新K线共多少根); 鼠标移出图表区仅隐藏该字段, 其余保持。

- updateAxisPointer 重写: 区分 悬停K线变化 与 竖虚线显隐, 分别控制信息栏重绘与副图 graphic
- 信息栏行高 height → min-height, 容纳「至今」字段不被裁剪

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-02 13:12:42 +08:00
richardandClaude ef66877529 feat(kline): prefetch neighbor stocks and stabilize dialog height
切股瞬间免 loading + 弹窗高度不抖动。

- 新建 lib/kline.ts: klineDailyQueryOptions 作为日K查询唯一权威配置,
  StockPanel(信息条)/StockDailyKChart(图表)/邻近预取三处共享同一 cache key
- StockPanel: 日K查询上提并新增 prefetchSymbols prop, 预取左右邻股日K+财务,
  日K到货后级联预取其默认选中日分时(klineMinute) —— 日K视图并排展示的分时图也免 loading
- StockInfoBar: 无数据时保持挂载(加载态占位), 按字段配置预留行高, 高度不塌陷
- useFinancials: 抽出 financialMetricsQueryOptions 供 prefetch 复用
- StockDailyKChart: 查询改走共享 options, 移除 onDataChange 上报链路

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-02 13:12:42 +08:00
richardandClaude ec95d71732 fix(dialog): dedup nav list so stock preview skips duplicate symbols
同一标的在榜单中多次出现(多概念/行业 leader、监控重复触发)时,
去重后保留首次出现, 避免切股与 n/N 计数空跳。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-02 13:11:54 +08:00
richardandClaude 571e828529 feat(kline): support in-dialog stock switching with arrow keys
K线弹窗支持在来源榜单内切股: 顶栏 ◀ n/N ▶ 按钮 + ←/→ 方向键(输入框/编辑器内让位),
首↔尾循环弱提示, 并给来源页当前预览行加高亮。

- StockPreviewDialog: 新增 navList/onNavigate props, 导出 NavItem/toNavItems;
  合并 ESC 与方向键监听; wrapMsg 弱提示浮层
- 9 个来源页面(自选/监控/选股/概念/行业/看板/连板/成分)构建 navList 并传 activeSymbol

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-02 13:11:54 +08:00
shy3130 bd84d4c0ae feat(ui): 侧边栏桌面三态 + 移动端抽屉 (落地 #166 设计)
桌面 (≥768px): 展开 14rem → 图标条 3.5rem → 隐藏 0 + 左缘悬浮按钮
(hover 1s 以 overlay 预览不挤压主区, 点击固定展开 push); 三态持久化
localStorage tf-nav-state, 自动迁移旧 tf-nav-collapsed 两态键。

移动端 (<768px): aside 换壳为 fixed 抽屉 (80vw / max 320px + 半透明
遮罩), 左上角汉堡唤出, ESC/路由跳转/点导航/点遮罩关闭; 原移动端
强制收起为图标条的旧逻辑移除, 抽屉内恒为完整形态。

数据挂起门控对齐: 图标条/隐藏/抽屉关闭态均不为侧栏隐藏 UI 发请求。

交互设计取自 PR #166 (intfoo), 贴现有 navCollapsed 体系实现而非
合并其平行 sidebar 组件树 (其桌面两态与 main 现有能力重复)。

验证: tsc 零错误 + build 通过 + 浏览器验收 8 项 PASS (桌面三态
两轮循环含隐藏恢复、移动抽屉开合/遮罩/ESC); 修复验收发现的
overlayPreview 残留导致的"恢复后侧栏 fixed 覆盖主区"bug。
2026-09-02 12:40:56 +08:00
shy3130 22add7179c merge: PR #167 监控自定义信号全显 + 信息条弹窗性能优化
冲突解法: SignalPicker 采用 options 形态 (PR 重构) + 保留 main 的
intradayDisabledSignals/intradayDisabledHint 变量 (含自选分组作用域
禁用分时穿越的增强语义, 自动合并会被 PR 旧内联表达式悄悄丢掉)
+ filterCustomByKind: false (监控场景显示全部自定义信号)。
验证: tsc 零错误, pnpm build 通过。
2026-09-02 10:56:49 +08:00
wshy 27d4a5bbca Merge pull request #207 from shuolol/feat/strategy-index-data
feat(strategy): 策略可读取指数/ETF日K (market_data 模块 + 白名单 + 测试)
2026-09-02 10:53:12 +08:00
wshy 7b754c0ff4 Merge pull request #192 from Marquis03/codex/fix-stocksdk-realtime-normalization
fix(stocksdk): normalize realtime quote units and timestamp
2026-09-02 10:53:08 +08:00
shy3130 576850d0fa feat(data): 数据页同步任务支持手动停止 (二次确认)
- 同步运行中顶栏出现「停止」按钮, 点击先弹二次确认: 注明协作式停止
  (当前分块完成后中断, 不损坏已写入数据) + 停止后再次拉取需重新走
  完整管道 (拉取→指标计算→监控规则), 无法从停止处续跑
- api.ts 新增 pipelineJobCancel, 调用既有 POST /api/pipeline/jobs/{id}/cancel
  (取消标志 + 分块回调检查 + JobCancelledError 协作式退出, 后端零改动)
- 补 cancel 端点契约测试: running/pending 可停、终态 400、未知 404、
  停止后可立即新建任务
2026-09-01 22:42:59 +08:00
shy3130 84725cd362 fix(pipeline): 解锁设置页 A 股拉取开关 (#216 维护者补丁)
后端 getter/白名单已随 pr-218 修复, 前端 PipelineScopeConfig 的
locked 特判 (v0.1.60 为配合后端硬编码所加) 未解锁 — 不删则 issue
的用户路径 (设置界面取消勾选 A 股) 依然走不通。删除特判, 恢复与
ETF/指数开关对称的行为。
2026-09-01 22:41:33 +08:00
shy3130 67b271285c Merge branch 'pr-218' into merge/pr-218 2026-09-01 22:40:50 +08:00
shy3130 bfe76e8273 Merge branch 'pr-206' into merge/pr-206 2026-09-01 22:38:50 +08:00
shy3130 d266131f90 Merge branch 'pr-213' into merge/pr-213 2026-09-01 22:33:28 +08:00
shy3130 e8c870af73 Merge branch 'pr-219' into merge/pr-221-220-219 2026-09-01 22:20:01 +08:00
shy3130 d0595eb4d7 Merge branch 'pr-220' into merge/pr-221-220-219 2026-09-01 22:20:01 +08:00
shy3130 a9c00fd567 Merge branch 'pr-221' into merge/pr-221-220-219 2026-09-01 22:20:01 +08:00
shy3130 c7a921cc60 merge: feat/full-minute-dataset (全量分钟数据集开放) 合入 main
分支已含 main 全部提交, 合并前验证: 涉改 106 用例 + 前端 tsc 零错误
+ 全量 1340 passed (test_mining_manager 偶发为存量, 合并前 main 可复现)。
2026-09-01 13:13:49 +08:00
shy3130 95cd99ab8c merge: 同步 main (辐射本地读 + 传输压缩/网络设置) 到全量分钟分支
冲突两处均为 minute-refresh status 字段两侧各自新增, 两者全保留
(healthy + provider/provider_effective/repair_only)。
2026-09-01 13:05:21 +08:00
shy3130 bc9461da9a feat(net): 分时/日K批量响应可选 gzip 压缩与网络设置
- _gzip_payload: 偏好开启 + Accept-Encoding 协商 + 超 1KB 才压
  (level 6); datetime 序列化与非压缩路径一致, 保证 since 增量
  字符串字典序合并不受影响
- minute-batch / daily-batch 端点各自独立偏好键, 逐请求即时生效;
  实测分时 9.1MB→1.28MB (86%), 日K 736KB→156KB (79%)
- 超时设置 tab 更名网络设置, 卡内新增压缩区: 大开关 OR 联动
  (任一子开即亮, 全关才灭, 点击全开/全关) + 分时/日K两个子开关
- preferences.save() 加线程锁: 修复并行 PUT read-modify-write
  互相覆盖 (总开关批量关不齐的根因), 存量偏好写入一并受益
- 测试: 双端点压缩/关闭直通/无协商头直通/偏好默认 + 并行 save 竞态
2026-09-01 13:04:00 +08:00
shy3130 f84cb671ef feat(data): 全量分钟健康时策略页与监控注入切读本地分时
- 策略页: healthy 时解除分时列 100 只截断并 prefer_local 读本地分区
- 监控信号注入: 股票 healthy 时直接读本地当日分区, 免每分钟 bucket
  一次的全量 API 拉取; ETF 不在服务 universe, 不健康/读失败回落原路径
- minute-refresh status 增加 healthy 读侧新鲜度字段 (前端共享判断)
- 测试: 注入本地读 3 用例 (健康读本地/不健康回落/ETF 恒走 API)
2026-09-01 13:03:54 +08:00
shy3130 010c484289 feat(data): 全量分钟 (full_minute) 数据集开放插件/自定义源接入
像其他能力一样可路由: 声明 full_minute 数据集并在设置页路由, 即接入
盘中全市场分钟落盘服务 (与 TickFlow Expert 同一能力键 intraday.universe)。

- policy: _DATASET_CAP_MAP 增补 full_minute → INTRADAY_UNIVERSE, 自定义源
  声明且被路由时自动补授能力, 服务门控对两类源统一口径
- capabilities 注册表: full_minute 从不可路由 (field=None) 改为
  full_minute_data_provider 偏好路由; preferences/settings API 收发新字段
- 插件契约: get_intraday_batch (修复轮, 未实现回退 get_minute 当日窗口) +
  get_intraday_latest (稳态增量, 可选; 未实现降级仅修复轮, 节奏下限 60s)
- YAML 声明式源: full_minute 数据集与 minute 同形, loader 白名单放行,
  源编辑器 UI 可配置; 仅修复轮语义
- kline_sync 边界: fetch_intraday_custom_batch / _fetch_intraday_custom_latest,
  帧过北京墙钟守卫, 与 TickFlow 边界函数同纪律
- minute_refresh: 删「自定义分钟源让位」逻辑, 改按路由取数;
  status 增 provider / provider_effective / repair_only
- 前端: 监控页卡片按能力驱动, 数据源页路由矩阵, api.ts 类型
- 测试: 门控/路由/降级/增广新增用例, 后端 1332 全过
- 文档: plugin-development / custom-data-source / configuration / features /
  CONTRIBUTING 契约细化 (AI 可照文档接入)
2026-08-31 22:53:24 +08:00
shy3130 dab8a2c676 test(screener): 矩阵策略计数 18→25 — 补 58f8d7b 新增 7 策略漏改 2026-08-31 22:53:12 +08:00
shy3130 5757950e45 docs(data): 补全量分钟 (full_minute) 能力接入说明
- 定位为独立能力: 当前接入方式为 TickFlow Expert, 而非档位封闭功能
- configuration.md: 档位表 Expert 行补全量分钟 + 新增接入小节 (配 Key→检测→
  开实时行情→自动落盘, 修复轮/增量轮/时段/幂等行为, ETF 不在标的池)
- features.md / plugin-development.md: 增对应条目与插件现状说明
  (数据集暂未纳入 loader 白名单; 自定义分钟源在位时内置服务让位)
2026-08-31 22:36:19 +08:00
shy3130 bdad0fefb5 feat(screener): 策略列标签折叠 — 表头全表开关 + 行级展开
- 默认收起: 每行显示前 N 个策略 + 计数 (跟随列设置"显示前N个", 未配置默认 3)
- 表头图标切换全表展开/收起, 收起时清除行级展开状态, 状态持久化
- 排列方向始终跟随列设置 tagLayout (展开不再强制横向)
2026-08-31 22:30:45 +08:00
shy3130 2fc7d3f439 feat(screener): 策略池支持一键清空与本组全加 2026-08-31 22:30:44 +08:00
shy3130 58f8d7b883 feat(strategy): 新增 7 个矩阵原生内置策略, 公开计数 18→25
- 趋势/形态: 均线粘合突破 · 平台整理突破 · 放量创60日新高
- 量价/涨停: 涨停基因活跃股 (max_change_pct 参数过滤当日已大涨)
- 反转/波动: MACD 零下回升 · 长下影反击 (close_position>=0.5 兼容假阴线) · RSI 中轴回踩
- 阈值统一小数制口径 (change_pct/momentum 除以 100), 一致性测试计数 26
2026-08-31 22:30:44 +08:00
shy3130 be799abfa0 fix(intraday): since 增量时区崩溃 — 客户端直传原始时间串, 服务端归一 aware 输入
客户端 toISOString 生成带 Z 的 UTC, Python 3.12 解析为 aware datetime,
与行内 naive 北京时间比较 TypeError (第二轮轮询 500), 且换算差 8 小时。
- 客户端: since 直接回传最旧最后一根的原始 datetime 字符串 (同格式同时区,
  字典序即时间序), 消灭一切换算
- 服务端: fromisoformat 后 aware 输入先转北京墙钟再去 tzinfo, 防御旧客户端
2026-08-31 22:01:46 +08:00
shy3130 ed2f81c312 feat(realtime): 首用门禁 — 本地无数据时禁止开启实时行情
日K/enriched 均空 (与看板首用弹窗同口径) 时开启实时行情返回 409 并给
同步指引, 不落偏好。展示/监控/梯队全部依赖本地数据底座, 空数据下轮询
只是空转耗配额且缺 instruments 维表。只拦开启不影响关闭, 已开后清库
下次重开自然被拦。
2026-08-31 21:45:07 +08:00
shy3130 320969497a perf(intraday): 分时链路增量传输 + SSE 续画 + 视口感知
- minute-batch 支持 since 增量响应: 只回 >= since 的K (含动态最后一根),
  客户端按 (symbol, datetime) upsert 合并, 轮询流量从全天序列降到每轮一两根
- 自选分时 SSE 续画: enriched tick 前端续写分钟序列最后一根/滚动追加新K
  (纯视图叠加不写缓存, 服务端定版值始终权威); tick 新鲜时轮询降为 30s 兜底
- 视口感知: 从虚拟器直读渲染中 symbol 集合 (可见+overscan), 数据层只拉视口内;
  since 只按本轮请求集合取最旧尾部, 视口外落后不放大窗口; 集合变化 300ms
  防抖补拉; 剔除指数保持端点契约
- since 过滤专项测试: 含 since 当根 / 早于全部K / 无 since 三态
2026-08-31 21:45:06 +08:00
shy3130 869c49bb0b fix(kline): 分钟增量起点改为最后一根本身 — 形成中的动态K需重拉覆盖 2026-08-31 20:54:56 +08:00
shy3130 b78ba9940d perf(kline): 分钟批量补拉取到即落盘 + 尾部增量窗口
- 补拉结果经 _write_minute_partition upsert 落盘 (持仓库写锁, 与全量分钟
  服务/盘后同步同一纪律), 下一轮命中本地, 大自选从每轮全天重拉降为增量
- 完整性判定由 0.9 根数比例改为 期望-2 根: 比例阈值会让持久化数据在 90%
  处冻结尾巴
- 分类三态: fresh 直读本地零请求 / 尾部落后从最后一根+1min 增量拉 /
  中间有洞 (间距非 1min/午休 91min) 退回全天重拉回填, 防增量窗口漏数据
- 落盘失败降级为仅返回本轮数据 (持久化是优化而非正确性前提)
2026-08-31 20:53:23 +08:00
shy3130 bfe01e06d9 feat(data): 无除权因子能力时同步前置二次确认
除权因子不可用时同步静默降级 (日K不复权入库、enriched 直接用 raw 价),
此前无任何提示。现于两个同步入口 (数据页同步按钮、首用欢迎弹窗开始获取)
检测能力矩阵 usable 标志, 不可用先弹确认: 告知不复权口径与除权事件后
需重新校准, 支持不再提示 (localStorage)。矩阵未加载完成时 fail-open 不拦截。
2026-08-31 20:34:27 +08:00
shy3130 bfc2eede3e style(monitor): 设置监控页右列「全量分钟」移至「连板梯队降级修正」上方 2026-08-31 20:04:14 +08:00
shy3130 bfcad563d3 feat(frontend): 自选分时请求带 prefer_local, 策略页行为不变
- klineMinuteBatch 加 preferLocal 参数, 响应类型补 full_minute_local
- 仅 Watchlist 分时轮询传 true (全量分钟健康时股票不走批量补拉);
  Screener 不传, 严格限定本轮只辐射自选场景
2026-08-31 17:10:09 +08:00
shy3130 df5cae143e feat(minute): 自选分时接入全量分钟本地供给 (prefer_local + freshness 判定)
- MinuteRefreshService.is_healthy(): 偏好开 + 线程活 + 最近一轮距今
  ≤ max(2×间隔, 30s)。last_round_at 只在取数+落盘成功后更新, 连续失败
  自动超时判不健康, 冷启动修复轮期间天然不健康
- /api/kline/minute-batch 加 prefer_local 标志: 服务健康时股票 incomplete
  不再批量补拉, 本地有多少给多少 (服务下一轮落盘补全; 停牌票补拉也是空,
  无损); ETF 不在全量分钟 universe 内维持补拉; 不健康回落现状兜底。
  响应加 full_minute_local 标记
- 大自选 (数百上千只) 不再每 6s 轮询持续打批量分钟接口
- 4 个新用例: 健康跳过股票补拉/ETF 仍补, 不健康回落, 无标志不受影响,
  is_healthy 三条件边界
2026-08-31 17:10:02 +08:00
shy3130 6d72efc624 docs: 指数固定清单契约 + 自定义源指数补充协议
- CONTRIBUTING 能力路由矩阵小节: 实时指数为产品级固定契约不走路由矩阵
  (index_const 单一权威, 指数页固定四只, 指数偏好已删, 监控标的不受限);
  自定义源 get_realtime_indices 可选协议与 fuyao 连坐语义注记
- plugin-development: get_realtime_indices 方法契约与软失败语义
2026-08-31 16:50:38 +08:00
shy3130 58b86a962b feat(frontend): 指数页固定核心四只, 删除全指数搜索与侧栏指数配置
- /indices 指数页保留: 左侧固定核心四只(核心指数卡片), 删除搜索框与
  全量指数列表; 右侧日K/分时详情与同步指数日K按钮不变
- 侧栏指数条固定四只常驻显示, 点击跳指数详情
- 监控设置"左侧菜单指数"配置卡删除(四选多选+固定显示开关)
- api.ts: 删 indexList/indexSearch, Preferences 移除 5 个指数偏好字段;
  queryKeys 同步清理
2026-08-31 16:50:28 +08:00
shy3130 3c6ed99922 feat(index): 指数收敛为固定核心四只 + fuyao 指数快照接入
- 新建 app/services/index_const.py 单一权威: 展示层固定四只核心指数
  (上证/深证成指/创业板/科创综指), quote_service/overview/
  market_overview_builder/sector_monitor 四处重复定义全部收敛
- fuyao 插件接入指数快照端点 (/api/a-share-index/prices/snapshot):
  client 增加 index_snapshot (批量上限 627 码), provider 实现可选协议
  get_realtime_indices — .BJ 后缀先行过滤 (未知代码整批 1002 连坐),
  volume 不做股转手; 修复 fuyao 路由下指数冻结在日K兜底的 bug
- quote_service 自定义源分支鸭子类型调用 get_realtime_indices 补拉指数,
  请求清单 = 核心四只 + 启用指数监控规则标的; 未实现的源走日K兜底
- TickFlow 分支指数固定按码显式拉取, 移除 CN_Index 全量 universe 与
  mode core/all 分支; 指数落盘固定 merge 不截断
- 指数偏好全套下线: realtime_index_symbols / sidebar_index_symbols /
  indices_nav_pinned / realtime_pull_index / realtime_index_mode
- /api/index/list 与 /search (全指数浏览搜索) 删除; daily/minute 保留
  供指数详情页, sync_instruments/sync_daily 保留供数据页
- sector_monitor 指数标的恒可监控, catalog 签名不再依赖指数偏好
- 新增 7 个用例: 指数快照映射/.BJ 过滤/软失败 + 自定义源指数补充链路
  (含监控规则并入/无协议源静默/指数失败软降级)
2026-08-31 16:50:21 +08:00
shy3130 e287a55e82 fix(capabilities): redetect 同步刷新 app.state 快照并升级 tickflow SDK 0.1.25
- /api/capabilities/redetect 重新探测后同步写回 app.state.capabilities,
  minute_refresh 等门控服务即时读到新档位, 不再需要重启
- tickflow 0.1.24 缺 intraday_universe 方法导致 Expert 档全量分钟探测失败,
  升级到 0.1.25
- 全量分钟轮次异常与模式补充 warning 日志, 便于线上诊断
2026-08-31 16:50:12 +08:00
shy3130 4d27f3139e Merge branch 'feat/capability-routing': TickFlow 列式直转提速与除权因子时区修复, 分钟增量间隔上限 120s 2026-08-30 22:29:57 +08:00