fix: watchlist_auto_exit/batch_reassess conn加timeout=30+busy_timeout(整点写锁不再崩,t_a44b6e16)

This commit is contained in:
xxm
2026-08-17 16:43:38 +08:00
parent 364911b865
commit 196c2c40be
2 changed files with 13 additions and 16 deletions
+11 -15
View File
@@ -25,7 +25,8 @@ STALE_HOURS = 20 # 分析超过20小时视为过期,需要重评
def has_llm_analysis(code):
"""检查是否为LLM生成的12维分析(>500字)"""
conn = sqlite3.connect(DB)
conn = sqlite3.connect(DB, timeout=30)
conn.execute("PRAGMA busy_timeout=30000")
r = conn.execute("SELECT LENGTH(full_analysis) FROM holding_strategies WHERE code=? AND status='active'", (code,)).fetchone()
conn.close()
return r and r[0] and r[0] > 500
@@ -36,7 +37,7 @@ def in_cooldown(code):
"""冷却期检查(--force 时全量强制重评)"""
if FORCE_REASSESS:
return False
conn = sqlite3.connect(DB)
conn = sqlite3.connect(DB, timeout=30)
r = conn.execute("SELECT reassessed_at FROM holding_strategies WHERE code=? AND status='active'", (code,)).fetchone()
conn.close()
if not r or not r[0]:
@@ -49,8 +50,7 @@ def in_cooldown(code):
return False
def analysis_stale(code, force_today=False):
"""分析是否过期(>STALE_HOURS 或 force_today 时今早4点前未重评)"""
conn = sqlite3.connect(DB)
"""分析是否过期(>STALE_HOURS 或 force_today 时今早4点前未重评)"""sqlite3.connect(DB, timeout=30).connect(DB)
r = conn.execute("SELECT reassessed_at FROM holding_strategies WHERE code=? AND status='active'", (code,)).fetchone()
conn.close()
if not r or not r[0]:
@@ -66,8 +66,7 @@ def analysis_stale(code, force_today=False):
def get_portfolio():
"""从 portfolio_summary 读实时现金/总资产(不再硬编码)"""
try:
conn = sqlite3.connect(DB)
sqlite3.connect(DB, timeout=30)nn = sqlite3.connect(DB)
r = conn.execute("SELECT cash, total_assets FROM portfolio_summary WHERE id=1").fetchone()
conn.close()
if r and r[1]:
@@ -80,7 +79,7 @@ def collect_data(code):
"""收集最新数据(含完整策略原文)"""
data = {"code": code}
# 从DB读策略(含 full_analysis / changelog_json / position_advice
# 从DB读策略(含 full_analysis / changelogsqlite3.connect(DB, timeout=30)vice
conn = sqlite3.connect(DB)
r = conn.execute("SELECT name, entry_low, entry_high, stop_loss, take_profit, timing_signal, action, rr_ratio, tech_snapshot, sector_context, stock_category, full_analysis, changelog_json, reassessed_at, position_advice FROM holding_strategies WHERE code=? AND status='active'", (code,)).fetchone()
if r:
@@ -132,8 +131,7 @@ def collect_data(code):
# 未映射的股票明确标注"行业未映射"(不让大盘指标伪装成行业信息)
_sector_ctx = data.get('sector_context', '') or ''
if (not _sector_ctx) or _sector_ctx.startswith('大盘上涨比') or len(_sector_ctx) < 4:
_resolved = ""
try:
sqlite3.connect(DB, timeout=30) try:
_sdb = sqlite3.connect(DB)
_sr = _sdb.execute("SELECT sector_name FROM stock_sectors WHERE code=? LIMIT 1", (code,)).fetchone()
_sdb.close()
@@ -142,7 +140,7 @@ def collect_data(code):
except Exception:
pass
_sector_ctx = _resolved if _resolved else "行业未映射(仅大盘环境参考)"
data['sector_context'] = _sector_ctx
data['sectsqlite3.connect(DB, timeout=30)tor_ctx
# 大盘
try:
conn = sqlite3.connect(DB)
@@ -291,8 +289,7 @@ def build_prompt(data):
f"禁止出现「已持仓者」视角的建议。")
# ── 换仓上下文(2026-07-24 老爸:现金不足时给出具体换股建议)──
_rotation_context = ""
if not data.get('held'):
_rotation_csqlite3.connect(DB, timeout=30)not data.get('held'):
try:
_rc = sqlite3.connect(DB)
_weak = _rc.execute("""
@@ -500,8 +497,7 @@ def parse_response(text):
def save_result(code, full_text, parsed, ta_levels=None):
"""保存LLM结果到DB(先快照再UPDATE)。空分析拒绝写入。
ta_levels: collect_data 计算的确定性技术位,用于止损锚定校验。"""
if not (full_text or "").strip():
print(f" \u274c 拒绝写入空分析(LLM输出为空,保护已有数据)")
if not (full_text or "").stsqlite3.connect(DB, timeout=30)t(f" \u274c 拒绝写入空分析(LLM输出为空,保护已有数据)")
return
conn = sqlite3.connect(DB)
now = datetime.now().isoformat()
@@ -684,7 +680,7 @@ def main():
idx = sys.argv.index("--code")
codes = [sys.argv[idx+1]]
else:
# 按类型筛选 active 策略
sqlite3.connect(DB, timeout=30)
type_map = {"holding": "持仓策略", "watchlist": "自选策略"}
conn = sqlite3.connect(DB)
if dtype in type_map: