fix: 全部写库scanner统一加busy_timeout=30000——整点撞锁SQLite自动等待,根治崩溃

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