fix: refresh_mtf_cache 循环后补 flush_mtf_cache 写回 mtf_cache 表(修复缓存no-op)

This commit is contained in:
xxm
2026-08-11 03:29:24 +08:00
parent e77d9767ce
commit 3254d4d9e0
+113 -103
View File
@@ -1,103 +1,113 @@
#!/usr/bin/env python3
"""多周期缓存刷新脚本 — 在开盘前预填充K线数据
为所有持仓+自选股预先拉取日/周/月K线,写入 multi_tf_cache.json
这样收盘后全量重评(regenerate_all)运行时K线数据已有缓存,无需逐个拉取。
运行时间:每天9:00(开盘前),no_agent模式。
无输出 = 成功(避免每天收到无意义消息)。
"""
import sys
import os
import json
from datetime import datetime
# 确保能找到 web-dashboard 模块
sys.path.insert(0, "/home/hmo/web-dashboard")
# 控制台UTC日志
def log(msg):
ts = datetime.utcnow().strftime("%H:%M:%S")
print(f"[{ts}] {msg}", file=sys.stderr)
def main():
from mofin_db import get_conn
# 收集所有股票代码
codes = []
seen = set()
conn = get_conn()
try:
rows = conn.execute("SELECT code FROM holdings WHERE is_active=1").fetchall()
for r in rows:
code = r["code"]
if code:
codes.append(("portfolio", code))
seen.add(code)
rows = conn.execute("SELECT code FROM watchlist_stocks WHERE is_active=1").fetchall()
for r in rows:
code = r["code"]
if code and code not in seen:
codes.append(("watchlist", code))
seen.add(code)
finally:
conn.close()
# 加入指数代码(用于多周期趋势研判)
INDEXES = {
"sh000001": "上证指数", "sz399001": "深证成指",
"sz399006": "创业板指", "sh000688": "科创50",
"hkHSI": "恒生指数", "hkHSTECH": "恒生科技",
}
for idx_code in INDEXES:
if idx_code not in seen:
codes.append(("index", idx_code))
seen.add(idx_code)
log(f"Pre-populating multi-timeframe cache for {len(codes)} stocks...")
# 从 DB 读取现有缓存(替代 multi_tf_cache.json
from multi_timeframe import _load_mtf_cache, _save_mtf_cache
existing = _load_mtf_cache()
import time
from multi_timeframe import full_multi_tf_analysis
cached = 0
fetched = 0
errors = 0
for source, code in codes:
cached_entry = existing.get(code, {})
updated_at = cached_entry.get("updated_at", 0)
now = time.time()
# 检查缓存是否新鲜:日K 1小时内,周/月K 1天内
has_daily = bool(cached_entry.get("daily"))
has_weekly = bool(cached_entry.get("weekly"))
has_monthly = bool(cached_entry.get("monthly"))
cache_fresh = (updated_at > 0 and (now - updated_at) < 3600)
if has_daily and has_weekly and has_monthly and cache_fresh:
cached += 1
continue
try:
r = full_multi_tf_analysis(code)
if any(k in r for k in ["daily", "weekly", "monthly"]):
fetched += 1
log(f" OK {code} ({source})")
else:
errors += 1
log(f" EMPTY {code} ({source})")
except Exception as e:
errors += 1
log(f" FAIL {code} ({source}): {e}")
log(f"Done: {cached} cached, {fetched} fetched, {errors} errors")
if __name__ == "__main__":
main()
#!/usr/bin/env python3
"""多周期缓存刷新脚本 — 在开盘前预填充K线数据
为所有持仓+自选股预先拉取日/周/月K线,写入 multi_tf_cache.json
这样收盘后全量重评(regenerate_all)运行时K线数据已有缓存,无需逐个拉取。
运行时间:每天9:00(开盘前),no_agent模式。
无输出 = 成功(避免每天收到无意义消息)。
"""
import sys
import os
import json
from datetime import datetime
# 确保能找到 web-dashboard 模块
sys.path.insert(0, "/home/hmo/web-dashboard")
# 控制台UTC日志
def log(msg):
ts = datetime.utcnow().strftime("%H:%M:%S")
print(f"[{ts}] {msg}", file=sys.stderr)
def main():
from mofin_db import get_conn
# 收集所有股票代码
codes = []
seen = set()
conn = get_conn()
try:
rows = conn.execute("SELECT code FROM holdings WHERE is_active=1").fetchall()
for r in rows:
code = r["code"]
if code:
codes.append(("portfolio", code))
seen.add(code)
rows = conn.execute("SELECT code FROM watchlist_stocks WHERE is_active=1").fetchall()
for r in rows:
code = r["code"]
if code and code not in seen:
codes.append(("watchlist", code))
seen.add(code)
finally:
conn.close()
# 加入指数代码(用于多周期趋势研判)
INDEXES = {
"sh000001": "上证指数", "sz399001": "深证成指",
"sz399006": "创业板指", "sh000688": "科创50",
"hkHSI": "恒生指数", "hkHSTECH": "恒生科技",
}
for idx_code in INDEXES:
if idx_code not in seen:
codes.append(("index", idx_code))
seen.add(idx_code)
log(f"Pre-populating multi-timeframe cache for {len(codes)} stocks...")
# 从 DB 读取现有缓存(替代 multi_tf_cache.json
from multi_timeframe import _load_mtf_cache, _save_mtf_cache
existing = _load_mtf_cache()
import time
from multi_timeframe import full_multi_tf_analysis
cached = 0
fetched = 0
errors = 0
for source, code in codes:
cached_entry = existing.get(code, {})
updated_at = cached_entry.get("updated_at", 0)
now = time.time()
# 检查缓存是否新鲜:日K 1小时内,周/月K 1天内
has_daily = bool(cached_entry.get("daily"))
has_weekly = bool(cached_entry.get("weekly"))
has_monthly = bool(cached_entry.get("monthly"))
cache_fresh = (updated_at > 0 and (now - updated_at) < 3600)
if has_daily and has_weekly and has_monthly and cache_fresh:
cached += 1
continue
try:
r = full_multi_tf_analysis(code)
if any(k in r for k in ["daily", "weekly", "monthly"]):
fetched += 1
log(f" OK {code} ({source})")
else:
errors += 1
log(f" EMPTY {code} ({source})")
except Exception as e:
errors += 1
log(f" FAIL {code} ({source}): {e}")
# 2026-08-11 修复: 循环结束后把模块级缓存刷回 mtf_cache 表
# (此前 full_multi_tf_analysis 只写 stocks/stock_daily 等表,
# mtf_cache 表从未被更新 -> 健康检查报 stale。flush 后写入。)
try:
from multi_timeframe import flush_mtf_cache
flush_mtf_cache()
log("mtf_cache flushed to DB")
except Exception as e:
log(f"flush_mtf_cache failed: {e}")
log(f"Done: {cached} cached, {fetched} fetched, {errors} errors")
if __name__ == "__main__":
main()