shy3130
|
697c27bb02
|
feat(v0.2): 市场阶段与主线识别 + 因子挖掘全链路 + 数据层完善
- 市场环境: 新增情绪周期6阶段(冰点/启动/主升/高潮/退潮/修复, 连板梯队驱动,
EMA平滑+2日确认+弱档否决, 平均段长9.7天)与概念/行业主线排名(涨停梯队聚合,
可配置宽基/风格标签过滤); 市场环境页重构, regime 透明加列, 与5档state并存
- 挖掘: 因子与策略挖掘全链路(API/worker/进程锁/候选库/前端工作台/文档),
周度调度默认关闭且永不自动发布
- 回测: 财务快照因子(点时口径), 批量回测预计算共享下期收益,
信号路径矩阵列依赖展开修复(consecutive_limit_ups 缺列报错)
- 数据/性能: enriched 生成与预热治理, 重任务限流, 行情/K线缓存复用, 时区修复
- 测试: 后端全量 914 通过; GUI 黑盒验证截图存证 gui-test-screenshots/
|
2026-08-16 23:39:07 +08:00 |
|
shy3130
|
8c00f7a3fd
|
feat(v0.2): 双击价格创建点位监控 + 分钟K补齐修复 + 超时设置独立
点位监控(双击图表):
- 日K/单日分时/多日分时价格主图支持双击, 自动预填目标价并按最新价判断上穿/下穿
- 成交量区与指标子图不触发; 自动生成通知文案, 用户手改后不再覆盖
- 已启用点位监控以横虚线显示 (上穿红/下穿绿), 并纳入三图 Y 轴范围
- 复用现有 PriceAlertDialog, 未改变后端 close>=/<= 规则语义与冷却机制
分钟K数据:
- 个股补齐强制回溯请求天数 (force_full_days), 修复切换日期范围只显示3天
- 单股并发补齐复用仓库写锁, 修复 Windows Parquet 临时文件替换失败
- DuckDB 读路径改用短生命周期 cursor, 释放对 Parquet 文件的占用
设置页:
- 数据任务超时从 DataSources 抽出为独立"超时设置"页签
- 设置侧栏垂直居中
验证: pytest 38 passed, pnpm build ok, git diff --check ok, 浏览器端到端 GUI 验证通过
|
2026-08-10 23:32:44 +08:00 |
|
shy3130
|
aaa888347c
|
Merge branch 'pr-169' into v0.2
|
2026-08-10 17:53:31 +08:00 |
|
shy3130
|
c90b83c3e4
|
feat: v0.2 UI 重构 + 自选分组侧边栏 + 扩展数据时间窗口 + 个股对话框优化
- 侧边栏美化:品牌改名/菜单 active 指示条/收起展开/底部精简
- 数据源+AI 状态卡:名称替换固定文字/档位 tag 条件显示
- 设置页重构:account 合入数据源 tab/数据源置顶/收起展开菜单
- 自选分组侧边栏:二级子菜单/分组跳转同步/清空分组
- 个股对话框:tab 移顶栏/分时关闭/放大全屏/操作按钮归位
- 扩展数据:定时拉取时间窗口(time_window_start/end)
- 版本号: 0.1.88 → 0.2.1
|
2026-08-10 17:53:14 +08:00 |
|
shy3130
|
0c5adb0046
|
Merge remote-tracking branch 'origin/main' into v0.2
|
2026-08-10 12:37:06 +08:00 |
|
shy3130
|
bc2b1ae397
|
fix(regime): 趋势图优化 — 线宽/阈值线补全/左右轴交换/涨停默认隐藏
- 综合分主线线宽 2.5 → 1.5(更细致)
- 阈值线补全 5 档状态边界: 加偏强55, 偏弱30标签改为「偏弱/弱势30」
- 阈值线醒目化: 灰线→状态色虚线, 标签白字+状态色背景块, 移到图表右侧外侧
- y轴交换: 左轴→涨停数, 右轴→综合分(0-100); series yAxisIndex 同步调整
- 涨停数默认不勾选(selected: false), 页面进入只显示综合分主线
|
2026-08-02 23:44:13 +08:00 |
|
shy3130
|
92e5db28fc
|
fix(regime): 趋势图阈值线醒目化 + 标签移到图表右侧外侧
- 强势/震荡/偏弱三条横虚线: 灰色淡线 → 状态色(红/灰/蓝)加粗虚线
- 标签: 灰色小字 → 白字+状态色背景块(加粗10px), 显示分值(强势70/震荡45/偏弱30)
- 标签位置: 图表内部 → 右侧外侧(position: end), 不遮挡曲线
- grid 右侧留白 48→64px 给标签腾空间
|
2026-08-02 23:25:47 +08:00 |
|
shy3130
|
6646d0a664
|
feat(regime): 市场环境页完善 — 顶部改造+日历热力图+趋势图修复
顶部 4 卡改造(去掉与看板重复的涨停/涨跌/成交额)
- 状态卡(保留) + 当前势头(连续天数+5日斜率+上次弱势距今)
- 四维拆解(赚钱/投机/抗跌/趋势 迷你水平条, 对应色填充)
- 状态转换(转换次数+节奏标签 稳定/中等/频繁)
日历热力图(纯 CSS 月份网格, 弃用 echarts calendar)
- 单行模式(默认): 月份网格横向排列+滚动条, 默认滚到最新, 月均分 tag
- 展开模式: flex-wrap 自动换行的完整网格
- 每日格子按状态色填充, 月均分用状态色 tag 凸显(不再灰色文字)
修复趋势图切换菜单后不显示(useEChart 容器条件渲染的 ref 时序问题)
- 日历热力图容器改为始终渲染(与趋势图/饼图一致)
其他
- 页面宽度 max-w-6xl → max-w-[1440px](大屏铺满, 与行业分析一致)
- 去掉最强/最弱 Top5 模块(用户反馈没用)
- 新增 scoreToColor 辅助函数(综合分→状态色)
验证: tsc + pnpm build 通过
|
2026-08-02 23:21:15 +08:00 |
|
shy3130
|
c9f01ba288
|
feat: 行业轮动分析(参数化复用概念版) + 扩展数据列数字格式化
行业轮动分析(完全对齐概念版)
- 概念轮动逻辑参数化支持 industry 维度, 一套代码服务两个页面(复用 _dimension_field)
- 后端 build_rps_rotation/analyze_rotation_stream 加 kind 参数; 缓存按 kind+level 隔离
- 行业层级: 1/2/3 级可切换, 默认 2 级(与 _dimension_rank 口径一致)
· 原始 257 个 3 级行业 → level=2 合并成 90 个
- AI 分析 prompt 动态化(概念/行业措辞), _SYSTEM_PROMPT 改为 _build_system_prompt(kind)
- 前端 RpsRotationDialog 加 kind prop; industry 显示层级选择器(1/2/3级默认2)
- IndustryAnalysis 加「涨幅RPS轮动分析」按钮 + dialog(kind=industry)
- ConceptAnalysis 不动(默认 kind=concept 向后兼容)
扩展数据列数字格式化(自选/策略列表)
- 列配置新增 3 项(仅数字类型字段): 千分位逗号 / 单位换算(万/亿/自动) / 小数位
- 新增 formatExtNumber 共享格式化函数(千分位+换算+小数位, 去尾零)
- Watchlist + ScreenerTable 的 number 渲染接 formatExtNumber
- ext source 加 fieldType; 旧列无 fieldType 时默认显示数字配置(放宽判断)
- ExtColumnDisplayConfig 加 thousandSeparator/unitConvert/unitDecimals 字段
验证
- 后端 583 passed; 行业映射实测 257→90(level=2)
- 数字格式化实测: 千分位 1,234,567 / 万换算 123.46万 / 自动 等均正确
- tsc + pnpm build 通过
|
2026-08-02 19:18:07 +08:00 |
|
shy3130
|
1f865ced79
|
feat(backtest): 高级策略设置新增「应用到策略」+ 修复浮点显示与输入体验
新增「应用到策略」按钮
- 底部按钮区(恢复默认/应用到策略/完成)新增按钮, 调用 api.strategySaveConfig
把当前弹窗的 overrides+params 持久化为策略定义(落盘 strategy_overrides/{id}.json)
- 所有页面加载该策略时都用这些参数(策略页加载的就是这里应用过去的)
- 成功后 toast 提示 + 刷新 detail + 关闭弹窗
- 仅用户自有策略(custom/ai/composite)显示, 内置策略不显示
修复浮点显示(止损 7.0000000000000001% → 7%)
- 根因: 5 个百分比派生变量用 Math.abs(x)*100, 浮点运算产生长尾
- 新增 round4() 辅助截断, 应用到 stopLossPct/takeProfitPct/trailingStopPct/
trailingTakeProfitActivatePct/trailingTakeProfitDrawdownPct
修复「删除即跳最小值」输入体验
- 根因: 受控 input 的 onChange 立即 clamp(n,min,max), 用户键入低于 min 的
中间值时立刻被钳到 min, 无法平滑输入/删除重输
- 新增 NumberField 组件: 输入时只更新文本草稿(不钳制), 失焦时才校正到 [min,max]
- 替换抽屉内所有数字输入框: risk tab 6个 + scoring tab 2个 + params tab 动态参数 + filter tab 6个
- 每个 onChange 移除立即 clamp, 业务逻辑(止损负号/回撤联动/整数取整)保留
验证: tsc + pnpm build 通过
|
2026-08-02 18:22:50 +08:00 |
|
shy3130
|
6a750de722
|
feat(regime): 趋势图可解释化 — 综合分主线 + 子维度曲线 + 状态背景色带
问题: 原趋势图标题「环境综合分·涨停数趋势」, 但综合分是4维加权结果,
图里只画涨停数一个副指标, 用户无法理解综合分为何涨跌(黑盒)。
后端(regime_builder.py)
- 抽出 _compute_subscores(metrics): 计算4子维度分(赚钱/投机/抗跌/趋势)+综合分
- classify_state 复用 _compute_subscores(逻辑不重复)
- _aggregate_daily 持久化4个子分列: profit_score/speculation_score/
resilience_score/trend_score(0-100), 供趋势图展示+未来策略按子维度过滤
前端
- RegimeRow 类型加8个可选字段(4子分+4原始指标, 兼容旧数据)
- 趋势图重构:
· 综合分主线(加粗2.5px置顶) + 半透明面积
· 4子维度点状曲线(赚钱橙/投机紫/抗跌绿/趋势蓝), 默认隐藏, 点图例展开
· 状态背景色带(markArea, 连续同状态日期段用状态色低透明度着色)
· 涨停数柱状降为半透明背景(opacity 0.35)
· 阈值横虚线更新为新模型 70/45/30
· 默认 legend.selected 只显示综合分+涨停数(简洁), 子维度按需展开
- 标题改为「环境综合分趋势」+ hint 说明各曲线含义
验证
- 后端 583 passed; 子分加权一致性100%(综合分=Σ子分×权重)
- 实测解释性: weak日(7-30综合23) 赚钱9+抗跌0 清楚显示普跌+大跌股多
- tsc + pnpm build 通过
|
2026-08-02 17:29:09 +08:00 |
|
shy3130
|
3ae7ead21a
|
refactor(regime): 重新设计评分模型对齐看板情绪分 + 修复 schema 迁移 + 饼图标签
评分模型重新设计(regime_builder.py)
- 归一化: _LIN 多点插值 → _score(low,high)(与看板 market_overview_builder 同款, 简洁不易设错)
- 维度: 赚钱效应/指数趋势/板块结构/活跃度 → 赚钱/投机/抗跌/趋势(对齐看板轻量维度)
- 新增「抗跌」维度(原模型完全缺失): 用 strong_down_pct 识别大跌日, 这是 weak 能出现的关键
原 board_structure(涨停-跌停对比, A股涨停常年>跌停致虚高)移除; activity(成交额曾恒满分)移除
- 权重调整 + _score 参考点用 A股真实分位数校准(非拍脑袋)
- 阈值与看板统一: 75/60/40/25 → 70/55/45/30
_aggregate_daily 增强
- 新增聚合列: avg_pct/median_pct/strong_up_pct/strong_down_pct(供新评分模型 + 未来策略扩展)
- 全部 polars group_by 向量化(不回退逐日 filter)
性能
- _scan_enriched_fallback needed 去掉 vol_ratio_5d(实测 compute_limit_signals 函数体未实际使用)
→ 全量补算数据量 657MB→617MB(省40MB), 配合分批内存峰值维持 ~1.9GB
修复 upsert schema 迁移(导致 recompute 500 的真实 bug)
- _aggregate_daily 新增4列后, 旧 regime parquet(15列)与新产出(19列)concat 报 schema lengths differ
- upsert_regime_history concat 前做 schema 对齐: 以新列名+顺序为权威给旧数据补缺失列(null)
→ 旧 parquet 首次重写时自动迁移到新 schema
前端饼图标签重叠修复(Regime.tsx)
- 状态分布饼图标签外置 + 虚线引导线(labelLine), 解决5个状态标签互相重叠
- labelLayout 防重叠, formatter 从两行改一行
验证
- 后端 583 passed(含新增抗跌维度专项测试)
- 真实数据全量分布: weak 从 0% → 有合理占比(原模型永不出现 weak)
- 内存峰值 ~1.9GB(分批+needed白名单保障)
- tsc + pnpm build 通过
|
2026-08-02 17:17:19 +08:00 |
|
shy3130
|
93558cf3b3
|
feat(regime): 市场环境页全面增强 — 内存可控/开关/画像/美化/分批可配
后端
- 修复 /recompute 全量分支误调增量函数致 computed 恒 0: 改为 earliest~today
走 run_regime_batch + upsert 强制覆盖
- 修复 /history 日期范围模式被 limit 默认 120 截断: limit 仅在未传 start/end 时生效
- _scan_enriched_fallback:
· 修复 compute_limit_signals 漏传 instruments 参数致慢路径必抛异常
· needed 白名单: 只算 regime 用到的列, 全量峰值 6.8GB→3.2GB
· 分批 + warmup: 范围超 batch_days 时切片, 每批带 warmup 前缀算后 concat,
全量峰值再降至 ~1.9GB; batch/warmup 参数从用户偏好读取
- _aggregate_daily: 逐日 filter 扫全表(O(N²))改为 polars 向量化 group_by
- 新增 enriched_date_set / earliest_enriched_date 辅助函数
- 盘后管道 regime 计算加开关(preferences.get_pipeline_regime_enabled), 默认关闭
- 新增偏好: regime_batch_days(默认60, 25~500) / regime_warmup_days(默认40, 35~90)
- 新增 API: PUT /preferences/pipeline-regime-enabled, PUT /preferences/regime-batch-params
前端
- 市场环境页时间范围控件: select 三档 → 4 档按钮组(1年/2年/自定义/全部)
· 自定义弹窗手动输入天数(1~1000 钳制) + 快捷预设
· 全部走 regimeCoverage 拿实际日期范围用 start/end 请求
- 市场环境页美化(对齐 Dashboard 设计语言): 渐变条头部/半透明卡片/SectionTitle/
指标卡进度条/语义色 bull-bear
- 新建 RegimeConfigCard: 盘后自动计算开关 + 全量回填分批参数(每批天数/预热天数/
快捷预设省内存·默认·更快)
- 数据页画像加市场环境卡片(独立 regimeCoverage 查询, 同步后刷新, 齿轮设置弹窗)
- 菜单排序设置 + 侧边栏 nav 加入市场环境, 默认排在复盘上面
- Layout 市场环境菜单 badge 改用琥珀胶囊(对齐 Settings 数据源标签)
验证
- 后端 582 passed; 真实数据全量回填产出 986 天, 内存峰值 ~1.9GB(原 6.8GB)
- 前端 tsc + pnpm build 通过
- 分批参数实测生效: batch=30 峰值 1896MB / batch=500 峰值 3772MB
|
2026-08-02 16:25:21 +08:00 |
|
shy3130
|
46ebcd89c8
|
fix(regime): 修复重算无产出并补全 beta 标签
后端
- /recompute 全量分支原本误调 compute_regime_incremental(增量补差),
无缺口/stale 时直接返回 0 行; 改为用 earliest_enriched_date ~ 今天
走 run_regime_batch + upsert 强制覆盖, 真正实现"全量重算"
- _scan_enriched_fallback 原本漏调 compute_limit_signals 的 instruments
参数致慢路径必抛异常 → enriched 缓存未预热时拿不到含信号列数据 → 聚合
返回空; 改用主管道同款 compute_all(df, instruments, historical_shares)
一站式补算, 与 indicators/pipeline.py 对齐
- 新增 enriched_date_set / earliest_enriched_date 辅助函数(抽出复用)
前端
- Regime 重算按钮: 加"重算中…"文字反馈 + 完成 toast(区分有/无新数据) +
catch 捕获错误(原异常被静默吞掉)
- 市场环境菜单加 beta 胶囊标签(对齐 Settings 数据源标签样式)
验证
- 后端 582 passed; 真实数据全量重算产出 986 行(2022-07-08 ~ 2026-07-31)
- 前端 tsc + pnpm build 通过
|
2026-08-02 12:22:48 +08:00 |
|
shy3130
|
4ee55e40c6
|
feat(regime): 新增市场状态识别系统并接入叠加策略回测过滤器
后端
- 新增 services/regime_builder.py:5 档日级市场状态分级(strong/lean_strong/range/lean_weak/weak)
- 新增 api/regime.py:5 个 regime 查询接口
- daily_pipeline 接入 regime 构建(step 2.6,soft-fail + 双检测自愈)
- 回测 strategy.py 新增 regime_filter 过滤:采用 T-1 防未来函数,仅作用于入场信号
在 composite / matrix_native / prepared 三处注入 entry_time_mask
- backtest API 透传 regime_filter(REST + SSE);_make_job_key 纳入 regime_filter 以隔离缓存
- 兼容 _RepoStub 测试夹具(store 属性缺失场景)
前端
- 新增 Regime 页面、路由、导航入口、api 类型与 queryKeys
- 叠加策略回测页新增 regime 过滤器控件
测试
- 新增 tests/test_regime_builder.py(18 项),覆盖分级逻辑、T-1 防未来函数、空值降级、三处 mask 注入
- 全量后端测试 582 passed;前端 pnpm build 通过;git diff --check 无空白错误
|
2026-08-02 12:05:20 +08:00 |
|
shy3130
|
a2bea0240a
|
fix(ui): 修复所有弹窗拖拽穿透导致误关闭的问题
问题: 用户在弹窗内容内拖选文本时, 鼠标移到遮罩松开会触发遮罩 click, 导致弹窗意外关闭(click 派发给 mousedown/mouseup 共同祖先)。
方案: 抽取共享 hook useDialogBackdrop, 用 mousedown 跟踪——只有按下和松开都在遮罩上才关闭。Modal.tsx 内置同样逻辑。所有手写遮罩弹窗统一接入。
|
2026-08-02 10:56:24 +08:00 |
|
shy3130
|
4696fef959
|
feat(composite): 新增叠加策略(composite)支持选股与回测
引入第四种执行后端 composite: 声明式引用多个子策略, 复用现有注册表/缓存/撮合全链路。
核心设计:
- 退出采用来源投影(每个子策略 exit 仅在自己持仓窗口生效, 不串平其他子策略仓位)
- 评分用标准化排名加权(跨子策略可比, 不依赖 per-strategy 的 min-max 量纲)
- 来源归因(entry_signal_code 标记来源子策略)
后端:
- engine.py: CompositeSpec 数据模型, 两阶段引用校验(孤儿移除/嵌套禁止/asset_types 子集/≤8 上限), _run_composite_strategy 选股执行, find_dependents 删除防护, override_loader 注入保证子策略与单独跑同口径
- composite.py(新): 选股 merge_results + 回测 merge_signal_matrices 合并器(退出投影/排名融合/归因)
- backtest/strategy.py: composite 回测分支(特征计划合并/逐子信号/统一风控/basic_filter/归因)
- api/strategy.py: POST /composite/save 端点, _strategy_detail 返回 composite_children(含 name/source), 删除依赖 409 防护
- monitor.py: 实时监控 fail-closed(回退盘后缓存)
- walkforward.py: 对 composite 显式中文报错
- worker.py: _strategy_dirs 补 composite 目录(修复回测子进程找不到 composite 的 bug)
前端:
- CompositeStrategyDialog(新): 创建/编辑弹窗(自动生成 composite_ ID, 权重归一, 类型标签, 增删子策略)
- StrategySettingsDialog: composite 设置面板(子策略增删改/归一/类型标签)
- StrategyBacktest: 回测页 composite 适配(分组/参数区/结果区展示子策略构成)
- api.ts: 类型扩展(source/backend 加 composite, composite_children 含 name/source)
测试: 36 个 composite 专项测试(加载/选股/回测退出投影/排名/归因/override 透传/API/删除防护), 端到端验证真实内置策略回测通过
|
2026-08-02 10:56:03 +08:00 |
|
shy3130
|
e803aa374d
|
chore: 版本号升至 0.1.88
统一升级 4 处版本号至 0.1.88:
- VERSION / backend/app/__init__.py / frontend/package.json: 0.1.87 → 0.1.88
- backend/pyproject.toml: 0.1.83 → 0.1.88 (原已滞后 4 个版本, 一并追上)
本版本包含:
- feat(search): 拼音首字母搜索 + 创业/科创/北交所徽标 (#151)
- fix(security): ext_columns DuckDB SQL 注入修复 (#152, closes #150)
|
2026-07-31 20:03:43 +08:00 |
|
shy3130
|
a4e580e314
|
fix(security): 修复 ext_columns DuckDB SQL 注入 (closes #150)
Issue #150 报告了 ext_columns 功能的 DuckDB SQL 注入, 经核查属实:
field_name 经裸双引号拼进 SQL, 攻击者可借 COPY TO 写文件 (RCE) 或
UNION 读数据。已修复, 详见 PR。
根因: 3 个 SQL sink 用未转义的 f"{field_name}", 仅 screener:147 一处
用 _quote_ident 转义; 且 parser 校验不一致 (screener 校验 config_id,
kline/watchlist 零校验)。
修复方案:
1. 新增 backend/app/db_safe.py 集中定义 quote_ident (双引号转义, 对任意
字符安全) + is_valid_ext_ident (config_id 白名单), 消除不一致根因
2. 3 个 sink 统一改用 quote_ident:
- screener.py:785 (limit_ladder)
- kline.py:376 (_attach_ext, GET /api/kline/daily)
- watchlist.py:279 (watchlist_enriched)
3. kline + watchlist parser 加 config_id 白名单 (screener 已有)
4. screener 复用共享原语, 删除私有 _quote_ident/_EXT_IDENT_RE
关键约束:
- field_name 不能加白名单: FieldDef.name 无校验 + infer_fields_from_df
直接采用原始 CSV/Parquet 列名, 合法可含中文/点。故只在 sink 转义。
- 不关闭 enable_external_access: 实测会同时禁用 read_parquet (项目核心
数据访问方式), 不可行。
对 Issue #150 报告的澄清:
- sink #2/#3/#4 (field_name 注入) 属实, 已修
- sink #1 (screener.py:343 conditions[]/order_by) 不存在, 为误报
(screener.py 无 conditions/order_by/execute 调用)
验证: 后端全量 527 passed (含新增 24 个安全测试, 含 2 个端到端注入
测试: COPY TO 不产生文件 / UNION 不泄漏数据 + 合法特殊字段名回归)
|
2026-07-31 19:56:33 +08:00 |
|
shy3130
|
192f6c4aa9
|
feat(search): 标的搜索支持拼音首字母 + 创业/科创/北交所徽标
## 1. 拼音首字母搜索 (同花顺式)
后端 search_instruments 新增拼音匹配层, 输入 payh 可命中「平安银行」。
- 辅助函数 _name_pinyin_keys 用 lru_cache 缓存「名称→首字母串」, 命中后
近似 dict 查找, 全市场遍历 < 1ms
- 多音字用 heteronym 笛卡尔积展开, 「重庆」同时匹配 cq/zq 两种读音;
并加载 A 股高频地名词典 (重庆/长安/长春/长沙/长城/长江)
- 拼音分支仅在纯 ASCII 字母输入时触发, 中文/数字搜索零开销跳过,
完全向后兼容
- 搜索分层: ① code/symbol 前缀 → ② 拼音首字母前缀 → ③ 包含匹配
新增依赖: pypinyin>=0.50 (纯 Python, 无 C 扩展)
新增测试: tests/test_instrument_search.py (15 用例覆盖拼音/多音字/兼容/边界)
## 2. 搜索结果显示板块徽标
自选/财务搜索/监控规则/回测选标的 四个搜索入口的结果项, 现在会显示
创业板(橙「创」)/科创板(青「科」)/北交所(紫「北」)彩色徽标。
- 复用项目既有的 boardTag (@/components/stock-table/primitives),
与自选/策略/Dashboard 表格徽标样式完全统一
- 沪深主板不显示徽标 (信息量低, 保持简洁)
## 验证
- 后端全量测试 503 passed (含新增 15)
- 前端 tsc --noEmit 零错误
|
2026-07-31 19:38:36 +08:00 |
|
shy3130
|
d29ceed73d
|
Merge branch 'feat/strategy-monitor-events'
|
2026-07-26 21:56:22 +08:00 |
|
shy3130
|
b43b177899
|
feat(monitor): add strategy signal event controls
|
2026-07-26 16:08:42 +08:00 |
|
shy3130
|
6f1c4032bb
|
feat(backtest): toggle auxiliary nav series
|
2026-07-26 00:31:38 +08:00 |
|
shy3130
|
6d7092089c
|
fix(data-source): harden custom source testing
|
2026-07-25 22:51:27 +08:00 |
|
shy3130
|
96fcbe4fff
|
fix(data-source): validate custom request settings
|
2026-07-25 22:13:38 +08:00 |
|
shy3130
|
8efc96d576
|
fix(docker): Codex CLI 挂载路径可覆盖 + 版本号单点维护
- docker-compose: ${HOME}/.codex 改为 ${CODEX_HOME_HOST:-${HOME}/.codex},
修复 Windows PowerShell/CMD 下 HOME 未设置导致挂载失败
- Dockerfile: codex-builder 阶段 ARG CODEX_CLI_VERSION 去掉重复默认值,
统一从顶层 ARG 继承(0.144.3 现仅出现一处)
- README: 补充 Windows 用户 CODEX_HOME_HOST 配置说明
|
2026-07-14 18:12:48 +08:00 |
|
shy3130
|
4df5cc3b27
|
fix(voice): 涨跌幅播报漏乘 100, 几乎所有股票都念成「涨0.0%」
fmtPctText 直接 pct.toFixed(1), 但后端 change_pct 是小数制
(0.0366 = 3.66%, 见 quote_service.py「不乘 100」注释)。屏幕显示的
fmtPct (format.ts) 正确 ×100, 但语音的 fmtPctText 单独写漏了。
0.0366 → 旧「涨0.0%」/ 新「涨3.7%」
0.10 → 旧「涨0.1%」/ 新「涨10.0%」
×100 后再 toFixed, 与 fmtPct 单位约定一致。tsc 通过。
|
2026-07-13 22:28:16 +08:00 |
|
shy3130
|
590de5d694
|
fix(monitor): 分时图刷新开关不生效 + Pro+ 默认开启 + 刷新条件统一
三处问题:
1. 后端 API 漏接线 (settings.py):
- 入参模型 RealtimeMonitorConfigIn 缺 minute_intraday_refresh →
PUT 时 Pydantic 静默丢弃, 开关拨了也不存
- GET /preferences 响应没返回该字段 → 前端永远读 undefined→false,
开关拨完弹回 OFF
服务层 (preferences.py) 本就有 get/set, 纯 API 层漏接。
2. 默认值 (preferences.py):
get_minute_intraday_refresh 原默认 False。改为三态: 未设置过的
key 按 Pro+ 权限定默认 (有权限=开, 无=关); 用户主动设置过的
(含 False) 以用户选择为准。用 'in data' 区分 未设置 vs 设为 False。
3. 刷新条件不一致 (Watchlist.tsx):
Watchlist 用 || (开关或实时行情任一即刷新), Screener 用 && (两者都要)。
与设置卡片描述「需 Pro+ 权限 + 实时行情运行」对齐, 统一成 &&。
后端 216 测试通过; 前端 tsc 通过。
|
2026-07-13 22:28:04 +08:00 |
|
shy3130
|
40c197149e
|
fix(dev): dev.ps1 Start-Job 子进程强制 UTF-8, 修后端中文日志乱码
Start-Job 开的是全新 powershell.exe 子进程, 不继承主进程第 25-28 行
设的 UTF-8, 默认用系统 ANSI (中文 Windows = GBK/cp936) 解码后端的
UTF-8 输出 → 中文变 '瀹氫箟缂哄皯' 式乱码 (UTF-8 被当 GBK 解)。
第 25 行注释 'so child process logs aren't garbled' 的意图因 Start-Job
开新进程而落空。在 backend/frontend 两个 scriptBlock 开头各设 UTF-8,
与 app/__init__.py 的 stdout/stderr 编码对齐。
PowerShell 语法校验通过。
|
2026-07-13 20:51:23 +08:00 |
|
shy3130
|
95c918c841
|
fix(walkforward): 汇总数值 NaN/Infinity 渲染兜底
#104 审查发现 StrategyWalkForward 的汇总卡和净值曲线在后端返回
NaN/Infinity (零成交折等边界) 时会渲染出 "NaN" 字样或空白 SVG:
- OosEquityChart: vals 含 NaN → lo/hi/span 全 NaN → SVG 路径空白,
页脚 last.toFixed(4) 显示 "NaN"
- IS→OOS 退化 / 目标均值: degradation != null 对 NaN 为 true,
toFixed(3) 显示 "NaN"; 颜色判断 (NaN > 0 = false) 方向也错
修复: 加 fin() 把非有限值归一为 null, JSX 外用 const 取出归一值
(TS 据此收窄类型), 下游统一走 '—' 降级。复利收益/一致性/OOS 收益
本就走 NaN-safe 的 fmtPct, 无需改。
前端 tsc -b + vite build 通过。后端未改动。
|
2026-07-13 18:54:13 +08:00 |
|
shy3130
|
7062dcd94d
|
fix(strategy): AI 生成 META: dict = {...} 时规范化报错「找不到 META 字典」
LLM 常给 META 加类型注解 (ast.AnnAssign 节点), 旧版 _find_meta_dict
只遍历 ast.Assign 漏掉注解形式 → 抛「找不到 META 字典」→ 上层包成
「规范化 META 失败」。校验 (_extract_meta) 与规范化 (_find_meta_dict)
用两套不一致逻辑, 导致「校验通过、规范化失败」。
两个函数统一增加 ast.AnnAssign 分支, 消除不一致。补充 4 个回归测试
覆盖注解形式 (含端到端 _normalize_build_result 路径)。
修复后无论哪台机器、哪个模型生成都不再触发该错误。
|
2026-07-13 18:39:17 +08:00 |
|
shy3130
|
570bcba8b9
|
fix(ext-data): List→string 字段直接 cast 报错 — 先 join 再 cast
手动创建的扩展配置拉取 THS 概念接口时, concepts 列为 List(String),
声明为 string 后 cast_df_to_schema 直接 cast(pl.Utf8) 抛
「cannot cast List type (inner: String, to: String)」。
cast_df_to_schema 检测到源列是 List 且目标为 Utf8 时, 先把元素
转字符串再以分号拼接 (与 _flatten_concept_rows 一致), 然后再 cast。
保护任意返回数组字段的配置, 不再依赖预设 id 走 flatten 分支。
|
2026-07-13 18:39:10 +08:00 |
|
shy3130
|
ede22336fa
|
docs: clarify Docker deployment behavior
|
2026-07-13 00:05:07 +08:00 |
|
shy3130
|
97e1cdcc78
|
feat(backtest): 交易记录显示具体触发信号 (不再只显示「信号」类别)
原问题: 多个信号在 _build_signal_mask 里 OR 成一个 mask 后, 只记录
exit_reason="信号", 具体哪个信号触发的信息丢失。回测里买入/卖出原因
只能看到笼统的「信号」, 不知道是 MA金叉还是 MACD死叉。
实现:
- 后端 TradeRecord 加 entry_signal_id/exit_signal_id 字段
- 新增 _resolve_signal_id() 在触发行回查 panel 列, 找出为 True 的具体信号
- 三个 simulate 方法加 entry_signal_ids/exit_signal_ids 参数
- strategy.py 把信号列表传给 engine, _trade_to_dict 透传新字段
- 前端 useSignalNames() hook 合并内置 (BUILTIN_SIGNAL_DEFINITIONS) + 自定义
信号名称; TradeLegCell/ExitReasonBadge 显示具体信号名
- 信号名称前端解析 (复用 cnSignal), 后端只返回 signal_id, 不读磁盘
效果: 买入腿显示「MA5上穿MA20」, 卖出腿显示「MACD死叉」, 原因列从
通用「信号」变成具体信号名。止损/止盈/到期等非信号退出不受影响。
验证: 191 passed, 前端类型检查无错误
|
2026-07-12 18:31:36 +08:00 |
|
shy3130
|
ff059a0cda
|
fix(backtest): 分钟K回测爆内存 — 按触发日精确读取 + 紧凑数组缓存
上一提交 (365f1cc) 修 index bug 时把 cache 从紧凑 numpy 数组改成臃肿的
polars DataFrame, 分钟K回测内存翻几倍导致 OOM 死机。且 _load_minute_for_fills
用 get_minute_range 扫描整个触发区间 (start~end), 触发日稀疏时读了大量无关
日期, 全市场长周期回测直接爆内存。
修复:
1. repository 新增 get_minute_by_dates — 按日期列表精确读 date=YYYY-MM-DD
分区文件, 不扫描区间。内存与回测区间长度解耦, 只随触发日数量增长。
2. _load_minute_for_fills 改用 get_minute_by_dates, 每批 50 天分批读取。
3. cache 改回 float64 紧凑 2D 数组 (6 列: open/high/low/close/volume/amount),
.cast(Float64) 保证 to_numpy 不退化回 object, 原来的 index bug 不复发。
4. _resolve_minute_fill 改用整数列索引 (arr[:,0]) 替代列名索引。
内存对比 (全市场 1 年):
之前: get_minute_range 扫全年 ~365 文件 + DataFrame 缓存 → 5-10GB
现在: 只读触发日文件 + float64 数组 → 几十 MB
验证: 191 passed (含 7 个分钟K回归测试)
|
2026-07-12 18:01:19 +08:00 |
|
shy3130
|
365f1ccbfb
|
feat(minute-k): 分钟K同步流式落盘 + 段大小可配 + 回测成交修复 + 卡死超时调整
1. 分钟K流式落盘 (修复1年全市场卡死)
- sync_minute_batch 加 on_segment 回调,每段拉完立即写盘
- 抽出 _write_minute_partition 公共函数,消除重复
- 内存峰值从全量(~25GB)降到单段,避免 OOM
2. 段大小可配 (默认20交易日,范围[5,30])
- 新增 minute_sync_segment_days 偏好项
- 「单次获取」与「获取1年」共用此分段设置
- 前端设置弹窗新增分段大小步进器
3. 回测分钟K精确成交修复 (从未成功跑通过)
- _resolve_minute_fill 改接受 DataFrame,避免 to_numpy() 退化为
object 数组后字段名索引抛 IndexError
- _load_minute_for_fills 用 partition_by 向量化分组替换逐行循环
- 新增 test_minute_fill.py 回归测试 (6 用例)
4. 卡死 watchdog 超时阈值按任务类型区分
- 普通任务 600s → 1200s;分钟K长任务 → 1800s
- create(timeout_s=) 支持按 job 存阈值,reap_stale 读 job 自身值
- 修复分钟K正常拉取被误杀导致僵尸线程继续写盘的问题
5. UI 优化
- 设置弹窗按 自动同步/手动获取/清空 三区块分组
- 「单次获取」改为按分段大小拉一段 (天数=分段设置)
- 状态文案: 盘后自动同步 → 自动同步已开启/已关闭
|
2026-07-12 14:23:22 +08:00 |
|
shy3130
|
a6e9987be6
|
fix(packaging): support legacy Polars CPUs
|
2026-07-12 14:08:24 +08:00 |
|
shy3130
|
2014da57a9
|
Merge PR #103: Codex CLI 增加 GPT-5.6 支持 + 安全隔离
冲突解决: 保留自定义预设 + GPT-5.6 模型选择 + reasoning_effort 配置
|
2026-07-12 11:07:16 +08:00 |
|
shy3130
|
f9a632ad54
|
feat(ui): 自定义信号字段选择改居中对话框 + AI配置新增自定义预设
- CustomSignalDialog: FieldPicker 从浮动小面板改为居中对话框(Portal)
条件行 flex-wrap 防截断; 字段按钮弹性宽度
- AI.tsx: 新增"自定义"预设(默认选中, 不自动填充); 新用户未配置AI时字段留空
|
2026-07-12 11:04:49 +08:00 |
|
shy3130
|
20ef070099
|
feat(backtest): 分钟K精确回测 — 穿越价/VWAP 成交 + Pro+ 门控
- engine.py: MatcherConfig 加 minute_fill; _resolve_minute_fill (穿越价/VWAP/降级)
+ _load_minute_for_fills; simulate_portfolio/independent_candidates 接入
- strategy.py: StrategyBacktestConfig 加 minute_fill
- backtest.py: strategy_stream 加 minute_fill 参数 + Pro+ 门控 + 数据范围检查
- repository.py: 新增 get_minute_range (多symbol x 日期范围)
- backtestTask.ts/StrategyBacktest.tsx: 激活 highGranularity 开关 + Pro+ 门控
|
2026-07-12 11:04:43 +08:00 |
|
shy3130
|
fc85d53bee
|
feat(minute-k): 分钟K重做 — 前复权 + 向前扩展 + 清空 + 单独拉取 + 进度
- kline_sync: adjust="forward" 前复权; sync_minute_batch 按月分段(57天/段)
突破 count=10000 上限; on_chunk_done 回调带日期段标签
- kline.py: 删除 extend_minute_history; 新增 sync_minute_single(单股拉取落库)
+ clear_minute(仅清分钟K二次确认) + sync_minute 可选 days/extend 参数
- preferences/settings: 默认 5 天上限 30 (恢复原始); 超时强制释放 _heavy_run_lock
- MinuteSyncConfig: 自动同步(5天/关闭) + 往前获取(单次拉满) + 获取1年(分段)
+ 清空按钮 + 进度回调 onJobStart
- StockIntradayChart: 单股获取改用 syncMinuteSingle (落库)
- daily_pipeline: _minute_chunk_progress 兼容 seg_label 参数
|
2026-07-12 11:04:34 +08:00 |
|
shy3130
|
7e6ea3afcd
|
feat(custom-signals): 自定义信号条件支持日期偏移 + 字段弹出选择器
- custom_signals.py: 新增 _col(name, days) helper (days>0 时 .shift().over('symbol'));
validate 加 leftDays/rightDays 校验 (0-60); build_expressions 加 allow_shift 参数
- signals.py: ConditionModel 加 leftDays/rightDays; options 端点加 maxDays + 字段分组 groups
- pipeline.py: 盘中路径 build_expressions(allow_shift=False), 带偏移的信号优雅跳过
- api.ts: CustomSignalCondition 加 leftDays/rightDays; options 加 groups/maxDays 类型
- CustomSignalDialog.tsx: 字段选择改为 Portal 弹出式 (搜索+分组), 解决下拉框过长;
日期偏移控件 (最新/前N日 两种态); 宽松布局
- CustomSignals.tsx: 只读卡片用 fieldWithDays 显示偏移标注
向后兼容: 旧 JSON 无 leftDays/rightDays 时当 0 处理, 行为不变
|
2026-07-11 19:15:54 +08:00 |
|
shy3130
|
d788183f01
|
feat(screener): 策略页新增分时列 + 按套餐截断 + 手动/自动刷新
- screener-columns.ts: 注册 builtin:intraday 列, 加入 signal 分组
- ScreenerTable.tsx: intraday 单元格渲染(MiniIntraday) + 表头眼睛开关
+ 手动刷新按钮(自动轮询关闭时显示) + 列间 border-l 分隔
- Screener.tsx: 分时数据全量加载, 按套餐 batch 上限截断(Pro=100/Expert=200);
截断提示内联工具栏可关闭; 复用 minute_intraday_refresh 偏好控制
盘中轮询(开关+实时行情运行双条件)
- Monitoring.tsx: 分时刷新开关描述补上策略页
- storage.ts: 新增 screenerIntraday 持久化键
|
2026-07-11 16:55:22 +08:00 |
|
shy3130
|
76fbd70e13
|
fix(ext-data): 行业/概念页拉取兼容字典信封, 修复新用户「接口返回不是数组」
_fetch_json 原硬性要求上游返回裸数组 [{...}], 部分用户网络环境
(CDN/WAF/网关) 会把数组包成 {data:[...]} 信封或返回错误 dict,
导致新用户首次「获取数据」必现 HTTP 400 弹窗。
- 兼容 {data/list/rows/result/results} 等常见信封键, 兜底遍历取首个数组
- 真不是数组时, 错误信息附带响应预览(截断200字)便于排查
- 通用拉取引擎已有 response_path 解包, 预设路径此前绕过了它
|
2026-07-11 13:17:56 +08:00 |
|
shy3130
|
56ee0e6c0f
|
feat(signals): 新增价格上穿/下穿 MA5 MA10 信号
- pipeline.py: compute_signals() 与 compute_enriched_today() 双路径
新增 signal_ma5_breakout/breakdown、signal_ma10_breakout/breakdown
(盘中路径同步补 _prev_ma10 到 sig_prev)
- ENRICHED_COLUMNS 登记新列
- signals.ts: BUILTIN_SIGNAL_DEFINITIONS 加 4 条定义
- monitor.py: _SIGNAL_CN 加 4 条中文标签
注: 价格上穿/下穿 MA20 已有 (signal_ma20_breakout/breakdown), 本次补齐 MA5/MA10
|
2026-07-11 13:17:45 +08:00 |
|
shy3130
|
17994445e2
|
feat(voice): 监控告警语音播报 (播报个股名称与信号) v0.1.84
- 新增 voiceBroadcast.ts: 浏览器原生 speechSynthesis, 零依赖/零后端改动
- 按 source 分类拼接文案, 必念个股名称不念代码, 含涨跌幅
· strategy: [名称] 进入/移出 策略「名」 [涨跌幅]
· signal: [名称] 买入/卖出信号触发 [涨跌幅]
· price/market: [名称] [条件摘要] [涨跌幅]
- 默认偏好 Google 中国大陆语音 (音质最佳), 异步注入自动同步回显
- 整批合并一句 + 正在播报时丢弃新批次 (防快行情叠噪音)
- AlertToast 加 dispatchSideEffects 聚合点: 弹窗逻辑与副作用职责分离
- System 设置页加语音播报区: 开关(默认关)/音色/语速/试听
- 版本号同步升至 0.1.84 (VERSION / __version__ / package.json)
- README 监控中心加语音播报特性说明
|
2026-07-11 11:21:57 +08:00 |
|
shy3130
|
26b7f552f0
|
fix(datepicker): 弹层改用 Portal+fixed 定位, 修复被布局遮挡
日期选择器弹层在参数优化页等含 overflow:hidden / transform 的容器内会被
裁剪或遮挡。改用 createPortal 渲染到 body, 配合 fixed 定位 + 视口坐标计算:
- 打开时按按钮位置计算坐标, 下方不足自动向上翻转, 水平溢出回拉
- 滚动/resize 时关闭弹层 (fixed 不跟随滚动, 关闭比重算更可靠)
- 外部点击检测适配 Portal (分别判断按钮与弹层 ref)
|
2026-07-11 10:57:56 +08:00 |
|
shy3130
|
bdbce71217
|
feat(ext-data): 概念/行业定时拉取默认开启 + 修复启动顺序
- 概念/行业预设 enabled 由 False 改为 True, 全新部署首次启动即自动调度
- 修复 main.py 启动顺序: ensure_builtin_presets 移到 pull_scheduler.refresh
之前, 否则全新部署时 scheduler 读不到刚创建的预设, 定时任务不启动
- 已有用户遵循"已存在则跳过"原则, 不受影响
|
2026-07-11 10:44:37 +08:00 |
|
shy3130
|
55c1984bf9
|
fix(ai): 兼容 reasoning 模型 temperature 限制 + 透出上游真实错误
Kimi kimi-k2.7-code 等 reasoning 模型拒绝非约定 temperature (Moonshot
报 "only 1 is allowed for this model"), 之前无条件下发导致 400 配置失败。
- 捕获 temperature 相关 400 后自动去掉 temperature 重试一次 (非流式 + 流式),
不再依赖模型名猜测, 对任意 reasoning 模型稳健
- _format_openai_error 优先透出上游真实 detail, 仅无可读 detail 时回落到
状态码通用文案, 避免吞掉 "model not found" 等排障关键信息
- 前端 Kimi 预设 model 更正为 kimi-k2.7-code
|
2026-07-11 10:20:03 +08:00 |
|
shy3130
|
fbcfd31d6a
|
feat: 优化策略创建流程
|
2026-07-08 22:17:11 +08:00 |
|
shy3130
|
1cb19872db
|
feat: 增加自选列表分时小图
|
2026-07-06 11:10:36 +08:00 |
|
shy3130
|
f7b56ec3c8
|
docs: 自定义数据源新增 AI 映射 prompt 模板
|
2026-07-05 23:16:18 +08:00 |
|
shy3130
|
887e404fc4
|
Merge branch 'feat/tickflow-rate-limits'
|
2026-07-05 23:04:35 +08:00 |
|
shy3130
|
044479dedd
|
fix: 后端版本号同步到 0.1.80
|
2026-07-05 23:03:43 +08:00 |
|
shy3130
|
fa08981851
|
feat: 自定义数据源扩展 + 限频集中化 (v0.1.80)
|
2026-07-05 22:57:46 +08:00 |
|
shy3130
|
5a46bf915e
|
Merge fix/desktop-launch: 修复 console=False 下桌面客户端打不开
|
2026-07-03 22:41:59 +08:00 |
|
shy3130
|
6a74fa9963
|
fix(desktop): 修复 console=False 下 exe 打不开
PyInstaller windowed 启动器 (runw.exe, console=False) 不分配控制台,
sys.stdout/stderr 为 None。desktop.py / main.py 的 logging.basicConfig
默认建 StreamHandler(sys.stderr), stderr 为 None 时首次写日志调用
None.write() 抛 AttributeError, 崩在导入早期, 进程被 OS 直接终止,
try/except 都拦不住 → 用户看到「双击一闪退出、查无日志」。
修复:
1. _guard_streams() - 启动最早期把缺失的 stdout/stderr 换成丢弃写入的
_NullStream, 让 logging/reconfigure/print 全部安全落地 (windowed 标准修法)
2. _setup_logging() - 追加 FileHandler 到 data/desktop.log, console=False
下不再吞日志, 事后可查
3. _run_uvmicorn() - except Exception 捕获后端导入/运行崩溃并写 traceback,
不再静默死亡 (主线程只报「超时」却查无原因)
4. main() - except Exception 顶层兜底: 崩溃时 logger.exception + 弹原生
MessageBox 显示完整堆栈, 让用户能截图反馈
验证: console=False 包本地能正常打开 (修复前打不开)
|
2026-07-03 22:02:13 +08:00 |
|
shy3130
|
085d50a744
|
Merge fix/strategy-delete-bugs: 自定义策略删除相关 bug 修复
|
2026-07-02 22:28:16 +08:00 |
|
shy3130
|
c7ad860dba
|
fix: 修复自定义策略删除导致策略池清空及删除失败静默问题
- bug2(删除后策略全没): prune 仅在拉取成功且非空时执行,加载中/失败/空列表不碰池
根因: 删除触发 engine.reload() 重扫所有文件,任一文件 import 失败被静默跳过,
前端拿到残缺列表后 prune 把池中有效 ID 永久清除并写 localStorage
- bug1(自定义策略删不掉): handleDelete 不再静默吞错误,失败时显式提示并保持弹窗打开
- ai_save 守卫回归: 放宽前缀允许 ai_/custom_,保留 path traversal 字符白名单(安全核心未动)
修复「AI 修改 custom 策略」因 strategy_id 非 ai_ 前缀被 400 拒绝
- 引擎加载失败可见化: _load_all 收集 load_errors,/api/screener/strategies 返回,
前端 toast 提示具体失败文件,不再静默消失
- 同步补全 ai_generator _SYSTEM_PREFIX 三条铁律(与 bbc92c4 docs 一致)
|
2026-07-02 22:19:46 +08:00 |
|
shy3130
|
bbc92c45de
|
docs: 优化策略提示词,新增文件与范围铁律约束
- step1/step2/guide 均补充不可触碰项目源码、不得放入内置策略目录的铁律
- 明确 AI 生成策略只属于 data/strategies/ai/,文件名/ID 用 ai_ 前缀
- 防止 AI 生成多文件、跨文件 import 或染指 backend/app/strategy/builtin/
|
2026-07-02 21:31:50 +08:00 |
|
shy3130
|
e7615fb9e6
|
fix: 扩展数据拉取修复与连板梯队queryKey修复
|
2026-07-01 23:02:37 +08:00 |
|
shy3130
|
14070c24b3
|
fix: 切页时 onboarding 守卫整屏 logo 闪烁
后台重取 (isFetching) 期间本地已有 stale 缓存可展示, 无需整屏占位。
仅首次加载 (isLoading) 才显示占位, 消除切页 logo 闪烁。
|
2026-06-30 22:36:07 +08:00 |
|
shy3130
|
e4f0a95ca2
|
fix: 升级 Expert Key 后财务页「全部同步」无反应
启动时无 FINANCIAL 能力导致调度器 _capset 为 None, 后续在设置页更新 Key
时 app.state.capabilities 已刷新但调度器未同步, trigger() 仍报
no FINANCIAL capability 而拒绝同步。新增 update_capabilities 并在设置 API
刷新能力时同步推给调度器; 前端对 started:false 一律给出提示, 不再静默。
|
2026-06-30 22:30:52 +08:00 |
|
shy3130
|
b315e531df
|
feat: 回测页加预热期说明徽标与滑点配置
- 回测区间旁加「预热≥120天」徽标,点击弹泡说明开头无交易原因
- 佣金旁新增滑点(万分之)输入,持久化并接入回测请求
- Auth 设密码页加访问密码部署文档链接
|
2026-06-29 22:45:16 +08:00 |
|
shy3130
|
b923352ea4
|
|
2026-06-28 22:15:53 +08:00 |
|
shy3130
|
8a4690f1f2
|
fix(auth): 登录页标题改为项目名称 TickFlow Stock Panel
|
2026-06-28 21:08:55 +08:00 |
|
shy3130
|
d123fa723e
|
chore: bump version to 0.1.64
|
2026-06-28 20:11:35 +08:00 |
|
shy3130
|
69cd7af8d9
|
feat: 新增访问密码认证(首次本机设密码 + 公网防护)
- 后端: PBKDF2 密码哈希 + 会话 token(auth.json 存储, 零数据库)
- 中间件: 未设密码时本机可设/公网拒绝(防裸奔+防抢占), 已设密码后 401 拦截
- 5个 API: status/setup/login/logout/change-password, 含本机限制+登录限流
- 前端: 登录页/设密码页 + 全局 401/403 拦截跳转
- 安全: HttpOnly cookie + 5次失败锁5分钟 + 改密码清会话
|
2026-06-28 20:02:00 +08:00 |
|
shy3130
|
5585f445fc
|
chore: bump version to 0.1.63
|
2026-06-28 18:20:57 +08:00 |
|
shy3130
|
8a8cd746dc
|
feat: — 数据目录/实时监控/定时复盘/老CPU兼容
1. 桌面客户端体验优化,Polars 兼容内核 (老 CPU 兼容)
2. 自选页实时监控优化
3. 个股监控逻辑优化
4. 新增定时复盘
6. 其他: 修复 settings.py 中 HTTPException 未 import 的既有 bug
|
2026-06-28 18:08:52 +08:00 |
|
shy3130
|
b79fe60a56
|
ci(docker): 优化镜像构建工作流 + 清理未启用的版本自增脚本
在 #22 (Docker 镜像构建工作流) 基础上的三点优化:
1. CI 关闭国内镜像源(USE_CN_MIRROR=0): GitHub runner 在海外,
让构建直连官方 npm/PyPI 反而更快更稳; 本地/国内手动 docker build
仍走 Dockerfile 默认的 CN 镜像。
2. 新增 .dockerignore: 排除 .git/data/node_modules/docs/screenshots 等
非构建必需文件, 减小上下文体积、加速传输。
3. 叠加 tag 触发 + build-push-action v5→v6: 打 v* tag 时额外产出
带版本号镜像(如 :v0.1.62), 便于固定回溯。
清理:
- 删除 scripts/bump_version.py (prepare-commit-msg hook 从未实际安装,
属于死代码; 发版版本号改为手动维护, 与方案 B 一致)。
- 同步修正 backend/app/api/data.py 中对该脚本的过时引用注释。
|
2026-06-28 16:18:46 +08:00 |
|
shy3130
|
014ff15766
|
chore: 更新 uv.lock 依赖锁
|
2026-06-28 16:01:54 +08:00 |
|
shy3130
|
10ac3b393f
|
docs: README 增加「更新代码」说明, 提醒勿用破坏性 git 命令
说明整个 data/ 不纳入 git, 概念/行业改为首次启动远程拉取;
警告切勿使用 git clean -fdx / git reset --hard (会删本地数据)。
|
2026-06-28 16:01:54 +08:00 |
|
shy3130
|
94e871a48b
|
feat: 概念/行业分析页数据缺失时显示「获取数据」按钮
数据缺失时引导用户手动触发拉取, 而非静默无数据。
前端:
- analysis-shared.tsx: 新增 PresetFetchState 共享组件 (图标+提示+按钮+错误展示)
- api.ts: 新增 extDataPresetFetch(id) 封装
- ConceptAnalysis/IndustryAnalysis: 两个空状态接入 PresetFetchState,
新增 fetchMutation + needsXxxFetch 判断 (内置预设存在但无数据时显示按钮)
|
2026-06-28 16:01:46 +08:00 |
|
shy3130
|
76431b588e
|
feat: 概念/行业数据改为用户手动获取
将内置概念(ext_gn_ths)/行业(ext_hy_ths)数据源从「自动拉取」改为
「用户在页面手动点获取」, 避免启动时网络请求阻塞, 也符合用户自主控制预期。
后端:
- ext_presets.py (新增): 内置预设配方 + 结构转换 (接口 concepts/industries
数组 → 拼接成字符串) + ensure_builtin_presets(只建config不拉数据) +
fetch_preset(手动拉取, 供 API 调用)
- ext_data.py: 新增 POST /api/ext-data/presets/{config_id}/fetch 专用接口
(放在动态路由前避免被当 config_id); 走结构转换保证 schema 一致
- main.py: lifespan 改为只 ensure_builtin_presets 创建 config, 不自动拉取
安全保证: 已存在则完全跳过, 绝不覆盖用户已有数据; 行业表去掉无用的
thscode/time 列。
|
2026-06-28 16:01:39 +08:00 |
|
shy3130
|
2d4befb8a2
|
fix: data 目录脱离 git 跟踪, 修正桌面版数据落位
解决「更新后数据丢失」问题的根因: ext_data 种子文件被 git 跟踪,
push/pull 时会覆盖用户本地数据。
变更:
- .gitignore: 整个 data/ 纳入忽略, 移除 ext_data 放行规则
- git rm --cached: 移除 ext_gn_ths/ext_hy_ths 4 个种子文件跟踪 (本地保留)
- config.py: 桌面版数据目录改为 exe 同级 TickFlowStockPanel_Data/
(在 {app} 外, 覆盖安装/卸载都碰不到; 不在 C 盘, 用户可见)
- tickflow.iss: 卸载询问逻辑指向新数据目录 {app}\..\TickFlowStockPanel_Data
种子数据改由首次启动从远程接口拉取 (见后续 commit)。
|
2026-06-28 16:01:29 +08:00 |
|
shy3130
|
119c1e0f8a
|
README 添加项目定位
|
2026-06-28 14:17:14 +08:00 |
|
shy3130
|
6666e355e0
|
添加个股分析、个股分析报告、复盘截图
|
2026-06-28 13:59:13 +08:00 |
|
shy3130
|
eaaf923d7b
|
修复看板显示bug
|
2026-06-28 13:49:18 +08:00 |
|
shy3130
|
33f10c2847
|
重新设计复盘页面并优化页面
|
2026-06-28 13:49:05 +08:00 |
|
shy3130
|
5d887cd383
|
chore: 移除无意义的发布说明文件
|
2026-06-27 23:44:25 +08:00 |
|
shy3130
|
cd7a08c1ce
|
docs(release): 添加 v0.1.60 发布说明
✨ 新增
- 实时行情分档:None 仅历史日K / Free 监控自选前 5 / Starter+ 全市场
- 自选股移到顶部,调整监控优先级
- 复盘页(Beta)
- 盘后管道数据范围页面化配置
🛠 优化
- Free 自选股实时卡片高亮 + 显示代码名称
- 档位说明弹层补充权益包含关系,更新各档描述
- 实时行情入口图标改设置齿轮,None 档补注册链接
- README 同步档位边界与数据通道说明
🐛 修复
- 盘后管道 _prefs 变量作用域崩溃
- 轮询间隔滑动条请求风暴(2 秒防抖)
- 自选股实时卡片只显示代码不显示名称
|
2026-06-27 23:41:41 +08:00 |
|
shy3130
|
53ec23e5d5
|
docs: add CHANGELOG for v0.1.60
|
2026-06-27 23:35:31 +08:00 |
|
shy3130
|
320304ab62
|
Merge remote-tracking branch 'origin/main' into release/v0.1.60
# Conflicts:
# README.md
|
2026-06-27 23:33:25 +08:00 |
|
shy3130
|
8d07e99ab2
|
docs: update README for v0.1.60
|
2026-06-27 23:27:20 +08:00 |
|
shy3130
|
2acaa38a2b
|
feat: release v0.1.60
|
2026-06-27 23:23:34 +08:00 |
|
shy3130
|
a832836938
|
docs(readme): 添加 GitHub star 徽章
|
2026-06-26 23:55:12 +08:00 |
|
shy3130
|
6bfb2a218f
|
chore: bump version
|
2026-06-26 23:37:56 +08:00 |
|
shy3130
|
56bf1ff1b2
|
Merge branch 'feat/stock-analysis-levels-refactor': 个股分析价位体系重构
|
2026-06-26 23:37:42 +08:00 |
|
shy3130
|
0a24e1e601
|
chore: bump version to 0.1.51
|
2026-06-26 23:37:04 +08:00 |
|
shy3130
|
00d856191b
|
refactor(stock-analysis): 价位体系重构 — 价量支撑 + 通道拆分 + 右侧标签带
压力支撑语义归位:从 BOLL 波动通道改为 Volume Profile 成交密集区
(价+量驱动,真正的市场结构支撑/压力),原 profile 组并入 sr 组。
通道拆分:原合并的「波动通道」拆为 4 个独立开关 —— 布林带(含中轨
MA20)+ Keltner 短/中/长三档,各自显隐。
图表布局:
- 价位文字改用 line series + endLabel 显示在右侧 grid.right 预留带,
不再压在蜡烛上;预留带加宽至 144px 保证标签完整
- 标题栏改两端布局,当前价右置并加大加粗、带涨跌色
- 价位统计面板恢复至图表下方
默认开启:压力支撑 + 枢轴点 + Keltner短期。
|
2026-06-26 23:34:54 +08:00 |
|
shy3130
|
11a972a980
|
feat(financials): AI 财务分析 — 流式生成 + 全局胶囊 + 历史报告持久化
后端:
- 新增 financial_analyzer 服务(CFA 级九维分析提示词 + LLM 流式调用)
- 新增 ai_reports 持久化存储(保留前 20 条)
- 新增 /analyze 流式接口 + 报告 CRUD 接口
- 同步时间持久化到 preferences.json,重启不丢失
前端:
- 全局 AI 分析对话框(store 驱动,支持最小化/历史模式)
- 全局可拖拽任务胶囊(玻璃拟态,三态配色,60fps 拖拽)
- 历史报告列表面板(财务页底部)
- 轻量 Markdown 渲染器(表格折行/列表/引用)
- 同标的历史二次确认 + 财务菜单改名「财务分析」
同步版本号至 v0.1.45
|
2026-06-25 22:39:34 +08:00 |
|
shy3130
|
02be6dede8
|
fix(ci): PyInstaller 产物输出到 backend/dist, 与 tickflow.iss Source 路径一致
修复 Inno Setup 找不到打包产物的错误:
No files found matching ..\backend\dist\TickFlowStockPanel\*
原因: workflow 用 --distpath ../dist 输出到项目根 dist/, 但 .iss 引用的是 backend/dist/
修复: PyInstaller 用默认输出 (backend/dist), DMG/Linux 步骤路径同步调整
|
2026-06-25 00:35:13 +08:00 |
|
shy3130
|
2f02f69668
|
chore: 同步 VERSION 至 v0.1.43
|
2026-06-25 00:28:56 +08:00 |
|
shy3130
|
2d574c17e7
|
Merge feat/financials-sync-progress-and-ai-btn: 财务同步进度三态可视化 + AI分析占位按钮
|
2026-06-25 00:17:42 +08:00 |
|
shy3130
|
48946267f2
|
chore: 同步版本号
|
2026-06-25 00:17:31 +08:00 |
|
shy3130
|
388a929d0a
|
feat(financials): 同步进度三态可视化 + 点击即时反馈 + AI分析占位按钮
后端 (financial_sync.py):
- run_now 全量同步改为逐表执行, 每张完成立即更新 last_sync
(原一次性更新, 前端轮询看不到中间进度; 现在前端能逐步看到 N/4)
- 修复 sync_all 函数缩进被破坏导致的 NameError (上版引入的 bug)
前端 Financials.tsx:
- 点击同步即时反馈: useFinancialSync 加 onMutate 立即刷新 status
+ syncMut.isPending 兜底, 消除请求阻塞期间 UI 无变化
- 同步进度按本次同步算 (记录 syncStartedAt), 不再用 rows>0 判断
(修复已有数据时一开始就显示 4/4)
- 卡片三态可视化:
· 全量同步: 4 张卡片依次 等待(沙漏)→同步中(转圈)→完成(绿勾)
· 单表同步: 只有目标卡片变化, 其他卡片不受影响
- 顶部进度: 全量显示 N/4, 单表显示表名
- 每张卡片底部加最后同步时间
- 完成态用绿色对勾 (不用红色 bull), 卡片保持中性配色
StockFinancialDetail.tsx:
- 头部加 AI 财务分析占位按钮 (紫色 Sparkles), 点击提示开发中
|
2026-06-25 00:17:10 +08:00 |
|
shy3130
|
70cb75c6e6
|
Merge feat/data-clear-and-ui-fixes: 清除数据缓存修复 + UI 优化 + 权限门控 + 同步状态指示
本次合并内容:
- fix(backend): 清除数据彻底清空三层内存缓存 + 监控触发记录 + 版本号统一 + Windows GBK 编码修复
- feat(ui): 看板无数据提示优化 + 数据页无 Key 引导 + 设置页文案
- fix: 权限门控避免 free/starter 报错 + 概念分析数据源失效容错
- feat(sidebar): 数据菜单项同步状态指示器 (转圈/完成闪烁)
|
2026-06-24 23:32:52 +08:00 |
|
shy3130
|
3d74abb1ed
|
chore: 同步版本号至 0.1.42 (VERSION/__init__/pyproject/package.json)
|
2026-06-24 23:25:22 +08:00 |
|
shy3130
|
5e1e1a7529
|
feat(sidebar): 数据菜单项同步状态指示器 (转圈/完成闪烁)
- 轮询 pipelineJobs: 有活跃 job 每 2s, 无活跃每 15s
- 同步中: 数据菜单项右侧显示蓝色转圈 Loader2
- 同步完成: 切换为绿色对勾 CheckCircle2 + pulse 闪烁, 3 秒后消失
(用 ref 检测 isDataSyncing true→false 跳变触发)
|
2026-06-24 23:24:51 +08:00 |
|