diff --git a/deploy/profile-scripts/accumulation_scanner.py b/deploy/profile-scripts/accumulation_scanner.py index e08881db..689f9656 100644 --- a/deploy/profile-scripts/accumulation_scanner.py +++ b/deploy/profile-scripts/accumulation_scanner.py @@ -70,6 +70,7 @@ def get_stock_pool(): """获取待扫描股票池""" import sqlite3 conn = sqlite3.connect(str(DB_PATH)) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 # 从holding_strategies拿已有策略股 existing = set() @@ -210,6 +211,7 @@ def main(): # 写入DB conn = sqlite3.connect(str(DB_PATH)) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 inserted = 0 for score, code, info, detail in candidates[:10]: # 最多10只 name = info["name"] diff --git a/deploy/profile-scripts/hk_scanner.py b/deploy/profile-scripts/hk_scanner.py index 66782e25..53cf0223 100644 --- a/deploy/profile-scripts/hk_scanner.py +++ b/deploy/profile-scripts/hk_scanner.py @@ -37,6 +37,7 @@ def get_hk_regime(): pass try: conn = sqlite3.connect(str(DB_PATH), timeout=5) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 row = conn.execute( "SELECT regime FROM market_regime WHERE market='hk' ORDER BY date DESC LIMIT 1").fetchone() conn.close() @@ -49,6 +50,7 @@ def trend_down_streak(): """trend_down 连续天数(防守用)""" try: conn = sqlite3.connect(str(DB_PATH), timeout=5) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 rows = conn.execute( "SELECT date, regime FROM market_regime WHERE market='hk' ORDER BY date DESC LIMIT 30").fetchall() conn.close() @@ -107,6 +109,7 @@ def main(): print(f" 激活策略: {versions}", flush=True) conn = sqlite3.connect(str(DB_PATH), timeout=5) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 inserted = 0 for v in versions: strat = HK_STRATEGIES[v] diff --git a/deploy/profile-scripts/mr_scanner.py b/deploy/profile-scripts/mr_scanner.py index adc8df2e..10bcf591 100644 --- a/deploy/profile-scripts/mr_scanner.py +++ b/deploy/profile-scripts/mr_scanner.py @@ -74,6 +74,7 @@ def load_regime(): # 补 adx/above_ma20(甜区门控需要) try: conn = sqlite3.connect(str(DB_PATH), timeout=5) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 row = conn.execute( "SELECT date, above_ma20, adx, regime FROM market_regime " "WHERE market='a' ORDER BY date DESC LIMIT 1").fetchone() @@ -89,6 +90,7 @@ def load_regime(): # 回退原始 try: conn = sqlite3.connect(str(DB_PATH), timeout=5) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 row = conn.execute( "SELECT date, above_ma20, adx, regime FROM market_regime " "WHERE market='a' ORDER BY date DESC LIMIT 1").fetchone() @@ -294,6 +296,7 @@ def main(): # ── 写 candidates 表(UPSERT,保留计算列)── conn = sqlite3.connect(str(DB_PATH), timeout=5) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 inserted = 0 for code, sig in found[:top_n]: name = code diff --git a/deploy/profile-scripts/predictive_oversold_scanner.py b/deploy/profile-scripts/predictive_oversold_scanner.py index 02c846c9..4e9bf272 100644 --- a/deploy/profile-scripts/predictive_oversold_scanner.py +++ b/deploy/profile-scripts/predictive_oversold_scanner.py @@ -91,6 +91,7 @@ def load_market_state(): # 补 adx/above_ma20 try: conn = sqlite3.connect(str(DB_PATH), timeout=5) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 row = conn.execute( "SELECT date, above_ma20, adx, regime FROM market_regime " "WHERE market='a' ORDER BY date DESC LIMIT 1").fetchone() @@ -106,6 +107,7 @@ def load_market_state(): # 回退原始 try: conn = sqlite3.connect(str(DB_PATH), timeout=5) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 row = conn.execute( "SELECT date, above_ma20, adx, regime FROM market_regime " "WHERE market='a' ORDER BY date DESC LIMIT 1").fetchone() @@ -122,6 +124,7 @@ def compute_market_filters(): 不再 fetch_tx_klines 自己拉指数K线算——使用层只读数据不采集,口径与回测一致)""" try: conn = sqlite3.connect(str(DB_PATH), timeout=5) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 row = conn.execute( "SELECT mkt_rsi, mkt_dd60, mkt_down_days FROM market_indicators WHERE market='a' ORDER BY date DESC LIMIT 1" ).fetchone() @@ -174,6 +177,7 @@ def fetch_fundamentals(code): """从 stock_fundamentals 表读 mcap_q/pe_q(分位由调用方算)""" try: conn = sqlite3.connect(str(DB_PATH), timeout=5) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 row = conn.execute( "SELECT pe, mcap_total FROM stock_fundamentals WHERE code=?", (code,)).fetchone() conn.close() @@ -222,6 +226,7 @@ def main(): # 3. 逐只检查 conn = sqlite3.connect(str(DB_PATH), timeout=10) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 hits = 0 for code in all_stocks: # 当日幂等:今天已写入则跳过 @@ -271,6 +276,7 @@ def get_market_percentile(code, field): 返回 None 表示数据不可用。""" try: conn = sqlite3.connect(str(DB_PATH), timeout=5) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 # 全市场分布 total = conn.execute(f"SELECT COUNT(*) FROM stock_fundamentals WHERE {field} > 0").fetchone()[0] if not total: @@ -295,6 +301,7 @@ def fetch_sector_momentum(code): (sector_index_builder 加工层产物)算20日涨跌。返回 None 表示无行业数据。""" try: conn = sqlite3.connect(str(DB_PATH), timeout=5) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 sector = conn.execute( "SELECT sector FROM stock_sectors_em WHERE code=? LIMIT 1", (code,)).fetchone() if not sector or not sector[0]: @@ -321,6 +328,7 @@ def fetch_news_count(code): """简化:查 stock_news 表近3日新闻数(部署时可完善)""" try: conn = sqlite3.connect(str(DB_PATH), timeout=5) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 row = conn.execute( "SELECT COUNT(*) FROM stock_news WHERE code=? AND date >= datetime('now','-3 days')", (code,)).fetchone() diff --git a/deploy/profile-scripts/s2_panic_v2_scanner.py b/deploy/profile-scripts/s2_panic_v2_scanner.py index af859f4d..2783f75f 100644 --- a/deploy/profile-scripts/s2_panic_v2_scanner.py +++ b/deploy/profile-scripts/s2_panic_v2_scanner.py @@ -42,6 +42,7 @@ def load_mkt_rsi(): """大盘 RSI14(stock_daily sh000001)""" try: conn = sqlite3.connect(str(DB_PATH), timeout=5) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 rows = conn.execute( "SELECT date, close FROM stock_daily WHERE code='sh000001' ORDER BY date DESC LIMIT 40").fetchall() conn.close() @@ -59,6 +60,7 @@ def mcap_quantile(code): """市值分位(2026-08-17 改用 stock_fundamentals.mcap_total,原 amount 不可靠)""" try: conn = sqlite3.connect(str(DB_PATH), timeout=5) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 row = conn.execute( "SELECT mcap_total FROM stock_fundamentals WHERE code=? ORDER BY updated_at DESC LIMIT 1", (code,)).fetchone() @@ -66,6 +68,7 @@ def mcap_quantile(code): if not row or not row[0]: return 0.3 conn = sqlite3.connect(str(DB_PATH), timeout=5) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 rows = conn.execute( "SELECT code, mcap_total FROM stock_fundamentals f WHERE updated_at = " "(SELECT MAX(updated_at) FROM stock_fundamentals f2 WHERE f2.code=f.code)" @@ -152,6 +155,7 @@ def main(): hits = hits[: args.top] conn = sqlite3.connect(str(DB_PATH), timeout=10) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 inserted = 0 for code, name, sig in hits: reasons = (f"rsi={sig['rsi']} mcap_q={sig['mcap_q']} score={sig['score']}") diff --git a/deploy/profile-scripts/s2_scanner.py b/deploy/profile-scripts/s2_scanner.py index 8e5b67df..3fc7af5c 100644 --- a/deploy/profile-scripts/s2_scanner.py +++ b/deploy/profile-scripts/s2_scanner.py @@ -52,6 +52,7 @@ def load_mkt_rsi(): """从 stock_daily 计算大盘 RSI14(与回测零偏差——回测用的就是 stock_daily)""" try: conn = sqlite3.connect(str(DB_PATH), timeout=5) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 rows = conn.execute( "SELECT date, close FROM stock_daily WHERE code='sh000001'" " ORDER BY date DESC LIMIT 40").fetchall() @@ -163,6 +164,7 @@ def main(): # ── 幂等:当天已有 s2_panic 候选则跳过 ── conn = sqlite3.connect(str(DB_PATH), timeout=5) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 try: _today = datetime.now().strftime("%Y-%m-%d") _n = conn.execute( @@ -207,6 +209,7 @@ def main(): # ── 写 candidates(sector='s2_panic',UPSERT)── conn = sqlite3.connect(str(DB_PATH), timeout=5) + conn.execute("PRAGMA busy_timeout=30000") # 2026-08-18 整点撞锁等待 inserted = 0 for code, sig in found[:top_n]: name = code