From 526b1820519f6d5a455f04aa35e9fd6caeecbbc3 Mon Sep 17 00:00:00 2001 From: Sakurasan <26715255+Sakurasan@users.noreply.github.com> Date: Mon, 10 Aug 2026 19:49:36 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20collector=5Floop=20?= =?UTF-8?q?=E5=B8=B8=E9=87=8F=E5=90=8D(NameError)=E5=B9=B6=E5=A1=AB?= =?UTF-8?q?=E5=85=85=E6=A0=B8=E5=BF=83=E8=82=A1=E6=89=80=E5=B1=9E=E9=A2=98?= =?UTF-8?q?=E6=9D=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude --- backend/services/daily_collector.py | 21 ++++++++++++++----- .../2026-08-10-daily-core-stock-history.md | 4 ++-- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/backend/services/daily_collector.py b/backend/services/daily_collector.py index f0d346c..c9b6a35 100644 --- a/backend/services/daily_collector.py +++ b/backend/services/daily_collector.py @@ -4,6 +4,7 @@ """ import asyncio +import traceback from datetime import datetime, time as dtime, timezone, timedelta from typing import Optional @@ -12,7 +13,7 @@ from services.themes import fetch_theme_list _CST = timezone(timedelta(hours=8)) -# 每天采集的后台任务:每 CHECK_INTERVAL 分钟检查一次 +# 每天采集的后台任务:每 300 秒(5 分钟)检查一次 CHECK_INTERVAL_SECONDS = 300 COLLECT_AFTER_TIME = dtime(15, 0) # 收盘后 15:00 开始允许采集 CORE_STOCK_LIMIT = 100 # 核心股前100 @@ -20,7 +21,7 @@ TOP_THEME_LIMIT = 10 # 题材前10 def _is_trading_day(d: datetime) -> bool: - """周一至周五视为交易日(与 themes._is_trading_time 一致,不处理法定节假日)""" + """仅按工作日判断:周一至周五视为交易日,不处理法定节假日""" return d.weekday() < 5 @@ -88,6 +89,15 @@ async def collect_daily(trade_date: str, dry_run: bool = False) -> dict: "INSERT OR IGNORE INTO daily_core_stocks (trade_date, stock_code, stock_name, f3, rank) VALUES (?,?,?,?,?)", (trade_date, s["stock_code"], s["stock_name"], s["f3"], i), ) + # 核心股所属题材:从 themes 列表(含 securityCode/themeCode/themeName)中 + # 为每个核心股收集其全部所属题材,写入 daily_core_stock_themes + core_codes = {s["stock_code"] for s in core_stocks} + for t in themes: + if t.get("securityCode") in core_codes: + conn.execute( + "INSERT OR IGNORE INTO daily_core_stock_themes (trade_date, stock_code, theme_code, theme_name) VALUES (?,?,?,?)", + (trade_date, t["securityCode"], t["themeCode"], t["themeName"]), + ) for i, t in enumerate(top_themes, start=1): conn.execute( "INSERT OR IGNORE INTO daily_top_themes (trade_date, theme_code, theme_name, bf3, hot_rank, rank) VALUES (?,?,?,?,?,?)", @@ -110,8 +120,9 @@ async def collector_loop(stop: Optional[asyncio.Event] = None) -> None: trade_date = now.strftime("%Y-%m-%d") if not _has_collected(trade_date): await collect_daily(trade_date) - except Exception as e: - print(f"[collector] 采集异常: {e}") + except Exception: + print("[collector] 采集异常:") + traceback.print_exc() if stop is not None and stop.is_set(): break - await asyncio.sleep(_CHECK_INTERVAL_SECONDS) + await asyncio.sleep(CHECK_INTERVAL_SECONDS) diff --git a/docs/superpowers/plans/2026-08-10-daily-core-stock-history.md b/docs/superpowers/plans/2026-08-10-daily-core-stock-history.md index 7214909..2e4332e 100644 --- a/docs/superpowers/plans/2026-08-10-daily-core-stock-history.md +++ b/docs/superpowers/plans/2026-08-10-daily-core-stock-history.md @@ -211,7 +211,7 @@ async def collector_loop(stop: Optional[asyncio.Event] = None) -> None: while True: try: now = datetime.now(_CST) - if _is_trading_day(now) and now.time() >= _COLLECT_AFTER_TIME: + if _is_trading_day(now) and now.time() >= COLLECT_AFTER_TIME: trade_date = now.strftime("%Y-%m-%d") if not _has_collected(trade_date): await collect_daily(trade_date) @@ -219,7 +219,7 @@ async def collector_loop(stop: Optional[asyncio.Event] = None) -> None: print(f"[collector] 采集异常: {e}") if stop is not None and stop.is_set(): break - await asyncio.sleep(_CHECK_INTERVAL_SECONDS) + await asyncio.sleep(CHECK_INTERVAL_SECONDS) ``` > 注:上面代码中 `_CORE_STOCK_LIMIT` 应为 `CORE_STOCK_LIMIT`(变量名一致),下面 Step 2 统一修正。