fix: 全部写库scanner统一加busy_timeout=30000——整点撞锁SQLite自动等待,根治崩溃
This commit is contained in:
@@ -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"]
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|||||||
@@ -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():
|
|||||||
"""大盘 RSI14(stock_daily sh000001)"""
|
"""大盘 RSI14(stock_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']}")
|
||||||
|
|||||||
@@ -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():
|
|||||||
|
|
||||||
# ── 写 candidates(sector='s2_panic',UPSERT)──
|
# ── 写 candidates(sector='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
|
||||||
|
|||||||
Reference in New Issue
Block a user