Commit Graph

267 Commits

Author SHA1 Message Date
claude_dev d5d3eea236 chore: gitignore data_cache(双源验证数据本地缓存,不入库) 2026-07-08 12:17:11 +08:00
claude_dev c6b19f4244 feat(data): 恢复双源(task#79)—撮合raw+策略qfq, 分红除权准确
用户要模拟=回测准确: raw除权缺口致MA假信号, 必须双源。
- data_source: qfq→qfq_dir(干净qfq), raw→raw_dir; _check_adjust_cfg(cfg提供才校验)
- engine 双bar流: step(raw_bars,qfq_bars)撮合/盯市raw+策略on_bar qfq; run zip(raw,qfq)
- live_orchestrator: warmup用qfq(信号am); 去adjust参数(双源固定)
- raw_redownload --adjust(''raw/'qfq'); config qfq_dir
- 113/113通过
2026-07-08 07:21:33 +08:00
claude_dev ab703e93ba feat(matcher): 集合竞价CALL_AUCTION撮合(分期项)—开盘价(最大成交量原则→open)
CALL_AUCTION枚举原拒单(unsupported), 现撮合用开盘价(open, 集合竞价确定开盘价).
当前定价同NEXT_OPEN(均为open); 未来区分开盘/尾盘集合竞价需扩枚举.
test: call_auction fills@open(原rejected用例改).
2026-07-08 07:02:51 +08:00
claude_dev 7eec983164 fix(live): C-S3实走warmup(am跨日)+fetch_day wrapper+端到端验证
- live_orchestrator warmup: 重放start~昨日raw到策略am使其inited(实走每日单根, 不warmup则ArrayManager永不inited→策略无信号)
- routes _DataSourceWrapper 加 fetch_day(给 live_step 拉当日raw)
- verify_live_step 容器端到端: 创建live account+live_step(07-07 warmup+step)+存pending, 跑通(pending=0系DoubleMa当日无交叉, 撮合/存已单测)
2026-07-08 06:59:24 +08:00
claude_dev 674cfadba7 feat(data): run_daily_update加raw增量—每日15:30拉最近5天raw推NAS(C-S3实走数据管道) 2026-07-08 06:51:00 +08:00
claude_dev 6931a7b541 feat(trader): C-S3实走后端骨架—live_orchestrator+全局scheduler job+routes live
架构(简化,避per-account闭包注入):
- live_orchestrator live_step(account_id)自包含: 恢复cash/positions/pending→fetch_day raw当日→engine.step→存状态
- run_live_step(db)遍历live accounts调live_step; scheduler register_live_step_job全局20:30 job
- app startup注册全局job; routes create mode=live存account running(不跑回放)
- TODO(分期项): prev_close昨日raw/listing_days IPO算/realized_pnl恢复
- 113/113通过, live_orchestrator import OK
2026-07-08 06:49:31 +08:00
claude_dev 20bdd689af feat(persistence): C-S3实走跨日状态—paper_pending_orders+positions/last_balance存取 2026-07-08 06:46:57 +08:00
claude_dev 3aca14f723 refactor(engine): 抽出step()单根推进(C-S3实走入口,task2基础)
run()循环体抽为step(bar_date,bars,prev_close,pending)→(pending,closes);
run()改为调step。实走scheduler每日喂当日bar调step单步推进。
- 回放行为不变(test_engine原3用例pass)
- 加test_engine_step_single_bar_advances: day1信号缓冲/day2撮合
- trader全量111/111通过
2026-07-07 23:41:18 +08:00
claude_dev 05dba7fe46 feat(trader): 科创板200股最小手数(分期项切片)—lot_size_for+matcher板块取整
科创板(688/689)最小200股1股递增(不整倍); 主板/创业/北交100整倍; 卖出不取整。
- limit.py 加 lot_size_for(symbol)
- matcher cross_order 买入取整按板块(star≥200不取整, 其余100整倍)
- routes_paper cta size=lot_size_for(symbol)
- test: 688981 买150拒/买250不取整; 主板用例不变; 63/63通过
2026-07-07 23:37:50 +08:00
claude_dev 1ed7b72aca feat(data): raw真实价数据源(task#79)—raw_dir+dir_key路由+新浪源重下
根因: daily_dir mixed-adjust(hfq bulk+akshare raw tail)致3-30 -94%假跌。
方案(Linus三问简化单raw, 除权留分期项#3):
- datareader read_parquet_daily/15min 加 dir_key 参数
- data_source iter_bars/fetch_day: adjust=raw→raw_dir(缺配置报错防混源), qfq→daily_dir
- engine PaperEngine 默认 adjust=raw
- config 加 raw_dir; scripts/raw_redownload.py 新浪源adjust='' 直连+单线程限速
- 验证: 浦发606行close 6.5/14.6 mean10.08 0跳变, 撮合成交价9.71-10.25真实
- 测试9/9+trader全量108/108通过
2026-07-07 22:19:11 +08:00
claude_dev fc39b549cf docs(data): 补齐数据脚本文档(v1调研5文档复制+11脚本清单表) 2026-07-07 20:00:50 +08:00
claude_dev 1a88954126 feat(data): v2 数据下载(SSH模式 STOCK_MOUNT+rsync) + launchd定时 + 文档
- v1 data_platform 脚本复制到 v2/scripts/data_platform/ 维护
- daily_all_update.py: 路径用 STOCK_MOUNT env(SSH模式) + STOCK_LIMIT(验证)
- run_daily_update.sh: rsync拉NAS→本地 + v1增量 + 推NAS(SSH key免密,不挂载)
- launchd com.sanguo.data-update 每日15:30(替代crontab,macOS FDA限制)
- 验证: STOCK_LIMIT=2 updated=2 records=24 拉到当天
- 文档 docs/deployment/data-download.md
2026-07-07 19:41:07 +08:00
claude_dev 0543154a62 fix(paper): save_account 兼容 start/end → start_date/end_date 字段映射 2026-07-07 17:45:43 +08:00
claude_dev ddc527b39c feat(web): Result 轮询(running每3s)+状态提示, New 默认 DoubleMaStrategy 2026-07-07 15:33:46 +08:00
claude_dev ba2138e1cf fix(trader): volume×size(A股1手=100股) — DoubleMa 真策略回放 filled=3 跑通 2026-07-07 15:15:27 +08:00
claude_dev 17a4801450 fix(trader): vnpy 桥接(am/trading/cancel_all/__getattr__兜底) + create 异步回放 2026-07-07 15:03:57 +08:00
claude_dev eb6aa34b82 fix(paper): create 接入回放(engine.run) + 日线 parquet 文件名 sh/sz 前缀+_daily 2026-07-07 14:47:20 +08:00
claude_dev 88bd001a97 test(paper): Phase 3c 端到端冒烟脚本(login+create+equity/trades/strategies) 2026-07-07 12:58:14 +08:00
claude_dev 36b4299934 feat(web): 模拟盘前端(点亮入口+router+New/Result页+归因/拒单展示) 2026-07-07 12:50:55 +08:00
claude_dev cacdb5ae24 feat(trader): C-S3 scheduler(APScheduler定时+启动恢复live job) 2026-07-07 12:48:24 +08:00
claude_dev 14088eac13 feat(paper): C-S2 分策略归因(/strategies 聚合成交/拒单/费用) 2026-07-07 12:07:37 +08:00
claude_dev 041dca59e2 feat(api): /paper/* 路由(create建account+equity/trades查询,JWT) 2026-07-07 12:06:26 +08:00
claude_dev 42877213ae feat(trader): PaperEngine 主循环(逐bar重放/next_open缓冲/current_close/双层记账/持久化)
- run(): T+1解冻→撮合上根pending(用当前bar)→喂策略收单→current_close当根/next_open缓冲→盯市入库
- 双层记账一致性(总账=分户之和), checkpoint续跑字段
- StrategyRunner +symbol 字段 3 tests passed.
2026-07-07 12:01:37 +08:00
claude_dev f0d8fd2a03 feat(trader): PaperCtaEngine 策略适配器(拦截send_order→PaperOrder) 2026-07-07 12:00:14 +08:00
claude_dev b2c5d8fd79 feat(data): read_parquet_15min + trader data_source(qfq/raw双源)
- datareader: +read_parquet_15min(sh/sz前缀+15min.parquet), get_database lazy(去tzlocal等依赖)
- data_source: iter_bars cross-section yield(date,{symbol:Bar}), raw首版fallback qfq+warning(spec§17)
- 本机 mock _read_fn 测调度逻辑, read_parquet_15min 容器冒烟 4 tests passed.
2026-07-07 11:57:16 +08:00
claude_dev 308d36f2b6 feat(trader): persistence 4表+checkpoint+WAL(spec§8/§9.1)
paper_accounts(含owner_id/checkpoint_date/scheduler_job_id/match_session)
paper_trades(rejected/reject_reason/blocked_by) paper_positions(scope)
paper_daily_balance(is_checkpoint) WAL多进程读写 5 tests passed.
2026-07-07 11:52:11 +08:00
claude_dev e5e4eef807 feat(trader): Account总账+StrategyRunner分户(双层记账/资金T0/股票T1)
- Account: cash资金T0/合并持仓/equity盯市/cash_enough买单检查
- StrategyRunner: 分户持仓+realized_pnl归因/unrealized_pnl
- transfer_fee 直接用(matcher已双向,不再×2,review H3)
- unfreeze_all 对称(总账+分户,T+1每日解冻)
7 tests passed.
2026-07-07 11:50:40 +08:00
claude_dev 05d74fc2c1 fix(trader): M+L 接口校验 (listing_days/NaN/输入校验/类型注数) review
M1: PaperOrder+limit+matcher 加 listing_days(创业/科创/北交所前5日不锁,0=已过)
M3: is_locked_for_*_symbol cfg 注解 AccountConfig
M4: matcher NaN bar 拒单 bar_missing
L3: PositionLedger price/volume 正数校验
L5: PaperOrder __post_init__ volume 类型校验(拒 float/bool)
M5: current_close 契约 docstring + H3 残留注释修正(transfer_fee 双向)
79 tests passed.
2026-07-07 11:23:16 +08:00
claude_dev b874be1d84 fix(trader): matcher slippage/过户费双向/限价超涨停拒单 (H2/H3/H4)
H2: fill_price 应用 slippage(买+/卖-,默认0不影响)
H3: 过户费改双向(matcher 直接×2,Account 不再×2,删单边注释)
H4: 限价单超涨停价拒单(price_above_limit/price_below_limit)
69 tests passed.
2026-07-07 11:15:19 +08:00
claude_dev f940841a9a fix(trader): 价格精度 _price_eq + Decimal ROUND_HALF_UP (C1/H1)
C1 CRITICAL: is_one_word_lock/is_t_lock 用 == 比较价格,浮点尾数差
(5.5600000000000005 vs 5.56) 导致一字板当可成交。改用 math.isclose
容差比较 (pricetick/2)。新增 _price_eq(),所有价格 == 改用之;
相对比较 (low<open, high>open) 保留原语义。

H1 HIGH: limit_up/down_price 用 Python round() 是 banker's rounding
(round(610.5)=610),导致 5.55×1.10→6.10 而非 6.11。改用
decimal.Decimal(str(x)) + ROUND_HALF_UP。

测试:
- 5.05 一字涨停 (浮点尾数差 case)
- 9.99×1.2 创业板一字板
- 0.35×1.05 ST T 字板
- 5.55×1.10 → 6.11 (banker's 消除)
- 4.45×0.90 → 4.01

60 tests pass, 100% cov 保持。

Refs: Phase 3c C-S0 review findings [C1][H1]
2026-07-07 10:47:39 +08:00
claude_dev 67ea7763cd feat(trader): matcher.py A股撮合(match_session/费率/100股/封板) Issue#3 2026-07-07 10:05:49 +08:00
claude_dev 84bf00ea8d feat(trader): PositionLedger 单标的持仓(T+1冻结/均价) 2026-07-07 10:03:42 +08:00
claude_dev 59c8133152 feat(trader): limit.py 涨跌停板块表+封板判断(T字板保守拒单) 2026-07-07 09:39:58 +08:00
claude_dev f573a328aa feat(trader): models 数据类 + AccountConfig 费率(Issue#3) 2026-07-07 09:37:03 +08:00
claude_dev 1b87d3f7c0 docs(plan): Phase 3c 模拟盘实现计划(C-S0~S3,19 任务)
C-S0 引擎核心 TDD 完整代码(models/limit/position_ledger/matcher);
C-S1 回放端到端接口+验收(适配器/引擎/双源/持久化/API/前端);
C-S2 分户归因;C-S3 实走。含 self-review。
2026-07-07 09:34:41 +08:00
claude_dev 6c0acd2374 docs(spec): Phase 3c 模拟盘设计 v2(吸收架构+业务双 review)
架构 + A 股业务双 sub-review 后修正 6 项 CRITICAL + 4 项 HIGH:
- 复权双数据源(qfq 信号 / raw 撮合),解涨跌停系统性失真
- 涨跌停板块表(主板±10/ST±5/创业科创±20/北交所±30)+ 封板判据收紧(T字板保守拒单)
- match_session 多撮合时点(next_open/current_close),支持尾盘抓涨停类策略
- 资金 T+0、印花税 0.05%(2023.8.28 新规)+ 过户费 + 最低佣金 5 元
- StrategyRunner 明确为 CtaTemplate 适配器(PaperCtaEngine 拦截 send_order)
- 任务模型:回放走共享 DB 进度+checkpoint 续跑;实走 APScheduler 启动恢复
- owner_id/checkpoint_date/scheduler_job_id 字段补齐
- 分红送股/归因软限额/科创200股/集合竞价 标注分期(C-S3 后)
2026-07-07 09:28:58 +08:00
claude_dev 3ee64ae7bb docs(deploy): NAS 访问改 key 免密(ssh sanguo-nas),清除 sshpass + 明文 SSH 密码 2026-07-07 07:53:10 +08:00
claude_dev 8ab2acc992 docs(deploy): rsync 排除 config/(部署态含真实密码,防覆盖) 2026-07-07 07:23:14 +08:00
claude_dev 395a6bcb8c merge: Phase 3b 投研+回测 Web 控制台(Vue 前端,4 切片 S0-S3 全通)
- S0 脚手架+切 sanguo_api+登录+4入口shell(公网 vnpy.mysanguo.top)
- S1 回测核心(对齐 vnpy client:统计/资金曲线/每日盈亏/成交/K线买卖点)
- S2 投研核心(IC 表 + tears 报告)
- S3 历史任务 + 参数优化
- 73 backend tests + frontend vitest/build 全绿
- 端到端冒烟全通(DoubleMaStrategy + ma5 因子 + 优化)
2026-07-07 06:36:56 +08:00
claude_dev 1862d813d9 docs(deploy): nas-deploy-plan 更新 Phase 3b(sanguo_api + 单 worker + SPA) 2026-07-07 06:36:52 +08:00
claude_dev 54fc1b656f feat(s3): 历史任务 + 参数优化端到端跑通
- result_store.load_result_by_task_id + orchestrator.get_result DB 兜底(历史回看)
- GET /task 列表、GET /task/{id}/optimization-results
- Task.raw_result 存优化结果 list(内存)
- cta_optimizer 修同款 bug(interval d / capital 1M / vnpy DB SETTINGS)
- get_status 返回 error_msg(str 守卫)
- 前端 优化页(网格输入+轮询+结果表)、历史页(任务列表+回看)、侧栏子菜单
- 修 5 个旧 test_routes 回归;73 tests passed
- 冒烟:历史 3 任务 + 优化 9 组合
2026-07-07 06:35:54 +08:00
claude_dev 212ad6426d feat(s2): 投研核心端到端跑通(IC 表 + tears 报告)
- Task 加 raw_result 字段;orchestrator get_raw_result(内存存 FactorReport)
- 路由 /factor/list、/task/{id}/ic-summary、/task/{id}/report/{factor}(query token 给 iframe)
- analyzer cfg=None 时加载 data_platform.yaml(修 API 路径 read_db_daily 崩)
- get_status 返回 error_msg(调试+前端 failed 展示)
- 前端 投研-新建(多因子/多标的/日期)+ 结果页(IC 表 + tears iframe)
- factor 冒烟通过:ma5 → IC 1D/5D/10D 真实数据
2026-07-07 06:28:01 +08:00
claude_dev 28aea67232 feat(s1): 回测核心端到端跑通(vnpy client 对齐)
- 修 submit_cta/optimize 策略字符串→类解析(get_strategy_class)
- cta_engine: worker 进程设 vnpy DB→quant_trading.db(修 0 根数据)
- equity_curve 取自 calculate_result 的 daily_df(修 get_all_daily_results 对象问题)
- kline 补 cfg(find_config_path 共享)
- 端到端冒烟通过:DoubleMaStrategy 600000 → equity111/pnl111/trades1/kline117
2026-07-07 06:21:17 +08:00
claude_dev 80d7f58589 feat(frontend): S1 回测核心页(新建/进度/结果 + ECharts 图表)
- api/strategy.ts、api/backtest.ts(含类型)
- 回测-新建(策略下拉+动态参数表单+日期+提交)
- useTask 组合式(轮询+WS 实时阶段)+ 进度页
- 结果页:统计全表 + 资金曲线 + 每日盈亏(红涨绿跌) + 成交表 + K线买卖点
- build 通过;result 接口扩 symbol/start/end 供 K线调用
2026-07-07 06:13:10 +08:00
claude_dev 3a0e75fdc1 feat(api): 回测结果接口(strategy list/params + equity-curve/daily-pnl/trades + kline)
- strategy_registry 枚举 vnpy_ctastrategy 策略(兜底 STRATEGY_NAMES)
- /strategy/list、/strategy/{name}/params
- /task/{id}/equity-curve、/daily-pnl、/trades(BacktestResult JSON 化)
- /kline(read_db_daily 历史 K 线)
- 9 tests passed(4 strategy_registry + 5 routes)
2026-07-07 06:08:53 +08:00
claude_dev 510f77e6ea fix(backtest): result_id 用 DB 行 id + equity/trades 落 JSON(S1.1+S1.2)
- BacktestResult 加 id;save_result 设 result.id=lastrowid(修 get_result bug)
- runner._on_done 用 result.id(getattr 兜底 FactorReport)
- cta_engine 构建 equity_curve/trades DataFrame;save 传 file_dir
- result_store parquet→JSON(去 pyarrow 依赖,本机/容器都稳)
- 16 tests passed
2026-07-07 06:06:10 +08:00
claude_dev 198321c4a9 feat(deploy): run_web.py 切 sanguo_api.main:create_app --factory(单进程) 2026-07-07 05:59:33 +08:00
claude_dev a5b00c2dea feat(frontend): S0 Vue3 脚手架 + auth + Layout shell(4入口,模拟/实盘灰显)
- Vite+TS+ElementPlus+ECharts+Pinia+Router+Axios
- auth store + JWT axios 拦截器 + 路由守卫
- 登录页 + Layout(侧栏 4 入口,回测/投研 active,模拟/实盘 disabled)
- 占位页(backtest/factor,S1/S2 填充)
- vitest auth store 3 tests passed + build 通过(dist 生成)
2026-07-07 05:56:24 +08:00
claude_dev 22fa87d4ab chore(deploy): 容器 uvicorn 切 sanguo_api.main:create_app --factory + 强制单 worker 2026-07-07 00:39:51 +08:00
claude_dev 4e86d9e00e feat(api): sanguo_api.main 容器入口(build_app + create_app factory,挂 SPA) 2026-07-07 00:37:38 +08:00