diff --git a/deploy/profile-scripts/b_td1_v3_scanner.py b/deploy/profile-scripts/b_td1_v3_scanner.py index 137a5cb0..6c166a62 100644 --- a/deploy/profile-scripts/b_td1_v3_scanner.py +++ b/deploy/profile-scripts/b_td1_v3_scanner.py @@ -51,26 +51,30 @@ def load_regime(): def mcap_quantile(code): - """从 stock_daily 算市值分位(mcap_q 近似)""" + """市值分位(mcap_q):用 stock_fundamentals.mcap_total(总市值,亿元) + 2026-08-17 修复:原用 stock_daily.amount 成交额不可靠(amount=None 导致全返回0.3缺省, + 而池条件 mcap_q<0.3 会挡掉所有——扫描0候选的根因)""" try: conn = sqlite3.connect(str(DB_PATH), timeout=5) row = conn.execute( - "SELECT amount, close FROM stock_daily WHERE code=? ORDER BY date DESC LIMIT 1", + "SELECT mcap_total FROM stock_fundamentals WHERE code=? ORDER BY updated_at DESC LIMIT 1", (code,)).fetchone() + conn.close() if not row or not row[0]: - conn.close() - return 0.3 # 缺省给中值(放宽) - # 全市场今日成交额分位 + return 0.3 # 缺省中值 + # 全市场市值分位(用基本面最新 mcap_total 全量) + conn = sqlite3.connect(str(DB_PATH), timeout=5) rows = conn.execute( - "SELECT amount FROM stock_daily WHERE date=(SELECT MAX(date) FROM stock_daily) AND amount IS NOT NULL" + "SELECT code, mcap_total FROM stock_fundamentals f WHERE updated_at = " + "(SELECT MAX(updated_at) FROM stock_fundamentals f2 WHERE f2.code=f.code)" ).fetchall() conn.close() - amounts = sorted([r[0] for r in rows if r[0]]) - if not amounts: + mcaps = sorted([r[1] for r in rows if r[1] and r[1] > 0]) + if not mcaps: return 0.3 import bisect - pos = bisect.bisect_left(amounts, row[0]) - return round(pos / max(len(amounts), 1), 2) + pos = bisect.bisect_left(mcaps, row[0]) + return round(pos / max(len(mcaps), 1), 2) except Exception: return 0.3 diff --git a/deploy/profile-scripts/s2_panic_v2_scanner.py b/deploy/profile-scripts/s2_panic_v2_scanner.py index e9fd4b68..e8773f67 100644 --- a/deploy/profile-scripts/s2_panic_v2_scanner.py +++ b/deploy/profile-scripts/s2_panic_v2_scanner.py @@ -56,22 +56,26 @@ def load_mkt_rsi(): def mcap_quantile(code): + """市值分位(2026-08-17 改用 stock_fundamentals.mcap_total,原 amount 不可靠)""" try: conn = sqlite3.connect(str(DB_PATH), timeout=5) row = conn.execute( - "SELECT amount FROM stock_daily WHERE code=? ORDER BY date DESC LIMIT 1", (code,)).fetchone() + "SELECT mcap_total FROM stock_fundamentals WHERE code=? ORDER BY updated_at DESC LIMIT 1", + (code,)).fetchone() + conn.close() if not row or not row[0]: - conn.close() return 0.3 + conn = sqlite3.connect(str(DB_PATH), timeout=5) rows = conn.execute( - "SELECT amount FROM stock_daily WHERE date=(SELECT MAX(date) FROM stock_daily) AND amount IS NOT NULL" + "SELECT code, mcap_total FROM stock_fundamentals f WHERE updated_at = " + "(SELECT MAX(updated_at) FROM stock_fundamentals f2 WHERE f2.code=f.code)" ).fetchall() conn.close() - amounts = sorted([r[0] for r in rows if r[0]]) - if not amounts: + mcaps = sorted([r[1] for r in rows if r[1] and r[1] > 0]) + if not mcaps: return 0.3 import bisect - return round(bisect.bisect_left(amounts, row[0]) / max(len(amounts), 1), 2) + return round(bisect.bisect_left(mcaps, row[0]) / max(len(mcaps), 1), 2) except Exception: return 0.3