fix(scripts): promote UNIQUE crash + candidate_filter DB lock (morning readiness)

Pre-open error sweep (all verified by manual run):
- promote_candidates.py: INSERT OR IGNORE + only newly-added stocks count
  toward promotion/XMPP (was crashing on first duplicate, never finishing;
  now completes 40s, promoted 74 with correct skip marking)
- candidate_filter.py: PRAGMA busy_timeout=30s (was dying on transient
  'database is locked' under concurrent cron writes; now completes 9.6s)
- price_monitor.py: verified completes 1m55s (< 120s cron timeout) with
  working LLM reassess via key6
- macro_context_collector.py / divergence_detector.py: previously
  'Blocked' by symlink check, now run fine (8.7s / 1m55s)
- memory_guardian.py: completes 1m55s with key6
- preflight sync diff: historical, files now identical

Production proof: 大脑任务执行 (was 429 every 10min) now status=ok at 01:21
This commit is contained in:
hmo
2026-07-20 01:34:37 +08:00
parent 57377e9dd3
commit 115292bb96
4 changed files with 52 additions and 16 deletions
+3 -1
View File
@@ -17,7 +17,9 @@ DB_PATH = Path("/home/hmo/MoFin/data/mofin.db")
UA = "Mozilla/5.0"
def get_conn():
return sqlite3.connect(str(DB_PATH))
c = sqlite3.connect(str(DB_PATH), timeout=30)
c.execute("PRAGMA busy_timeout=30000")
return c
def log_candidate(conn, code, stage, passed, detail):
"""记录过滤日志"""
+20 -15
View File
@@ -83,8 +83,8 @@ def main():
reason_text.append(f"评分{score}")
action = " | ".join(reason_text) if reason_text else f"市场扫描发现(评分{score})"
conn.execute("""
INSERT INTO holding_strategies
cur = conn.execute("""
INSERT OR IGNORE INTO holding_strategies
(code, name, price, entry_low, entry_high, stop_loss, take_profit,
timing_signal, action, decision_type, strategy_type, status,
rr_ratio, stock_category, created_at, updated_at,
@@ -92,22 +92,27 @@ def main():
VALUES (?,?,?,?,?,?,?,?,?,'自选策略','scan',
'active',0,'关注',?,?,'', 'pending')
""", (code, name, 0, el, eh, sl, tp, timing_signal, action, now, now))
newly_added = cur.rowcount > 0
conn.execute("UPDATE candidates SET promoted=1 WHERE code=?", (code,))
promoted += 1
print(f"{code} {name} 评分{score} → 已加入自选({timing_signal})", flush=True)
if newly_added:
promoted += 1
print(f"{code} {name} 评分{score} → 已加入自选({timing_signal})", flush=True)
else:
print(f"{code} {name} 已在自选策略中,标记promoted", flush=True)
# 触发全量重评(生成完整9维策略)
try:
import subprocess as _sp
r = _sp.run(["python3", "/home/hmo/MoFin/scripts/per_stock_reassess.py", code],
capture_output=True, text=True, timeout=60)
if r.returncode == 0:
print(f" 重评完成", flush=True)
else:
print(f" 重评失败: {r.stderr.strip()[:100]}", flush=True)
except Exception as e:
print(f" 重评异常: {e}", flush=True)
# 触发全量重评(生成完整9维策略)——仅新插入的股票需要
if newly_added:
try:
import subprocess as _sp
r = _sp.run(["python3", "/home/hmo/MoFin/scripts/per_stock_reassess.py", code],
capture_output=True, text=True, timeout=60)
if r.returncode == 0:
print(f" 重评完成", flush=True)
else:
print(f" 重评失败: {r.stderr.strip()[:100]}", flush=True)
except Exception as e:
print(f" 重评异常: {e}", flush=True)
conn.commit()
print(f"\n[PROMOTE] 本次提拔{promoted}", flush=True)