diff --git a/backend/app/api/kline.py b/backend/app/api/kline.py index 84bea75..c2e7b2e 100644 --- a/backend/app/api/kline.py +++ b/backend/app/api/kline.py @@ -736,8 +736,9 @@ def get_minute_batch(request: Request, body: dict): _pull("stock", [s for s in full_pull if s not in etf_set], day_start) _pull("etf", [s for s in full_pull if s in etf_set], day_start) if stale_last: - # 增量公共起点 = 最旧尾部 + 1min; 起点更早的重叠由落盘/合并去重吸收 - inc_start = min(stale_last.values()) + timedelta(minutes=1) + # 增量公共起点 = 最旧的最后一根本身: 最后一根是形成中的动态K (分钟内 + # 收盘/量/额持续变化), 必须重拉并以定版值覆盖; 重叠由 upsert/合并去重吸收 + inc_start = min(stale_last.values()) if inc_start < session_end: _pull("stock", [s for s in stale_last if s not in etf_set], inc_start) _pull("etf", [s for s in stale_last if s in etf_set], inc_start) diff --git a/backend/tests/test_minute_routing.py b/backend/tests/test_minute_routing.py index 4c38ee5..2d732b8 100644 --- a/backend/tests/test_minute_routing.py +++ b/backend/tests/test_minute_routing.py @@ -363,7 +363,7 @@ def _endpoint_mocks(monkeypatch, local_df: pl.DataFrame, sync_ret: pl.DataFrame def test_minute_batch_tail_stale_pulls_incremental_and_persists(monkeypatch): - """尾部落后 (本地连续但根数不足) → 从最后一根+1min 增量拉; + """尾部落后 (本地连续但根数不足) → 从最后一根本身增量拉 (动态K重拉覆盖); 拉取结果落盘, 响应为本地+增量合并去重。""" from app.api import kline as kline_api @@ -376,7 +376,7 @@ def test_minute_batch_tail_stale_pulls_incremental_and_persists(monkeypatch): result = kline_api.get_minute_batch(req, {"symbols": ["600519.SH"], "date": "2026-01-15"}) assert len(captured) == 1 - assert captured[0]["start"] == datetime(2026, 1, 15, 9, 34) # 最后一根 + 1min + assert captured[0]["start"] == datetime(2026, 1, 15, 9, 33) # 从最后一根本身重拉 (动态K覆盖) assert captured[0]["asset"] == "stock" assert writes and writes[0].height == 2 # 取到即落盘 rows = result["data"]["600519.SH"]