shy3130
|
e737db0c76
|
fix(docker): 放行 scripts/generate_manifest.py 进构建上下文
feat(guard) 提交在 Dockerfile 新增 COPY scripts/generate_manifest.py,
但 .dockerignore 的 scripts 整目录排除规则把该文件挡在构建上下文之外,
导致 docker.yml 双平台构建失败 (CopyIgnoredFile → not found)。
改为 scripts/* + 取反例外, 并修正头注释中"不支持取反语法"的过时说明。
已用仓库真实上下文 + scratch Dockerfile 本地验证三个 COPY 均可用。
|
2026-10-16 16:56:40 +08:00 |
|
shy3130
|
d6f6962909
|
feat(guard): 二次开发升级保护 — 程序文件常备备份/升级对比报告/一键恢复
|
2026-10-16 16:45:03 +08:00 |
|
shy3130
|
be7db8d8b8
|
feat(ui): AI 设置操作卡新增测试连接按钮与内联结果徽章
|
2026-10-16 16:44:54 +08:00 |
|
 intfooandGitHub
|
991cb6768c
|
feat(strategy): 策略参数 UI 元数据(级联显隐 / 分组 / 预设批量应用) (#447)
* feat(strategy): 策略参数 UI 元数据(级联显隐 / 分组 / 预设批量应用)
META["params"] 的 dict 项本就由后端 _normalize_param_item 原样透传额外
key,三个可选 UI 元数据字段零后端改动即可生效,未声明的参数行为不变:
- visible_if: 级联显隐,支持 {param,in} 单条件与 all/any 递归组合;
隐藏仅是显示层过滤,参数值仍按当前值随请求提交(策略语义不受影响)
- group: 相同组名的相邻参数在参数面板归并为一节(带节标题)
- option_applies: select 选中某选项时批量应用一组参数值(如标的池预设)
实现:
- 新增 lib/strategyParams.ts(递归条件求值 + 分组归并,含 vitest 单测)
- 回测页参数面板:分节渲染 + 级联联动 + 命名组内横排布局
- 策略设置弹窗:同样分节 + 级联 + 预设应用
- paramSweep:级联隐藏参数不参与扫描(按持久化默认值判定显隐)
- strategy-guide 双文档补元数据说明
* fix(strategy): 精简指南移除 UI 元数据注释行 — 修复 5000 字符上限测试
* fix(frontend): 参数扫描面板短标签加组名前缀 — paramDisplayLabel
分组内短标签(「止盈」「入池」)脱离分组上下文后不可区分: 扫描面板是
平铺列表, 同名参数挤在一起无法辨认, 级联隐藏提示行同样不可读。
新增 paramDisplayLabel (组名 · 标签), 用于扫描行与隐藏提示;
参数面板本身有组标题不受影响。
|
2026-10-16 14:06:37 +08:00 |
|
 intfooandGitHub
|
d3363b5a10
|
perf(frontend): 策略设置界面渲染优化 — 行级 memo/去 backdrop-filter (#448)
两处策略设置界面在参数较多时交互与滚动掉帧,根因与修法相同:
1. 参数行无差别重渲: 任何参数修改都触发整个界面重渲染。ParamField
(选股页策略设置弹窗) 与 StrategyParamInput (回测页高级策略设置抽屉)
memo 化, onChange 改 (pid, v) 签名 + 父组件 useCallback 稳定回调,
单参数修改只重渲对应行
2. backdrop-filter 拖垮滚动合成路径: 移除选股弹窗面板 backdrop-blur-xl
(背景 95% 不透明, 模糊视觉无感) 与回测抽屉遮罩 backdrop-blur-[1px]
(1px 模糊视觉无感)
3. 选股弹窗 Section 新增 animateCollapse prop (默认 true 行为不变):
内容很高的「策略参数」区跳过 framer-motion height 0→auto 动画
(每帧全量 layout 导致展开卡顿), 直接显隐
无行为/语义变化, 纯渲染性能优化
|
2026-10-16 13:46:48 +08:00 |
|
 yi111andGitHub
|
fbf9c8b767
|
fix(dates): use cn_today() for A-share date defaults across APIs and services (#429)
|
2026-10-16 13:32:26 +08:00 |
|
shy3130
|
4f9af038d8
|
fix(paper): 自动跟单卖出按可卖持仓封顶, 金额超出持仓不再整单被拒 (#462)
# Conflicts:
# backend/app/strategy/paper_auto.py
|
2026-10-16 10:07:31 +08:00 |
|
  
|
b7892e49e2
|
fix(paper): 模拟盘读日线改用 scan_daily_parquet, 容忍分区间 quote_ts 列差异 (#463)
实时行情写入的当日 kline_daily / kline_index_daily 分区带 quote_ts 列, 管道与
历史扩展写入的分区没有。裸 pl.scan_parquet 以首个文件定 schema, 遇到多列即抛
SchemaError 并被吞成 None: 昨收取不到(涨跌停校验失效)、次日开盘/收盘单与盘后
定版拿不到价格、基准收盘缺失。改用仓库既有的 scan_daily_parquet。
Claude-Session: https://claude.ai/code/session_01WydecjgAwEPFurSvKVZCJu
Co-authored-by: zelongji <4558700+zelongji@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
|
2026-10-16 09:45:42 +08:00 |
|
shy3130
|
95e1519994
|
fix(enriched): warmup 世代漂移丢弃后有界重建 GH #480
|
2026-10-16 09:06:04 +08:00 |
|
shy3130
|
d118d3fe99
|
fix(sector): 分钟涨跌幅超物理边界视为脏点剔除 GH #473
|
2026-10-16 09:06:04 +08:00 |
|
shy3130
|
df2da2dc8a
|
fix(ext): 两级拉取 429 限流感知退避 + 失败补拉轮
429 改等配额窗口(30s+抖动)再重试; 主轮后对失败条目补拉最多 3 轮,
持续限流则记 warning 跳过, 稍后重执行即整体重试。
|
2026-10-15 16:25:26 +08:00 |
|
shy3130
|
1c2e4db980
|
Update
|
2026-10-15 16:10:20 +08:00 |
|
 
|
67ee83fba9
|
fix(数据源): 支持自定义五挡盘口路由 (#479)
Co-authored-by: shy3130 <415333856@qq.com>
|
2026-10-15 15:45:39 +08:00 |
|
shy3130
|
99efc808e8
|
docs: 补 v0.3.7 版本表与二开指南
二开指南补去内置化/叠加条件/string 参数; 安全校验描述同步 #475 后口径。
|
2026-10-15 12:27:59 +08:00 |
|
shy3130
|
72e97cc790
|
fix(ui): 端点测速应用按钮打开即显示
不再要求测速成功才出现, 测速期间保持可点击。
|
2026-10-15 12:27:59 +08:00 |
|
shy3130
|
a292f7bc58
|
feat(migrate): 内置策略按 ID 种入 custom — 修复升级丢失 25 个策略
启动时按文件名补缺, 不覆盖已有, 标记防复活; 桌面打包 datas 落盘,
前端迁移 toast 同步提示。
|
2026-10-15 12:27:59 +08:00 |
|
shy3130
|
db300cad45
|
refactor(ui): 页面包更名为页面插件
消除断句歧义, 与数据源插件命名对齐; 仅改文案, 代码层标识不动。
|
2026-10-15 12:27:59 +08:00 |
|
 intfooandGitHub
|
2a1c076831
|
fix(frontend): AI 未配置提示跳转链接改用 BASE_URL,兼容子路径部署 (#476)
* fix(frontend): AI 未配置提示链接改用 BASE_URL,兼容子路径部署
CustomSignalDialog 的 <a href="/settings?tab=ai"> 硬编码根路径,
部署在子路径(vite base ≠ /,如反向代理挂载子目录)时点击会落到
站点根被兜底 404;改为模板字符串拼 import.meta.env.BASE_URL,
根部署(BASE_URL=/)行为完全不变。
验证: pnpm build (tsc -b && vite build) 通过。
* fix(frontend): 三处 AI 未配置跳转改用 BASE_URL,兼容子路径部署
StockAnalysisDialog / AiAnalysisDialog / StrategyBuilderDialog 的
window.location.href = '/settings?tab=ai' 同样硬编码根路径,子路径
部署下 404;统一改为 import.meta.env.BASE_URL 拼接,根部署行为不变。
验证: pnpm build (tsc -b && vite build) 通过。
|
2026-10-14 19:11:25 +08:00 |
|
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
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
v0.3.6
|
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 |
|
 zelongjiandClaude Opus 5.5
|
a900230ba0
|
fix(paper): 自动跟单卖出按可卖持仓封顶, 金额换算超出持仓时不再整单被拒
卖出规则的仓位只能按金额/权益换算股数, 与实际持仓对不上: 换算多了
create_order 以「可卖数量不足」整单拒绝, 换算少了只卖一部分, 无法表达清仓。
自动卖出以可卖数量(扣除已挂 pending 卖单)为上限; 可卖/挂单口径抽成
paper.sell_capacity, 与 create_order 的校验共用。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WydecjgAwEPFurSvKVZCJu
|
2026-10-12 15:56:05 +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 例全部通过。
v0.3.5
|
2026-10-08 13:27:10 +08:00 |
|
 
|
3fd1f6f95a
|
chore(lint): ruff 忽略中文全角标点 + 启用 BLE(移植本机 f67d9ed 的 lint 配置;⛔ 不含业务代码) (#456)
问题:
本仓 [tool.ruff.lint] 的 select 含 "RUF" 但未忽略 RUF001/002/003,而注释/文档字符串通篇中文
⇒ `ruff check backend/app` 实测 **1420 条**,其中 RUF001/2/3(全角标点)占 **815 条(57.4%)**;
另有 **271 处** `# noqa: BLE001`(禁止裸 except)因 `BLE` 未启用而**全是"无效指令"**(RUF100 293 条)
⇒ 「禁止裸 except」这条规则**从来没有被真正强制过**。
⚠️ 且本仓 CI 不跑 ruff(ci.yml 只有 `uv run pytest tests -q`)⇒ 这条门禁一直没人守。
改动(仅 backend/pyproject.toml 的 [tool.ruff.lint] 一段;⛔ 无任何业务代码改动):
- ignore 增加 RUF001/002/003 —— 理由:全角标点是中文书写的正常形态,不是笔误
- select 增加 BLE(flake8-blind-except)⇒ 271 处既有 noqa 立即生效
- ⚠️ 文字与理由照抄本机 f67d9ed 的原注释,但**注释里的数字一律按本仓实测重写**
(本机数字 1442/801/642/518/291 与本仓实测 1420/815/611/594/271 **不同**,⛔ 不照抄)
- ⛔ 不跑 `--add-noqa` 批量承认(那会改上百个业务文件,与在途改动冲突)
验证(隔离 worktree,基于 origin/main 30fcade;ruff 0.15.14):
- **P2/P3 逐规则对账 1420 → 594(净 −826)**:
BLE001 0→236(+236) · RUF001 189→0(−189) · RUF002 403→0(−403) · RUF003 223→0(−223)
· RUF100 293→46(−247)
⭐ **出现正增量的规则只有 BLE001**,其余规则全部不变或减少(⛔ 不是"看总数下降就算过")
- **P5 配置语义(可 FAIL 的差集断言)**:用 tomllib 解析 `origin/main` 版与本版 ⇒
line-length/target-version 逐字不变;select 差集**恰为** {BLE}、ignore 差集**恰为**
{RUF001,RUF002,RUF003},两侧**无任何删除**。核验脚本:
research/oneshot/_verify_ruff_config_port_20261005.py(判别力 = 差集不等即 FAIL)
- P4 改动面:`git diff --stat` = 1 file;`git diff --check` rc=0
- P6 辅助:`pytest tests/test_regime_builder.py -q` ⇒ **22 passed**(配置改动不影响测试)
- ⚠️ 本件**没有回归测试可守**(纯配置改动):靠上面的数值/差集对账,⛔ 不假装有单测
影响与取舍(⛔ 不粉饰):
`ruff check backend/app` 从 1420 条降到 594 条 ⇒ 噪声大减、门禁**变得可执行**;
但启用 BLE 会**显形 236 条**既有「尚未表态的 `except Exception`」(本机对应 166 条)——
这是**暴露既有沉默违规**,不是本次新引入的错误;是否进一步 `--add-noqa` 批量承认,
留给维护者决定(本提交不替上游表态)。
⛔ CI 无 ruff 步骤 ⇒ 本改动**不会打断 CI**,同样也**不会自动守住** lint。
兼容/回滚:
纯 lint 配置,无 schema/数据/接口影响;`git revert` 即可回滚(不影响任何历史产物)。
说明:本提交在基于 origin/main(30fcade) 的隔离 worktree 内完成,本机主线工作树未被改动;
⛔ 未推送;⛔ 与 port/regime-isfinite-guard(_score 防护)**是两个独立分支/提交**。
Co-authored-by: JackChan83 <JackChan83@users.noreply.github.com>
|
2026-10-08 13:08:52 +08:00 |
|
 
|
9f065dd3dd
|
test(quote): 补 boot_check() 启动决策与可观测性回归测试(4 分支 + 1 xfail) (#457)
背景(本机实测事故 2026-09-16):面板 08:58 起,直到用户 09:35:33 手动开启才有行情
⇒ 开盘后 6 分钟实时评估全空。根因 = 旧版 `stop()` 把 `realtime_quotes_enabled` 写成 False
(lifespan shutdown 也调 `stop`)⇒ 次日 `boot_check()` 读到 False 就**静默不启动**,
且**一行日志都不打** ⇒ 排查只能靠排除法。
⭐ 为什么只补 `boot_check`(而不是把本机整套测试原样搬来):
· 根因那一半上游**已有**测试:`tests/test_realtime_preference_persistence.py` 断言
「`stop()` 不写偏好 / `disable()` 才写 False」—— 与本机那份同向 ⇒ ⛔ 本提交**不重复造**
· `boot_check()` 本身上游**没有任何测试**(`test_data_integrity.py:537` 那个同名 `boot_check`
是**数据修复**用的,⛔ 不是本函数)⇒ 缺口正是「**启动决策** + **有没有留下痕迹**」
新增 `tests/test_quote_service_boot_check.py`(**4 例 + 1 xfail**):
1. 偏好开 + 档位允许 ⇒ **必须** `start()`(⭐ 反向对照:防守卫写成"永远不启动")
2. 偏好关 + 档位允许 ⇒ **不得** `start()`
3. 档位 none ⇒ 不得 `start()` **且必须留日志**(含「未启动」)
4. 档位 none + 偏好为开 ⇒ 必须把偏好**同步写 False**(防 UI 误显示"已开启")
5. ⚠️ `xfail(strict=True)`:偏好关 + 档位允许时**期望**留日志;上游该分支当前**仍静默**
⇒ 用它编码**期望行为**:上游修好那天会 XPASS ⇒ strict 让它 FAIL 以提示更新测试
(⛔ 本提交**不改被测代码**;若维护者不接受这种用法,删掉这一例即可,其余 4 例完全独立)
验证(隔离 worktree,基于 `origin/main` 30fcade):
· **P1** 新文件 ⇒ `4 passed, 1 xfailed`
· ⭐ **P2 判别力**(4 个**单变量**变异,每个都**只**让对应用例 FAIL,且源码**逐字节还原**):
M1 删 tier-none 的 `logger.info` ⇒ `test_logs_and_does_not_start_when_tier_disallows` FAIL
M2 删 tier-none 的 `_save_enabled(False)` ⇒ `test_demotes_preference_when_tier_disallows` FAIL
M3 `boot_check` 永不 `start` ⇒ `test_starts_when_preference_enabled` FAIL
M4 `boot_check` 无条件 `start` ⇒ `test_does_not_start_when_preference_disabled` FAIL
· **P3** 零回归:`tests/test_realtime_preference_persistence.py` + `tests/test_realtime_mode.py`
⇒ **5 passed**(与改动前一致)
· **P4** 改动面:分支相对 `origin/main` **只新增 1 个文件**;工作树干净;`git diff --check` rc=0
· **P5** `ruff check tests/test_quote_service_boot_check.py` ⇒ **All checks passed**
⚠️ **自曝(当轮修,留痕)**:初版把**中文全角标点**写进 docstring ⇒ 上游当前 ruff 配置
(未忽略 RUF00x)报 **43 条 RUF002**。实测上游 `tests/` 的惯例是 **ASCII 标点**
(288 个文件里 **271 个**无 RUF00x 告警)⇒ 已把文档串/注释改为 ASCII 标点、强调引号改用「」
⇒ 复测 **0 告警**。⚠️ 这与「上游应否忽略 RUF00x」是**两个问题**:本文件按**现状惯例**写,
⛔ 不依赖任何"改 lint 配置"的提交。
⚠️ 边界(⛔ 不含糊):`start` 被 monkeypatch 成**记录器** ⇒ 验的是「**决策**」,
⛔ 不能据此说"实时行情真能跑";日志断言用**子串**匹配(含「未启动」)⇒ 上游改文案会 FAIL
—— 这是**故意**的:那行日志正是本事故的**可观测性承诺**。
⛔ 未推送。回滚 = `worktree remove` + `branch -D`。
(由 DSH agent 在用户授权下完成。)
Co-authored-by: JackChan83 <JackChan83@users.noreply.github.com>
|
2026-10-08 13:08:47 +08:00 |
|
 
|
e15fff13c1
|
fix(regime): _score 对非有限输入取中性 50(上游缺此防护,移植本机 f67d9ed 的防护) (#455)
问题(本机 2026-09-15 实测事故;上游同名表达式逐字相同):
停牌股补零 ⇒ change_pct = close / prev_close - 1 = inf ⇒ 当日 avg_pct 被单个 inf 污染
⇒ _score 里 round((value - low) / (high - low) * 100) 抛
OverflowError: cannot convert float infinity to integer
—— round 是**最内层**调用,在 min/max 钳制**之前**求值,钳制救不了它
⇒ compute_regime 整段中止、regime_history 停更。上游原先没有覆盖该路径的测试。
改动(三处逐字副本,+15 行,无 schema 变更、无数据迁移):
- app/services/regime_builder.py:新增 `import math` + `_score` 非有限值取中性 50.0
- app/services/market_overview_builder.py:同款防护(math 已在 import 中)
- app/api/overview.py:同款防护(math 已在 import 中)
- tests/test_regime_score_non_finite.py:新增 3 例(_score 单元 / classify_state / _aggregate_daily 端到端)
取 50 = 「该维度不可计算」:既不崩,也不把 inf 钳成 100(那等于伪造「极度看多」)。
验证(P1 先红后绿;全部在 origin/main 隔离 worktree 内执行):
- P1 红:**未改代码**上 pytest tests/test_regime_score_non_finite.py → 3 failed,
报错与生产逐字一致(OverflowError: cannot convert float infinity to integer)
- P2 绿:修后同命令 → 3 passed
- P3 行为:三处 `_score(nan / inf / -inf, -1.2, 1.3)` 全部 = 50;
常规值 `_score(0.5, -1.2, 1.3)` 三处仍 = 68.0 ⇒ 正常口径未漂移
- P4 基线:tests/test_regime_builder.py → 22 passed(与改动前一致)
- P5 lint:ruff 三个改动文件 + 新测试 → 有改动 24 / stash 回上游原状 24 ⇒ **0 新增**;
`git diff --check` rc=0
- P6 相关回归:引用这三个模块的既有 5 个测试文件 → 35 passed
- P7 逐字一致:三处 hunk 与本机 f67d9ed 的同名 hunk 完全相同(仅行号因上游位移);
新增测试与本机 f67d9ed 版仅差 docstring 中一句(见下「边界」)
边界(本移植**未**包含):
本机同批修复里「上游 `change_pct` 对非正前收取 NULL」(`ratio_over_positive`,
app/indicators/pipeline.py)及 tests/test_pipeline_price_ratio.py 未移植
⇒ 本件只堵「坏值已产生后不崩」,**不堵「坏值的产生」**。
⚠️ 自动测试通过 ≠ 上游真实数据上不会再出现非有限值 ⇒ 仍需**上游真实运行**验证;
本提交是把本机已验证的防护**预置**过去,不是对上游线上事故的结论。
影响与回滚:
仅改计算口径(非有限输入的去向),无 API 形状 / schema / 数据迁移变更,历史 Parquet 不受影响。
`git revert <sha>` 即可回滚。
本提交在基于 origin/main(30fcade) 的隔离 worktree 内完成,本机主线工作树未被改动(status 为空)。
Co-authored-by: JackChan83 <JackChan83@users.noreply.github.com>
|
2026-10-08 13:08:41 +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 |
|