Simon
|
36fe018075
|
docs+chore: 同步操作说明与端到端自检(字段库/单位换算、因子参数化)
- docs/USAGE.md:
· 因子层一行改为「代码注册表投影 + 参数化实例,参数写在名字里以冻结口径」;
· 新增 `GET/POST/PATCH /api/factors`、`GET /api/factors/templates` 与
`/api/condition-fields`、`/fields` 的说明;
· 新增「参数化因子(2026-10)」块:受控范围、键必须写全参数(缺项就靠可改的
默认值兜底 = 追溯改义,所以拒绝)、口径文案按代码收敛、停用 ≠ 删除、
参数化因子也能当过滤条件;
· 自检清单一并更新(pytest 500 条;verify_strategy_workspace 145 项 skip-job;
verify_ui_alignment 8 页 160 项;新增 verify_unit_conversion、verify_factor_params)。
- scripts/:新增 verify_unit_conversion.py(单位只能在给定范围里选 + 界面单位⇄
基准单位换算)、verify_factor_params.py(参数暴露/界面新建/越界拒绝/停用语义,
跑完自动清掉临时因子);verify_strategy_workspace.py 加 [5.7b] 因子参数化一节,
临时因子的清理挪进 finally(断言中途失败也不给真人库留垃圾)。
- .gitignore:docs/screenshots/ 是临时验证证据,不入库(文件留在磁盘)。
|
2026-10-01 16:38:54 +08:00 |
|
Simon
|
50a1030afa
|
fix(web): 参数表单收束 + 一句话说明改多行(按截图实测修两处失调)
用户给了真实截图,指出两处肉眼可见的不协调,逐项定位后修复:
1. 「一句话说明」是单行 input 被塞进 ~360px 的格子,placeholder
「例:全市场股息率最高的 2」直接截断 —— 内容太多、框太小。
→ 改为整宽多行 <textarea>(rows=2、min-height 64px、可纵向拉伸),
与定宽 340px 的策略名并排(.params-meta flex),窄屏自动上下堆叠;
实时字数 (N/300) 已在提示里。
2. 「太多地方没有对齐」的根因:表单铺满 ~1900px 内容区,5 列各 ~360px,
控件拉得太开;因子下拉用 1fr 撑到 ~1500px 而权重框才 118px,比例失调;
数字输入还有 max-width:180px 上限,比同行下拉窄一截。
→ .params-form 约束到 ~1100px(每列 ~210px,所有控件按 1fr 等宽,
左右边缘严格对齐);移除已多余的 max-width:180px(限宽后它反而
制造新的不等宽),数值/日期改为填满单元格;因子行首列封顶 460px、
整行限宽 720px,条件行同理(首列 ≤360px、限宽 760px);
复权口径选项去掉括号里的「股息策略推荐」(已在 hint 说明),不再截断。
验证方式也升级了:这次是**截图后用 read_image 看渲染像素**确认,而不只量几何。
对齐自检同步把 textarea(高度随行数变、本就该比单行高)排除出「同排等高 /
高度归一」比较,并把数字过宽阈值调到 240px(限宽后 ~210px 属正常)。
门禁:tsc 0 错误、图表单测 7/7、next build 成功、页面 200、
对齐自检 140/140、契约自检 59/59;/backtest 与 /strategies 截图复核通过。
|
2026-09-30 19:56:40 +08:00 |
|
Simon
|
9aaca12751
|
fix(web): 控件对齐与输入友好整改(控件高度令牌化 + 对齐自检脚本)
问题不是"不好看",而是**可测量的错位**:同一行里原生 date 输入 38.8px、数字输入
36.8px、按钮 34px;16px 的勾选框与 36.8px 的下拉同排;因子行的下拉与权重框没有
可见标签;列表里的勾选框点不中;参数非法时「运行回测」直接置灰且不说原因。
根因:控件高度靠「上下 padding + 行高」拼出来,而 input / select / button 的原生行高
各不相同(Chrome 的 date 还会多 2px),必然参差;加上各处内联像素宽度
(style={{width:220}}、flex:1)与自搓布局,列自然对不齐。
改动:
- 新增控件高度令牌 --ctl-h-sm/md/lg(28/34/38px)与 --ctl-px,.input/select/.btn/
.icon-btn/date 统一显式 height(不再拼 padding);原生 checkbox/radio 统一 16px,
点击热区交给外层 label(.check/.radio-row/.check--cell),表格整格可点
- 因子行、选股条件行改为「表头 + CSS 栅格」成列对齐,列宽由样式决定,
去掉内联像素宽度与 flex 拉伸,配 aria-label 供读屏分辨重复行
- 表单友好化:错误提示改为**失焦或提交后**才出现(清空重填的瞬间不再标红);
提交被拦下时一次展开全部行内错误 + 自动聚焦并滚动到第一个问题字段;
运行/保存按钮不再因参数非法而置灰(灰按钮不说原因 = 看起来不可点却无响应),
改为可点击并讲清原因;补齐 topN/costs 两处「产生了却没人显示」的行内错误落点
- 数值字段补 inputMode/step/min/max 与单位、取值范围提示;工具条检索/筛选用
.input--search/.input--filter/.input--picker 类,不再写内联宽度
- /experiments 筛选无结果的空态与「暂无实验」区分开(原文案会让人以为归档丢了)
- 同一页面可能挂两份表单:radio name 与 label/for 加表单实例前缀(useId),
否则两边单选互相取消、label 指错控件
- 新增 scripts/verify_ui_alignment.py:系统 Chrome + 原生 CDP(仅标准库,
独占随机端口与临时 profile),按 7 个页面 × 1500/375px 检查同排等高、
高度取值归一、点击目标、标签与无障碍名、字号圆角一致、尺寸匹配内容、
横向溢出、提示裁切;本次基线 108/32 → 现 140/140
验证:pytest 388 passed、ruff 全绿(顺带清掉 qlib_verify.py 一处死代码)、
tsc 0 错误、图表单测 7 passed、next build 成功、契约自检 59/59、
对齐自检 140/140(含 375px 小屏)。
|
2026-09-27 09:01:55 +08:00 |
|
Simon
|
82240e383d
|
docs: 同步操作说明/架构/路线图(归档操作、图表基座、数据库目标硬约束)
- USAGE 新增 §6.3.1「归档的日常操作」:查看 / 筛选(回写 URL)/ 导出完整 JSON /
以此参数再跑 / 删除(写明「删除即失去结果,结果只存归档一份」)/
历史归档用 restore_experiment_from_job 按原 id 重建;并说明归档完整度如何标注
- USAGE/README 更正技术栈与图表基座:TradingView Lightweight Charts 4.2.3 为唯一
图表基座(ECharts 已从 package.json、pnpm-lock.yaml、node_modules、文档与
架构图标注中全部清除),并记录实测证据(个股页图表根节点为
div.tv-lightweight-charts,页面 canvas 无一来自其它图表库)
- ARCHITECTURE 更正「当前数据库」(原写 SQLite/未来 MySQL):现为本机 MariaDB 10.11,
§6 补目标库硬约束;USAGE 补服务器身份与实测连接证据
- AGENT.md 新增 §0.1:数据库目标只允许本机 MariaDB,禁止 192.168.1.10,
由 config.py::assert_db_target_allowed 硬拦截(命中直接抛错,不静默降级)
- DEV_PLAN_DIVIDEND_BACKTEST 记录三轮实施与验证、归档恢复边界(§12.5)、已知限制
- DEV_PLAN v2/v3 标注为历史记录(避免把当时的远端库地址当现状照抄);
ROADMAP 更正 M3 图表选型
|
2026-09-20 07:31:20 +08:00 |
|
Simon
|
adaf97f6d7
|
docs: 记录 v3 开发执行状态(M9 + 支撑线 + 延后项)
|
2026-09-09 07:43:53 +08:00 |
|
Simon
|
8abfd6538c
|
docs: 制定架构 v3 下阶段开发计划(DEV_PLAN_v3,Chart/Signal↔Fill/个股页主线)
|
2026-09-09 07:01:10 +08:00 |
|
Simon
|
314bfc159f
|
docs: 同步 README/USAGE 至 M6–M8(选股系统主线 + MySQL + 新 API/Agent 工具/限制)
- README:架构分层示意(Selection/Signal/Portfolio/Composite Engine)、MySQL 默认配置、
核心能力表、里程碑 M0–M8
- USAGE:概览模块与页面清单、引擎分层 §6.0、API 表新增 /api/selections /api/signals
/api/strategies /api/composites、Agent 10 工具、已知限制(M8.4 延后/全市场选股同步耗时)
|
2026-09-09 06:29:51 +08:00 |
|
Simon
|
db147c4232
|
docs: 记录 M6–M8 执行状态(ROADMAP 里程碑行 + DEV_PLAN 章节)
|
2026-09-09 00:42:17 +08:00 |
|
Simon
|
697ffc767b
|
docs: DEV_PLAN_v2 以选股系统为下一阶段主线(用户定调)
- 新路线:M6 选股系统(Universe 选股范围 + Selection Engine A 条件/B 评分 +
selection_result/snapshot 落库 + /api/selections + 回测共用引擎 + Web 选股页)
→ M7 因子层落地(原 M6 内容后移为支撑)→ M8 Signal/Portfolio/Strategy/Agent/模型选股
- 选股 MVP 复用现有数据与 9 因子/composite_score,不阻塞于因子入库
- 明确历史/当前 as_of 一致性、selection_reason 可解释、未来函数防护与范围控制
|
2026-09-09 00:06:31 +08:00 |
|
Simon
|
0ffd574f30
|
docs: 下阶段开发计划(架构 v2 落地 M6-M8)+ MySQL 迁移文档同步
- docs/DEV_PLAN_v2.md:基于 ARCHITECTURE_v2 与 M0-M5 现状的下一阶段计划
(M-DB 迁移收尾 → M6 因子定义入库/复合因子/口径修复 → M7 Selection/Signal/
Portfolio 引擎分层 → M8 Strategy 平台化/Web 做实/Agent 工具补齐;含本机 Redis
127.0.0.1:6379 的接入触发点与执行顺序)
- ROADMAP.md:登记 M-DB 里程碑并指向 DEV_PLAN_v2
- USAGE.md / README.md:数据库描述由 SQLite 更新为 MySQL(config.yaml database.mysql)
|
2026-09-08 23:58:51 +08:00 |
|
Simon
|
a3fabf9ae9
|
docs: 新增架构文档 v2(ARCHITECTURE_v2)
|
2026-09-08 21:48:23 +08:00 |
|
Simon
|
442999f701
|
feat(data): 财务/日线同步增量 + 新浪「两边一致」校验兜底 + 逐只进度
- financial 默认增量:按 A 股披露节奏判断已最新并跳过;--full 强制全量重拉
- Tushare fina_indicator 增加报告期窗口与 100 条/请求自动分页(修复老报告期静默截断)
- 新浪兜底收紧为校验兜底:两源重叠历史一致才导入缺失键,行标记 source=sina;
财务可比字段取 eps/销售毛利率(ROE 两端口径不同不作依据),日线只比较最近重叠交易日
- CLI 输出逐只进度与导入内容描述(来源/行数/报告期与公告区间),失败股票留待重跑
- financial_indicator 增 source 列(迁移 d3f6c9a21b04);新增一致性/分页/服务测试
|
2026-09-08 21:48:09 +08:00 |
|
Simon
|
55b684fbe1
|
feat(scripts): dev.sh 前后端一键 start/stop/restart/status/logs
- 启动后端 uvicorn(:8000, --reload, 0.0.0.0) + 前端 next dev(:3000),setsid 独立进程组
- 停止按 pidfile + 监听端口双定位,整进程组清理(无子进程残留,实测残留 0)
- 端口探测 ss 优先(lsof 在该环境对 socket 不可靠)
- status/logs/restart;支持 API_PORT/WEB_PORT/BACKEND_API_URL 覆盖
- 日志落 logs/,pid 落 .run/(均已 gitignore);USAGE §5 增加用法
|
2026-09-07 20:13:39 +08:00 |
|
Simon
|
b78852f01b
|
fix: 前端同源代理 /api → 后端(任意 IP 访问不再 NetworkError)+ SQLite 写锁等待
- 根因①:页面硬编码 http://127.0.0.1:8000/api,从 192.168.1.160:3000 访问时浏览器请求自身/跨域失败
- 根因②(500):全市场数据同步(长写事务)持有 SQLite 锁导致读接口 database is locked
- 前端:next.config.ts rewrites /api/* → http://127.0.0.1:8000/api(BACKEND_API_URL 可覆盖);
lib/api.ts 默认相对 /api 同源(NEXT_PUBLIC_API_BASE 保留为直连覆盖项);.env.local.example 说明两种方式
- 后端:CORS 开发期 allow_origins=["*"](无凭据,上线前收紧);SQLite engine busy_timeout=30s
- USAGE FAQ 同步;验证:192.168.1.160:3000/api/health 与 /api/factors 经代理 200,CORS 头 access-control-allow-origin: *
|
2026-09-06 19:00:49 +08:00 |
|
Simon
|
fc12ba89ad
|
docs(USAGE): 更新至 QlibEngine v1 / Parquet 导出后的最新状态
- 适用版本 HEAD、技术栈(pyarrow/pyqlib/LightGBM)
- 新增 §6.1 双引擎说明(LocalEngine 默认 / QlibEngine v1 切换与 float32 差异)
- 补 export 命令、API 端点(health/stocks/{symbol})、引擎与 Parquet 相关 FAQ
- 测试计数与覆盖清单更新(86 passed)
- 限制与说明同步(QlibEngine init 幂等、Alpha158+LightGBM 仍为 TODO)
|
2026-09-06 18:23:37 +08:00 |
|
Simon
|
bbb5c1ea52
|
feat(cli): sync export — 日线按年导出 Parquet(data/parquet/stock_daily/<year>.parquet)
- 对应 ROADMAP §1.4「历史时序大数据转 Parquet」;pyarrow 随 qlib 依赖已可用
- 用法:uv run python -m app.cli.sync export [--years 2023,2024]
- 实测:9680 行 → 2023/2024 两个 parquet(data/parquet 已被 gitignore)
- ruff clean / pytest 86 passed
|
2026-09-06 18:21:55 +08:00 |
|
Simon
|
b8f67f99ae
|
feat(quant): QlibEngine v1 — 本地行情落盘 QlibDataset → D.features 读取 → 因子回测
- qlib_adapter/provider.py:SQLite 行情按 qlib 0.9.8 二进制格式落盘(起始索引头 + 逐日 float32、instruments 3 列、小写 instrument、晚上市 offset)
- qlib_adapter/dataset.py:qlib.init 幂等({'day': uri})+ D.features 读取 close 面板
- qlib_adapter/engine.py:QlibEngine(QuantEngine)v1 —— Qlib 数据管线回测与 LocalEngine 同记账规则(无未来函数/成本/涨跌停标注),factor_test 复用共享实现;Alpha158+LightGBM 为 TODO
- 真实 20 股验证:qlib 落盘 142 文件→读取→回测(-12.81%,Local 对照 -12.97%,差异为 qlib float32 存储)
- tests/test_qlib_engine.py 5 项(格式/roundtrip/晚上市 offset/回测/因子测试)→ pytest 86 passed / ruff clean
|
2026-09-06 18:20:28 +08:00 |
|
Simon
|
880f4c50fe
|
docs: Qlib 安装可用性验证报告 + 基线验证脚本
- pyqlib(0.9.8.dev32 源码安装)验证:import / 数据落盘 / storage 底层读回 / Alpha158 / LGBModel 均通过(scripts/qlib_verify.py 可重复)
- 记录格式要点:小写 instrument、instruments 3 列、provider_uri 需 {'day': path} 字典
- 如实记录未打通项:D.features→训练→回测高层链路仍待 QlibEngine 实现(建议按官方 dump 规则落盘)
- 项目回归保持 81 passed / ruff clean
|
2026-09-06 18:02:22 +08:00 |
|
Simon
|
01d818e12a
|
docs: 使用说明 docs/USAGE.md;LLM URL/模型名配置移到 config.yaml(.env 仅 Key)
- config.yaml 新增 agent.llm:base_url / model 明文配置(默认百炼兼容端点 qwen-plus),api_key 只从 .env 的 LLM_API_KEY 读取;LLM_BASE_URL / LLM_MODEL 仍可经 .env 覆盖
- .env.example 注释同步;core.config 读取逻辑 env > yaml > 默认
- docs/USAGE.md:安装/配置/数据同步/启动/研究 API 与 Job/Experiment/Agent/测试门禁/已知限制/FAQ
- README 增加使用说明入口
- 新增 config LLM 测试 2 项(yaml 默认 + env 覆盖)→ pytest 81 passed / ruff clean
|
2026-09-06 17:57:15 +08:00 |
|
Simon
|
8f8b6d274f
|
feat: 解决 aarch64 上 Qlib 安装(源码 git 固化依赖)并记录下载代理规则
- backend/pyproject.toml + uv.lock: pyqlib 以 git+https 固定 commit 79633dd 注册为核心依赖,
替代无法在 Linux aarch64 安装的 PyPI wheel(ROADMAP §2 旧备注)
- engine.py: 更正占位说明(Qlib 现已可安装,工作流实现待 Phase 2 补齐)
- AGENT.md §0: 网络下载困难时使用 HTTP 代理 192.168.1.160:3128
- README / ROADMAP: 同步 Qlib 安装方式与代理说明
|
2026-09-06 17:45:01 +08:00 |
|
Simon
|
d9be75a98f
|
feat: Phase 5 — AI Research Agent(受控工具白名单 + LLM 编排 + API)
- agent/tools.py:Tool 元数据(JSON Schema)+ 白名单调用(异常转可读反馈,不中断对话)
- agent/tools_impl.py:6 个受控工具 search_stocks / get_market_data / test_factor / run_backtest / get_experiment / compare_experiments —— 全部只读经 Job/Experiment 链路,研究自动归档;无 shell/任意执行/写删数据能力
- agent/llm.py:LLMClient 抽象 + OpenAI 兼容客户端(LLM_API_KEY/LLM_BASE_URL/LLM_MODEL 走 .env,未配置给出引导提示)+ 研究纪律 system prompt(反过拟合/样本外/成本)
- agent/service.py:编排循环(tool/final JSON 决策 → 执行 → 回喂 → 结论),轮次上限兜底,未知工具拒绝
- /api/agent/chat;httpx 移至主依赖;Job 默认工厂抽取(api/agent/executor 复用)
- 测试 6 项(白名单无 shell、完整研究循环产出、未知工具拒绝、轮次兜底),全量 79 passed / ruff clean
|
2026-09-06 17:22:05 +08:00 |
|
Simon
|
e9f59d3cf8
|
feat(backend): Phase 2 研究引擎 — ResearchSpec / 因子 / 评估 / 低频回测 / 引擎抽象
- domain:ResearchSpec(universe/factors/selection/rebalance/costs 校验)+ 标准化 BacktestResult / FactorTestReport
- 因子引擎:注册表 + 元数据,内置 9 个行情因子(momentum/volatility/量比/乖离/反转),支持自定义注册;只用行情字段规避未来函数
- 评估:横截面 IC / RankIC(rank+pearson 免 scipy)/ ICIR / 分层收益
- 回测:TopK 等权低频,无未来函数记账(t 收盘成交、自 t+1 计收益),成本/涨跌停/停牌约束,未建模项显式写入 unimplemented(AGENT §24)
- 引擎抽象 QuantEngine + LocalEngine(pandas 默认实现);qlib_adapter 桥接占位 —— pyqlib 无 aarch64+cp312 wheel(ROADMAP 已备注)
- 真实链路冒烟:600519 2024 月度动量回测闭环产出标准结果
- 测试 60 passed / ruff clean
|
2026-09-06 17:08:00 +08:00 |
|
Simon
|
7a89d97c0b
|
docs: 新增开发路线图与架构 / 数据流水可视化图
- docs/ROADMAP.md:M0-M5 里程碑与 Phase 1-5 开发计划(含验收口径与硬约束自查)
- docs/diagrams/qlib-architecture.html:系统架构图(Web→API→Service→Domain→存储,Qlib Adapter 与数据源支线)
- docs/diagrams/qlib-dataflow.html:数据流水图(Tushare/Sina→落地→特征→研究→实验→消费)
- 均按 archify showcase 校验交付,1440×900 ~ 2048×1320(light/dark)无溢出
|
2026-09-06 16:27:16 +08:00 |
|
Simon
|
8eb3b4ac2a
|
chore: 项目初始化 — 工程文档、配置与目录骨架
- AGENT.md / docs/ARCHITECTURE.md 约束与架构文档入库(README 覆盖远端模板)
- 根级配置:.gitignore / .env.example / config.yaml(密钥只走 .env,不入库)
- 目录占位:data(parquet/qlib/raw/normalized) / experiments / docker / frontend/web / scripts
|
2026-09-06 16:09:07 +08:00 |
|