fix: system_audit/stale_push_wlin/refresh_mtf → DB, remove final JSON refs

This commit is contained in:
知微
2026-07-03 23:19:32 +08:00
parent 9bc0cca174
commit 8e487f400f
3 changed files with 1233 additions and 1242 deletions
+3 -7
View File
@@ -50,13 +50,9 @@ def main():
log(f"Pre-populating multi-timeframe cache for {len(codes)} stocks...") log(f"Pre-populating multi-timeframe cache for {len(codes)} stocks...")
# 检查当前缓存,只更新需要更新的 # 从 DB 读取现有缓存(替代 multi_tf_cache.json
mtf_cache_path = "/home/hmo/web-dashboard/data/multi_tf_cache.json" from multi_timeframe import _load_mtf_cache, _save_mtf_cache
try: existing = _load_mtf_cache()
with open(mtf_cache_path) as f:
existing = json.load(f)
except (FileNotFoundError, json.JSONDecodeError):
existing = {}
import time import time
from multi_timeframe import full_multi_tf_analysis from multi_timeframe import full_multi_tf_analysis
+12 -9
View File
@@ -17,9 +17,9 @@ import re
import json import json
import os import os
import threading import threading
from mo_data import read_portfolio, read_decisions
import time import time
from datetime import datetime, time from datetime import datetime, time
from mo_data import read_portfolio, read_decisions
# ── MoFin unified model ────────────────────────────────────────────── # ── MoFin unified model ──────────────────────────────────────────────
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
@@ -225,11 +225,14 @@ def trigger_regen_sync(stock_codes=None):
def load_cash(): def load_cash():
"""mo_data 实时读可用现金""" """portfolio.json 实时读可用现金(可用 ≈ 实时买力),不硬编码"""
try: try:
pf = read_portfolio() data = read_portfolio()
if isinstance(pf, dict): if isinstance(data, dict):
return pf.get("cash_available", pf.get("cash", 0)) # 先读 cash_available(拆分了可用/冻结),fallback 到 cash
return data.get("cash_available", data.get("cash", 0))
if isinstance(data, list) and len(data) > 1 and isinstance(data[1], dict):
return data[1].get("cash_available", data[1].get("cash", 0))
return 0 return 0
except Exception: except Exception:
return 0 return 0
@@ -332,7 +335,7 @@ def main():
cooldown = load_cooldown() cooldown = load_cooldown()
now_ts = datetime.now().timestamp() now_ts = datetime.now().timestamp()
# 读 decisions 获取完整策略数据 # 读 decisions.json 获取完整策略数据
code_data = {} code_data = {}
try: try:
dec = read_decisions() dec = read_decisions()
@@ -388,7 +391,7 @@ def main():
to_reassess = list(set(s[1] for s in stocks) | set(s[1] for s in stale_list)) to_reassess = list(set(s[1] for s in stocks) | set(s[1] for s in stale_list))
if to_reassess: if to_reassess:
trigger_regen_sync(to_reassess) trigger_regen_sync(to_reassess)
# 重评完成,re-read decisions 获取最新策略 # 重评完成,re-read decisions.json 获取最新策略
code_data = {} code_data = {}
try: try:
dec = read_decisions() dec = read_decisions()
@@ -474,8 +477,8 @@ def main():
# 加载基本面缓存(PE等) # 加载基本面缓存(PE等)
fund_cache = {} fund_cache = {}
try: try:
with open("/home/hmo/web-dashboard/data/multi_tf_cache.json") as f: import multi_timeframe as mtf_mod
mtf = json.load(f) mtf = mtf_mod._load_mtf_cache()
for code, v in mtf.items(): for code, v in mtf.items():
fund_cache[code] = v.get("fundamentals", {}) fund_cache[code] = v.get("fundamentals", {})
except Exception: except Exception:
+5 -13
View File
@@ -18,6 +18,7 @@
import json, sqlite3, subprocess, sys, time import json, sqlite3, subprocess, sys, time
from pathlib import Path from pathlib import Path
from datetime import datetime, timedelta from datetime import datetime, timedelta
from mo_data import read_portfolio, read_decisions, read_watchlist
DATA_DIR = Path("/home/hmo/MoFin/data") DATA_DIR = Path("/home/hmo/MoFin/data")
WEB_DATA = Path("/home/hmo/web-dashboard/data") WEB_DATA = Path("/home/hmo/web-dashboard/data")
@@ -53,7 +54,7 @@ def audit_signals(conn):
def audit_stocks(conn): def audit_stocks(conn):
# 关注列表 # 关注列表
try: try:
wl = json.loads((WEB_DATA / "watchlist.json").read_text()) wl = read_watchlist()
watching = [s for s in wl.get("stocks", []) if s.get("status") == "watching"] watching = [s for s in wl.get("stocks", []) if s.get("status") == "watching"]
formal = [s for s in wl.get("stocks", []) if s.get("status") != "watching"] formal = [s for s in wl.get("stocks", []) if s.get("status") != "watching"]
log_ok("股票池", f"正式自选{len(formal)}只, 关注列表{len(watching)}") log_ok("股票池", f"正式自选{len(formal)}只, 关注列表{len(watching)}")
@@ -70,7 +71,7 @@ def audit_stocks(conn):
# ── 3. 策略状态审计 ── # ── 3. 策略状态审计 ──
def audit_strategies(conn): def audit_strategies(conn):
try: try:
dec = json.loads((WEB_DATA / "decisions.json").read_text()) dec = read_decisions()
active = [d for d in dec.get("decisions", []) if d.get("status") in ("active", "updated")] active = [d for d in dec.get("decisions", []) if d.get("status") in ("active", "updated")]
stale_count = 0 stale_count = 0
no_stop = 0 no_stop = 0
@@ -99,7 +100,7 @@ def audit_strategies(conn):
# ── 4. 建议闭环审计 ── # ── 4. 建议闭环审计 ──
def audit_advice(conn): def audit_advice(conn):
try: try:
dec = json.loads((WEB_DATA / "decisions.json").read_text()) dec = read_decisions()
pending = 0 pending = 0
for d in dec.get("decisions", []): for d in dec.get("decisions", []):
for a in d.get("advice_timeline", []): for a in d.get("advice_timeline", []):
@@ -116,19 +117,10 @@ def audit_advice(conn):
# ── 5. 组合健康 ── # ── 5. 组合健康 ──
def audit_portfolio(conn): def audit_portfolio(conn):
try: try:
# 优先从 portfolio.json 读总仓位(更准确,基于实际市值/总资产) pj = read_portfolio()
pj_path = WEB_DATA / "portfolio.json"
if not pj_path.exists():
pj_path = DATA_DIR / "portfolio.json"
if pj_path.exists():
pj = json.loads(pj_path.read_text())
pos = pj.get("position_pct", 0) pos = pj.get("position_pct", 0)
cash = pj.get("cash", 0) cash = pj.get("cash", 0)
available = pj.get("available_cash", cash) available = pj.get("available_cash", cash)
else:
# 兜底:SQLite position_pct 之和
pos = conn.execute("SELECT SUM(position_pct) FROM holdings WHERE is_active=1").fetchone()[0] or 0
available = 0
log_ok("组合", f"总仓位{pos:.1f}%") log_ok("组合", f"总仓位{pos:.1f}%")
if pos > 90: if pos > 90: