Files

121 lines
3.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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
# ── 消息通道统一路由(broadcast/xmpp by delivery) ──
try:
from messenger import install_stdio_hook as _msh
_msh()
except Exception:
pass
# 确保能找到 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()