claude_dev
|
d2cd8fa945
|
feat(portfolio): get_security_info_batch + get_value_metrics_batch 批量接口
策略层提速第三轮(filters 通病 + 策略01):
- get_security_info_batch: 2 条 SQL(symbol IN chunk + GROUP BY sym,exc 拿
min/max; constituent_unified 拿 name)替 N×2 逐只。filters.py filter_st_stock/
filter_new_stock 自动探测批量(hasattr + isinstance dict 回退逐只, 向后兼容)。
三策略 ST/次新过滤通病: 万次查询压成 2 条。
- get_value_metrics_batch: ThreadPool 并发逐只委托 lpp.get_value_metrics
(多期 ROE/FCF/流动比率逻辑不变, 只并发)。策略01 价值精选提速。
- 接口3 get_ticks_batch 不做: 实证 get_current_tick 无 last_price/paused 字段
→ 回测涨跌停/停牌 filter 恒不过滤(死代码), 批量化无意义; 真问题是回测
涨跌停检测失效(策略层另修)。
Mac TDD parity 测试全绿(batch==逐只); 93 回归通过。
|
2026-07-29 08:23:21 +08:00 |
|
claude_dev
|
32dbcb8958
|
feat(portfolio): P2/P3 策略层向量化 + fundamentals批量提速解锁长回测
P2 行情向量化(get_price→get_closes_panel,口径实证 max_abs_diff=0.0 零偏差):
- momentum_timing: _cal_rps/_select_stocks/_cal_buy_sign 三处向量化
- small_cap: _cal_momentum_score 用 close.min/max 代理 low/high(方案A)
P3 fundamentals 批量(small_cap _pick_stocks 加 fields=[market_cap,eps],
对接数据session f416a17 get_fundamentals_df 按需短路):
- 02 000985 全市场 5128只 ~19min卡死 → 195s 跑通解锁
验收: 72单测全过; VPS 03短回测+138%(口径与get_price一致diff=0)/
02全市场-11%(2024Q1小盘股灾期合理)/01沪深300可跑
|
2026-07-29 07:49:35 +08:00 |
|
claude_dev
|
f416a17b6d
|
feat(portfolio): get_fundamentals_df 批量提速(fields= 按需短路 + ThreadPool 并发)
策略02 _pick_stocks 对 5128 只按 market_cap+eps 排序, 旧实现逐只读 4 表(valuation+
income+balance+financial_abstract)+算 calc_roic, 首仓全 cache miss 卡死。
优化(就地, 策略代码零改动, fields=None 向后兼容):
- fields= 参数: 只读请求字段依赖的源表(策略02 只要 market_cap+eps → 跳 balance/
financial_abstract/roic, 省一半 parquet 读)
- ThreadPool 并发逐只(>64 只; 本地文件 I/O 非 baostock 网络, 不触不并发铁律)
- _build_fundamental_row 加 need= 守卫读取(lpp + unified 两层)
Mac TDD 4 测试(子集/短路/回归/并发保序)全绿, 124 回归通过。
注: 策略02 要拿满提速需在其 get_fundamentals_df 调用加 fields=[market_cap,eps](策略层, 归策略session)
|
2026-07-28 23:31:13 +08:00 |
|
claude_dev
|
de04a8904b
|
feat(portfolio): 移植3聚宽策略到BulletTrade + 8bug修正 + 数据缺口文档
三策略(聚宽py2→BulletTrade 0.9.2,BrokerFacade注入跨版本兼容):
- momentum_timing 动量择时(牛熊分界+行业RPS+均线,切回10中证行业指数)
- value_selection 价值精选(6条基本面过滤,切回沪深300)
- small_cap 小市值(去IC对冲,切回000985中证全指)
框架:
- runner_backtest 加 --strategy 分发(原硬编码all_weather)
- provider 加 get_value_metrics(价值精选6条基本面,NOTICE_DATE治前视偏差)
- 72单测全过(21+27+24)
修8个回测实测发现的真bug:
- 01第⑥条EPS绝对值0.08~0.5与①大盘矛盾→6条交集恒空致全程空仓,按注释本意改净利润同比8~50%
- 03原帖calRPS取数区间错(get_price start=end只取1天)→涨跌幅恒0 RPS失效;date.today()取真实今天非回测日
- 02 universe 000985不在constituent_unified→候选池空
VPS实测(短区间验证逻辑,非长期表现): 01价值+23%/03行业轮动+48%/02选出20只小盘
数据缺口(详见docs/research/joinquant_strategies/SUMMARY.md + data_gaps_fix_plan.md):
- 三表"1/3损坏"误报已撤回(全扫5530文件/表0损坏,沪深95%+健康,仅北交所920xxx空,不做北交所)
- 真实缺口: 行业成份股(G1已补)/000985(G2已补)/IC期货(02对冲去掉)/provider批量接口(G5待做,解锁长回测)
|
2026-07-28 22:20:49 +08:00 |
|
claude_dev
|
c8f26bef80
|
feat(portfolio): LocalUnifiedProvider 批量行情接口 get_closes_panel (G5-Phase1)
单条 dbbardata 参数化查询 (symbol,exchange) OR + pivot 返宽表, 替代 N 次 get_price, 为策略向量化提速铺路。raw close 口径一致, 缺失 NaN 列, symbol-exchange 配对防歧义。22 tests 含 batch-vs-逐只回归。本文件另含 get_value_metrics 透传(策略移植)。
|
2026-07-28 20:36:11 +08:00 |
|
claude_dev
|
670498ab01
|
fix(data): akshare 三表下载鲁棒性 — 原子写 + --repair (G4)
write_parquet_and_marker 改原子写(tmp→os.replace→marker) kill 不产残缺 parquet; 新增 --repair 只重取 missing/empty/corrupt 忽略 marker(周度补漏不必等财报季 --force 全量); is_parquet_healthy 辅助。top_holders 修复无回归, 106 tests。
|
2026-07-28 20:36:11 +08:00 |
|
claude_dev
|
f94a145587
|
fix(data): bs_eod 卡死根治 — per-stock commit + baostock 超时包装 + 周期 relogin
根因(py-spy dump + netstat CLOSE_WAIT 实证): baostock 服务端关长连接→CLOSE_WAIT, send_msg 静默阻塞不抛异常, socket.setdefaulttimeout 不被 baostock 自己 socket 遵守, relogin 只在 error_code≠0 救不了; 一把大事务全程持 WAL 锁阻断全库。修复: per-stock commit 去大事务 + _with_timeout 线程超时包 fetch_k 打破静默 hang + 周期 relogin 每500主动刷连接。VPS --limit 3 验证 11s 不 hang。
|
2026-07-28 20:36:11 +08:00 |
|
claude_dev
|
955c05357a
|
fix(data): ak-stock top_holders KeyError 'sdltgd' 根治(_safe 捕 KeyError+匹配sdltgd,跳北交所920/83/87/43)
|
2026-07-27 21:08:53 +08:00 |
|
claude_dev
|
8b2693423a
|
feat(data): xt_eod 扩展补全北交所 920xxx 日线(exc_of+universe+import容错,复用×100 normalize)
- exc_of: 920 -> BJSE (3 位前缀优先于 2 位 SSE/SZSE 判断, 防 sym[:2]='92' 落 SZSE)
- universe: 沪深ETF/基金 ∪ 北交所920xxx (从 constituent_unified 932000 取, baostock 不覆盖)
- import xtquant 容错 (mac xd=None 可单测 exc_of, main() 开头 return 2)
- --full-bj: 北交所 backfill start=20240101 (默认 LOOKBACK=30 与 ETF 同窗)
- 复用 normalize_daily_dt + ×100 volume 口径, 不动已有 ETF 写入路径
Tests: tests/data_platform/test_xt_eod_bj.py 14 cases RED -> GREEN (3 位前缀 critical + ETF/沪深/深市 覆盖)
|
2026-07-27 20:56:16 +08:00 |
|
claude_dev
|
11f383a8e2
|
fix(data): akshare top_holders Length mismatch bug 根治
bug 根因 (实证 akshare 1.18.x stock_gdfx_em.py:418):
报告期未披露 (如 sz002673 的 20260630 在 2026-07-26 还未发) 时,
东财 PageSDLTGD 接口返 sdltgd=[], akshare pd.DataFrame([])+reset_index()
得 1 列 df, 然后 columns=[12 列] 抛
ValueError('Length mismatch: Expected axis has 1 elements, new values have 12')
这是确定性无数据 (非瞬时故障), 但 call_ak_with_retry 当网络错重试 3 次
(14s 退避) + 噪声 ERROR 日志, 浪费时间且消耗断路器配额。
修复:
新增 _safe_top_10_em 包装 ak.stock_gdfx_free_top_10_em: 子串匹配
'Length mismatch' (pandas 错误信息稳定) → 返空 df 带 8 列 schema
(TOP_HOLDERS_COLUMNS), 不抛; 其他 ValueError/ConnectionError 透传重试。
fetch_top_holders_one_period 改调此包装。
验证:
- Mac: sz002673/20260630 从 ~14s (3 重试) 降到 0.04s, 返 0×8 空 df
- 有效期 sz002673/20251231, sh600519/20250930 正常返 10×8 数据
- 9/9 新单测通过 (tests/data_platform/test_top_holders_parse.py)
|
2026-07-26 11:54:19 +08:00 |
|
claude_dev
|
b06af336c3
|
fix(data): bs_eod 15min datetime 格式 bug 根治 + --no-daily 选项
bug 根因(2026-07-25): baostock 15min 实测 date='2026-07-21'(带 -),
time='20260721094500000'(17 位 YYYYMMDDHHMMSSmmm)。原代码假设 date 纯数字 +
time[:6] 取年月, 产乱 datetime 致 dbbardata 15min 全市场停 2026-07-17(8 天
没正确累积), 日线正常(7-24)。
修复:
- 提纯函数 _build_15m_dt(date_series, time_series): date 直连 + 从 17 位 time
第 8-12 位提取 HHMM, 产出 'YYYY-MM-DD HH:MM:00' (符合 GLOB 清理模式)
- upsert_15m 调用 _build_15m_dt 替代内联拼接
- 新增 --no-daily 选项(只跑 15min, 用于重灌快), 与 --no-15m 对称
- TDD: 8 case 覆盖(09:45/14:30/15:00/13:00/跨日/多行混合/GLOB 格式)
- conftest.py 修补 sibling import 在 pytest 下可用
|
2026-07-25 21:14:12 +08:00 |
|
claude_dev
|
b237c2d7e7
|
fix(data): 中证1000/2000 历史成份股补全(parse+migrate 聚合)
parse_csindex_announce.py 3 处修复:
- 932000 launch xlsx header 定位"证券代码"列(原 row[0]=指数代码 bug, distinct=1)
- 000852 列表搜索用 indexCode payload 精准拉(28 -> 96 公告, 回溯到 2016)
- akshare current snapshot header 定位"成分券代码"列(原 iloc[0]=日期 bug, current=0)
migrate_constituent.py:
- 加 _read_announce_union_aggregated(): 000852/932000 用 announce_union 全集
替换原 snapshot-only 路径, was_removed 治幸存者偏差
- 缺 announce_union 时回退旧 snapshot 逻辑(向后兼容)
TDD: tests/portfolio/test_migrate_announce_union.py 7 测全过(5 unit + 2 integration)
Mac 产出验证:
- 000852: distinct 1220 -> 1672, was_removed 0 -> 672
- 932000: distinct 1 -> 2684(launch 修复), was_removed 0 -> 684
|
2026-07-23 23:45:55 +08:00 |
|
claude_dev
|
114a69e997
|
fix(data): dbbardata 日线双行根治(统一纯日期+helper,留ROWID max去重)
根因: dbbardata UNIQUE(symbol,exchange,interval,datetime) 按字符串字面比较,
多写入路径混用 'YYYY-MM-DD' 与 'YYYY-MM-DD 00:00:00' -> 同一交易日双行,
INSERT OR REPLACE 不去重 -> 回测交易日翻倍/pivot duplicate/信号异常。
方案A (统一纯日期, 详见 Main Agent 诊断):
- 新增 scripts/data_platform/dbbardata_utils.py: normalize_daily_dt(s)
取前 10 字符, None/短串安全
- 4 个日线写入脚本写入前调 helper:
- bs_eod.py (sanguo-bs-eod 个股日线 baostock)
- migrate_daily_baostock.py (历史迁移)
- xt_eod.py (sanguo-xt-eod ETF/基金 xtata)
- import_vnpy_daily_fast.py (NAS 日线 parquet 导入, 加防御)
- TDD: tests/data_platform/test_dbbardata_utils.py 9 cases 全过
- 回归: tests/data_platform + tests/portfolio 199 passed 12 skipped
peewee DateTimeField formats 含 '%Y-%m-%d' (阶段0 VPS 实测确认),
读纯日期不崩, 方案A 前提成立。
15min 干净, 不动 (分钟必须带时分)。只改日线 interval='d'。
数据层根治, 不在 provider 适配兜底 (用户铁律)。
|
2026-07-23 12:18:41 +08:00 |
|
claude_dev
|
48c67d05d2
|
fix(data): 成份股 merge/migrate pipeline 可重跑(idempotent, 读 bs_index_constituent_old)
|
2026-07-23 09:04:00 +08:00 |
|
claude_dev
|
41cc6d13bf
|
feat(portfolio): LocalUnifiedProvider spec §6 使用层落地 + VPS E2E(Task6)
spec §6 使用层 provider — 读方案A 权威数据层, 零 online, 治幸存者偏差:
- get_price: dbbardata('d') raw + bs_adjust_factor 前复权(asof, qfq[t]=raw[t]*factor[t])
- get_index_stocks/get_constituent: constituent_unified 并集治偏差(300=940含被踢, 无date时点)
- get_fundamentals_df: baostock pe/pb/ps/pcf + akshare 市值 + 三表委托 LocalParquetProvider
- 辅助: trade_days/security_info/current_tick/split_dividend/all_securities
VPS E2E 实证修复(Mac fixture 盲区):
- dbbardata datetime 混合格式("2024-09-26" vs "2024-09-26 00:00:00")
→ pd.to_datetime format='mixed' + SQL substr(datetime,1,10) 比日期(字符串比漏边界)
- 补 TestMixedDatetimeFormat 单测覆盖
验证: VPS 真数据 E2E 全通过(600519在市raw/qfq复权/000005退市治偏差/510300ETF/
fundamentals市值+pe+eps全字段/辅助方法); Mac 37单测+149回归绿
交付: 使用说明 docs/portfolio_local_unified_provider.md(其他 session 直用)+
plan+probe+E2E 脚本
|
2026-07-23 08:25:44 +08:00 |
|
claude_dev
|
9243f86773
|
feat(portfolio): LocalUnifiedProvider 辅助方法(Task4)
|
2026-07-23 08:12:34 +08:00 |
|
claude_dev
|
011c9d4ddb
|
feat(portfolio): LocalUnifiedProvider fundamentals baostock估值+akshare市值(Task3)
|
2026-07-23 08:11:35 +08:00 |
|
claude_dev
|
b46a0c26c8
|
feat(portfolio): LocalUnifiedProvider 成份股并集治偏差(Task2)
|
2026-07-23 08:07:37 +08:00 |
|
claude_dev
|
4b4dca2f44
|
feat(portfolio): LocalUnifiedProvider get_price+前复权(Task1)
|
2026-07-23 08:06:45 +08:00 |
|
claude_dev
|
e12c66acd5
|
feat(portfolio): LocalUnifiedProvider 代码转换+复权因子(Task0)
|
2026-07-23 08:05:09 +08:00 |
|
claude_dev
|
b270faf4b9
|
feat(portfolio): 本地数据 provider 层(baostock/local_parquet)
- BaostockProvider: 读 VPS daily_baostock_full(本地,不调online,守 provider-local-data-only 铁律)
- LocalParquetProvider: 读 parquet 兜底,回测117交易日0.4s/月出JSON
- all_weather 策略 + runner_backtest 适配
- 数据源融合使用层(单 Provider 内部路由,见 data-fusion spec §6)
|
2026-07-22 10:35:23 +08:00 |
|
claude_dev
|
96b1924fd5
|
feat: 实盘模拟(live) + 组合回测MVP(portfolio)
[live] 实盘模拟 vnpy+miniQMT 直连(supervisor 轮询, 前后端):
- sanguo_live: LiveTradingEngine + AShareCtaTemplate(定寸/禁做空) + runner_supervisor(DB驱动) + persistence(4表WAL)
- sanguo_api/routes_live: 9路由(create/start/stop/positions/trades/account/status)
- frontend live: New/List/Monitor + api/live.ts; config/live.yaml
[portfolio] 组合回测 MVP(BulletTrade, 链路代码完成待验证):
- runner_backtest 加 JSON 入口(--json, BacktestEngine 顶层 import)
- sanguo_api/routes_portfolio: POST /portfolio/backtest SSH 触发 VPS 跑
- frontend PortfolioBacktest.vue + api/portfolio.ts: 表单+结果+净值曲线
- 路由/菜单注册(/backtest/portfolio 组合回测)
- 已知: MVP 链路未端到端验证, agent 改至中途被停; 待 Mac 起服务联调
|
2026-07-18 20:04:16 +08:00 |
|
claude_dev
|
a68cf4905e
|
feat(portfolio): sanguo_portfolio 组合策略框架(BulletTrade+miniQMT,不用jqdatasdk)
把聚宽"全天候轮动"(post48819)搬到 BulletTrade。融合=pip+扩展点注入
(SanguoMiniQmtProvider 继承 MiniQMTProvider 只 override get_fundamentals,
set_data_provider 公开 API 注入, BulletTrade 源码 0 改动)。
- providers: SanguoMiniQmtProvider 补 get_fundamentals(PershareIndex+自算PE/PS/PB/PCF/市值/ROIC)
- strategies/all_weather: 4选股函数+大小盘轮动+ETF兜底+涨停止损(聚宽风格翻译)
- factors(估值/ROIC自算) + filters(ST/涨跌停/次新/停牌)
- 88/88 测试 Mac+VPS 双过; VPS 回测 pipeline 跑通(修9bug:Capital单位/日期格式/百分数口径/11字段alias)
- 实盘 runner_live+runbook 就绪等交易日; DEFAULT_DATA_PROVIDER=miniqmt env 不装 jqdatasdk
- 文档: sanguo_portfolio_plan / portfolio_backtest_result / portfolio_live_runbook
|
2026-07-18 19:08:18 +08:00 |
|
claude_dev
|
e3b688354f
|
fix(data): data_platform硬化(增量merge/verify+raw_redownload/run_daily_update)+测试
merge_increment/verify_increment 增量staging→验证→合并工具; raw_redownload/run_daily_update/import_vnpy_daily 强化; 补 data_platform 与 index_downloader 测试.
|
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
|
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
|
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
|
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
|
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
|
b50a0f97be
|
feat(backtest): metrics模块—empyrical算10指标+5时序(聚宽同源口径)
|
2026-07-11 13:27:44 +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
|
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
|
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
|
164690373f
|
feat(trader): C期分期项收尾—资金占用成本+分红送股+_restore_ledger修复
- 资金占用成本(spec§195): StrategyRunner.daily_borrow_cost(used×risk_free/365)
归因per_strategy_pnl(不碰account总账, account.equity真实净值不变);
config risk_free_rate=0.02; engine.step mark_to_market后计扣; =0向后兼容跳过
- 分红送股(spec§295): dividend_source.py(akshare stock_history_dividend_detail,
实测600000/000001纯现金分红); PositionLedger.apply_split(volume×factor/avg÷factor);
Account.apply_cash_dividend; engine._apply_dividends(除权日调整,现金先split后);
mark_to_market停牌prev_close兜底(今收→前收→均价); _run_replay注入dividends日历
- 修_restore_ledger预存bug: PositionLedger.__init__加volume/frozen/avg_price参数
(原只symbol, live_orchestrator跨日恢复4参数调用会TypeError, 首次step空仓未暴露)
- 139 passed(119基准+20分红+3占用成本), 无回归
- live_step dividends注入待分期项(每日拉全市场分红慢, 需run_daily_update预拉日历)
|
2026-07-10 08:44:35 +08:00 |
|
claude_dev
|
252deb5ec7
|
feat(api): paper positions/pending 端点(实走监控用,Phase 3c Live页后端基础)
|
2026-07-09 22:33:35 +08:00 |
|
claude_dev
|
193064c953
|
feat(trader): 软限额max_allocation(分期项)—每策略资金额度消除顺序依赖
spec §195: 多策略并发下单"先到后到"不可复现 → 每策略独立max_allocation
- StrategyRunner: max_allocation字段(默认inf) + used_allocation(持仓市值)
- engine._match: BUY cash_enough后查 used+成交额>max_allocation → 拒单max_allocation_exceeded
- live_orchestrator: runner传max_allocation(默认initial_capital)
- routes_paper: StrategyCfg加max_allocation(API→DB→live_step数据流)
- test_soft_limit: 3测试(累计超限拒单/默认不限/SELL不受限)
116 passed(113旧+3新), 无回归.
|
2026-07-09 22:05:35 +08:00 |
|
claude_dev
|
0810259911
|
feat(data): 15min双源集成(data_source路由 + baostock格式适配)
- _resolve_dir_key: 15min支持raw/qfq双源(移除raw15min抛错)
- _check_adjust_cfg: 按interval查dir(minute_15_raw_dir/qfq_dir)
- read_parquet_15min: datetime列优先(baostock时分,旧date兼容)
- config: 加 minute_15_qfq_dir/minute_15_raw_dir
- test: 更新raw15min路由断言(6 passed)
实测容器: 600000 15min qfq 336bars close6.1977 / raw 336bars close6.6200,
datetime时分正确(09:45:00). 15min双源分期项落地.
|
2026-07-09 19:34:43 +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
|
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
|
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 |
|