From e2741a02360fd7b838af60c5d82bbb68114a1cf4 Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 6 Sep 2026 20:43:49 +0800 Subject: [PATCH] =?UTF-8?q?feat(cli):=20daily=20--resume=20=E5=AF=B9?= =?UTF-8?q?=E5=B7=B2=E6=9C=80=E6=96=B0=E8=82=A1=E7=A5=A8=E7=9B=B4=E6=8E=A5?= =?UTF-8?q?=E8=B7=B3=E8=BF=87=E5=B9=B6=E6=98=8E=E7=A4=BA=E5=A2=9E=E9=87=8F?= =?UTF-8?q?=E7=BB=93=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 增量基准改为「本地全局最新交易日」:股票本地已含该日期 → 跳过,不再发空区间 API 请求(此前 end=今天 在周末/盘前会多调一次返回 0 根,观感像非增量) - 汇总输出区分写入量与跳过数:…写入 N 根;增量跳过(已最新)M 只(本地最新 YYYY-MM-DD) - smoke:600519.SH(已到 2026-09-04)→ 即时返回『跳过 1 只』,无 API 空调用 --- backend/app/cli/sync.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/backend/app/cli/sync.py b/backend/app/cli/sync.py index 6bd16f2..930ba98 100644 --- a/backend/app/cli/sync.py +++ b/backend/app/cli/sync.py @@ -91,21 +91,34 @@ def _symbols_of(args) -> list[str]: def cmd_daily(args) -> int: + from sqlalchemy import func + + from app.infrastructure.persistence.sqlalchemy.models.market import StockDailyModel + symbols = _symbols_of(args) start = _parse_day(args.start) if args.start else date(2005, 1, 1) end = _parse_day(args.end) if args.end else date.today() total = 0 + skipped = 0 with _session_ctx() as session: provider = _failover_provider(session) bar_repo = SqlAlchemyDailyBarRepository(session) factor_repo = SqlAlchemyAdjustFactorRepository(session) + # 增量基准:本地数据已到该日期即视为「已最新」,resume 时不再调 API + global_latest = ( + session.scalar(select(func.max(StockDailyModel.trade_date))) if args.resume else None + ) for i, symbol in enumerate(symbols, start=1): begin = start if args.resume: latest = bar_repo.latest_date(symbol) if latest is not None: + if global_latest is not None and latest >= global_latest: + skipped += 1 # 已同步到本地最新交易日,无需续拉 + continue begin = max(begin, latest + timedelta(days=1)) if begin > end: + skipped += 1 # 无待拉区间(如区间已含在本地) continue try: bars = provider.get_daily(symbol, begin, end) @@ -119,7 +132,10 @@ def cmd_daily(args) -> int: except DataSourceError as exc: print(f" [warn] {symbol} 拉取失败: {exc}", file=sys.stderr) session.commit() - print(f"[daily] {len(symbols)} 只股票合计写入 {total} 根日线(含复权因子)") + detail = f"[daily] {len(symbols)} 只股票合计写入 {total} 根日线(含复权因子)" + if args.resume: + detail += f";增量跳过(已最新){skipped} 只(本地最新 {global_latest})" + print(detail) return 0