Commit Graph
100 Commits
Author SHA1 Message Date
shy3130 ae93849d55 test(contract): 同步 Tier A 开放契约快照
b14f367 模拟盘重构新增 DELETE /api/paper/account 与 GET /api/paper/rounds,
按网关 paper:trade 前缀规则自动进入开放面, 补进快照。
2026-10-14 17:01:03 +08:00
shy3130 b22a970097 fix(strategy): 堵住策略安全校验绕过 GH #475
别名赋值与字符串拼接可绕过 AST 名单, 在主进程执行任意命令。
改为拦截危险引用、dunder、模块句柄与文件原语; 加载层 fail-closed。
2026-10-14 16:26:33 +08:00
shy3130 ec8307eb3b chore: v0.3.7 2026-10-14 15:11:55 +08:00
shy3130 b14f3679d5 feat(paper): 模拟盘重构 — 多账户对比与策略自动执行
- 对比榜单 14 列可排序, 盘中实时估值; 行展开完整账户操作台
- 创建即绑策略自动执行: 入场信号买入 · 出场信号全平, 支持最大持仓
  (对齐回测口径)、仓位、订单类型、冷却; 批量创建同享
- 账户删除 (两步强确认)、冻结; 回合明细; 基础配置 (新账户默认参数)
- 策略联想下拉重设计: 全量候选、两行式选项、portal 防裁剪
2026-10-14 15:11:54 +08:00
shy3130 ac7d8c1c8f fix(ui): 无全市场分钟能力时隐藏板块轮动卡 2026-10-14 15:11:46 +08:00
shy3130 ca7801dc14 fix(ui): 界面缩放改用 transform scale — 修复缩放非 100% 时图表鼠标命中偏移 2026-10-14 15:11:46 +08:00
shy3130 af45efcf01 修复readme格式乱码 2026-10-13 22:40:05 +08:00
shy3130 506d66f1ef fix(desktop): TdxQuant Key 探测打包版失效 — 哨兵重执行 + tdxaidata 入包
- probe: worker 移入主模块, frozen 以「重执行自身 + TDX_PROBE_WORKER 哨兵」
  拉起子进程 (sys.executable -c 被 PyInstaller bootloader 无视, 子进程会
  重启整个桌面应用 → Key 永远验证失败); dev 保持 python -c, 共用 run_worker
- spec: tdxaidata 显式入包 — 后端全部懒导入 Analysis 不跟随; lib/ 跨平台
  原生库按 datas 整目录复制 (collect_all 会让 macholib 解析 Linux ELF 崩)
- desktop: 单实例 _pid_alive Windows 改 OpenProcess+GetExitCodeProcess
  (os.kill(pid,0) 在 Windows 是 TerminateProcess, 会误杀在跑实例);
  main() 哨兵分发探测 worker, 先于单实例/后端/窗口
- 测试: 新增 test_tdxquant_probe.py (8 例); 全量 2692 passed;
  打包产物端到端实测探测 API ok, tdxaidata 真实加载连服
2026-10-13 18:37:29 +08:00
shy3130 25fd5a0fad fix(desktop): macOS 数据目录移出 .app 包 — 覆盖安装不再清空用户数据 + 包内旧数据自动迁移 2026-10-13 17:23:13 +08:00
shy3130 68368ac8c2 Update 2026-10-13 14:40:32 +08:00
shy3130 ecb49cbaca release: v0.3.6 — 核心+扩展架构完善版
合并 0.3.6 分支全部内容 (36 提交, 详细历史见 0.3.6 分支):

■ 数据与插件
- TdxQuant 数据源: 通达信量化接入 (实时/五档/日K/复权/分钟), tdxaidata 收进默认依赖
- 扩展表两级拉取配方: 概念/行业出厂即带完整可拉配置, 可作自定义接入参考示例
- 能力门禁日志带生效源; 标的池解析只走 instruments 维表

■ 页面扩展化
- 11 个官方页面全量迁移为单文件扩展 (custom/*/extension.tsx), 删目录即卸载
- 运行时页面包系统: 打包产物上传即挂载, 免重建宿主
- 新装用户扩展页默认隐藏, 老用户升级菜单无感

■ AI
- Responses 协议接入; 会话历史与长任务跨设备同步 (服务端注册表)
- 助手头部快捷入口 + 悬浮球拖拽 zoom 坐标系修复 + 系统设置开关

■ 界面
- 设置「关于」子菜单: 版权/更新/打赏 + 开源许可弹窗与合规声明双保险
- 侧栏两态收起、数据/AI 助手快捷行 (同步呼吸光晕)、核心/扩展 ext 标记
- 界面缩放默认 90%; 菜单设置徽标 Swiss 化; 策略池「叠加」分组
- 情绪评分口径可配置; 财务画像 5 张子表手动拉取

■ 文档与其他
- README 重构「核心+扩展」主线 + 架构图重画; 开放端点数核实为 65
- 版本号 bump 0.3.6; tdx 物化库测试夹具补 macOS dylib
2026-10-13 13:40:17 +08:00
shy3130 53ed6755ff fix(strategy): 信号种子迁移改为按 id 合并种入 — 修复升级用户丢失内置涨跌停信号
- seed_if_empty 原逻辑「目录存在任一 json 即整体跳过播种」令升级前已有
  自定义信号的用户丢失 20 个默认信号定义 (signal_limit_up /
  signal_limit_down / 跌停翘板 / 炸板), 表现为看板跌停恒 0、连板梯队
  无数据; 现改为仅种入缺失的 id, 绝不覆盖任何已有文件。
- 历史遗留的 skipped: user signals present 标记视为未种子化, 升级后自动
  补种缺失项。
- 播种提前到 repo.refresh_cache 之前: enriched 缓存构建时编译自定义信号
  表达式, 晚种会让本次启动的看板/梯队引用的 signal_limit_* 列缺失,
  直到下一次缓存刷新才自愈。
- 测试: 跳过断言重写为合并断言 + skipped 标记补救 + 同 id 不覆盖 3 个用例。
2026-10-12 22:50:50 +08:00
shy3130 c5ffe38c75 fix(test): ETF 分钟回填测试注入迁移信号定义 — 干净环境缺 signal_limit_* 定义导致回测解析报错 2026-10-11 15:51:50 +08:00
shy3130 350ffbf612 chore(build): 精简 Dockerfile 可选构建阶段, 清理文档与引导页冗余引用 2026-10-11 15:42:55 +08:00
shy3130 6a2a9bb2a7 chore(build): 清理打包 spec 冗余双声明与文档参考段落 2026-10-11 15:03:58 +08:00
shy3130 c565afefd9 fix(ui): AI 助手双入口降至 z-30 常驻入口层, 弹窗不再被悬浮图标遮挡
菜单侧栏对话入口(z-[55])与可拖动悬浮球(z-[59])原本高于 z-50 标准弹窗层,
任何弹窗打开时都悬浮其上且可点击遮挡。统一降至 z-30 常驻入口层:
高于页面内容、低于 z-40 遮罩与 z-50 弹窗; AI 助手面板(z-60)仍在入口之上。
2026-10-11 10:46:43 +08:00
shy3130 c3afd3470a refactor(ui): 分区命名统一 —「纪律与触发」改为「风控触发」(弹窗+回测抽屉+测试+文档) 2026-10-11 10:44:26 +08:00
shy3130 da51ff5711 feat(migrate): 旧数据目录一次性自动迁移 — 信号自动种入 + 失效策略自动归档
老环境升级后进入策略页逐文件报错刷屏、信号库为空, 需要用户手动搬运。
改为启动时自动完成, 前端只提示一次:

- 信号种子: data/user_data/custom_signals 为空且从未种过(.seeded_v1
  标记防重)时写入 20 个默认定义(原内置信号, 带 signal_* 列名), 写入
  即用户数据可编辑可删; 用户已有自定义信号时不掺入只落标记; 全删后
  重启不复活
- 失效策略归档: 引擎加载后把「内置残留」类失败(composite 子策略断链/
  import 已删内置模块/引用不存在的策略)移入同目录 _archive_unloadable/
  (引擎只扫顶层 *.py), 归档后 reload; 语法错误等普通失败不归档仍走
  原提示; 同名碰撞追加序号不覆盖
- 提示一次: /api/strategies 透出 legacy_migration 摘要, 前端按迁移
  指纹 localStorage 防重, 一条 toast 说明种入/归档结果

单一事实源: app/strategy/signal_seeds.py (tests/fixtures JSON 同内容,
tests/signal_seeds.py 改为从此读取)。回归: 6 个新迁移测试 + 后端 66
passed + 前端 vitest 125 + tsc 0; 本机实启验证 66 策略/0 错误/不重复
种入(标记落盘)
2026-10-10 22:15:17 +08:00
shy3130 9fdf7266a3 fix(screener): 旧数据目录升级的宽容降级 — 兼容垫片 + run_all 跳过失效 ID + 报错聚合
内置策略移除后, 老环境(策略池残留内置 ID / 自定义文件 import 旧模块 /
composite 断链)进入策略页会刷屏报错。三层修复:

- 兼容垫片: app/strategy/builtin/factor_rank_research 透明转发到
  app.strategy.research —— 旧策略文件 import 零改动继续可用
- /run_all 宽容: 混合未知 ID 跳过继续跑并回 skipped_unknown(全部未知
  才 404); 前端据此自动清策略池并提示一次, 空库场景 prune 的兜底
- 前端 load_errors toast 聚合: 多个失败合并为一条带文件名与修复指引,
  不再逐条刷屏

配套回归: tests/test_legacy_upgrade_degrade.py(垫片转发/混合跳过/全未知
404); 后端 34 passed + 前端 vitest 125 passed + tsc 0 错
2026-10-10 21:47:46 +08:00
shy3130 e077fc2729 Merge branch 'refactor/de-builtin-strategies-signals' 2026-10-10 21:30:28 +08:00
shy3130 918c7ade7e refactor(core): 策略与信号全面去内置化, 转为用户自定义定义
- 策略: 引擎只加载 data/strategies/{custom,ai,composite} 与研究模板目录,
  原 25 个内置策略一次性迁移为用户自定义文件(ID 不变, 引用零迁移);
  研究模板移至 app/strategy/research, 打包 spec 同步; 新装环境策略库为空
- 信号: 管线不再硬编码任何信号表达式; 涨跌停判定价成为运行时列
  limit_up_price/limit_down_price(生效价∓0.005 容差), 20 个信号转为
  data/user_data/custom_signals 定义(显式 column 沿用 signal_* 原列名);
  依赖解析/注入顺序/当日路径 prev-join 全部定义驱动; 语义统一为历史路径
  口径(顺带修正当日路径 BOLL 比较符与翘板/炸板空值两处既有偏差)
- 前端: 信号库单列表(全部可编辑), SignalPicker/监控选项/信号标签全走
  定义接口; 回测页新增免责声明(模拟性质/数据源准确性不作保证/不构成
  投资建议)
- 测试: 25 个策略夹具与 20 个信号种子入库 tests/fixtures, 受影响测试
  全部自包含化(不依赖运行目录用户数据); 77 万行 MA 死叉新旧表达式对拍
  逐行一致; 回测实跑 45 笔卖点信号出场验证矩阵链路
- 同批包含工作区既有进度: 策略结果 ext 列同日投影修复(含测试)、数据源插件、fuyao/auth/api_gateway/data_integrity 调整、README 信号库
  描述与 strategy.md 导入路径补充

验证: 后端 2592 passed(空数据目录 CI 模拟 2588 passed, 4 例为模拟环境
伪影复验排除); 前端 vitest 125 passed + tsc 0 错 + vite build 通过
2026-10-10 21:10:44 +08:00
shy3130 ae9feb869c fix(sources): 自定义源全量分钟/分钟K amount 改为可选 + 保存先验后存
amount 按契约可空, 缺成交额的源此前被整体拒绝且保存静默失败;
现在校验不过返回 400 带原因, 不落盘。
2026-10-09 16:21:29 +08:00
shy3130 b65d2691d9 feat(strategy): 每策略「叠加条件」overlay_filter — 零代码硬过滤叠加
策略设置新增「叠加条件」分区: 字段+运算符+值 多行 AND 硬过滤, 直接叠加在
策略自身规则之上, 选股/回测/监控三处一致生效, 不改策略代码、无需另建
信号或叠加策略 (扩展数据因子如 ext_ext_fuyao_hot_rank 可直接选)。

- 条件结构与自定义信号同源 (allowed_fields 白名单含注册表因子/字符串扩展
  字段), 禁用日期偏移, 最多 8 条
- 只挡入场/候选: exit_signal_hits 在过滤前收集, 已持仓卖出不受影响
  (与 basic_filter 既有口径一致)
- null/缺数据 ≡ 不命中 (fail-closed); 引用列缺失时报可读错误
- 仅日线 polars_expr/matrix_native 支持, composite/minute 保存期+运行期双拦;
  matrix 路径拒绝字符串字段 (矩阵 fields 为 float 数组)
- 保存时条件实际变化才清策略结果缓存, 普通保存不受波及
- 回测: polars 路径在裁剪前完整 panel 上评估掩码 AND 入场; matrix 路径条件
  字段并入 feature_plan 进矩阵 fields, NaN 一律不命中
- 前端提取 ConditionEditor 共享组件, 自定义信号弹窗复用 (净减 ~240 行)

测试: 后端新增 16 项 + 回测/关联模块回归全绿; ruff 对比基线零新增;
前端 6 项组件测试 + tsc/vite build 通过。
2026-10-09 00:19:59 +08:00
shy3130 fb69f382e7 fix(screener): 策略池草稿区仅列 AI 来源草稿,非 AI 研究模板不再显示发布按钮
内置研究模板 factor_rank_research 带 research_only=True,此前混入 AI 草稿
分区并渲染「发布」按钮,点击必被发布闸(仅接受 source=ai)以 400 拒绝。
草稿过滤补 source==='ai' 校验;新增 vitest 测试复现该问题(无修复时红)。
2026-10-08 22:02:13 +08:00
shy3130 17093a8c36 fix(front): 对齐 @tanstack/react-query 至 5.104.1, 与持久化配套包同版
三包此前后台实际为 react-query 5.100.11 + persist-client/persister 5.104.1,
peer 依赖形式上不满足且打包存在 query-core 双拷贝。统一到 5.104.1 后
peer 精确满足, query-core 收敛为单一版本。安装/构建/vitest 105 例/
node:test 5 例全部通过。
2026-10-08 13:27:10 +08:00
shy3130 f17260587b fix(watchlist): 分时缩略图续画按资产类型行情日期守卫, ETF 旧价不再拼尾K
enriched 响应新增 dates; 未开实时拉取的资产类型 (enriched close 为旧日K回退值)
不续画, 修复自选页 ETF 分时尾部错价长刺。
2026-10-08 12:04:41 +08:00
shy3130 625f5c7b56 chore: bump version to 0.3.5 — 前后端版本同源(package.json 唯一权威, fallback/VERSION 同步) 2026-10-08 10:36:26 +08:00
shy3130 0929253620 fix(packaging): app/custom 扩展双声明随桌面包发布, 修复 AI 对话助手 405 (#459)
loader 运行时 importlib+pkgutil 发现 app/custom/*, 静态分析不可见;
未声明时冻结包里扩展静默消失, 助手路由未注册 → SPA 兜底返回 405。
datas 落盘 _internal/app/custom + hiddenimports 进 PYZ, 仿 fuyao 双声明;
新增 test_packaging_spec.py 锁定打包不变量。
2026-10-08 10:36:26 +08:00
shy3130 85b8a3f930 chore: 补提交 .zcodeignore(AI 工具扫描忽略配置) 与 mcp-server/uv.lock(与 backend 锁文件入库惯例一致) 2026-10-08 00:00:56 +08:00
shy3130 a358e07b01 feat(paper): 模拟盘持仓表显示股票名称 (#454)
代码列内联灰色小字显示名称(股票/ETF/指数), 批量 instrumentNames 查询
(与监控/持仓提醒页同模式, 5min staleTime, 空持仓不发请求), 查不到名称优雅降级不显示。
2026-10-07 22:24:33 +08:00
shy3130 39f2543ccc chore: bump version to 0.3.4 — 前后端版本同源(package.json 唯一权威, fallback/VERSION 同步) 2026-10-07 21:49:30 +08:00
shy3130 badab07619 feat(adj): 除权因子独立同步 + 事件明细扩列 + 按需窗口优化
- 扩列: adj_factor 表扩至 8 列(dividend/bonus/allot/allot_price/prev_close 明细, 可空), fuyao 从事件 dump 原始成分回填; merge 变更检测按 ex_factor diff>1e-9, 仅明细回填不计入受影响列表; 字段说明补齐
- 独立同步: /api/pipeline/adj-factor/run 端点(共用任务机制: 单飞+重任务槽+行情暂停), Data 页除权因子卡片设置齿轮弹窗(生效数据源/能力徽标/TickFlow 无明细提示), 因子变更个股自动 enriched 局部重算
- 按需优化: 独立同步事件窗口钳到本地日K起点(更早事件在前复权 cum/total 两侧抵消, 对已存价格零影响); fuyao 配价由全有或全无改为逐只按需(远古事件只拖累自己, 不再整轮回退单标的接口); 实测全市场因子阶段 15min+ → ~11s, 配价 3676/3676 走本地 dump 零回退
- 盘后管道步骤条显示各能力路由徽标(矩阵驱动); README 补桌面端 macOS 安装注意事项
- 测试: 明细列 merge 语义 4 例 / 独立同步联动 5 例 / 远古事件不连累全场回归; 全量回归通过(2 例历史遗留失败与本改动无关, 基线同样失败)
2026-10-07 21:45:40 +08:00
shy3130 a1ae815f4f docs: 更新交流群二维码 2026-10-06 15:25:37 +08:00
shy3130 597afbb5f4 fix: 图标缓存刷新改用 SHChangeNotify, 不再依赖 ie4uinit(无IE系统刷新不到) 2026-10-06 13:26:37 +08:00
shy3130 29b54e5dac fix: pywebview 依赖链显式 hiddenimports, 构建环境缺包时构建报错而非产出坏包 2026-10-06 13:12:01 +08:00
shy3130 11977ce6bf fix: 安装完成自动启动失败(错误码740)改用 shellexec 2026-10-06 12:52:29 +08:00
shy3130 4ba0c9bcc0 修复部分已知Bug 2026-10-06 12:40:16 +08:00
shy3130 2b73e89b81 feat(app): 桌面端体验优化 — 界面缩放(80%-150%, 修复缩放黑条)/每小时检查更新/侧栏橘黄色呼吸灯下载图标(点击定位并自动检查)/发现新版本徽章带版本号/官网入口/顶部工具栏不折行/页面标题渐变字效; build: 安装包文件名带版本号 + 安装后自动刷新图标缓存 2026-10-06 12:10:32 +08:00
shy3130 30fcade330 docs(readme): 官网徽章移至标语下方, 配色改黑底+品牌紫 2026-10-05 22:39:30 +08:00
shy3130 fdb8a0f435 fix(packaging): 补齐 fuyao 插件 — plugin.yaml 落盘 + provider/client 入 hiddenimports, 打包后设置页恢复数据源 2026-10-05 19:41:17 +08:00
shy3130 b23db4ecd7 brand: 品牌统一为 TSP — 应用名/图标(浅色圆角卡, Windows/macOS 双平台)对齐 brand 资产, README 新增官网入口与标题行内嵌 logo 2026-10-05 18:45:09 +08:00
shy3130 af63614610 perf(front,back): 查询缓存持久化 + staleTime 分层 — 重开应用秒出上次数据, 不再全量重拉
- 新增 lib/queryPersist.ts: PersistQueryClientProvider 接入 localStorage 持久化,
  白名单 13 个慢变查询族 (设置/偏好/能力矩阵/自选清单与分组/策略池/regime 全家/自定义信号),
  键首段精确匹配不误伤 watchlist-enriched 等实时行情族; 24h maxAge + 版本 buster;
  快变数据 (实时价/分钟K/告警) 刻意不持久化, 避免陈旧价格误导
- staleTime 分层: settings/preferences 30s, capability-matrix 5min, 自选清单 30s,
  策略池 60s, 自定义信号 60s — 切页不再对慢变数据反复请求
- regime_builder.load_regime_history 加 (path,mtime,size) 签名缓存: Regime 页
  三个端点原先每请求各自全量重读同一 parquet, 现共享一份, 写入后 mtime 失效

验证: pnpm build 通过; 浏览器实测持久化恢复路径 (注入缓存刷新后守卫直接放行,
不再整屏 loading); regime 相关 pytest 22 passed; ruff 零新增; git diff --check 干净
2026-10-05 15:16:16 +08:00
shy3130 f3804215f9 perf(front,back): 首屏弹窗/设置页懒加载落地页 -1.5MB + 后端取数锁收窄/分钟K分区直读/缓存治理 + 错误态与轮询门控
前端 (bundle/渲染/体验):
- StockPreviewDialog/DimensionMembersDialog/ListColumnCustomizer 拆薄壳+lazy 内容 (关闭不挂载, 保留 300ms 退出动画), 落地页静态依赖不再含 echarts/lightweight-charts (~2.2MB→~540KB); Settings 八 tab 与 Onboarding/Auth 按需加载; 字体自托管 @fontsource 替换 CDN 外链; 删除零引用依赖与 buildQuoteMap 死代码
- Watchlist O(n²) symbol 派生链修复 + 批量查询 placeholderData; LimitUpLadder 回调稳定化让 memo 生效; AbnormalMoves 两行组件 memo 化
- 非交易时段轮询降频 (quote_status.is_trading_hours 门控, 字段缺失保持原频); StockPreviewDialog 尊重异动页主开关不再意外触发全市场计算
- 六处错误伪装空态补 isError+重试 (新增共享 ErrorState); Monitor 涨跌色统一 priceColorClass (修 0 值显红); AI 复盘取消生成 (修 reviewStore 中断空指针与半途归档); Regime 主线过滤面板配置晚到回填

后端 (热路径):
- quote_service 监控评估链移出 _fetch_lock, 独立 _evaluate_lock 保两轮不并发; depth_service 网络拉取出锁, parquet 写仍串行
- get_minute/get_minute_batch 优先直读 date= 分区 (缺失回退全树扫描); get_daily_batch 复用 300 天 enriched 历史缓存 (与单股 get_daily 同源判据)
- secrets_store mtime 缓存; 总览 ext 读取 (path,mtime) memo; screener 历史缓存 LRU 硬上限; final 同步状态按日清理; webhook 线程池挂入 lifespan shutdown

验证: pnpm build 通过; 后端 pytest 全量 2489 passed (test_worker_process 1 例时序 flaky 已隔离复跑确认与本次无关); ruff 修改文件零新增告警
2026-10-05 15:07:53 +08:00
shy3130 490c62bca7 fix(paper): 对比榜单三处小修 — 空值恒垫底/副标题随排序可变/徽章高亮去歧义
- 可空列 (累计收益/最新日/盈亏比/最近结算) 无值行排序时恒垫底, 不再随升序翻到顶部
- 页头副标题去掉写死的「收益降序」, 改为「点表头排序」
- # 徽章仅在累计收益降序时高亮为收益名次, 其他排序弱化为列位

验证: pnpm build 通过; 浏览器实测默认高亮/名排序弱化/全空列升降序稳定
2026-10-05 00:13:27 +08:00
shy3130 3aa07d5ef5 feat(paper): 对比榜单加盈亏比列 (胜率旁, 可排序) — 无亏损回合显示 —, 排序空值垫底
后端 compare 已返回 profit_loss_ratio (round 2位), 纯前端改动:
表头 12 列 + 排序键 + 展开行 colSpan 同步, min-w 860→920

验证: pnpm build 通过; 浏览器实测列显示/排序切换/空值 — 正常
2026-10-04 22:19:01 +08:00
shy3130 35e21cf126 feat(paper): 对比榜单表头点击排序 — 8 列升降序切换, 统计卡与净值图固定收益口径
- 可排序列: 账户/总资产/累计收益/最新日/胜率/回合/持仓/最近结算; 默认累计收益降序, 同列再点翻转
- 空值垫底 (数值 -1e9 / 字符串空串), 账户名换列默认升序, 其余默认降序
- 「收益最高」统计卡与归一化净值叠加 (收益前 8) 不受表头排序影响, 始终按收益口径
- 排序表头样式随 Review._DtTh (活动列方向箭头, 非活动列 hover 淡箭头)

验证: pnpm build 通过; 浏览器实测点「账户」表头升降序切换正确、活动列指示正确、恢复默认排序正常、截图无布局错乱
2026-10-04 22:17:39 +08:00
shy3130 379b7d283a feat(paper): 对比视图二期 — 全面去擂台化措辞 + 行内嵌完整账户面板替代跳转
- 措辞: 擂台/参赛/比拼全部改为对比定位 (标题/按钮/卡片/测试/端点文案), 移除 Trophy/Swords 图标
- 交互: 删除「进入」按钮, 点行展开内嵌 AccountPanel (下单/跟单/费用/冻结/持仓/台账/净值/策略对比), 单账户视图仅保留新建向导
- compare 增量字段: created_at/last_nav_date/day_change_pct/auto_rules/auto_enabled/holdings_count (加法契约)

验证: pytest 全量 2485 passed 6 skipped; ruff 通过; pnpm build 通过; 浏览器实测展开面板无擂台字样、无跳转、布局正常
2026-10-04 22:11:55 +08:00
shy3130 ca30bdaa84 feat(paper): 模拟盘擂台主视图 — 多账户收益对比榜单 + 同规格批量创建
参考擂台模式重构模拟盘默认视图, 对比从弹窗提升为页面主形态;
数据层零改动, 老账户自动上榜, 原单账户记账功能全量保留为下钻视图。

后端 (加法契约):
- POST /api/paper/arena/batch_create: 同本金/同费率一次开 N 个账户
  (≤20, 服务端生成 arena_ id), 各绑一条自动跟单规则; 规则整体先校验
  再落盘, 任一非法 400 不留半创建状态
- GET /api/paper/compare 增量字段: holdings_count / created_at /
  last_nav_date / day_change_pct(末两定版净值) / auto_rules / auto_enabled,
  旧前端可忽略
- 开放契约快照 +1 端点 (test_openapi_contract)

前端:
- Paper.tsx 拆为 ArenaView(默认: 摘要卡 + 归一化净值叠加 + 收益降序
  榜单[排名/徽章/迷你走势/跟单规则chip] + 行展开持仓与近期成交) 与
  AccountView(原视图全量保留, 头部加返回擂台); compare 查询 60s 轻轮询
- ArenaCreateModal: 策略/监控规则联想添加 + 全部策略一键加入(≤20),
  方向/仓位/订单类型/冷却为全表共享参数保证同规格
- api.ts: PaperCompareRow 扩展可选擂台字段 + PaperArenaSource 类型
  与 paperArenaCreate; 查询键复用 paperCompare/paperAll

验证: 全量 pytest 2485 passed (含新增 test_paper_arena 4 用例);
ruff 通过; pnpm build 通过; 浏览器实测擂台渲染/行展开/下钻返回/
批量创建弹窗交互均正常 (未在真实数据目录实际建账户)
2026-10-04 22:01:59 +08:00
shy3130 16ece46861 fix(backtest): close_t 卖出遇收盘封死跌停拦截+递延 — 涨停拒买的镜像问题(严重)
回测体检确认的严重项: _can_sell 只拦「一字跌停」, exit_fill=close_t 时尾盘
封板股(盘中正常交易、收盘=跌停价)按跌停收盘价"卖出" — 现实中收盘封死的
卖队排队排不出去, 带止损策略的亏损被系统性低估, 收益虚高。与已修的买入侧
涨停拒买(a64f573e)同构。

- engine.py 四处同构 _can_sell(矩阵/数组 × 独立/组合): exit_fill=close_t 且
  无 override(计划出场: 信号/max_hold/期末)时, 凡收盘跌停(limit_down_locked,
  含一字)一律拦截, 计数键沿用 sell_limit_down(前端已有「跌停阻塞」标签);
  日内风控线(止损/移动止损/止盈, override 盘中价)是封板前穿越成交, 不拦 —
  避免把盘中已触发的保护性离场误递延
- 被拦出场经既有 pending_exit 机制递延到下一可卖日成交, TradeRecord 的
  blocked_exit_days 保留受阻天数
- 修复递延机制的尾部漏洞: 独立候选两路径原会在窗口末尾静默丢弃仍被递延的
  持仓(封板/停牌卡死时 trade 凭空消失) — 改为期末按末日价格强制落账
  (_try_close 新增 force 参数跳过可卖性闸门), reason 取 pending 原因,
  blocked_exit_days>0 标记; 组合路径本就保留持仓并计入 pending_exit_positions,
  无需改
- open_t+1 按次日开盘卖出, 行为不变; signal_next_minute 分钟触发价照旧

测试: test_limit_down_close_exit.py 五场景 — 封板日出场递延到次日/正常日
当日出场不变/日内止损线价当日成交不被误拦/open_t+1 不受影响/期末卡死持仓
强制落账不再丢弃。本地与 TZ=UTC 双跑全量 2481 passed 6 skipped
2026-10-04 21:51:31 +08:00
shy3130 a64f573ef2 fix(backtest): 用户报告两处修复 — close_t 收盘封涨停拦截 + 移动止盈回撤不再静默钳制
报告①(严重, 收益虚高): _can_buy 只拦「一字板」(收盘涨停且四价合一),
entry_fill=close_t 时尾盘封板股(盘中正常交易、收盘=涨停价)以涨停收盘价
"成交" — 现实中收盘封板的买队排队排不进, 动量类策略信号集中在涨停日,
回测收益系统性虚高(报告实测 55.7% 买单落在涨停收盘日, close_t +586% 对比
open_t+1 -71%)。修复: close_t 口径下凡收盘涨停(limit_up_locked, 含一字)
一律拦截, 拦截原因沿用 buy_limit_up; open_t+1 按次日开盘成交保持只拦次日
一字板。engine.py 四处同构 _can_buy(_simulate_independent_matrix /
simulate_independent_candidates_legacy / _simulate_portfolio_matrix /
simulate_portfolio_legacy)同步修改。旧 simple 路径 simulate() 无任何涨停
守卫但生产代码无调用方, 未动。

报告②(严重, 配置不生效): strategy.py 移动止盈的 min(drawdown, activate)
把用户填的回撤值静默改写成激活值, 无任何提示。改为显式校验报错
「移动止盈回撤(x%)不能大于激活涨幅(y%)」, 与同函数内其他参数组合错误的
 _err 风格一致。

测试: test_limit_up_close_fill.py 四场景(封板拦截/正常日成交/open_t+1
信号日封板不影响次日开盘买入/次日一字仍拦截) + test_trailing_drawdown_
validation.py 两场景(超限报错/未超限放行)。本地与 TZ=UTC 双跑全量
2476 passed 6 skipped
2026-10-04 18:01:52 +08:00
shy3130 eefd9521bb fix(jobs): 分钟K同步「卡死空转」修复 — 排队等槽有上界 + pending 纳入 reap + SDK 批量调用守护 deadline
用户反馈(升级后数据页分钟K同步无限停在「等待其他计算任务完成…」): 被取消/
已终止的残留线程挂死在单次 SDK 网络读里(SDK timeout=30s×3 只保护其覆盖的
阶段), 协作式取消要到分块边界才生效 → 它持有的独占槽(capacity=2, exclusive
权重=2)永不释放; 排队任务等槽无超时且 status=pending 不在 reap_stale 视野
(旧实现只回收 running), 无限空转只能重启进程。机制为 0.3.1 统一重任务并发
控制(b16957a8)引入, 非 0.3.2 回归。

- pipeline_jobs.run_with_capacity: 槽位等待加 timeout(取 job 自身 timeout_s,
  与停滞阈值同源、用户可配), 超时以可读错误失败并按已取消上报 — fn 未执行,
  零数据副作用, 四个调用方(kline/pipeline/daily/integrity)的异常分支免改
- pipeline_jobs.reap_stale: pending 排队停滞纳入回收(pending 无 started_at,
  总时长硬上限跳过); create() 锚定 last_progress_at, executor 排队中从未
  上报进度的任务也有兜底
- kline_sync: SDK 批量调用(日K区间/日K条数/复权因子/分钟K区间/分钟K条数共
  5 处)统一 _sdk_call_with_deadline 守护(600s, daemon 线程执行 + join 超时
  放弃); 超时走既有分块失败路径, 且补发 on_chunk_done 心跳保留进度上报与
  协作取消检查点 — 持有侧线程可退出并释放槽位, 被放弃线程为 daemon 不阻
  塞进程退出

测试: 新增排队超时可读失败/槽空闲行为不变/pending 回收与不误杀/硬上限跳过/
SDK deadline 单元与分块循环心跳(分钟+日K); test_queued_pipeline_is_
cancellable_and_not_reaped 按新契约改写为 cancellable_and_reaped_when_stalled
(其旧断言「排队不被 reap」即本 bug 的排队侧契约)。本地与 TZ=UTC 双跑全量
2470 passed 6 skipped
2026-10-04 16:50:58 +08:00
shy3130 146bc2418f fix(custom): config_from_dict 白名单补上 full_minute — loader 清洗白名单含它而配置模型构建阶段漏了, 自定义源的「全量分钟」数据集被静默丢弃, 表现为设置页试拉报 does not configure dataset 'full_minute'、provider_has_dataset 为 False、分钟全量批量同步链路静默失效; 回归测试覆盖 清洗→YAML加载→load_all 注册→provider_has_dataset 全链路 (此前能力授予层测试 mock 掉了该函数, 真实路径无覆盖)
Fixes #451
2026-10-04 00:47:17 +08:00
shy3130 ff91eca3c0 fix(jobs): JobStore 快照落盘原子化 + get() 取锁 — 旧实现在 succeed()/fail() 的 pop→写盘窗口内, 无锁的 get() 会读到写一半的 JSON 而静默返回 None, 轮询方瞬时看到任务凭空消失 (CI test_pipeline_capacity 偶发 TypeError 的根因; 压力复现: 旧代码 2000 轮 2340 次 None, 修复后 0 次) 2026-10-04 00:41:01 +08:00
shy3130 88e4c19bc2 test(abnormal): 盘中基准动量测试的「今天」改用 cn_today() — 实现按北京日切今日, 测试脏行用宿主 date.today() 在 UTC 16-24 点窗口错开一天不再被排除, CI(UTC runner) 每晚必红 (#446 合并触发的既有时间炸弹, 与其改动无关) 2026-10-04 00:29:59 +08:00
shy3130 b410f1530c feat(packaging): 桌面图标统一品牌渐变 — generate_icon.py 标记色改 #A78BFA→#7C3AED(影线 70%)并重新生成 ico/icns, tickflow-logo.svg 同步 2026-09-28 18:17:30 +08:00
shy3130 18cc8f27b2 feat(frontend): favicon 与侧栏菜单图标换新品牌渐变 — 新增 BrandIcons 组件族(19 个 24 网格直角图标, currentColor 跟随主题), nav 全量替换并清理未用 lucide 导入 2026-09-28 18:17:26 +08:00
shy3130 a982b35410 feat(brand): 品牌资产库扩充与设计提案归档 — logo-dark 深底变体/场景底卡切图/16-24 小尺寸补齐/icon.ico, 另存 19 案 logo 提案评审页(含 12 向图标系统与主标尺寸规范) 2026-09-28 18:17:21 +08:00
shy3130 1ecdd4acbe docs(readme): 修正「个人开源」徽章乱码 — URL 编码多出 %E4%BA%AA 致渲染为「个亪人开源」
alt 文本一直正确, 仅 shields.io URL 路径部分有误, 故 README 上显示为 5 个字的乱码徽章。乱码自 0.3.2 的 369f04d4 README 大改版引入, 经合并带入 main。已用解码与 shields.io SVG title 双重核对。
2026-09-28 12:19:30 +08:00
shy3130 2134e2e3c4 merge: 0.3.2 合并到 main — 开放能力版与看板自定义布局
- 开放能力: API Token 网关(scope 默认拒绝) + SSE 事件流 + MCP 服务器 + 助手动作能力
- 看板: 12 列吸附网格自定义布局(react-grid-layout) + 后端持久化
- 更新检查: 启动静默检查 + 侧栏 NEW 徽标 + latest.json 清单
- 版本: 0.3.1 -> 0.3.2; 附 CI 启用与 watchdog 回移
2026-09-28 10:45:32 +08:00
shy3130 3d03bf8dba test(fuyao): test_dataset 预览用例改用相对日期 — 硬编码日期滑出近30天窗口导致必失败 2026-09-27 23:03:07 +08:00
shy3130 1ba83821a6 test(fuyao): test_dataset 预览用例改用相对日期 — 硬编码日期滑出近30天窗口导致必失败 2026-09-27 23:01:53 +08:00
shy3130 74c1021763 fix(watchdog): 探测循环取消不再被吞 — stop() 不会再永久挂起(自 0.3.2 回移修复与回归测试) 2026-09-27 23:01:53 +08:00
shy3130 a341cfc31e ci: 启用 main 持续集成(自 0.3.2 引入) — 后端全量 pytest + 前端 tsc/vite 构建; 同时修复 0.3.2 README 的 CI 徽章(默认分支无此 workflow 导致 404 裂图) 2026-09-27 22:48:55 +08:00
shy3130 cb4dc820f0 feat(update): 启动静默检查新版本, 侧栏版本号旁 NEW 徽标 — 自 0.3.2 移植共享单例 updateCheck store(24h 缓存+latest.json 兜底), 设置→系统复用同一 hook; 顺带修复设置页检查更新按钮仍指向改名前仓库 2026-09-27 18:53:09 +08:00
shy3130 a1edb94bec update readme 2026-09-27 18:47:50 +08:00
shy3130 39981d2537 feat(dashboard): 默认布局定稿 v2(用户手动调整版) — 中段四列等高(分布/雷达 h7→8), 双热度/四榜单行顶对齐(y12/y21); 坐标为压实稳定形态, 恢复默认等值落null闭环复验通过 2026-09-27 11:12:29 +08:00
shy3130 1a37e5515f feat(dashboard): 用户定稿布局设为代码默认 — 四列中段(分布/雷达/趋势/梯队)+双热度+右侧监控高栏(22行)+四榜单; 坐标取竖直压实稳定形态(列内不留空隙), 保证恢复默认的JSON等值判断成立并落null 2026-09-26 23:58:24 +08:00
shy3130 a39f8f4520 fix(dashboard): 根治组件内容溢出互相压盖 — 格子内容自然高度可大于定高格子(热度+35/榜单+88/监控+146px, overflow:visible 直接画到下一排上, 榜单DOM靠后把概念热度第5行盖住), 格子 overflow-hidden + 卡片 h-full 物理根除; 默认布局高度按实测校准(热度9/榜单13/监控14行)默认视图零裁切 2026-09-26 23:05:41 +08:00
shy3130 2f657e3d07 feat(dashboard): 编辑态交互重设计 — 整卡可拖(顶部被遮挡也能从任意位置拖起), 内容 pointer-events:none 阻断内部点击/悬停/iframe 吞拖拽, 八向缩放(四边通长细条+四角直角标线, accent 主题色), 占位格虚线框吸附反馈; 修复 RGL 浏览态残留 104 个隐形手柄 span 挡内容/滚动条(display:none 根除) 2026-09-26 22:47:33 +08:00
shy3130 fbf390187f fix(dashboard): 布局加载路径消解重叠坐标 — normalizeLayout 渲染前 compactLayout 兜底, 异常保存的 blob 不再组件压盖(注入重叠blob实测: gainers/losers 自动下沉), 拖拽回写同防线, 修正不实注释 2026-09-26 22:36:52 +08:00
shy3130 e65002a478 fix(dashboard): 添加组件弹层 portal 到 body + fixed 锚定 — 按钮移入头部后 absolute 弹层受祖先层叠上下文遮挡, 改为脱离文档流顶层渲染(z-9999), 右缘视口钳位, 页面滚动关闭/面板内滚动不关 2026-09-26 22:23:43 +08:00
shy3130 2461c3df96 fix(dashboard): 默认布局复刻原版排布 — 监控中心回到右栏(榜单右侧/梯队下方), 四榜单收窄为2列占左8列, 不再整行占满把监控挤到页面最底部 2026-09-26 22:20:26 +08:00
shy3130 553a38a44e feat(dashboard): 自定义布局入口移至看板头部「重载」右侧 — 编辑态控制组(添加组件/恢复默认/完成)同处一排, editing 状态提升至 Dashboard 页, 网格组件只保留编辑提示与覆盖层 2026-09-26 22:13:03 +08:00
shy3130 64e69dffd7 feat(update): 启动静默检查新版本, 侧栏左下角版本号旁显示 NEW 徽标 — 共享单例 updateCheck store(24h 本地缓存+latest.json 兜底), 设置→系统检查更新同源复用, 仓库地址修正为改名后名称 2026-09-26 22:08:53 +08:00
shy3130 2ef36e6ba1 docs(readme): 看板条目补充自定义布局能力说明 2026-09-26 20:52:39 +08:00
shy3130 44e8b7ebbd feat(dashboard): 布局后端持久化(preferences链路) + 外部链接组件(sandbox iframe+新窗口兜底) + 添加组件面板 + useDashboardLayout持久化hook(7用例) 2026-09-26 20:52:04 +08:00
shy3130 26e23ef01a feat(dashboard): 12列吸附网格自定义布局 — react-grid-layout v2 封装, 编辑态拖拽/角柄调宽高/删除/恢复默认, 布局规范化与默认布局复刻原排布 2026-09-26 20:12:42 +08:00
shy3130 adfb9da8ac refactor(dashboard): 抽出看板 widgets 到 components/dashboard (纯搬移, 行为不变), 引入 react-grid-layout 依赖 2026-09-26 20:04:02 +08:00
shy3130 0e777e0d3c fix(assistant): 徽标行为助手入口预留右侧空间, 模型名不再延伸到按钮下、状态点不再被覆盖 2026-09-26 19:25:17 +08:00
shy3130 32a42b9de4 fix(assistant): 宽表格标的列不再折行(自适应+不折行+横向滚动); 走势双图固定日K左侧/分时右侧 2026-09-26 19:21:47 +08:00
shy3130 f5d9d6af71 feat(assistant): 工具轮次检查点支持在设置→AI 手动配置 (默认100, 0=不检查, 最小5) 2026-09-26 19:04:54 +08:00
shy3130 c6c4fd2819 feat(assistant): 工具轮次 6 轮硬限改为 100 轮检查点(继续/停止选择卡)
- 到达 _TOOL_ROUND_CHECKPOINT(100) 时复用动作确认闸门(PendingRegistry+决策端点)
  弹 rounds_confirm 事件: 点「继续」重置计数再跑一个周期, 点「停止」或 120 秒
  未选则优雅收尾(notice + done, 已生成内容保留, 不再是 error)
- 前端 rounds_confirm 以合成足迹记录承载选择卡(继续/停止按钮), 复用 decideAction;
  流结束时仍悬挂的 awaiting 确认统一收敛为已取消
- 旧 test_chat_stream_stops_at_rounds_limit 改写为新契约; 新增 3 项检查点测试
  (批准继续/拒绝停止/超时停止)
2026-09-26 18:04:37 +08:00
shy3130 24c1d10f7f fix(assistant): 策略 id 不存在的报错附带可用策略清单, 模型一次自纠
- run_strategy(助手本地) 增加 engine.has 预检; 与 run_backtest(核心目录) 的
  「策略 xxx 不存在」统一升级为附带前 12 个可用策略 id 的提示
- 起因: 模型用中文名/自造 id 直接调 run_strategy 时足迹卡报失败, 需再花一轮
  list_strategies 才能修正; 现在错误信息本身即可自纠, 用户看到的失败原因也可读
- 测试 3 项: 两工具的未知 id 提示文案 + 同步路径
2026-09-26 17:44:47 +08:00
shy3130 86a01a66e3 feat(assistant): 快捷建议 12→18 条 + 芯片按文字自适应排布
- 新增 6 条建议: 主要指数表现 / 横向对比几只股票 / 个股财务速览 /
  对比两个策略(两次确认卡回测后横向对比) / 跑一个选股策略 / 有没有任务在跑
- 建议芯片由固定两列网格改为 flex-wrap 自适应宽度, 芯片随文字长短伸缩, 每组自然成行
- README 交互设计条目同步(18 条 · 文字自适应); 测试补对比类建议与 id 唯一性断言
2026-09-26 17:24:58 +08:00
shy3130 f42bceed4b docs(readme): 助手文档与最新能力对齐 — 21 查询工具 + 扩展内容问答
- 工具数 19→21(新增 list_ext_tables / query_ext_table), 三处同步: 特性总览/能问什么/路线图
- 能问什么表新增「扩展内容」行: 扩展数据表(列表·字段·数据日期, 过滤/排序/日期范围) · 自定义策略与信号
- 交互设计补「分组快捷建议」条目(四组 12 条 + 扩展内容提示卡)
- 扩展机制行措辞校正: 「零核心文件修改」→「扩展无需改动核心」(与 AI 章节的共用触发函数说明一致)
- 快速开始示例补「我的扩展数据表里有什么」
2026-09-26 16:57:12 +08:00
shy3130 6d810d138d feat(assistant): 空会话建议重设计 + 扩展数据表问答工具
- 快捷建议 8→12 条并按 4 组分区(行情与大盘/我的与个股/策略与信号/数据与扩展),
  新增板块轮动、盘中异动、批量行情、扩展数据表 4 条; suggests 契约新增 group 字段
- 空会话页重设计: 欢迎卡(图标+主副标题) + 分组图标头 + 两列建议芯片 +
  虚线提示卡「扩展内容同样可以问」(扩展数据表/自定义策略与信号可问答互动)
- 新增只读工具 list_ext_tables / query_ext_table(复用 ext_data 同一条读取链):
  列表含模式/字段/最新分区日期; 读行支持 等值过滤/排序/日期范围, limit 封顶 100
- prompt 工具策略补扩展内容问答指引; 足迹卡/前端工具标签同步
- 测试: 扩展表工具回路 7 项(快照/时序/过滤排序/范围/错误契约/摘要/分组断言)
2026-09-26 16:48:27 +08:00
shy3130 5fcc9bf064 docs(readme): 架构流程图重设计 — 横向挤压图改为五层纵向分层(消费端→网关→应用→核心域→扩展域)
- 旧 LR 图自然宽度 3144px, GitHub 830px 渲染下文字仅 ~3.4px 完全不可读
- 新图自然宽度 966px, GitHub 下有效字号 ~11px; 语义分层自上而下与开放能力版叙事一致
- 核心域三阶段管线(数据底座→计算研究→生产管道)带 enriched 口径/信号事件流向标签
- 扩展域底部通栏 5 通道横排, custom 模块星标强调 AI 助手参考实现
- 按 dagre 布局约束重构: 全下行边避免回边抬升, 去子图级边避免成员链式竖排
2026-09-26 15:42:06 +08:00
shy3130 6b233ed95f docs(readme): AI 助手章节补动作能力 — 19 查询 + 4 动作工具(确认卡)、数据健康检查、共用同步触发路径说明
- 能问什么表新增「数据健康」与「动作(须确认)」两行, 回测归入动作类
- 交互设计新增「动作确认卡」条目(完整待执行参数 + 确认/取消/120s 超时)
- 解耦说明改为如实描述: 数据补全与数据页共用核心层抽取的触发函数
- 功能总览 bullet / 对比表 / 快速开始示例问句 / 路线图行同步更新
2026-09-26 15:13:26 +08:00
shy3130 1d855de03b feat(assistant): 数据完整性与补全 — check_data_coverage 只读检查 + sync_data 确认闸门 + get_sync_status 进度
- check_data_coverage: 分区目录轻量扫描(与 /api/data/status 同口径, 不读
  parquet)输出日线/enriched/分钟K覆盖区间、财务表覆盖、进行中任务与 issues
  问题清单(数据停更/指标落后/财务缺失); 可选 symbol 参数查单标的日线+财务
- sync_data(动作, 须确认): 复用数据页同一条触发路径 — pipeline 盘后管道 /
  financials 财务表调度器 / minute_extend 分钟K向前扩展(days 钳制 30-1095);
  后台执行立即返回, 单飞去重, async 工具经事件循环调度后台任务
- 核心层最小抽取: api/pipeline.trigger_pipeline_job 与
  api/kline.trigger_minute_sync, HTTP 端点与助手共用(端点行为不变)
- get_sync_status: 活跃任务阶段/进度 + 最近 5 任务 + 财务同步状态
- 提示词/快捷指令(数据是最新的吗)/前端足迹标签同步补齐
- 测试: +7 项(覆盖检查缺口与新鲜数据/单标的滞后/共用触发路径与钳制/
  财务同步与参数校验/闸门拒绝不触发/摘要), 助手套件 21+34 项通过;
  全套 2428 passed(1 项 backtest spawn 时序 flake 单独重跑通过);
  线上 mock 验收: 真实数据发现缺口 → 建议补全 → 确认卡 → 拒绝不触发
2026-09-26 15:09:10 +08:00
shy3130 502b960ab3 feat(assistant): 动作能力 — 生成信号/回测/加自选经用户确认闸门执行
- 新增动作工具: create_signal_strategy(白名单声明式条件落盘信号库+失效缓存链),
  add_to_watchlist(复用 watchlist 服务, 重复标的不重复添加), 既有 run_backtest
  纳入闸门(spawn 子进程重计算)
- 确认闸门 actions.py: 进程内 PendingRegistry(call_id→asyncio.Event),
  action_confirm NDJSON 事件 + POST /actions/{call_id}/decision 决策端点,
  120s 未决策视为拒绝; 拒绝/超时按 ok=False 回填模型, 不重试不打断流
- 前端: 确认卡(风险说明+完整待执行参数+确认/取消按钮), 足迹卡 awaiting 态
  强制展开, 决策后由 tool_result 终态覆盖; client/store 事件与 decideAction
- 系统提示词: 只读边界改为动作工具确认语义与策略生成引导; 快捷指令新增
  帮我生成一个信号
- 测试: 14 项(registry 批准/拒绝/超时/未知id、闸门事件序、写工具往返、
  决策端点 404、摘要); 全套 2422 passed; 线上经 mock 供应商完成
  批准/拒绝/写入三链路与浏览器 UI 点击验收
2026-09-26 14:54:19 +08:00
shy3130 0c096632c1 docs(readme): 开放能力配真实界面截图 — Token 管理(明文一次性弹窗) + 菜单核心/扩展标注
0.3.2 的两个门面此前只有文字没有画面; 现开放能力章节顶部嵌入双图,
截图库同步补录。演示 Token 截图后已吊销。
2026-09-26 14:14:13 +08:00
shy3130 369f04d401 docs(readme): 大改版 — 网关居中的新架构叙事 + 性能前置 + 数字面板
- 头部数字面板: 61 端点 / 6 权限档 / 12 MCP 工具 / 2400+ 测试 / ms 级扫描 / 1 容器 六格大数字
- ⚡ 性能 升为一级章节并前置 (核心功能之后): 拆 '核心引擎' 与 '开放层(0.3.2 新架构)' 两表,
  每行 表现+靠什么, 全部真实口径
- 架构图彻底重画: 旧 '数据→路由→存储→计算→呈现' 纵向流水线 → 新 '消费端双通道 → 开放网关
  (认证/scope/限流/契约) → FastAPI → 核心域三簇(数据底座/计算研究/生产管道, 内嵌增量链路)
  → 扩展域五通道虚线契约消费', 事件总线经 SSE 票据回推网关的完整闭环
- 新增 '核心域/扩展域边界' 表: 8 域 vs 5 通道 + 划线依据 + 页面可替换示例
- 章节重排: 性能/架构前置, 界面预览与 AI 助手后移; 开放能力章节收窄为能力表+十行上手
- 27 个相对链接与 mermaid 结构 (subgraph/end 配对/引号/节点 id) 校验通过
2026-09-26 13:54:44 +08:00
shy3130 b8f56c7457 docs(readme): 重新设计 — 开放能力入列, 新增性能板块, 架构图补开放层
- 头部: 新增 CI / Open API / MCP 徽章, 一句话定位与标签行加入开放能力, 导航补 开放能力+性能 锚点
- 为什么做 TSP: 新增一行 '想做自己的工具只能爬页面 → 开放接口+MCP'
- 核心功能 15 卡 → 18 卡 (补 开放接口 / MCP 服务器 / AI 对话助手)
- 新增 🌐 开放能力 章节: ASCII 架构示意 + Token/六档 scope/61 端点/写闭环/SSE/MCP 能力表
- 架构图: 新增开放层 (MCP 服务器/外部程序 → 开放网关), 应用层补事件总线; 新增核心域/扩展域边界说明
- 关键机制表补 开放网关/事件总线 两行
- 新增 ⚡ 性能 表: 9 个场景的真实表现与支撑机制 (扫描毫秒级/15列存68列现算/增量分区/61端点120rpm O(1)限流/亚秒事件推送/2400+测试CI/新老CPU双内核)
- 路线图: AI助手 转 ✅, 新增 v0.3.2 开放能力版行; 文档表补 open-platform-plan/mcp-server/examples
- 快速开始首跑清单补第 7 步: 开放接口建 Token / MCP 接入
- 全部 28 个相对链接验证存在
2026-09-26 13:48:26 +08:00
shy3130 826eed8cf4 feat(mcp): MCP 服务器 — 开放接口的 AI 工具桥 (Model Context Protocol)
mcp-server/ 独立薄桥包 (MCP SDK 2.x, stdio 传输):
- 12 个精选工具: 标的搜索/日K/指数/市场总览/环境阶段/策略清单与定义/
  告警/扩展表查读写/策略回测 — 按 TSP_SCOPES 声明暴露, 权限裁决仍在
  面板网关 (桥零业务逻辑, 面板升级自动受益)
- 模拟盘交易类端点刻意不包装 (不建议把下单交给 AI)
- smoke_test.py 完整协议冒烟: 握手/tools列表/真实调用; 实测只读 Token
  暴露 10 工具、全量 Token 暴露 12 工具, 三次调用 (搜索/总览/环境) 全通
- README: Claude Desktop 等客户端配置示例; features.md 增 MCP 接入小节
2026-09-26 12:47:08 +08:00
shy3130 d3500b1e76 docs(examples): 示例脚本实测修正 — 演示值按字段语义 / 回测走纯 Polars 引擎 / hello 输出规整
四个示例以真实 Token 完整跑通: 01 行情 / 02 写入+读回 / 03 策略清单+回测 /
04 票据+事件流 (种告警实时收到 4 条 alert)。
- 02: 演示行不再把占位值写进 date/name, 按字段名给合理值
- 03: POST /api/backtest/run 依赖 vectorbt (可选 extra), 改走所有安装自带
  纯 Polars 引擎的 /api/backtest/strategy/run, 近 90 天单标的控制耗时
- 04: hello 帧打印规整
2026-09-26 11:42:22 +08:00
shy3130 f20772d7b7 feat(open-api): 开放能力闭环 — write:ext 数据写入 + SSE 事件流 + 契约守护
二开闭环补齐三块: 数据进得来 (写入)、事件推得出 (SSE)、契约有人守 (快照+CI)。

- write:ext scope (第六档): POST /api/ext-data/{id}/ingest 对 Token 开放,
  复用管理端同一校验/落盘/视图刷新路径; 结构配置/上传/拉取仍不开放,
  外部只能写行数据, 不能改写表结构
- SSE 短期票据 (V2 收尾): POST /api/events/ticket 换 60s 一次性票据 →
  GET /api/events?ticket=… 订阅事件流; 票据只继承 Token scope 不放大权限;
  进程内事件总线 (services/events.py, 慢消费者丢旧保新), 告警落盘点已挂
  (alert_store.append/append_many → bus), 事件按 scope 过滤双向验证
- 契约守护: test_openapi_contract.py 冻结 tier=a 开放面 (61 端点),
  增删须显式更新快照; 新增 ci.yml (后端全量测试 + 前端构建) 把契约
  变化拦在 PR 上
- examples/open-api: 四个零依赖可运行示例 (行情/写入/回测/事件流) + README
- 菜单设置架构标注: 每页核心/扩展徽标 + 悬停原因 + 图例 (按 open-platform-plan
  §2 依赖方向分类, 核心 8 页/扩展 11 页); 顺带补上 MenuSettings 缺失的 模拟盘
- 测试: 网关 write矩阵/票据语义 + 票据生命周期/总线/SSE帧/告警联动 + 契约快照,
  全量 2408 passed / 102s; 线上实测: ingest 200 / 票据一次性 / SSE hello+
  alert 推送 / scope 过滤双向 / 契约 61 路径
2026-09-26 11:31:11 +08:00
shy3130 4c7f7be484 fix(watchdog): stop() 取消死锁 — CancelledError 不得计入探测失败
_loop 的 except BaseException 把 task.cancel() 送来的 CancelledError 当
"探测失败"吞掉并继续循环: 当 cancel 恰好落在 wait_for(to_thread) 内时
(而非轮间的 sleep), 任务永不结束, stop() 的 await self._task 永久挂起 —
生产关闭 (lifespan) 与测试收尾均会死锁, 全量测试偶发卡死 45min+ 的根因。

修复: CancelledError 单独穿透; 新增确定性回归测试 (任务停在探测内时
stop 必须立刻返回)。纯 asyncio 200 次压测复现脚本由必挂转全过。

顺带说明: 本机旧 venv 装的是 polars 1.40/py 慢版本而 lock 早已钉
pytest 9/polars 1.44, fresh clone 同样命中; 现已同步 venv 到 lock 口径,
全量 2395 passed / 96s。
2026-09-26 11:02:46 +08:00
shy3130 559cee7062 chore: uv.lock 同步项目版本 0.3.1 -> 0.3.2
pyproject bump 后未更新 lock, uv run/uv sync --frozen 会因 lock 过期
触发重新解析 (开发机撞镜像 403, CI --frozen 直接失败)。
2026-09-26 10:01:02 +08:00
shy3130 7f628816b9 feat(open-api): 0.3.2 开放能力版 — API Token 网关 + Tier A 契约 + 版本清单
- Token 域模块: tsp_ 前缀 + SHA-256 哈希存储 (0600), 明文仅创建时返回一次,
  吊销立即生效, last_used_at 节流落盘 (≥60s)
- Bearer 网关中间件 (与密码会话并行): 五档 scope 校验 (read:market/read:ext/
  read:analysis/run:backtest/paper:trade) + 滑动窗口限流 (默认 120/min,
  OPEN_API_RATE_LIMIT_PER_MIN 可调) + X-RateLimit 响应头; 管理接口永不对 Token 开放
- GET /api/openapi.json?tier=a 契约视图: 按网关规则表过滤 OpenAPI 规范 (58 路径),
  规则表即唯一契约源
- 设置 → 开放接口: Token 管理 UI (创建表单/scope 说明/明文一次性展示/吊销)
- 设置 → 系统设置 检查更新: 静态链接升级为真实版本对比 (GitHub API 优先,
  latest.json 清单兜底), 发现新版本给下载入口
- release.yml 新增 manifest job: Release 附 latest.json (版本/三平台下载地址/sha256),
  支持分批发布按实际资产生成
- 版本 0.3.1 → 0.3.2 (后端 __init__/pyproject + 前端 package.json)
- docs: features.md 开放接口章节; open-platform-plan.md V1/V2 标记已实现
- 测试: test_api_gateway.py 8 项 (域模块/scope 映射/E2E 401-403-200 矩阵/
  429+Retry-After/吊销即拒), 全量 2394 通过
2026-09-25 22:38:58 +08:00
shy3130 5f39f7dd8d feat(ext-data): 数据出口强化 + 核心开放设计方案 (0.3.2 起点)
- /rows 查询五件套: filter 等值过滤 / sort / offset 分页 /
  start_date+end_date 范围合并 (自动补行级 date 列, diagonal 容忍分区
  schema 漂移), 快照模式范围查询明确 400
- /values 字段取值枚举端点 (filter 下拉配套, 去重+计数降序)
- 市场级表 (market_level): 行=全市场每日一条, 无标的列; 创建/更新 API、
  ingest 与拉取链路放行、创建向导开关跳过标的关联 —— 市场环境类数据
  发布为扩展数据的底座
- 拉取分页协议 (仅 GET): page_param/page_size_param/page_size/max_pages,
  空页/短页判停; 拉取面板新增分页配置输入
- docs: features.md 分页与 /rows 契约章节; open-platform-plan.md
  核心能力开放与插件化改造设计稿 (Token/scope/限流/Tier A/分期路线)
- tests: 22 个新用例 (查询语义/分页判停/市场级全链路/values),
  ext 全量 261 通过
2026-09-25 21:29:23 +08:00