Commit Graph
413 Commits
Author SHA1 Message Date
wshy 464a5d9d50 Merge pull request #273 from kevin9327/fix/test-endpoint-cold-cache
fix(settings): 端点清单缓存未预热时端点测速 500
2026-09-09 09:04:11 +08:00
wshy 99f478b257 Merge pull request #272 from kevin9327/fix/report-created-at-beijing-time
fix(reports): AI 报告 created_at 改用北京墙钟, 修复 UTC 部署下「8 小时前」
2026-09-09 09:04:05 +08:00
wshy 970296e82e Merge pull request #271 from kevin9327/fix/minute-sync-beijing-window
fix(kline): 分钟K增量同步窗口统一按北京时区
2026-09-09 09:04:00 +08:00
wshy eebe533986 Merge pull request #270 from kevin9327/fix/rotation-signal-date-alignment
fix(rotation): 轮动信号缺失日按日期归位补齐, 新晋概念不再被误判为退潮
2026-09-09 09:03:54 +08:00
kevin9327 ea27376e03 fix(kline): 分钟K增量同步窗口统一按北京时区
sync_and_persist_minute 的起点取自本地分钟K的北京墙钟, 终点却用服务器
本地墙钟 datetime.now(); _datetime_to_ms 按服务器时区解释两者, UTC 容器上
起点反而晚于终点, time_segments 为空, 增量补拉一个请求都发不出去。

_latest_minute_datetime / _earliest_minute_datetime 返回值带上 CN_TZ,
now 改用 cn_now(), 与 fetch_minute_single 已有的时区纪律保持一致。
2026-09-09 07:15:02 +09:00
kevin9327 e349f2ba9b fix(settings): 端点测速在清单缓存未预热时 500
_endpoints_cache 初值是 {"ts": 0.0, "data": None}, "data" 键存在, 所以
dict.get("data", {}) 的默认值不生效, 返回的是 None。进程启动后到第一次
GET /api/settings/endpoints 之前, POST /api/settings/test_endpoint 不带
rounds 会在 None.get("testRounds", 5) 上抛 AttributeError → HTTP 500。

前端 endpoints 查询有 5 分钟 staleTime, 后端重启后用户再点测速正好落在
这个窗口: 前端不会重新拉清单, 后端缓存却已清空。

改为先 `or {}` 兜底再取 testRounds, 保持原有默认 5 轮语义。
2026-09-09 07:12:54 +09:00
kevin9327 a0925cb0c8 fix(reports): AI 报告 created_at 改用北京墙钟
三类 AI 报告(财务分析 / 个股分析 / 大盘复盘)共用的 JsonReportStore 用
datetime.now() 补 created_at, 取的是宿主机时钟。容器默认 UTC 时写入的是
UTC 墙钟, 前端 fmtRelative 再按浏览器本地时区解析这串 naive 时间, 刚生成
的报告被显示成「8 小时前」; stockAnalysisStore 的「今天是否已生成过报告」
判定(created_at 前 10 位 == 浏览器今天)在北京 00:00-08:00 也会误判。

改用 app.market_time.cn_now(), 保持原有 naive 秒精度格式不变。
2026-09-09 07:10:55 +09:00
kevin9327 2266ecc1d8 fix(rotation): 轮动信号缺失日按日期归位补齐
_compute_rotation_signals 把缺失日的 (999, 0.0) 占位一律追加到序列末尾,
而下游按 ranks[0]=最早日 / ranks[-1]=最新日 解读。概念在部分日期缺席时
(build_rps_rotation 已过滤掉当日无有效 avg_pct 的成员) 实际排名被压到左端、
占位落到右端, 只在最近几日上榜的新晋概念因此被判成退潮。

改为按日期归位补齐, 并补充 tests/test_concept_rotation_signals.py 覆盖
早期缺席 / 最近缺席两个方向。
2026-09-09 07:10:35 +09:00
0112020179 f325a9676c fix(pipeline): 避免停牌分区反复误删重算 2026-09-08 23:49:55 +08:00
wshy cdd41a6d15 Merge pull request #266 from 0112020179/codex/fix-kline-transfer-minute-capability
fix(kline): 压缩详情响应并限制无权限分钟回退
2026-09-08 21:06:40 +08:00
wshy de250f72bc Merge pull request #268 from kevin9327/fix/pull-window-beijing
fix(ext-data): 定时拉取的时间窗口与落盘日期改用北京时间
2026-09-08 21:06:36 +08:00
kevin9327 9a9903cf69 fix(ext-data): 定时拉取的时间窗口与落盘日期改用北京时间 2026-09-08 19:56:03 +09:00
0112020179 a8bb7a25bf fix(kline): 压缩详情响应并限制无权限分钟回退 2026-09-08 18:09:59 +08:00
shy3130 908b385501 feat(ext-data): 拉取接口支持 API Key 鉴权 + 扩展数据弹窗加宽可滚动
后端:
- PullConfig 新增 auth (none/bearer/header/query, 与自定义行情源
  AuthConfig 同口径); 拉取/测试/回补共用 _request_json, 鉴权注入
  只有一套口径, 用户自定义 Headers 仍优先于 UA 标识头
- Key 本体存 secrets_store (data/user_data/secrets.json, 0600),
  不落 config.json; EXT_{ID}_API_KEY 环境变量兜底; 配置了鉴权但
  未设 Key 时 fail-closed 拒绝请求
- 新增 GET/PUT /api/ext-data/{id}/api-key (GET 只返回脱敏值);
  删除配置时清理残留 Key; 历史 config.json 无 auth 字段读为 None
  行为不变; PUT /pull 不带 auth 时沿用现有鉴权

前端:
- 拉取面板新增"接口鉴权"区块: 方式下拉 + 请求头名/参数名 + Key
  密码框 (输入新 Key 覆盖, 清空保存删除), 随保存/测试/开关一起生效
- SettingsModal 加 width prop, 扩展数据设置弹窗与 EditExtDialog
  加宽至 max-w-2xl; SettingsModal 加 max-h-[88vh] + 内容区独立
  滚动, 矮视口下不再被截断
2026-09-07 22:54:05 +08:00
shy3130 f8a23b7ce5 fix(api): quote_service 缺失时 quote-interval 兜底返回默认档位 (#261)
PUT /preferences/quote-interval 的 if not qs 分支错误调用
qs.get_min_interval(),此时 qs 必为 None,触发 AttributeError → 500。
改为返回硬编码默认值 6.0,与 GET 接口兜底写法及
QuoteService.DEFAULT_INTERVAL 保持一致,并新增复现测试。
2026-09-07 22:01:12 +08:00
shy3130 f03bc38a16 feat(screener): run_all 渐进式返回, 快策略先出、慢策略后台补算
策略页全量 run_all 需 ~2 分钟, 期间卡片全空。现在按历史耗时升序执行,
首返时限 (strategy_run_all_first_return_s, 默认 15s) 内算完的策略随
响应返回, 慢策略转后台继续算并逐个写入策略缓存, 前端轮询
cached-summary 逐个点亮卡片数字 (未出的显示脉冲占位)。

后端:
- services/strategy_run_queue: 单飞 daemon 工作线程 + handle 状态。
  相同 key (资产/周期/日期/策略集) 且未完成的请求搭车现有执行不重算;
  已完成的重跑即新执行。后端全局同时只跑一个 run_all, 补上前端
  防重入之外的第二道 Numba 并发防线
- run_all 渐进分支 (仅日线 + summary_only): 逐策略增量写缓存 (同日
  按 sid 合并), 收尾整体重写保持旧口径; 结果带 computed_at 时间戳;
  分钟周期与明细请求保持整段阻塞不变
- 历史耗时落盘 user_data/strategy_run_timings.json, 次日起快策略自动
  排前; cached-summary 透传 computed_at

前端:
- 请求通用 30s 超时 + 慢接口豁免清单 (run_all/run/backtest/factor 等
  300s), 避免一个挂起请求占满 HTTP/1.1 连接拖死全站
- Screener: 收到 pending 后 summaryQuery 每 2s 轮询, 以
  computed_at >= started_at 判新 (防同日旧缓存冒充), 8 分钟兜底;
  StrategyCard 三种尺寸新增 computing 脉冲占位

验证: 新增 13 测试 (排序/落盘/搭车/串行化/端点行为/旧路径兼容),
全量套件 1762 passed; pnpm build 通过。
2026-09-07 15:25:54 +08:00
shy3130 a1ef095334 perf(strategy): run_all 逐策略计时日志与可选并行执行
- 每策略计时: ≥1s 用 INFO、否则 DEBUG, 热点策略 (macd_below_zero_revival
  ~155s / platform_consolidation_breakout ~131s / bullish_alignment ~82s)
  可直接从日志定位; 矩阵构建单独计时
- parallel 参数 + strategy_run_all_workers 配置 (默认 1=串行): 实测
  2026-09-07 外层 4 worker 并发 41 策略 299.6s 慢于串行 ~112s (polars
  eager 内部已多线程, 外层并发属超订), 故默认串行、保留开关供调优
- 叠加策略递归 run_all 固定 parallel=False, 防嵌套线程数爆炸
- 单测: 并行与串行结果/失败语义一致
2026-09-07 15:25:48 +08:00
shy3130 5618b4ef1d perf(polars): 并发闸+写锁收缩+看门狗三层防死锁, 升级 polars 1.44
线上曾出现并发 LazyFrame.collect 触发 polars streaming 执行器死锁,
叠加 _write_lock 区间内做重活, 放大为全站请求冻结。本次按触发缩小、
爆炸半径收缩、自动恢复三层布防:

- polars_guard: BoundedSemaphore 并发闸 (总闸 4 + 后台车道 2, 后台
  先拿子闸再拿总闸防死锁); repository 18 处 collect 按交互/后台分级接入
- repository 写锁区间收缩: 分区合并移出锁外, 锁内 (mtime_ns,size)
  指纹校验 + 3 次乐观重试, 失败回退锁内合并; 5 处 _write_lock 重构
- watchdog: 周期探测 collect 闸与全局写锁, 连续 2 次失败退出交由
  supervisor 拉起 (可配置, 默认开)
- polars >=1.44,<1.45 (1.44.1); 附并发压测脚本
  scripts/stress_polars_concurrency.py 供复现验证

另: config 新增 polars_collect_permits / watchdog_* /
strategy_run_all_workers / strategy_run_all_first_return_s 旋钮
(后两者供后续 run_all 优化提交使用, 默认保持旧行为基准)。
2026-09-07 15:25:41 +08:00
shy3130 58b161b16d fix(enriched): 自愈孤儿 publishing 标记, 步进优化不再误报 publishing
清库半删除等异常会留下 owner 已死但状态仍为 publishing 的 generation
标记, 后续读取直接抛 EnrichedGenerationUnavailableError, 步进优化连锁失败。

- 读取侧仅在「owner 是其他进程且该进程已死」时判孤儿并在独占锁内
  自愈 (换新 uuid 重建 ready 标记); 同 pid 无活跃对象时保守不判,
  避免暴露清库半删除的数据 (fail-closed)
- 回测引擎改为 data_generation_await 轮询等待 (300s 上限), 遇短暂
  publishing 自动重试而非直接失败; worker 错误文案同步为可重试提示
2026-09-07 15:25:27 +08:00
kevin9327 6876db1a86 perf(ext-data): CSV 编码转换改为分块进行, 峰值内存不再随文件线性增长 2026-09-07 08:10:38 +09:00
kevin9327 f2fac2e8f0 fix(ext-data): CSV 编码转换保留原始换行, 避免最后一列被推断为字符串 2026-09-07 08:07:02 +09:00
shy3130 4a27dc45d5 fix(docker): 修复容器启动卡死 — uv 锁过期触发运行时重装 + 运行时无镜像源
47 服务器部署实测暴露两个连环问题:
1. main 上的 uv.lock 停留在 0.2.2 (pyproject 已 0.2.3), 容器 CMD 是
   'uv run uvicorn', 启动时 uv 校验锁不一致 → 在容器内重新锁+重装依赖;
2. uv 国内源 (UV_DEFAULT_INDEX) 只在构建期 RUN 内 export, 未持久化为
   ENV —— 运行时重装走默认 pypi.org, 国内网络直连极慢, 容器表现为
   零日志不监听。

修复: 重新生成 uv.lock (仅项目版本 0.2.2→0.2.3, 依赖版本不变, 源 URL
改用阿里云镜像); Dockerfile 将 UV_DEFAULT_INDEX/UV_EXTRA_INDEX_URL
持久化为运行时 ENV, 与构建期同源。

验证: 本地 uv run --locked 通过 (锁与 pyproject 一致, 0.2.3)。
2026-09-07 00:34:34 +08:00
shy3130 8131cfe853 feat(pipeline): 定时复盘默认 15:40 — 等盘后管道跑完再复盘
默认 15:10 的"即时复盘"走实时快照缓存, 不含盘后管道产出的最终口径
(含盘后量校正的日K/enriched)。默认改为 15:40: 盘后管道默认 15:35
启动后留 5 分钟缓冲, 复盘直接使用管道数据。

强制下限仍为 15:00, 偏好即时复盘的用户可自行调早; 存量已保存的
review_schedule 不受影响 (读取不迁移)。

验证: 无本地存储时默认生效 {'hour': 15, 'minute': 40}; prefer/pipeline/
review 相关测试 67 通过; ruff 与 HEAD 一致无新增。
2026-09-06 23:38:55 +08:00
shy3130 ddb265b0f8 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
shy3130 ecbb45b8ef 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
shy3130 cd9e20610f feat(ext-data): 时序表历史回补 — date_param 按日拉取 + tickflow-hub 404 契约
人气排行等 timeseries 扩展表此前只能从开启拉取之日起逐日累积。拉取配置
新增日期参数名 (date_param), 接口支持按日查询时即可历史回补: 按本地交易日
逐日请求 ?{date_param}=YYYY-MM-DD 写入对应分区, 幂等 (已有分区跳过),
单次上限 120 天, 429 限流退避重试 + 连续限流中止可续补。

适配 tickflow-hub PR#19 (/exports、/fuyao-rank 按日历史截面):
- 该日无快照返回 404 → 计入 empty 跳过, 不进失败清单 (主循环与 429
  退避重试两条路径均覆盖)
- 防污染契约: 响应行 date 与请求日期不一致 (接口忽略日期参数) 时
  fail-closed 拒写该分区, 避免当日值污染整个历史时序
- 修复调度器 next_run 计算的 UTC 未导入 NameError

前端拉取面板新增日期参数名配置与回补入口; 回补落盘的历史数据立即进入
信号/因子/回测按日对齐通道 (PIT)。

验证: pytest tests/test_ext_backfill.py 16 通过 (含 404/429/幂等/防污染),
ext 全套 144 通过; pnpm build 通过。
2026-09-06 22:35:08 +08:00
wshy f275edafeb Merge pull request #256 from SummerCaptain/feat/recap-push-gate
feat(preferences): 复盘推送 review_push_mode 门控
2026-09-06 20:53:29 +08:00
wshy f0c0fd3bf8 Merge pull request #255 from SummerCaptain/feat/ai-strategy-draft-gate
feat(strategy): AI 策略保存为 research_only 草稿 + publish 端点
2026-09-06 20:53:25 +08:00
wshy c94fe2bf31 Merge pull request #251 from 0112020179/codex/fix-fuyao-history-oom
修复扶摇历史日K同步内存溢出
2026-09-06 20:53:22 +08:00
shy3130 e3a2fbce13 feat(ext-data): 扩展表字段接入信号与因子(数值因子/评分 + string 归属筛选)
数值字段(int/float) → 信号+因子双通道:
- ext_factors: 帧组装时 join 扩展列并注册 kind=base 因子(分组「扩展数据」),
  时序模式按 (symbol,交易日) 精确对齐无未来函数, 快照模式仅当日单日帧
  注入(历史帧跳过防未来函数)
- registry.all_factors 惰性同步(配置目录签名幂等, 以注册表为权威增删);
  custom_signals.allowed_fields 自动并入 → 信号下拉/因子库/AI提示词/检验
  同一份清单; factor 补算入口按需注入
- 失效链: 上传/拉取/配置变更自动清扩展帧缓存+策略缓存, API层补
  repo.clear_cache; 写入后下一次计算立即生效
- 列名保留中文(预设表字段名), 非ASCII数值字段只进信号不注册因子
  (DSL标识符ASCII-only)

string 字段(概念/行业归属) → 仅信号条件通道:
- 运算符 包含(contains,字面量匹配非正则)/等于/不等于, 右值为字符串字面量,
  可与数值条件混合(强势板块归属 AND 热度阈值)
- 前端信号编辑器按字段类型切换运算符与右值输入; /options 暴露
  stringFields; AI 提示词含字符串字段清单与 contains 用法
- string 不注册为因子(数值口径), 空值不误报

测试: test_ext_factors 18个(PIT对齐/跨日不泄露/快照门控/写入失效/
contains字面量/中文列名端到端等); 存量因子计数测试补 data/ 运行时隔离
夹具(黄金断言不依赖本机扩展表); 受影响回归148个全过; pnpm build 通过;
ruff 对齐 main 基线
2026-09-06 18:27:33 +08:00
shy3130 716897f41a feat(signals): 信号库新增盘中信号(分钟K特征)
- intraday_features: 会话对齐特征帧构造器(vwap/涨跌幅/1·3·5分钟放量比/
  日内与开盘30分钟高低点距离, 滚动窗口不跨午休, 只用已收盘bar防未来函数)
- custom_signals: timeframe=daily|intraday 双 schema, 盘中条件支持
  cross_up/cross_down 穿越算子; 输出为当日条件上升沿(首bar不触发,
  null特征判false绝不误报)
- 旧4个分时穿越信号列名零迁移(评估器回映射历史列名, 存量监控规则不动)
- 引擎单点注入 csgi_ 列: 监控/分钟策略/分钟回测共用同一构造器;
  日线策略引用盘中信号显式报错
- 回放验证 API /api/custom-signals/intraday/replay(本地历史分钟K重放,
  区间≤60天标的≤200, 先验证再配置监控)
- 能力门槛: 分钟K能力(订阅池)或全量分钟能力(本地分区); 回放仅需本地历史

验证: 新增16个测试(特征数值/边界/旧4信号黄金等价/引擎注入/回放端点),
受影响回归109个全过, ruff对齐基线, docs/features.md 同步
2026-09-06 18:26:29 +08:00
0112020179 3d6beb3c35 fix(fuyao): 根据审查完善流式同步 2026-09-06 17:39:43 +08:00
sc 9d55c237ed feat(preferences): review_push_mode 端点与前端开关配套
- settings: GET 返回 review_push_mode, PUT review-push 支持 mode 入参
- market_recap: push 移入 SaveReportRequest body(显式外发)
- Review 页: 推送触发方式 auto/manual 开关
- 门控测试: 手动/定时两条路径的 manual/auto 推送断言
2026-09-06 16:20:42 +08:00
sc e6c7fa4a43 feat(strategy): 策略池 AI 草稿分区与发布闸前端配套
- 后端 publish 失败由 ValueError 改为 HTTPException(500) 返回给前端
- 策略池 AI 标签新增「草稿」分区, 展示 research_only 策略并提供发布按钮
- 导入/保存 AI 策略为草稿时提示发布后可用, onSavedId 对草稿态跳过入池校验
2026-09-06 16:05:02 +08:00
sc 905fb8846c feat(preferences): 复盘推送 review_push_mode 门控 2026-09-06 13:41:52 +08:00
sc f6fc22fef1 feat(strategy): AI 策略保存为 research_only 草稿 + publish 端点 2026-09-06 13:41:51 +08:00
0112020179 1c022a1c7c fix(fuyao): 流式同步历史日K避免内存溢出 2026-09-06 12:35:26 +08:00
wshy 900dbea59c Merge pull request #246 from 0112020179/codex/custom-depth-provider-245
feat(data-source): support custom depth providers
2026-09-06 09:51:41 +08:00
wshy 2ebb9f0b11 Merge pull request #249 from kevin9327/fix/watchlist-upload-cap
fix(watchlist): 自选导入上传分块读取, 越限即拒绝而非读完再拒
2026-09-06 09:51:36 +08:00
wshy c08e26ddd1 Merge pull request #250 from kevin9327/fix/feishu-test-attempt-count
fix(notifications): 飞书推送按传入的 max_attempts 退避与记日志
2026-09-06 09:51:33 +08:00
0112020179 b5a005a8ac feat(data-source): support custom depth providers
Closes #245
2026-09-05 22:49:52 +08:00
shy3130 c289ac5767 fix(backtest): 步进优化支持 python_history_legacy/polars_expr 策略
问题: WalkForwardService._prepare_shared_matrix 对非 matrix_native 策略直接抛
"步进优化暂仅支持矩阵策略", filter_history 类自定义策略 (如 everbloom 系列)
无法做步进优化。

根因: 闸门把非矩阵后端一刀切, 但 run() 内部本就存在 shared_market_data=None
的通用路径 (每折独立优化 + 独立 OOS 回测), 只是永远不会被走到。

方案: 闸门改分流 —— matrix_native 仍走共享矩阵加速路径; python_history_legacy
与 polars_expr 返回 None 走通用每折回测路径 (正确但无矩阵加速); composite /
minute_filter 维持 fail-closed 拒绝, 错误文案同步更新。

兼容: matrix_native 行为不变; 结果字段 shared_market_data=false 标识通用路径。
性能: 非矩阵策略每组合×每折一次完整回测, 大网格耗时线性放大 (UI 已有耗时提示)。

验证: uv run --frozen pytest tests/backtest/test_walkforward.py -q (23 passed,
含新增 3 例: legacy 走通用路径/polars_expr 放行/minute_filter 拒绝);
tests/backtest 全套 282 passed; ruff 无新增告警;
真实 API 端到端: everbloom_tupengpan 2x2 网格 120/30 步进 8/8 折全部完成。
2026-09-05 20:33:31 +08:00
kevin9327 d46e601863 fix(notifications): 飞书推送按传入的 max_attempts 退避与记日志
_post_feishu 的退避判断与最终 WARNING 仍用模块常量 _FEISHU_MAX_ATTEMPTS(3),
设置页「发送测试消息」传 max_attempts=1 时: 唯一一次失败后仍 sleep 1 秒才返回,
日志写「已重试 3 次」而实际只试了 1 次。两处改用 max_attempts; 生产路径不变。

测试: 单次尝试不退避且日志计数为 1 (未修复时失败), 默认 3 次仍退避 1s、2s。
2026-09-05 21:14:53 +09:00
kevin9327 e12e0c7d02 fix(watchlist): 自选导入上传分块读取, 越限即拒绝而非读完再拒
import-csv / import-image 原先 `await file.read()` 之后才比较长度, 上限只在
整个文件进入内存之后生效, 与 issue #204 修复前的扩展数据上传同类。新增
_read_upload_capped 分块读取, 累计超过上限的那一块立即返回 400 并停止读取,
状态码与文案不变; 内存占用不超过上限 + 一块。

测试: 新增 5 例 (含「越限后不再继续读取」的字节计数断言); test_watchlist_csv
的上传 mock 改为像真实 UploadFile 一样读尽返回 b""。
2026-09-05 21:11:44 +09:00
shy3130 2ff909cd36 fix(notifications): #244 维护者补丁 — 移除预埋类型并修正全角标点
- 移除 api.ts 中与通知无关的 MainCostEstimate/StockLevels.main_cost 类型(对应后端字段在本仓库不存在, 属跨 PR 预埋, 全仓库零引用)
- settings.py 5 处 PR 新增字符串的全角逗号改半角, RUF001 恢复到 main 基线(28 ≤ 29)
- 验证: 通知测试 48 passed, 前端 build 通过
2026-09-05 17:16:58 +08:00
wshy c1cad36449 Merge pull request #244 from yushenglin01/feat/notification-channels
feat(notifications): add custom webhook and email channels
2026-09-05 17:14:25 +08:00
shy3130 e0cd625ef4 feat(platform): 因子平台与因子↔策略双向联动 v0.2.3
- 因子平台: /factors 一级页(检验/因子库/编辑器/组合/挖掘), DSL 公式因子(25 算子点选、双语字段、我的因子模板、脏公式守卫), 版本与生命周期, 自动挖掘 L1 统计筛选
- 因子↔策略四条桥: 触发器 Zap 快建因子条件信号、因子一键生成排名策略、自定义信号 AI 提示词接入因子分组、策略回测因子归因(胜/败单入场信号日因子均值, 独立 tab, 双语因子名)
- 回测: 统计卡新增盈亏比(≥1 红/<1 绿), 蒙卡回撤合并为中位/95% 双值卡(自适应字号), 高级设置基础过滤与策略编辑器参数对齐(5 组区间)
- 信号库独立页 /signals(原设置 tab 迁出), 持仓提醒入导航; 挖掘并入因子页第 5 tab, /mining 旧链接重定向
- 研究线配套: 因子目录 61→77(评分/矩阵双内核), stats_v2(Newey-West/BH-FDR/DSR), enriched 管道与异动/报价服务配套调整
- 文档: README 导航与特性表、features.md 因子平台章节、操作说明书 9.2、factor-platform-plan 执行状态与 §5、二开文档桥接说明; 交流与支持节改版
- 版本 0.2.2 → 0.2.3; 后端全量 1625 passed(1 例环境性跳过), 前端 build 通过
2026-09-05 15:41:15 +08:00
yushenglin 5289cde13e feat(notifications): add custom webhook and email channels 2026-09-04 16:37:06 +08:00
shy3130 bab609b2d4 fix(ai): DeepSeek thinking 禁用参数被 400 拒绝时去参重试 (#240 跟进)
_openai_kwargs 对 DeepSeek V4 官方域名注入的 thinking 禁用参数
(extra_body) 属外部 API 契约, 模型/接口版本差异可能报 400。照
temperature / reasoning_effort 既有模式补第三条定向回退: 400 且
错误信息指向 thinking 时移除 extra_body 重建请求 (回退默认思考
模式; 若正文因此被推理挤占, 由 _iter_openai_text 显式报错指引)。

与 thinking 无关的 400 不触发回退, 直接抛出。
2026-09-04 12:50:50 +08:00
wshy 3fee4ecba5 Merge pull request #240 from yushenglin01/fix/ai-analysis-focus
修复 AI 分析关注重点不突出及静默失效问题
2026-09-04 12:47:39 +08:00