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
|
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
|
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 |
|
 kevin9327andClaude Opus 5
|
7fde21c8c9
|
fix(ext-data): 文件上传与接口写入的缺省落盘日期改用北京日期, 非法日期返回 400
定时拉取的落盘日期已改用 cn_today() (#268), 同一张时序表的另外两条写入
路径仍是裸 date.today():
- POST /{id}/upload: 前端「文件」页签从不传 snapshot_date, 每次都走缺省值
- POST /{id}/ingest: 「接口」页签的 curl 示例不带 date, 同样走缺省值
- write_ext_parquet(snapshot_date=None) 的服务层缺省值
UTC 容器里北京 00:00-08:00 之间写入的数据落进前一天的分区。显式传入的
日期直接 date.fromisoformat, 非法值抛 ValueError 变成 500; 改为复用同文件
/rows 已有的 _partition_date 校验, 返回 400。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-09-14 19:31:15 +09:00 |
|
shy3130
|
72cbf67070
|
feat(ext-data): 拉取超时进配置, 默认 30 秒与历史行为一致
大响应接口 (如全量集合竞价 /day, 实测 ~77s) 在硬编码 30s 超时下必然失败。
- PullConfig.timeout_seconds: 5~300, 默认 30; config.json 缺字段或手改
非法值时归一 30 (fail-closed), 旧配置零迁移
- _request_json (定时拉取/手动拉取/测试/回填共用) 与 detect-url 探测
均读该配置; detect-url 请求体新增同名字段, 创建对话框可随测试识别传入
- 编辑面板 (ExtDataPullPanel) 与创建对话框 (CreateExtDialog) 增加
拉取超时输入框, 创建时随拉取配置一起落盘
|
2026-09-14 15:38:45 +08:00 |
|
 kevin9327andClaude Opus 5
|
467d3eb896
|
fix(sector-rotation): 分钟涨跌幅基准价为 0 时板块切换与板块分时不再返回 500
板块切换 (services/sector_rotation) 与板块分时 (api/ext_data
dimension-intraday) 同口径计算 pct = 分钟 close / ref - 1, ref 优先前一
交易日日K收盘, 缺失退化为当日首根分钟 close。两处都没有排除 <= 0 的价格:
前收为 0 或首根分钟 close 为 0 时 pct 为 inf, drop_nulls 不剔除 inf,
Starlette JSONResponse 以 allow_nan=False 渲染, 只要一只成分股数据异常,
整张卡片 500。
仓库其它同口径计算已经守护: quote_service 指数涨跌幅 prev_close != 0、
intraday_features pct_vs_prev_close 的 _prev_close > 0、kline
_get_previous_closes 的 isfinite 且 > 0。
两处各改两行, 口径一致:
- _prev_daily_close: 前收 <= 0 / 非有限视为缺失, 由调用方退化为首根有效分钟 close
- 分钟行: close <= 0 / 非有限视为无效行, 不作基准也不作分子 (否则是 -100% 假跌幅)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-09-14 07:00:29 +09:00 |
|
shy3130
|
4abe9e9caa
|
feat(ext-data): 日内序列表 — time_field 配置支持集合竞价等多盘数据接入
- PullConfig 新增可选 time_field (空值归一 None, 旧配置兼容); API PullConfigReq 透传, rows 端按时间列升序
- 时序表写入去重键: 配置 time_field 时按 [symbol, 时间列] 去重 (同 symbol 同时刻幂等, 不同盘并存), 未配置行为不变
- enriched/因子链路无需排除: _load_ext_value_maps 与 ext_factors 既有 unique(symbol) 兜底, 多行表确定性收敛
- 前端拉取面板新增时间字段输入框; 配合 hub auction_flow /day 端点逐日回补竞价多盘数据
- 新增 test_ext_time_field.py: 多盘并存/覆盖/默认行为不变
|
2026-09-13 23:50:10 +08:00 |
|
shy3130
|
7cb736e23c
|
feat(ext-data): 历史回补支持时间戳类日期参数 (date_format)
- PullConfig 新增 date_format: iso/compact/ts_s/ts_ms, 非法值归一为 iso
- 时间戳口径为交易日北京时间 00:00:00, ts_s 秒 / ts_ms 毫秒
- 回补逐日请求按配置替换 date 参数值; API configure_pull 接受 date_format
|
2026-09-13 14:14:07 +08:00 |
|
kevin9327
|
ba3d6d9e65
|
fix(ext-data): rows 的 date 入参先校验再拼分区路径
`_read_ext_dataframe` 把 `date` 查询参数原样拼进 `timeseries/date=<值>`, 未经校验,
于是 `date=x/../../../../kline_daily` 读到的是 `ext_data/<id>/timeseries/` 之外的
`part.parquet` 并从 /rows 返回。同一文件的 /sync、/ingest、/backfill 都先
`date.fromisoformat` 再用, 只有这条读取路径没有。
拼路径前规范成 YYYY-MM-DD, 非法值按本文件既有约定返回 400。合法日期、
分区不存在、不传 date 三种情况的行为不变。
|
2026-09-11 00:50:33 +09:00 |
|
kevin9327
|
387de3b2f1
|
fix(ext-data): 卡片「最新」时间按北京墙钟, 不再随服务端时区漂移
扩展数据页同一张卡片上两个时间对不上: 底部「最新」显示 10:30:00, 而设置
里拉取面板的「上次」显示 18:30 —— 说的是同一次同步。Docker 镜像默认 UTC,
差的正好是一个时区。
latest_sync_date 由 parquet mtime 经 datetime.fromtimestamp(mtime) 格式化,
拿的是宿主机时钟, 且不带时区后缀; 前端 ExtDataStatCard 原样展示这串裸时间,
没有任何换算余地。旁边的 pull.last_run/next_run 是 datetime.now(timezone.utc)
的带偏移 ISO, 前端 new Date(iso) 按浏览器时区渲染, 所以那一侧是对的。
快照与时序两条路径都改成 fromtimestamp(mtime, tz=CN_TZ), 与
json_report_store._now_iso「用北京墙钟而非宿主机时钟」同口径。
展示格式不变。
|
2026-09-10 08:19:30 +09:00 |
|
shy3130
|
27a019721d
|
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
|
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 |
|
shy3130
|
057d52733a
|
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 |
|
shy3130
|
cf14a65c23
|
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
|
3f861c9e00
|
Merge branch 'pr-221' into merge/pr-221-220-219
|
2026-09-01 22:20:01 +08:00 |
|
shy3130
|
6f0e367377
|
feat(abnormal,dashboard): 盘中异动聚合、维度 source_field 与板块分时端点
- abnormal_moves 新增 build_intraday: enriched 七类当日信号聚合,
优先级(涨停>炸板>翘板>跌停>新高>新低>放量)+涨跌幅排序, GET /api/abnormal/intraday
- 维度排名项携带 group_source 与 source_field(configId.field),
前端可精确判定概念/行业而非字符串包含
- ext_data 新增 dimension-intraday: 成分股×当日分钟分区等权聚合,
prev_close 优先/首根退化基准、成分网格化 ffill、全市场对照线,
小数制涨跌幅契约、60s 进程内缓存、点击触发不预计算
- 板块分时 7 测 + 盘中异动 4 测
|
2026-08-30 19:05:32 +08:00 |
|
 kevin9327andClaude Opus 4.8
|
45354e3501
|
fix(ext-data): 扩展数据上传增加体积上限并分块落盘 (#204)
问题: 扩展数据上传 /api/ext-data/{id}/upload 与字段检测 /api/ext-data/detect-fields
都直接 `content = await file.read()`, 无任何字节/行数限制。上传超大 CSV/XLSX
会把整个文件读入内存再交给 Polars/Excel 解析, 可能造成高内存占用、进程 OOM 或
服务不可用。自选截图 OCR 已有 12MB 上限, 扩展上传却没有统一上限。
修复: 抽出 _write_upload_capped(file, dest, max_bytes), 以 1MB 分块把上传写入
临时文件, 累计超过上限即拒绝(413), 不再一次性读入内存; 两个上传入口统一改用它。
上限常量 _MAX_UPLOAD_BYTES = 50MB(对扩展快照数据足够宽裕, 亦便于按需调整)。
兼容性: 后缀白名单、解析与映射逻辑不变; 仅新增体积上限。413 由 detect_fields 的
`except HTTPException: raise` 与 upload_data 的 finally 清理临时目录正常传播。
验证: 新增 tests/test_ext_upload_size_limit.py 覆盖未超限完整写入、恰好等于上限、
超限抛 413 三例, 全过; ruff 无新增告警(B008 与 origin/main 同为 2 个, 均为既有
FastAPI File(...) 默认值写法)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-08-30 18:51:24 +09:00 |
|
shy3130
|
2c02f3125e
|
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
|
a07d32811f
|
feat: release v0.1.86
|
2026-07-18 00:49:28 +08:00 |
|
wshy
|
dc267e762c
|
feat(ext-data): 新增扩展数据支持 URL 创建并调整设置弹窗 tab (#64)
- 新建扩展数据弹窗加入 URL/文件/手动 三种接入方式, URL 模式支持探测字段、预览、保存拉取配置并可选立即导入或定时拉取
- 后端新增 /api/ext-data/detect-url 探测接口, 自动识别 JSON 行数组路径、字段类型与 symbol/code 候选列
- 抽出 infer_fields_from_df / detect_symbol_candidates / apply_config_mapping 公共逻辑, 文件上传与 URL 探测复用
- 拉取写入支持仅含 code 的数据, 按 code_map 自动生成标准 symbol
- 设置弹窗 tab 顺序调整为 拉取/推送/上传, 默认显示拉取
|
2026-07-07 18:04:49 +08:00 |
|
shy3130
|
96ce227030
|
fix: 扩展数据拉取修复与连板梯队queryKey修复
|
2026-07-01 23:02:37 +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
|
001a60a0d5
|
fix(ext-data): 上传 CSV 时自动转码 GBK/GB18030,修复 invalid utf-8 sequence
国内行情软件(同花顺/东财/通达信)及 Windows 中文 Excel 导出的 CSV 多为
GBK 系编码,而 Polars read_csv 默认按 UTF-8 解析,遇中文即抛
'invalid utf-8 sequence'。
新增 ensure_utf8_csv():先尝试 UTF-8(合法则原样返回,零副作用),
否则依次尝试 gb18030/gbk/gb2312/big5 转成 UTF-8 临时文件再交给 Polars。
覆盖上传(upload_data)与字段探测(detect_fields、parse_upload_file)三处入口,
无需新增依赖(编码均为 Python 标准库内置)。
|
2026-06-24 12:05:04 +08:00 |
|
shy3130
|
d93dc0cbf4
|
Initial release v0.1.19
|
2026-06-18 17:18:23 +08:00 |
|