Commit Graph

179 Commits

Author SHA1 Message Date
claude_dev 8c06ef1e53 feat(bridge): 补 /orders+/cancel 端点与客户端(实盘查委托/撤单)
bridge.py: POST /cancel + GET /orders; xt_gateway: query_orders/cancel_order(含xtquant状态映射50挂单/56已成/57拒单/54撤单); bridge_client: get_orders/cancel_order. 已在 VPS 生产验证.
2026-07-15 07:12:46 +08:00
claude_dev 0761342baf feat(trader): live bridge token 改从 config 读取,免容器重建
容器 docker run(非 compose)注入 BRIDGE_TOKEN env 需重建容器,风险大。改为 live_cfg.bridge_token 优先、fallback BRIDGE_TOKEN env。run_live_step 每次 load_config,改 config 免重启即生效。

- _shadow_trades_to_bridge + reconcile_from_bridge 两处 token 读取
- config: live.bridge_token 占位空值(真实值填 NAS gitignored config,不入库)
- tests: +6 测试(config优先/env fallback/都无跳过),191 passed
2026-07-13 19:30:58 +08:00
claude_dev c041227139 chore: gitignore放行tests/data+docs/data(老坑data/误伤),补回硬化测试
data/ 规则匹配任意 data 目录,误伤 tests/data(硬化测试)和 docs/data(15min设计文档),
此前靠 git add -f 临时绕。加 !tests/data/ !docs/data/ 例外一劳永逸。
2026-07-13 11:59:39 +08:00
claude_dev 4b83452294 fix(data): backfill硬化—重登on-error/登录超时/断路器/marker-resume+冷却续跑watcher
首跑5yr 673/5493后baostock连接死、定时重连没恢复、登录卡死=被限流。修四个硬伤:
- 重登on-error: except分支强制bs.logout+login建新socket再retry(原只sleep重试同死socket)
- 登录超时: SIGALRM给bs.login套30s闹钟,防永久挂起
- 断路器: 连续30只failed→save_progress+break+exit 2,不再假完成空跑2000票
- marker-resume: load_progress扫.baostock marker文件(非done JSON),failed无marker永远重试
- watcher: 每30min探测baostock,可登就续跑,冷却就等,exit 0则退出
9/9单测绿(Mac venv311 mock baostock)。
2026-07-13 11:56:23 +08:00
claude_dev b322f4e07b fix(backtest): degenerate改status=done+flag—前端status map兼容
degenerate 原为独立 status 值,但前端 statusLabelMap 只认 done/failed/running/pending,
21个零成交结果在 Dashboard 计数/History 筛选/chip 标签消失或空白。改 status='done'+
statistics.degenerate=True+reason,结果页诚实显示 0+空成交,列表/计数正常。
2026-07-13 11:56:23 +08:00
claude_dev 8d55e414fa fix(backtest): A股适配层—定寸/做空拦截/真实费用/口径统一(Phase1+2)
审计发现包装层系统性失真(2 CRITICAL+7 HIGH),vnpy底座可信但A股场景未适配:
- C1 定寸: engine.size=N(满仓手数),策略volume=1手=N股,开平对称(pos归零)
- C2 做空拦截: SHORT+OPEN拒单,long-only,SHORT+CLOSE平多允许
- H3 A股费用: AShareDailyResult重算(佣金保底5元/印花税卖方/过户费沪市)
- H4 收益口径: simple return从balance算(不再用vnpy log return喂empyrical)
- H5+口径: benchmark ffill对齐不缩样本; sizing_shares_per_lot暴露
- H7 退化检测: 零成交/空数据标degenerate不静默done
- H8 task_id: optimize/factor用uuid4(原id()内存地址)
- 静默except改warning

验证: 容器内真实vnpy DoubleMa 600000 2022-2024, total_return 1e-6→42.3%,
end_balance 100万→142万, SHORT+OPEN成交0笔, N=7800股/手.
22 backtest测试全绿(含集成测试), API健康200.
2026-07-12 23:39:45 +08:00
claude_dev 292de31eaf perf(data): backfill支持--shard/--total分片并行(6-worker,39h→6h) 2026-07-12 09:15:12 +08:00
claude_dev d77e1ff7a1 fix(data): backfill脚本参数化NAS_ROOT/BS_START_DATE(Mac/NAS+5.5yr兼容) 2026-07-12 08:57:15 +08:00
claude_dev cf4b3a2cb0 feat(data): 15min数据补全—路径参数化+cron入口+回填+设计文档
- download_minute.py: STOCK_ROOT环境变量参数化(Mac/NAS兼容); 修tencent备源amount聚合 last→sum
- refresh_15min_daily.py: 新建cron入口(交易日判断baostock/直连pop代理/日志)
- 回填470缺口(170 SH/SZ成功, 300 BSE源不支持)
- docs/data/15min-data-design.md: 15min数据层设计文档(源/覆盖/脚本/刷新/约束/路径映射)
2026-07-12 08:26:30 +08:00
claude_dev 10508db11d fix(backtest): 结果页4个显示bug—成交枚举/时间/浮点精度/日志空
1. 交易详情方向/开平显原始枚举: Direction.LONG/Offset.OPEN → 买/卖、开仓/平仓/平今/平昨
   (TradesTable 加 fmtDir/fmtOff, 方向带涨跌色)
2. 交易详情时间 2024-06-25T00:00:00+08:00 → 2024-06-25 (日内带时分则保留)
3. 每日收益浮点精度 0.6533000000054017 → 0.65 (toFixed2, 涨跌色), 日期去 00:00:00
4. 日志tab硬编码"暂无日志数据": 前端接 getLog(/task/:id/log) + 后端 cta_engine 加
   stdout tee 把引擎 load/run/stats 输出落盘到 {task_id}.log (worker 进程内隔离)
   → 新回测日志 tab 显示真实引擎输出(2117字)

验证: 交易 买/开仓/2024-06-25, 收益 0.15, 日志 2117字真实内容
2026-07-11 23:31:50 +08:00
claude_dev 0c7b030773 fix(charts): 回测结果5图canvas宽度仅100px被压扁
根因: useChart 在 onMounted 调 echarts.init 时, 容器(在 el-tab-pane 内)尚未拿到
真实宽度 → canvas 用默认 100px; 且 setOption 后从不 resize, 数据异步到达后 canvas
仍停在初始窄宽 → 5 条曲线全被压成窄条。

修复(useChart 一处, 全部图表受益):
- setOption 后调 chart.resize() (数据到达时容器已布局, 同步真实宽度)
- 加 ResizeObserver 监听容器尺寸变化 (兼容 init 偏早 / tab 切换 / 窗口缩放)
- ensureChart() 懒初始化兜底

验证: canvas 宽 100→830px(满宽), 5 图横向铺满曲线正常
2026-07-11 23:16:05 +08:00
claude_dev a8105264cd fix(layout): 顶栏被挤成窄条、用户区跑到中央不在右上角
根因: Layout 内层 <el-container> 用原生 <header>(非 <el-header>),
element-plus 不会自动转纵向 → flex-direction 保持 row, header 与 el-main
横向并排, header 被挤成 308px 窄条(应满宽 ~992px), 用户区(头像/用户名/登出)
随 justify-content 落到屏幕中央, 不在右上角。

修复:
- 内层 <el-container direction="vertical"> 强制纵向 → header 回到顶部满宽栏,
  el-main 在下; 用户区回到右上角
- 顶栏静态口号 "投研·回测·模拟 控制台" 换成动态面包屑(分组/页名, 按路由推断)
2026-07-11 22:53:04 +08:00
claude_dev 59da65b839 fix(backtest): 结果页指标全显"—" + 任务重启后404
两个根因:

1. relative_metrics 缺字段(routes.py): get_result 的 relative_fields 列表
   漏了 total_return/annual_return/sharpe_ratio/max_drawdown 4 个字段, 导致
   这 4 个指标永远进不了响应 → 前端 MetricCards 显"—"。补全为 11 字段。

2. 任务 task_id 不持久(runner/cta_engine): submit_cta 用 cta_{symbol}_{id(params)}
   (内存地址) 作 runner id, 而 run_cta_backtest 内部另生成 cta_{uuid} 存 DB,
   两者持久层不相交 → 重启后 pool 内存映射丢失, get_result(runner_id) 的
   load_result_by_task_id 查不到 → /result 404 → 前端指标全 0 + 图表无数据。
   改为 submit 前置生成稳定 uuid, 透传给 run_cta_backtest 复用, 使
   runner-id == DB task_id (单一 id, 重启可查)。

附: Dashboard 最近任务"策略/因子"列 min-width 150→190(长策略名不再截断)
测试: test_runner task_id 断言同步新格式
2026-07-11 22:10:48 +08:00
claude_dev 41a788c431 feat(frontend): P2全平台聚宽级复刻—模拟盘/因子/回测表单页重做+模拟盘列表页
模拟盘模块:
- 新增模拟盘列表页(List.vue):统计行+富表格(名称/模式/频率/收益/最新净值/状态/操作)+搜索筛选
- 后端加 GET /paper 列表端点(类比 GET /task,带最新净值+收益率)
- paper/New 分区富表单(卡式模式选择+频率+撮合时点说明)
- paper/Result 重做(收益/年化/回撤/夏普/波动指标卡+净值曲线+归因表+成交明细,净值客户端算指标)

因子模块:
- factor/Result 重做(最优ICIR/平均IC/显著数指标卡+彩色IC表+tears报告tab化)
- factor/New 重做(因子按类分组多选+标的批量+实时计数)

回测模块:
- backtest/Progress 重做(步骤时间线+进度条+实时日志尾3s刷新)
- backtest/New 重做(策略/参数/标的区间/基准分区富表单)
- backtest/Optimize 重做(结果列头可排序+Top1高亮+按收益默认降序)
- History 迁移scoped chip→全局chips.css(DRY清理)

全局:深色主题统一,复用 tokens.css + chips.css
2026-07-11 21:10:27 +08:00
claude_dev e0d32c0d1a feat(frontend): P1仪表盘首页(统计卡+快捷入口+最近任务)+全局chip样式+侧栏工作台入口 2026-07-11 20:45:57 +08:00
claude_dev d52db7f00c feat(frontend): P0样板—历史任务页聚宽级重做(计数+类型筛选+状态色chip+搜索+分页+刷新) 2026-07-11 19:37:17 +08:00
claude_dev b2ee9f7341 fix: 深链SPA fallback(刷新/收藏结果页不再404) + 新建回测加基准选择器(hs300/zz500) 2026-07-11 16:20:41 +08:00
claude_dev 9a0b2f6131 fix(frontend): MetricCards格式化null-safe—退化指标NaN→null不再崩toFixed(显'—') 2026-07-11 16:10:22 +08:00
claude_dev 0cee8353fe deps: baostock加入requirements-docker.txt—持久化(容器重建不丢沪深300下载能力) 2026-07-11 16:05:39 +08:00
claude_dev f1fc18bc86 feat(backtest): 补全第5图VolatilityChart—metrics加rolling波动率时序+risk-series端点+前端接入(凑齐聚宽5图全套) 2026-07-11 15:03:30 +08:00
claude_dev 468f5829b9 fix(data): baostock参数 adjustfield→adjustflag(真实参数名) 2026-07-11 15:00:05 +08:00
claude_dev 4ea740083a fix(data): index_downloader baostock error_code判断修(真实为'0'非'success',容两者)——mock与真实baostock分歧 2026-07-11 14:59:34 +08:00
claude_dev 21dd30969f fix(api): _get_metrics_file_path 两步查找(直查task_id→回退result.task_id)—兼容单测直查与API的uuid文件名 2026-07-11 14:48:35 +08:00
claude_dev 5e1ea6efa1 fix(api): _get_metrics_file_path 先解析 result.task_id(uuid)—修 runner task_id≠文件名 task_id 导致 benchmark-curve/risk-series 404 2026-07-11 14:43:08 +08:00
claude_dev 3c6f25d1b0 fix(backtest): NaN/Inf浮点→None消毒(vnpy统计+empyrical指标+时序)修JSON序列化500 2026-07-11 14:33:41 +08:00
claude_dev f7c2e2eea3 fix(backtest): benchmark全链路透传(API→runner→engine) + metrics分支用_dcfg修cfg=None导致relative_metrics空 2026-07-11 14:27:19 +08:00
claude_dev 5e5a6cf84a test(backtest): sys.modules mock 改条件式(find_spec)—容器里真模块可导入则不mock,根除collection期污染 2026-07-11 14:17:01 +08:00
claude_dev 41a855d400 test(backtest): 修复test_cta_engine的sys.modules全局污染—加模块级还原fixture(消9个级联失败) 2026-07-11 14:11:49 +08:00
claude_dev c81d254196 feat(frontend): Result.vue重构—聚宽级10指标+5图+4tab+时间缩放 2026-07-11 13:57:35 +08:00
claude_dev d0315ccbdf feat(frontend): 结果页组件—MetricCards指标卡+5图(基准/Alpha/Beta/波动率/回撤)+API封装 2026-07-11 13:54:05 +08:00
claude_dev 304844903c feat(api): 回测结果API加relative_metrics+基准曲线/风险序列/持仓/日志4端点 2026-07-11 13:48:23 +08:00
claude_dev b9197a8889 feat(backtest): 回测流程集成基准对比—产出相对指标+时序json 2026-07-11 13:44:27 +08:00
claude_dev feb32163ca feat(data): 沪深300指数下载+read_index_daily(补基准数据缺口) 2026-07-11 13:35:53 +08:00
claude_dev b50a0f97be feat(backtest): metrics模块—empyrical算10指标+5时序(聚宽同源口径) 2026-07-11 13:27:44 +08:00
claude_dev e1b8c4ac68 docs(plan): 富回测结果页实施计划—8任务TDD(metrics→数据→引擎→API→前端→部署) 2026-07-11 13:20:30 +08:00
claude_dev 6c461d4d9c docs(spec): 富回测结果页设计(v1)—聚宽级10指标+5图+4tab, empyrical后端算相对基准指标 2026-07-11 13:16:49 +08:00
claude_dev a1048690c1 test: 前后端对齐—容器复跑验证+清理僵尸测试
- test_main: FastAPI 0.139 _IncludedRouter 不再 flatten,改用 TestClient 探测路由
- datareader: 文件名(sh600000_daily)/patch target(vnpy.trader.database) 对齐 lazy import 实现
- alpha_lab/analyzer/data_adapter: vnpy.alpha/alphalens 容器专用本地 skip
- 删 4 个测废弃 sanguo_web 的僵尸测试(-1267 行死代码)
- pytest.ini: asyncio_mode=auto
- frontend: package.json 加 test script(npm test 可跑)
- NAS 容器 309 passed 全绿验证(Python 3.10,本机 303+6skip)
2026-07-11 11:45:26 +08:00
claude_dev 928a52b96f docs(live): D期§8更新—D-2含bridge完善+半自动更新, D-4b加120141诊断, 运维发现(120141/行情关/重连/token分离) 2026-07-11 08:33:51 +08:00
claude_dev aef46124b6 docs(deploy): Windows clone改sparse checkout只拉sanguo_qmt_bridge(不全量) 2026-07-11 08:07:32 +08:00
claude_dev 8f51b026fa docs(deploy): Windows bridge部署+半自动更新一站式md(git clone+update.bat, 照着做) 2026-07-11 07:48:41 +08:00
claude_dev b25b1e0331 feat(bridge): D-2 update.bat半自动更新脚本(git pull+重启bridge, 双击运行) 2026-07-11 07:44:52 +08:00
claude_dev cadc59e6dc feat(bridge): bridge稳定性完善—自动重连miniQMT+health探活+交易日判断
- xt_gateway: _open_session抽离, reconnect(stop旧trader+重建), is_alive(query探活), _retry_with_reconnect(query/order失败重连重试一次)
- query_account/positions/place_order包重试: 断线(异常/None)→reconnect→重试, broker拒单(order_id<=0)不重连
- bridge /health: is_alive真实探活(5s缓存)+断线后台reconnect(不阻塞), 不再假阳性
- trade_calendar: is_trading_day(周一-周五), /order非交易日加warning(120141提示)
- test_gateway15+test_trade_calendar6=NAS21passed, 回归bridge_client/d4a 10绿
- 修复Issue#4运维发现: miniQMT重启后bridge自动重连(无需手动重启)
2026-07-11 07:32:23 +08:00
claude_dev a93d5ed8d8 docs(live): D期§8状态更新—D-1/D-2/D-3/D-4a/D-4c验证通过, 仅D-4b等周一 2026-07-11 06:31:53 +08:00
claude_dev e77c9df0d4 feat(live): D-4c模式B reconcile—bridge回报驱动账本(真桥验证通过)
- bridge_client: from_bridge_code(sh/sz→纯数字码, to_bridge_code逆函数)
- live_orchestrator: reconcile_from_bridge 读bridge /account /positions校正account现金+持仓+持久化, 默认mode_b=false
- live_step step8: 影子后调reconcile(mode_b=true生效, mode_b=false跳过)
- config: live.mode_b开关(默认false模式A)
- test_reconcile: 10例(cash/positions校正+code转换+失败降级+mode_b跳过)
- NAS环境15 passed(reconcile10+shadow5无回归)
- 真桥集成: live_step mode_b=true → reconcile读bridge → account校正(1000万/空仓=bridge真实账本)+持久化
安全: mode_b默认关+bridge失败降级不阻断+token走env
2026-07-11 06:30:08 +08:00
claude_dev 2393097074 test(live): D-4a集成测试(mock bridge真HTTP, sanguo半边4例绿)
- _MockBridge HTTP server模拟bridge(health/order/account/positions+鉴权)
- bridge_client真发HTTP(urlopen+X-Bridge-Token)+响应解析+错token 401返回None
- _shadow_trades_to_bridge真HTTP链路:注入成交→真POST→mock收到下单+symbol转sh600000→paper_shadow_orders记录
- NAS容器4 passed
- D-4a sanguo半边端到端验证(真HTTP); miniQMT真报单另半边待Windows bridge实跑
2026-07-11 05:41:43 +08:00
claude_dev 38f5635b59 test(live): D-3持久化测试(bridge_client+影子下单集成, NAS环境11例绿)
- test_bridge_client: to_bridge_code转换(sh/sz/前缀) + HTTP mock(成功/失败返回None不抛)
- test_shadow_orders: 幂等persistence + enabled跳过 + 正向记录+symbol转换 + 幂等不重复 + bridge失败不阻断
- NAS容器真实环境(Python3.10/pytest) 11 passed
- 补 D-3 测试空缺(Sub Agent临时自测未沉淀成持久测试)
2026-07-11 05:35:20 +08:00
claude_dev 379836d34e docs(live): D期任务状态更新(D-1/D-3完成)+Windows部署联调清单
- 设计文档§8: D-1/D-3标代码完成+commit号, D-2/D-4待Windows, 附代码层验证说明
- d-phase-windows-deploy.md(新): Windows端一站式清单(D-1实测/D-2自启/D-4a联调/故障排查)
2026-07-11 00:07:18 +08:00
claude_dev ff84b3d4b0 feat(live): D-3 sanguo实盘分支(影子下单)+D期设计文档
D-3 模式A影子下单(spec §5):
- bridge_client.py: QMT bridge HTTP客户端(urllib, X-Bridge-Token, 失败不抛返回None)
- live_orchestrator: _shadow_trades_to_bridge 当日成交POST bridge(默认enabled=false)
- persistence: paper_shadow_orders幂等表+save_shadow_order/is_trade_shadowed
- config: data_platform.yaml加live段, token走env(BRIDGE_TOKEN)
- to_bridge_code symbol转换与guess_exchange一致(2位前缀)
安全: enabled=false默认关+token走env+幂等防重复+影子失败不阻断live_step

docs: phase3d-live-trading-design.md(D期完整设计)
2026-07-11 00:03:46 +08:00
claude_dev eff9ed2ae9 feat(bridge): D-1 bridge MVP—FastAPI 4接口(xtquant封装+token鉴权+sh/sz代码转换)
- bridge.py: lifespan连miniQMT, health/order/account/positions, 连不上不崩
- xt_gateway.py: xtquant单例封装(延迟import), 照搬check_xtquant验证模式
- auth.py: X-Bridge-Token校验(hmac防时序攻击), 未配token返回503不裸奔
- requirements.txt(fastapi+uvicorn) + README.md(Windows部署步骤)

安全: 无硬编码secret, token/userdata/account均走环境变量(grep验证CLEAN)
2026-07-10 23:48:59 +08:00
claude_dev 6a40ae9336 fix(bridge): check_xtquant step3改用StockAccount对象(xtquant本版无xttrader.STOCK_ACCOUNT) 2026-07-10 23:25:04 +08:00