Commit Graph
87 Commits
Author SHA1 Message Date
shy3130 e94b074910 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 bd39f886f6 fix(backtest): 分钟K回测爆内存 — 按触发日精确读取 + 紧凑数组缓存
上一提交 (2441c53) 修 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 2441c53646 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 75cf2b19c2 fix(packaging): support legacy Polars CPUs 2026-07-12 14:08:24 +08:00
shy3130 418462c181 Merge PR #103: Codex CLI 增加 GPT-5.6 支持 + 安全隔离
冲突解决: 保留自定义预设 + GPT-5.6 模型选择 + reasoning_effort 配置
2026-07-12 11:07:16 +08:00
shy3130 d26726bfee feat(ui): 自定义信号字段选择改居中对话框 + AI配置新增自定义预设
- CustomSignalDialog: FieldPicker 从浮动小面板改为居中对话框(Portal)
  条件行 flex-wrap 防截断; 字段按钮弹性宽度
- AI.tsx: 新增"自定义"预设(默认选中, 不自动填充); 新用户未配置AI时字段留空
2026-07-12 11:04:49 +08:00
shy3130 7b75c9767f 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 2e67a085f2 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 94d6142f93 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 7e4f29169b 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 86d31e31f5 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 f13e77dde5 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 776c39ccba 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 6f69ab974a fix(datepicker): 弹层改用 Portal+fixed 定位, 修复被布局遮挡
日期选择器弹层在参数优化页等含 overflow:hidden / transform 的容器内会被
裁剪或遮挡。改用 createPortal 渲染到 body, 配合 fixed 定位 + 视口坐标计算:

- 打开时按按钮位置计算坐标, 下方不足自动向上翻转, 水平溢出回拉
- 滚动/resize 时关闭弹层 (fixed 不跟随滚动, 关闭比重算更可靠)
- 外部点击检测适配 Portal (分别判断按钮与弹层 ref)
2026-07-11 10:57:56 +08:00
shy3130 9ed4b57fa6 feat(ext-data): 概念/行业定时拉取默认开启 + 修复启动顺序
- 概念/行业预设 enabled 由 False 改为 True, 全新部署首次启动即自动调度
- 修复 main.py 启动顺序: ensure_builtin_presets 移到 pull_scheduler.refresh
  之前, 否则全新部署时 scheduler 读不到刚创建的预设, 定时任务不启动
- 已有用户遵循"已存在则跳过"原则, 不受影响
2026-07-11 10:44:37 +08:00
shy3130 e438e0d17f 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 5376a137d0 feat: 优化策略创建流程 2026-07-08 22:17:11 +08:00
shy3130andshy3130 31a5deae80 feat: 增加自选列表分时小图 2026-07-06 11:10:36 +08:00
shy3130 fec3887107 docs: 自定义数据源新增 AI 映射 prompt 模板 2026-07-05 23:16:18 +08:00
shy3130 c629cd187c Merge branch 'feat/tickflow-rate-limits' 2026-07-05 23:04:35 +08:00
shy3130 22b89af7c6 fix: 后端版本号同步到 0.1.80 2026-07-05 23:03:43 +08:00
shy3130 7b5d345910 feat: 自定义数据源扩展 + 限频集中化 (v0.1.80) 2026-07-05 22:57:46 +08:00
shy3130 d597615ada Merge fix/desktop-launch: 修复 console=False 下桌面客户端打不开 2026-07-03 22:41:59 +08:00
shy3130 6ffcc5bb24 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 7246b092a0 Merge fix/strategy-delete-bugs: 自定义策略删除相关 bug 修复 2026-07-02 22:28:16 +08:00
shy3130 f4fc5020fc 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 三条铁律(与 1f00f1b docs 一致)
2026-07-02 22:19:46 +08:00
shy3130 1f00f1b306 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 96ce227030 fix: 扩展数据拉取修复与连板梯队queryKey修复 2026-07-01 23:02:37 +08:00
shy3130 e6f90292d3 fix: 切页时 onboarding 守卫整屏 logo 闪烁
后台重取 (isFetching) 期间本地已有 stale 缓存可展示, 无需整屏占位。
仅首次加载 (isLoading) 才显示占位, 消除切页 logo 闪烁。
2026-06-30 22:36:07 +08:00
shy3130 e0e5a59e24 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 5ac8e03198 feat: 回测页加预热期说明徽标与滑点配置
- 回测区间旁加「预热≥120天」徽标,点击弹泡说明开头无交易原因
- 佣金旁新增滑点(万分之)输入,持久化并接入回测请求
- Auth 设密码页加访问密码部署文档链接
2026-06-29 22:45:16 +08:00
shy3130 d1fd3d743e 2026-06-28 22:15:53 +08:00
shy3130 471b517f5d fix(auth): 登录页标题改为项目名称 TickFlow Stock Panel 2026-06-28 21:08:55 +08:00
shy3130 a1a0b13718 chore: bump version to 0.1.64 2026-06-28 20:11:35 +08:00
shy3130 433f4c857d 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 1b8895dbc1 chore: bump version to 0.1.63 2026-06-28 18:20:57 +08:00
shy3130 484050ac06 feat: — 数据目录/实时监控/定时复盘/老CPU兼容
1. 桌面客户端体验优化,Polars 兼容内核 (老 CPU 兼容)
2. 自选页实时监控优化
3. 个股监控逻辑优化
4. 新增定时复盘
6. 其他: 修复 settings.py 中 HTTPException 未 import 的既有 bug
2026-06-28 18:08:52 +08:00
shy3130 028a042f93 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 5144fa31d4 chore: 更新 uv.lock 依赖锁 2026-06-28 16:01:54 +08:00
shy3130 03b1ac11ac feat: 概念/行业分析页数据缺失时显示「获取数据」按钮
数据缺失时引导用户手动触发拉取, 而非静默无数据。

前端:
- analysis-shared.tsx: 新增 PresetFetchState 共享组件 (图标+提示+按钮+错误展示)
- api.ts: 新增 extDataPresetFetch(id) 封装
- ConceptAnalysis/IndustryAnalysis: 两个空状态接入 PresetFetchState,
  新增 fetchMutation + needsXxxFetch 判断 (内置预设存在但无数据时显示按钮)
2026-06-28 16:01:46 +08:00
shy3130 43ccf846a8 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 872c000406 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 8916df9831 添加个股分析、个股分析报告、复盘截图 2026-06-28 13:59:13 +08:00
shy3130 4ad7362843 修复看板显示bug 2026-06-28 13:49:18 +08:00
shy3130 d27873bbfc 重新设计复盘页面并优化页面 2026-06-28 13:49:05 +08:00
shy3130 6c5cd2deee chore: 移除无意义的发布说明文件 2026-06-27 23:44:25 +08:00
shy3130 976469a45c 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 8163499f1d docs: add CHANGELOG for v0.1.60 2026-06-27 23:35:31 +08:00
shy3130 d832d8ed5e feat: release v0.1.60 2026-06-27 23:23:34 +08:00
shy3130 08f131c680 docs(readme): 添加 GitHub star 徽章 2026-06-26 23:55:12 +08:00
shy3130 5eedd4d49f chore: bump version 2026-06-26 23:37:56 +08:00
shy3130 6b56380426 Merge branch 'feat/stock-analysis-levels-refactor': 个股分析价位体系重构 2026-06-26 23:37:42 +08:00
shy3130 e07d8a6441 chore: bump version to 0.1.51 2026-06-26 23:37:04 +08:00
shy3130 aa7528b2f6 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 214896ea7d 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 f8f7fc6488 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 e57ff0ed45 chore: 同步 VERSION 至 v0.1.43 2026-06-25 00:28:56 +08:00
shy3130 e0c257bca3 Merge feat/financials-sync-progress-and-ai-btn: 财务同步进度三态可视化 + AI分析占位按钮 2026-06-25 00:17:42 +08:00
shy3130 29bbacb361 chore: 同步版本号 2026-06-25 00:17:31 +08:00
shy3130 71d0809499 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 baa9e34923 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 3ba7cb4b16 chore: 同步版本号至 0.1.42 (VERSION/__init__/pyproject/package.json) 2026-06-24 23:25:22 +08:00
shy3130 0622a10de2 feat(sidebar): 数据菜单项同步状态指示器 (转圈/完成闪烁)
- 轮询 pipelineJobs: 有活跃 job 每 2s, 无活跃每 15s
- 同步中: 数据菜单项右侧显示蓝色转圈 Loader2
- 同步完成: 切换为绿色对勾 CheckCircle2 + pulse 闪烁, 3 秒后消失
  (用 ref 检测 isDataSyncing true→false 跳变触发)
2026-06-24 23:24:51 +08:00
shy3130 bcc40b6c1d fix: 权限门控避免 free/starter 报错 + 概念分析数据源失效容错
StockPanel:
- 财务指标请求增加 FINANCIAL 能力判断, 无能力时不请求
  (修复 free/starter 点个股弹 'capability not available: financial' 报错)

Indices:
- 指数分时区无 kline.minute.batch (Pro+) 能力时显示锁提示, 不请求接口

ConceptAnalysis:
- 配置的 configId 失效 (扩展数据被删) 时自动回退 pickBestConfig, 避免报错
- 空状态也显示配置按钮, 让用户能重新选择数据源

ExtDimensionAnalysis:
- 顶部数据源/分组字段配置区始终显示 (去掉 !menu 条件)
2026-06-24 23:24:38 +08:00
shy3130 0710eb2d28 feat(ui): 看板无数据提示优化 + 数据页无 Key 引导 + 设置页文案
Dashboard:
- hasNoData 改用 trading_days 判断 (后端 status rows 恒为 0 导致提示无法消除)
- 无数据提示改 warning 黄色风格 + AlertTriangle 图标
- 无数据/无 Key 两提示互斥: 无 Key 优先, 有 Key 无数据才显示同步提示
- API Key 横幅: 邀请码加复制按钮, 文案调整

Data:
- 无 Key 时立即同步按钮置灰禁用 + 显示未配置提示
- 指数数据卡片设置按钮与其它卡片一致 (有数据才显示)

System:
- '清理浏览器缓存' 改名 '刷新前端缓存', 避免误导为清数据
2026-06-24 23:24:25 +08:00
shy3130 f76d8bb2d9 fix(backend): 清除数据彻底清空三层内存缓存 + 监控触发记录 + 修复版本号
修复清除数据后看板/监控仍显示旧数据的根因:

数据缓存清理 (repository/screener/overview):
- repository.py: 新增 clear_cache() 无条件清空全部 Polars 内存缓存;
  修复 _refresh_enriched() 磁盘无数据时不清内存导致旧数据残留的 bug
- screener.py: 新增 clear_history_cache() 清进程级 _history_cache (TTL 缓存)
- overview.py: 新增 invalidate_overview_cache() 清看板聚合结果 5s TTL 缓存

清除数据完整性 (data.py):
- clear_data 删除 parquet 后统一调用三层缓存清理
- 新增清除监控运行数据: alert_store.clear() 清 alerts.jsonl + _pending_alerts 内存队列
  (原 clear_data 漏删 user_data/alerts.jsonl, 导致触发记录清不掉)

版本号统一:
- /api/data/version 改为优先读 app.__version__ (与 /health 同源),
  原 pyproject.toml 路径解析有误读不到, 回退到陈旧的 VERSION 文件
- Windows GBK 编码修复: __init__.py 强制 stdout/stderr UTF-8,
  避免 TickFlow SDK 输出含 emoji 的指数名称时崩溃 (gbk codec can't encode)
2026-06-24 23:24:04 +08:00
shy3130 5c8c595480 feat: 桌面客户端完善 — 安装包/图标/系统通知/版本对齐 2026-06-24 00:18:46 +08:00
shy3130 6aff0b1389 feat: Release 说明加下载按钮 (markdown 链接直连附件)
- release.yml body 模板: 下载表格每行加「⬇️ 立即下载」按钮
  · 用 $github.repository + 版本号变量拼稳定下载 URL
  · CI 自动填充, 无需手动改链接
- v0.1.35 Release 已同步更新 (本地 gh release edit)
- 新增 generate_icon_designs.py (图标设计方案生成, 选定方案后产出最终 ico)
2026-06-23 22:33:05 +08:00
shy3130 5933ef1bc8 feat: Windows 打包改为 Inno Setup 安装包 (Setup.exe)
- 新增 packaging/tickflow.iss: Inno Setup 脚本
  · 用户目录安装 (不弹 UAC), 桌面+开始菜单快捷方式
  · 卸载时询问是否删除用户数据
  · 内置简中语言包 (ChineseSimplified.isl, 官方仓库获取)
- 新增 packaging/generate_icon.py + icon.ico: 应用图标
  · 与 favicon.svg/Logo.tsx 一致 (紫色方括号 + K线)
  · 用 Pillow 绘制, 多尺寸 (16/32/48/64/128/256)
- spec 加 icon: exe 图标 = 安装包图标 = 快捷方式图标
- release.yml: Windows 步骤改为 choco install innosetup + ISCC 编译
- 本地验证通过: 安装→快捷方式→启动→health 0.1.35 全 OK
2026-06-23 22:26:31 +08:00
shy3130 a424ef1bcf fix: bump_version 同步 app/__init__.py 版本号 (health 接口对齐)
bump 脚本之前只更新 pyproject + package.json, 漏改 app/__init__.py,
导致 /health 报的版本号停留在 0.1.31。现在三处版本号源统一更新。
2026-06-23 21:52:48 +08:00
shy3130 f0982f52a3 chore: uv.lock 同步 desktop 依赖 2026-06-23 21:50:41 +08:00
shy3130 0a17526e33 chore: 同步版本号至 0.1.35 (打包对齐 tag) 2026-06-23 21:49:48 +08:00
shy3130 90e7d64bab chore: 同步版本号至 0.1.34 2026-06-23 21:48:29 +08:00
shy3130 168f996c49 feat: 桌面客户端打包 (pywebview + PyInstaller) + 系统通知
- 桌面入口: desktop.py (单实例锁 + 端口探测 + uvicorn + pywebview 窗口)
- 配置层: config.py 加 sys.frozen 检测, frozen 下 data_dir 指向用户目录
- 系统通知: notify_adapter.py 三平台 (Win winotify / mac osascript / Linux notify-send)
  接入 quote_service 告警出口, preferences 开关控制, 前端监控设置加 toggle
- 前端: 监控设置加系统通知开关, 系统设置加检查更新入口
- 打包: packaging/tickflow.spec (onedir, collect-all 原生库, 排除 vectorbt)
- CI: .github/workflows/release.yml 手动触发 + 平台可选 (windows/macos/linux)
- 依赖: platformdirs/winotify/plyer 入主依赖, pywebview 入 desktop extras
- README 加桌面客户端下载章节
- bump 版本号到 0.1.33
2026-06-23 21:47:29 +08:00
shy3130 995a44273c chore: bump version 2026-06-21 22:31:24 +08:00
shy3130 1d5c0452df chore: bump version to 0.1.29 2026-06-21 22:31:10 +08:00
shy3130 9c2bcc5f60 feat: 统一监控引擎 + AlertToast通知 + 声音/角标/看板/Dev页 + 股票名称批量查询
监控引擎 (backend):
- MonitorRuleEngine 统一规则引擎,支持策略/信号/价格/行情四种类型
- JSONL 追加存储 (alert_store.py),支持分页 + 清理
- alert/monitor_rules CRUD API + seed 演示数据
- POST /api/kline/instruments/names 批量股票名称查询
- SSE strategy_alert 事件触发前端通知

前端通知体系:
- AlertToast 自定义弹窗 (Framer Motion + AnimatePresence)
- Web Audio API 合成音效 (12种预设,无需音频文件)
- 侧边栏角标 (monitorBadge.ts) localStorage 持久化未读数
- pendingSeen 机制解决 markSeen/setCurrentTotal 竞态
- 系统设置页: 通知开关 + 最大条数 + 音效选择
- 菜单设置页: 角标数字开关

监控中心 (Monitor.tsx):
- 双栏布局: 左侧实时告警列表 + 右侧规则管理
- RulesList 股票代码后显示中文名称
- RuleEditor 完整规则编辑器组件
- 告警支持查看详情 (StockPreviewDialog)

Dashboard:
- MonitorWidget: Top 10 实时告警卡片

Dev 页面:
- 一键填充演示告警 + 规则 + 分钟探测
- 可视化 SSE 事件流查看

其他:
- v0.1.19 → v0.1.28 (VERSION 从 pyproject.toml 读取)
- dev.ps1/dev.sh 添加 --host 0.0.0.0 (局域网访问)
- 修复 Screener.tsx presets.length 可选链
- README 截图表格更新 (6张) + 监控章节重写
- 删除 MinuteDataProbe 页面 (合并至 Dev)
2026-06-21 14:18:08 +08:00
shy3130 b44fb99cdd feat: 策略买卖触发器改为可编辑并持久化
- 选股页策略设置弹窗: 买入/卖出由只读文本改为可点选信号控件, 保存写入策略配置
- 回测页: 复用共享 SignalPicker 组件, 消除重复的 SIGNAL_LABELS/toggleSignal 内联实现
- 新建 lib/signals.ts 作为信号映射权威来源(对齐后端 _build_signal_mask)
- 新建 components/screener/SignalPicker.tsx 共享组件(entry蓝/exit橙主题)
- 弹窗增加说明: 买卖触发器对回测和监控生效, 选股扫描仍按策略筛选规则
- README 标题更名为 A股智能量化工作台

后端无需改动(overrides dict 透传自动持久化 entry/exit_signals)
2026-06-20 14:47:53 +08:00
shy3130 67af6bc380 feat: 个股日K信息条支持自定义指标(扩展数据/财务/单独显示)
- 信息条(StockInfoBar)行末加配置齿轮,复用自选列表抽屉自定义显示项
- 新增指标: 成交量/振幅/开高低 + 扩展数据(ext) + 财务(EPS/BPS/ROE/PE/PB等)
- 后端 klineDaily 新增 ext_columns 参数,按 symbol JOIN 扩展数据
- 财务数据前端直拉 useFinancialMetrics, PE/PB 用现价现算
- 每列可设单独显示(standalone),独占一行渲染
- ext 标签支持 maxTags 截断 + 点击 +N 同页展开/收起
- 修复重开弹窗信息条消失(symbol 重置与子组件 onDataChange 竞态)
- 修复 ext 勾选不显示(query key 未含 extColumns 导致缓存命中)
- 配置按钮左侧加监控通知图标占位(BellRing)
- ListColumnCustomizer 新增 showExtColumns/showStandaloneToggle prop
2026-06-20 14:42:54 +08:00
shy3130 3e747c9a08 chore: 项目更名 tickflow-stock-panel + 菜单logo两行显示 2026-06-19 21:33:11 +08:00
shy3130 0de26d0b9e docs: 添加连板梯队截图 + README截图改为一行两个 2026-06-19 21:31:43 +08:00
shy3130 77f1cb1ff2 style: favicon深紫透明+加粗 + 菜单logo单行显示 2026-06-19 21:31:39 +08:00
shy3130 a4c330e3c7 chore: 项目名称规范化调整 2026-06-19 21:31:35 +08:00
shy3130 62af50cbe2 feat: 默认扩展数据表结构(概念/行业/新股) + gitignore放行ext_data config 2026-06-19 20:21:21 +08:00
shy3130 3b816fff3f feat: 首次使用引导页增强 2026-06-19 20:11:03 +08:00
shy3130 1337428494 feat: 五档盘口真假涨停修正 + 连板梯队涨跌停切换 + 自动版本管理
连板梯队:
- 新增涨停/跌停方向切换(胶囊式, 涨停红/跌停绿)
- 跌停侧三状态: 跌停/翘板/止跌(对称涨停侧)
- 涨跌停双计数 + 真假板修正/降级标识(问号弹窗)

五档盘口 sealed(真假涨停):
- depth_service 独立旁路线(只读enriched, 不动计算逻辑)
- 涨跌停一体(一次depth.batch双向覆盖)
- 假涨停归炸板/假跌停归翘板, 真封板显示封单量
- 三层防护节流(套餐clamp+限速clamp+接管通知)
- Pro/Expert盘中轮询 + 盘后定版job + 启动补跑
- 收盘job可配置(15:01~18:00, 默认15:02)
- 设置页'连板梯队降级修正'卡片(开关+配置+立即修正)
- 看板页同步应用sealed修正+降级标识

配置/SDK:
- tiers.yaml拆分depth5/depth5.batch, 补全quote.batch
- tickflow SDK升级0.1.21→0.1.23(depth.batch可用)
- 实时行情轮询间隔下限调整(pro 2s/expert 1s)
- capabilities缓存schema版本化(v3)

其他:
- 档位配色抽共享组件TierTag/tierStyle
- Keys页档位问号弹窗(4档位tag+检测说明)
- git hooks自动版本号+0.0.1+打tag
2026-06-19 20:09:09 +08:00
shy3130 b66bd6879c fix: 端点套餐门控/探测重试/分钟K月单位 + 财务页新功能 + localStorage 残留自愈
## Bug 修复
- 端点测速:Expert+ 用户现可选用专线端点(premium),非 Expert 仍锁定(EndpointTestDialog)
- 能力探测:try_call 对瞬时错误(429/5xx/超时)重试,避免抖动误丢 capability(导致"需 Free"误导徽章)
- 数据画像 CapBadge:tierReq='Free' 时不显示无意义的"需 Free"徽章
- 财务同步:用服务端 is_syncing 标志驱动 UI,刷新后仍正确显示"同步中",防重复点击 + 进度提示

## 新功能
- 财务页重设计:中间模糊搜索框(代码/名称),选股后展示 4 标签页详情
  (核心指标/利润表/资负表/现金流),字段格式化(百分点/金额转亿/每股)
- 分钟K向前扩展:Expert+ 新增「月」单位(1~6 月,180 天),Pro 仍只「天」(15 天)

## localStorage 残留自愈(拉新代码后不再显示本地开发残留)
- 策略池:加载后自动清除失效的自定义策略 ID
- 回测页:校验 selectedStrategy 是否存在,失效则重置;result 不跨会话恢复

## 重构
- 提取共享 tier 工具到 capability-labels.ts(TIER_RANK/isExpertOrAbove)
2026-06-19 00:10:01 +08:00