Commit Graph
115 Commits
Author SHA1 Message Date
shy3130 316ae2954a feat(backtest): 增加未来数据检查与数据版本追溯
Signed-off-by: shy3130 <shy3130@qq.com>
2026-11-01 17:20:55 +08:00
shy3130 762e04ab88 feat(data-sources): 支持外部插件安装与版本管理
Signed-off-by: shy3130 <shy3130@qq.com>
2026-11-01 10:47:19 +08:00
shy3130 c63ee7648c refactor(resources): 清理导入导出残留并合并包处理逻辑
移除无调用的前端策略包接口封装和类型,将依赖收集、ZIP 打包与安全检查、资源预检统一到 resource_bundle,strategy_bundle 仅保留兼容入口。

保留旧包和旧接口的逐文件导入语义,以及当前资源导入的整批预检和回滚;补充新旧导出格式互通、本机依赖解析、逐文件失败报告和 ZIP 安全回归测试。

验证:相关后端回归 106 项、后端完整测试 3726 项、前端测试 389 项通过;前端构建、Ruff 与 git diff --check 通过。

Signed-off-by: shy3130 <shy3130@qq.com>
2026-10-30 22:29:44 +08:00
shy3130 5a4702edcb fix(tdxquant): 修复分钟同步时区与失败状态
在 SDK 清理响应前保留并脱敏服务端错误,明确的鉴权拒绝立即停止请求并触发熔断。历史分钟同步显式传递数据源失败,避免任务显示成功但落盘为零行。

将带时区的请求窗口归一为北京墙钟,补充鉴权、任务失败、UTC/北京时间窗口及 Parquet 落盘回归测试,并更新插件契约文档。

Signed-off-by: shy3130 <shy3130@qq.com>
2026-10-30 22:29:34 +08:00
shy3130 8fb23fcf09 feat(data): 新增日K自检、精准修补及数据版本管理
- 数据页提供股票、ETF、指数历史日K自检与报告,区分已确认异常和待核实缺口
- 按异常股票和日期暂存校验、备份并修补,使用完整原始历史重算受影响指标
- 跨重启保留异常与待重算状态,失败或取消后可继续处理
- 修补完成后更新行情、指标、矩阵、策略和前端查询缓存,重算市场环境与主线
- 对已知异常阻止相关计算,提示历史回测和优化结果的数据版本过期
- 复用插件日K取数,修正 ETF 历史回补起点及任务阶段进度重置

补充自检 API、精准修补、失败恢复、资产隔离、缓存失效及前端交互测试。
前端全量 389 项及构建通过,后端执行完整回归。

Signed-off-by: shy3130 <shy3130@qq.com>
2026-10-30 20:42:48 +08:00
shy3130 ea24378033 feat(resources): 完善资源传输兼容性与策略池交互
- 策略、因子与信号页各使用一个小盒子入口,在当前页面预览并导入导出
- 支持多选 ZIP 批量导出,自动携带因子、信号、调参与策略辅助代码
- 保留单文件导入并兼容无清单 ZIP、外层分享目录及 macOS 附加文件
- 预检依赖与同 ID 冲突,按选择计算依赖闭包,写入失败整批回滚
- 修正矩阵原生策略生成信号被误判为外部依赖的问题
- 重排策略池布局,支持搜索、来源/周期筛选、排序和撤销清空
- 单策略导出入口收纳到配置对话框顶部,支持旧排名策略导入路径

验证:资源传输/策略包/配置备份 95 项后端测试通过;前端全量 389 项及构建通过。
两个真实 25 策略 ZIP 已在隔离目录验证识别、导入、加载和再次导出。

Signed-off-by: shy3130 <shy3130@qq.com>
2026-10-30 20:42:27 +08:00
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
shy3130 4d42fc6b14 docs: 补充策略包/仓位策略/模拟盘绑定即评估的能力说明 2026-10-27 18:45:27 +08:00
shy3130 5909155fb1 feat(ext): 盘中多盘表增量续传 — pull.since_param 游标免全量重拉
拉取前读本地目标日分区 time_field 列最大值, 以 ?{since_param}={值} 附到
请求, 源只返回新于本地的盘次; 缺口感知天然成立 (本地缺多少源补多少)。
未配置/首拉/分区缺失/schema 漂移/文件损坏一律不带参数回退整日全量,
回退方向永远安全; 历史回补与 fanout 两级拉取不注入游标。

- PullConfig 归一: 未配置 time_field 时 since_param 失效
- 分页拉取每页携带 since 过滤器
- API since_param 参数名合法性校验
- 前端拉取面板/统计卡片与 features.md 同步
2026-10-26 22:10:39 +08:00
shy3130 c932098ae7 docs(ext-architecture): P4 交付记录补齐前端消费面 (选择器/定义目录页签/导入冒烟展示)
Signed-off-by: shy3130 <shy3130@qq.com>
2026-10-26 15:56:02 +08:00
shy3130 f3c30b728b feat(definitions): P4 统一定义目录 + 导入即冒烟 — 导入到可回测全链 <2s, P0-P4 收官
「一切皆扩展」的消费面与验收闭环:

- GET /api/definitions: 跨 kind (signal/factor) 统一目录视图 (label/lang/
  依赖/warmup/状态) — 统一选择器的数据半边; 单个坏定义不阻断目录 (隔离)。
- POST /api/definitions/smoke: 导入冒烟 (静态层) — validate → 编译 → 依赖
  可解析性 (enriched/指标/注册表因子/扩展字段的并集判据, 拼错列名 W001
  当场报出)。信号编译告警经日志捕获转为 issue, 不静默。
- 备份导入内置冒烟: apply_archive 对每个导入的信号/因子落盘后立刻冒烟,
  结果随响应返回 (smoke 字段); 冒烟自身异常不阻断导入 (fail-open)。
- 验收 (docs/ext-architecture-plan.md P4 ≤2 分钟): 自动化全链测试 —
  构建含新信号+新因子的备份 ZIP → apply (冒烟 ok) → 立即用引用该信号的
  策略跑回测成功, 全程 <2s。
- 前端选择器组件/参数表单自动渲染属前端后续工作, 数据与 API 契约已就绪。
- 回归: config_backup/definitions/factor 67 测试全过; ruff 新增文件全清
  (main.py/config_backup 存量告警与 HEAD 逐条一致)。

Signed-off-by: shy3130 <shy3130@qq.com>
2026-10-26 14:59:52 +08:00
shy3130 0f12836401 feat(factors): P3 T2 表达式级 Python — SKDJ 类口径零 DSL 可表达
自定义因子新增第二档编写语言 (lang=python): 受限 Python 表达式块,
只返回单个 Polars 表达式。三档编译层就此齐备: T1 DSL < T2 表达式级
Python < T3 自由 Python 策略。

- app/factors/py_expr.py: AST 白名单文法 (仅赋值/表达式语句; 名字限
  ctx/pl 与已赋值局部量; 禁 import/def/lambda/循环/推导式/下划线属性/
  map_*/apply/IO 类调用) + {ctx, pl} + 空 builtins 求值; ctx.col 构造期
  登记依赖 (无需推导); warmup 从窗口常量保守求和 (显式声明只能增大,
  少算失真是错误方向)。
- 贯通链路: FactorSpec.lang (默认 dsl, 存量零影响) → to_spec 编译分支 →
  materialize 按 lang 分发 (T2 结果同样进 P2b 内容寻址缓存, 依赖即缓存键
  输入) → API /validate 与 /trial 支持 lang=python。
- 验收 (docs/ext-architecture-plan.md P3): 看板口径 SKDJ — 9日RSV
  (分母 0 时取 50) → EMA(α=0.5) 两级 — 的 T2 单表达式与策略文件的分阶段
  列实现逐元素一致; 19 个契约测试 (含依赖登记/warmup 下限/11 种文法拒绝
  形态/物化与缓存贯通), 相关回归 568 全过, ruff 新增文件全清。

Signed-off-by: shy3130 <shy3130@qq.com>
2026-10-26 14:46:42 +08:00
shy3130 6d51bb52de feat(factors): P2b 内容寻址因子列缓存 — +10 因子热路径增量 0.1ms, P2 两项验收达成
自定义 (DSL) 因子此前每次求值都全量重算 frame_transform (132 万行帧上
每因子 ~36ms, 随因子数线性增长 — 回测/守护复验/实验室批量的共同热路径)。

- app/factors/materialize_cache.py: 键 = sha256(定义 + 依赖列内容指纹 +
  行数) — 内容指纹即失效传播 (公式变/输入任何值变 → 键变), 无需数据版本
  号。两层: 进程内 LRU (字节上限) + 磁盘 parquet (跨进程, 文件数上限,
  目录可整删)。fail-open: 任何故障回退现算。列指纹按帧记忆化 (weakref
  finalize 回收), 同帧 K 个因子每列只哈希一次 (~8ms/百万行)。
- materialize_scoring_columns 两段式: 命中列一次批量附着 (成本与因子数
  无关); 未命中逐个现算 (依赖顺序)。DSL 分阶段临时列不再泄漏进下游帧
  (与命中路径列集合完全一致)。
- 顺带修复存量 bug: winsorize(x) 省略 k 时 DSL 编译器直接 IndexError
  (该写法此前完全不可用), 补回归测试。
- 基准 (132 万行, K3→K13): 热路径 0.0ms→0.1ms (+10 因子绝对增量 0.1ms,
  基线 +400ms 线性); 冷启动 480.7ms vs 无缓存 478ms (开销 ~0.5%)。
  端到端优化器复测 trials 4.23×/含 prepare 3.16×, stats 完全一致。
- 回归: 552 个相关测试全过 (含 6 个缓存契约测试: 命中等价/输入与定义
  变更失效/损坏回退/小帧旁路/临时列不泄漏); ruff 新增文件全清。

Signed-off-by: shy3130 <shy3130@qq.com>
2026-10-26 14:36:58 +08:00
shy3130 583462a704 feat(backtest): P2a-2 共享矩阵编码 — 参数无关半边一次编码, 调参循环 3.14×
build_market_matrix 内部的参数无关成本 (build_market_data_matrix 行情
矩阵 + _encode_axes 轴 + _signal_code_matrix 信号码, 占剩余每组成本
~55%) 拆出复用:

- matrix.py 新增 PanelMatrixEncoding / encode_panel_matrix /
  build_market_matrix_from_encoding; build_market_matrix 改为两者的组合
  (单一实现, 无平行路径)。score 场随参数变化 (universe 置空), 不进共享
  编码 — 逐组散布进信号矩阵, 非有限值→nan 语义与 _float_matrix 一致。
- PreparedPanelBacktest.sim_encoding: prepare 期构建 sim 窗口编码 (失败
  回退逐组建矩阵, 只损失性能); run 侧列序 (忽略 score 列) 与行数比对
  通过才走共享编码, 否则整建 — 回退是优化放弃, 不是正确性闸门。
- 基准 (同进程交错 A/B, 15 组): 试算 4.24×, 含 prepare 3.14× (P2a 单
  面板共享为 1.8×); stats 剔除计时字段后完全一致。对应 P2 验收 ≥2×。
- 回归: tests/backtest 410 全过 (含新增矩阵级逐元素等价测试); ruff
  零新增 (与 HEAD 逐条相同)。

Signed-off-by: shy3130 <shy3130@qq.com>
2026-10-26 14:27:37 +08:00
shy3130 e382232243 feat(definitions): 统一定义契约 P1b — Store 基类收口四处持久化 + kind 注册分发
- app/definitions.py 新增 JsonDefinitionStore: 原子写 + 损坏跳过告警 +
  目录 mtime 签名, glob/日志名/逐条归一化参数化; 自定义信号/自定义因子/
  监控规则/批次四处同型实现收口为委托, 公开签名零变化。
- DefinitionKind 注册表 + validate_definition / definition_dependencies
  统一分发入口; 内置 kind (signal/factor) 惰性导入, 消费方无需预导入领域
  模块。signal 依赖提取复用编译表达式 root_names (与回测/管线同源),
  factor 复用 to_spec DSL 编译 — 不引入第二套提取逻辑。
- 验收: 新增第三种 kind = 注册一个描述器即走同一存取/校验/依赖管线
  (test_new_kind_reuses_same_pipeline), 对应路线图 P1b 验收标准。
- 契约视图归一化渲染留给 P4 消费方; 失效广播/文件锁随 P2 叠加。

Signed-off-by: shy3130 <shy3130@qq.com>
2026-10-26 14:02:54 +08:00
shy3130 e9b938a3ac docs(arch): 一切皆扩展架构优化路线 (P0-P4) — 分层物化/统一契约/依赖推导
Signed-off-by: shy3130 <shy3130@qq.com>
2026-10-26 13:39:39 +08:00
shy3130 b573ca43eb feat(mining): 挖掘锁撞锁降级启动 + 持有者诊断 + 一键强制释放
复现的原始问题: 旧实例挂死在 shutdown (热重载撞上挖掘运行) 或 worker
成为孤儿后, `.mining_process.lock` 被无限期占用, 后续所有后端实例
在 lifespan 抢锁时直接启动失败, 用户只能对着笼统报错手动找进程。

- 锁文件记录持有者 {pid, started_at, role, host} (flock 仍是唯一
  事实, 内容只是诊断线索; 旧格式 "0" 兼容, 视为持有者未知);
  新增非阻塞探测, 无需抢锁即可判断是否被持有。
- 撞锁降级启动: lifespan 抢锁失败不再上抛, 面板照常可用; 挖掘
  启动入口 (手动/自动/周度调度) 返回 409 并指引到挖掘页; 桌面版
  预检从「秒退失败页」改为留日志继续启动; 守护复验不受影响。
- 挖掘页锁占用横幅: 显示持有者 pid/角色/挖掘存储静默时长; 满足
  陈旧判定时可一键「强制停止并接管」(SIGTERM→SIGKILL→当前后端
  获取锁, 挖掘入口立即恢复)。
- 陈旧判定全部 fail-closed: 持有者信息可读、进程存活且 pid 未被
  复用 (POSIX 比对进程实际启动时间)、无进行中的挖掘运行、挖掘
  存储 10 分钟内无写入 — 任一不满足即拒绝并给出原因。不做启动
  时自动清理, 终止进程必须人工确认。

测试: 新增 test_mining_lock_admin (含真实外部持锁进程的强停回路与
五类拒绝路径), 重写 lifespan 降级契约与桌面预检继续启动契约;
后端全量 3239 通过, 前端 308 通过, ruff 零新增; 沙盒 E2E 完整
复刻「持锁→降级→强停→接管→恢复」事故场景通过。

Signed-off-by: shy3130 <shy3130@qq.com>
2026-10-26 00:01:20 +08:00
shy3130 21279ecfa2 feat(lab): 自动策略实验室 — 守护复验 + 稳健选冠/权重精调 + 组合建议 + 闭环编排
在既有挖掘链路之上补齐「发布后持续验证与持续组合」闭环
(设计: docs/auto-strategy-lab-plan.md):

- P1 策略守护: 挖掘发布自动落 mining_gate 基线 (天然 OOS); 每日收盘
  数据更新后在新数据上切 K 段真实回测复验, 按稳健分对比基线判定
  健康/观察/退役三态 (段回测失败只降级观察不退役; 新数据 <30 交易日
  跳过本轮; retired 不再自动复验)。任意策略可手动入护 (尾随参考基线,
  判定只针对入护后新数据)。回测页稳健性验证新增「策略守护」子页。
- P2a 稳健选冠: 冠军排序分从外层折 Sharpe 均值改为 0.6×中位+0.4×最差
  (复用 robust_score); artifact 新增可选列 oos_worst_sharpe (v2 旧档
  兼容读取); strict 档发布额外要求最差折 Sharpe>0; 算法版本升
  mining-v3 并进数据指纹, 防止升级后 claim 幂等复用旧口径结果。
- P2b 权重精调: 冠军组合在 {0.5,1.0,1.5,2.0} 比率网格 (首因子固定
  1.0, 截面分位打分天然尺度不变) 两段式精调 — 外层测试窗选优 + 全窗
  复验退化>20% 放弃; 消耗 run 剩余预算 (不足自动跳过); 产物为独立
  签名候选行, run summary 带 refinement 摘要。
- P2d 组合建议: 守护运行时扫描健康冠军间近 126 个交易日日收益 Pearson
  相关性 (≥30 共同交易日, ≤0.7 入选); 前端人工确认后生成等权
  composite 策略 (fail-closed 建议对校验 + blake2b 幂等) 并自动以
  尾随参考基线入护。
- P3 闭环编排: lab_mined_slot_limit 偏好 (默认 10, 0=不限) 在发布
  门槛通过后校验, 名额满则新冠军停在 pending 等位;
  /api/backtest/lab/report 聚合守护/挖掘/名额战报 (前端总览卡);
  lab_schedule 单入口编排周度挖掘 + 日度守护 (失败互不阻断)。

测试: 新增 guardian 判定/运行时/存储/调度/API/组合与挖掘 v3 选冠/
精调用例; 后端全量 3224 通过, 前端 308 通过; 真实数据沙盒 E2E
(挖掘 v3 全链路 / 发布门槛 / 名额边界 / 复验语义 / 组合扫描 /
战报核对 / 性能延迟) 通过。P2c (overlay 候选) 按设计稿按需启动,
默认不做。

Signed-off-by: shy3130 <shy3130@qq.com>
2026-10-25 23:43:34 +08:00
shy3130 62c8a8bd56 fix(backtest): 矩阵回测接入扩展时序数据
扩展数值列按设计不落 enriched parquet (只存 14 列), 此前矩阵回测引用
ext_* 字段直接报 fields unavailable — 叠加条件/评分引用扩展数据的策略
无法回测, 扩展数据失去回测意义。

修复: 引擎在矩阵加载后按矩阵自身 (日期×标的) 骨架现场注入时序模式数值
扩展字段 (attach_matrix_ext_fields, 与策略页帧路径同一台 PIT 安全 join,
缺失补空值=条件不命中), 与财务因子 attach 同构; parquet 矩阵缓存不受
影响。快照模式与字符串扩展字段仍拒绝 (快照回看历史=未来函数), 引用时
前置校验给出明确报错。

实测: 隔夜溢价精选·迭代优化 + 人气排名 20~100 叠加条件, 回测 1.1s 跑通,
交易数 29→22 证明过滤真实生效; 新增 7 个单测 (对齐/NaN/拦截/叠加联动/
端到端正反例), 全量回归 3131 通过。

Signed-off-by: shy3130 <shy3130@qq.com>
2026-10-25 20:14:17 +08:00
shy3130 da9dbca422 feat(backtest): 稳健参数筛选与滚动样本外检验重构 (P1-P4)
参数排名从单窗样本内得分改为 K 段折外稳健分 R = 0.6×中位 + 0.4×最差
(设计: docs/robust-optimizer-plan.md), 四阶段全部落地:

- guards 共享护栏: 主目标白名单 + 最小交易数门槛 (fail-closed, 缺交易数
  按不达标处理), 两模式一处实现
- robust_optimizer: 等分切窗 (2-6 段, 每段≥14天) / 稳健分 / 冠军收敛诊断
  (unanimous/majority/scattered) / Top-20 全窗 IS 细化与退化率 /
  高原判据 (邻域得分衰减, 零额外回测); worker 接线 robust_optimize 任务
- 滚动样本外检验补强: 每折 OOS 最小交易数门槛 (无效折透明跳过),
  前端折预览 / 参数漂移轨迹 / 采用最新折参数
- 前端: 冠军卡 (收敛/高原徽章/乐观偏差) + K 段排名表 + 验证窗预览 +
  应用参数闭环 (POST /strategies/config, 可逆); SSE 重连与跨设备接回
- P4 摒弃旧路径: 删 /optimize/stream 与 /optimize/cancel 端点及 worker
  optimize 任务类型; 白名单全面生效 (optimizer.VALID_OBJECTIVES 收敛到
  guards; walkforward 端点校验退化目标 400)
- 附带修复: 叠加条件×矩阵路径 SignalMatrix 只读违规 (np.where 产物
  可写), optimizer_trial 轻量统计恒保留 n_trades

实测: 126 组合全市场网格 1.71× 旧版耗时 (视图复用优化自 2.01×; 差额
为引擎层每 run 固定开销, 详见方案文档第九节); 全量回归 3131 通过。

api.ts 同时带入稳健优化折预览客户端与声效语音包 API 客户端
(语音包功能随后续提交落地界面)。

Signed-off-by: shy3130 <shy3130@qq.com>
2026-10-25 20:14:10 +08:00
shy3130 ddaab1fbf1 fix(minute): 全量分钟服务落盘持仓库写锁 + 原子写临时名唯一化 + 基准状态暴露
- minute_refresh 落盘改持 repo._write_lock: 与 minute-batch 补拉/盘后同步
  同一纪律。此前服务是唯一不持锁的写者, 并发替换同一分区时后写者以过期
  基底覆盖丢整批行, 且共用固定名 tmp 会交错损坏且无自愈。实测增量轮落盘
  ~10ms, 锁占用可忽略
- _atomic_write_parquet 临时名加 uuid 后缀: 消除两写者共用同一 tmp 的
  交错损坏窗口; 崩溃孤儿 tmp 不匹配 *.parquet glob
- 服务每轮记录本地库 raw 基准状态 (status 新增 minute_basis_raw 字段),
  未迁移库一次性警告不刷屏; 插件契约文档补"full_minute 必须返回原始价"条款
- 修正头注释 clamp 漂移 ([3,300]→[3,120])

Signed-off-by: shy3130 <shy3130@qq.com>
2026-10-25 17:31:05 +08:00
shy3130 6e1c178c24 docs(deploy): 补充 host.docker.internal 访问与 data 挂载保护说明 2026-10-22 21:51:09 +08:00
shy3130 01257c83ee feat(pages): 设置三页合一为「页面管理」+ 源码扩展删除/URL 嵌入页/源码导入
- 菜单设置/扩展页面/页面插件三个设置 tab 合并为「页面管理」(?tab=pages, 旧链接与 /analysis 重定向兼容)
- 源码扩展页(frontend/src/custom/<ns>/)支持界面内物理删除: 先自动备份 zip 到 data/backups/pages/(可下载)再删目录, 命名校验+防穿越, 产物部署无源码树 409
- 扩展页面新增 URL 嵌入模板: 仅填菜单名+网址生成 iframe 内嵌页, 复用看板外链安全约定(仅 http(s)/拒同源/sandbox 白名单/新窗口兜底)
- 页面插件新增源码导入: 上传 .tsx 或从本项目 custom/ 选择, 后端用自带 esbuild 编译+契约适配(component→mount, 独立 react 实例自挂 Provider/Router, 图标映射白名单), 产物即标准页面插件; 无工具链部署 409
2026-10-22 17:47:59 +08:00
shy3130 c36fea348a test(index-sync): 钉死 ETF 日K测试的日K路由并补全 daily 契约文档 (#502 后续)
- test_etf_adj_factor 的 TickFlow 分支用例补路由钉死: #502 后指数/ETF
  同步跟随 daily_data_provider 偏好, 不钉死会被本机 preferences.json
  配置的自定义日K源干扰
- docs/custom-data-source.md 补全 daily 数据集的指数/ETF 路由说明:
  按契约传 asset_type(stock/index/etf), 仅支持股票的源对其他资产类型
  返回空数据, 该轮同步告警回退 TickFlow
2026-10-21 20:57:05 +08:00
shy3130 e1e332ced4 merge: PR #492 优化扩展数据拉取连接复用
分页/历史回补/两级拉取共用一个 HTTP 客户端, 任务结束或取消时关闭。
冲突仅 ext_pull.py 顶部 import: 保留 timedelta + contextlib + contextvars。
2026-10-19 15:38:23 +08:00
Zhangergou eea2ca4cd4 优化扩展数据拉取连接复用 2026-10-19 14:37:21 +08:00
shy3130 b63c17e9ec feat(custom): 自定义数据源支持五档盘口与财务数据接入
后端拉取/路由/能力增广链路此前已就绪, 本次补齐缺口:

- 编辑器新增「五档盘口」「财务数据」数据集 tab: 五档预填
  symbol/asks/bids; 财务预填骨架三列, 下拉可选五表全部 canonical
  列(带中文标注); 两者均为逐批代码参数快照型, 隐藏起止时间参数
- test_dataset 财务分支注入 table=metrics, 与生产同口径
- validate: depth5/financial 豁免起止时间重名检查; 新增映射目标
  重复拦截(运行时 rename DuplicateError 会整表拉空)
- mapper.map_rows 改全量推断: 默认 100 行采样把稀疏财务列推断成
  Null 列, 第 101 行数值 append ComputeError → 整表拉空(batch=100
  必现, 与 fuyao 插件同因)
- 契约文档: 五档/financial 字段契约与五表 canonical 列清单,
  映射一对一限制、缺失列跨批合并补 null 的降级语义
- 回归 6 条: table/latest 注入、validate 豁免与拦截、metrics
  探测、稀疏列推断修复

验证: 后端全量 2798 passed + 前端 155 passed + tsc 通过;
mock 接口 E2E 真连 + 浏览器 UI 用户旅程实测。
2026-10-17 22:05:56 +08:00
shy3130 d6f6962909 feat(guard): 二次开发升级保护 — 程序文件常备备份/升级对比报告/一键恢复 2026-10-16 16:45:03 +08:00
shy3130 1c2e4db980 Update 2026-10-15 16:10:20 +08:00
shy3130 99efc808e8 docs: 补 v0.3.7 版本表与二开指南
二开指南补去内置化/叠加条件/string 参数; 安全校验描述同步 #475 后口径。
2026-10-15 12:27:59 +08:00
shy3130 db300cad45 refactor(ui): 页面包更名为页面插件
消除断句歧义, 与数据源插件命名对齐; 仅改文案, 代码层标识不动。
2026-10-15 12:27:59 +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 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 c3afd3470a refactor(ui): 分区命名统一 —「纪律与触发」改为「风控触发」(弹窗+回测抽屉+测试+文档) 2026-10-11 10:44:26 +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 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
kevin9327andClaude Opus 5.5 3563b14eb9 docs(features): 内置策略数改为 25 并同步代表策略表, 与策略指南口径一致
features.md 写 18 个, strategy.md 写 25 个; 按 builtin/ 各模块 META 核对,
普通选股列表 25 个, 另有一个仅供挖掘 worker 使用的研究模板。

Closes #426

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 19:18:54 +09: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 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 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
shy3130 ecc418bd94 feat: AI 助手推广位、显示细节优化与模拟盘设计方案
- AI 助手: RunningHub 推广位(标题行跑马灯、一周静默、无缝循环、悬停暂停), 抽屉头部与侧边栏模型名完整显示
- 测试: mining manager 终态事件轮询收敛, 消除状态先于事件落盘的读侧竞态
- 文档: 新增虚拟账户(模拟盘)功能设计方案 docs/paper-trading-plan.md
2026-09-24 13:59:14 +08:00
shy3130 c37f450e28 feat: 更新 README, 新增快速预设, 调整 AI 默认上下文/输出限制
README:
- 更新顶部说明区块, 新增静态展示资源

快速预设 (设置页):
- 新增预设项, 调整官网链接与介绍文案, 高亮样式适配明暗主题
- 模型输入框支持下拉选择: 经后端代理拉取模型列表, 支持关键词过滤

AI 默认配置:
- 输出上限 8192 → 16384, 上下文窗口 64000 → 128000, 对齐当前主流模型能力
- 后端新增模型列表代理接口, 前端 api 同步封装
2026-09-24 11:39:54 +08:00
wshyandGitHub 411913e761 Merge pull request #259 from 0112020179/codex/hide-missing-intraday-average
fix(intraday): hide average when amount is unavailable
2026-09-06 23:27:36 +08:00
shy3130 ddfe57f063 feat(ext-data): 出站请求默认携带 tsp 标识头
扩展数据的三个出站点 (定时/手动拉取与历史回补、内置预设拉取、URL 探测
测试) 统一经 outbound_headers() 注入 User-Agent: tsp/<版本> 与
X-TSP-Client: tick-stock-panel, 服务端 (如 tickflow-hub) 可据此识别
本项目的请求来源。

用户在拉取配置里显式设置的同名请求头优先 (大小写不敏感匹配, 不重复
发送), 需要特定 UA 的数据源不受影响。

验证: pytest 22/22 (含 3 个新用例: 默认标识头/用户头优先/实际请求携带);
逐文件 ruff 与 HEAD 对比零新增。
2026-09-06 23:16:27 +08:00
0112020179 59d8d4674b fix(intraday): hide unavailable average line 2026-09-06 23:15:21 +08:00
shy3130 70c102f3d0 feat(pipeline): 盘后管道默认 15:35, 与盘后固定价终点 (15:30) 拉开缓冲
实测 2026-09-04 数据: 836 只可比标的中 24 只日K量大于分钟K合计 (最大
5.4%), 差额产生于 15:00 收盘后的盘后时段 (盘后固定价/大宗类成交计入
日成交量但不产生分钟K) —— 盘中实时落盘的日K注定缺失该尾巴, 只有
15:30 之后的官方日线才完整。

- 默认调度 15:30 → 15:35: 避开供应商日线未定稿窗口, 也与 quote 定版
  重试窗口终点 (15:30) 不再精确重合
- set_pipeline_schedule 保存下限从 15:00 收紧到 15:35 (存量已存配置
  不迁移, 读取不钳制, 仅下次显式保存时生效)
- 定时复盘默认 15:10 (即时复盘走实时快照缓存, 不依赖管道) 刻意不动

验证: set 钳制冒烟 (15:30→15:35, 15:35/15:36 原样); ruff 与 HEAD 基线
一致无新增; pytest prefer/pipeline/daily 相关 128 通过。
2026-09-06 22:35:24 +08:00