#!/usr/bin/env python3 """ macro_signal_consumer.py — 消费宏观风险信号,写入风险状态 no_agent 模式:有HIGH风险→输出风险摘要 | 无→静默 管道位置: macro_risk_scanner (8:30/11:30) → signal_news(source=macro_watch) → 本脚本 ↓ macro_risk_state.json — 供所有监控 cron 读取 ↓ 如果 HIGH → 推送到 Dad """ import sqlite3, json, os from pathlib import Path from datetime import datetime BASE = Path("/home/hmo/MoFin") DATA = BASE / "data" DB_PATH = DATA / "mofin.db" STATE_PATH = DATA / "macro_risk_state.json" def main(): conn = sqlite3.connect(str(DB_PATH)) conn.row_factory = sqlite3.Row # 读取未处理的 macro_watch 信号 rows = conn.execute( "SELECT * FROM signal_news WHERE source='macro_watch' AND (processed=0 OR processed IS NULL)" ).fetchall() if not rows: # 无新信号时状态文件维持 15 分钟过期 try: state = json.loads(STATE_PATH.read_text()) created = datetime.strptime(state.get("created_at", "2000-01-01"), "%Y-%m-%d %H:%M:%S") if (datetime.now() - created).total_seconds() > 900: # 15 min state["level"] = "none" state["expired"] = True STATE_PATH.write_text(json.dumps(state, ensure_ascii=False, indent=2)) except: pass conn.close() return # SILENT # 聚合风险等级 levels = {"宏观-WATCH_HIGH": "high", "宏观-WATCH_MEDIUM": "medium", "宏观-WATCH_INFO": "info"} highest = "info" all_summaries = [] for r in rows: sentiment = r["overall_sentiment"] lv = levels.get(sentiment, "info") if lv == "high": highest = "high" elif lv == "medium" and highest != "high": highest = "medium" all_summaries.append({ "sentiment": sentiment, "summary": r["summary"][:300], "key_articles": r["key_articles"], "created_at": r["created_at"], }) # 写入风险状态文件 state = { "level": highest, "signals": all_summaries, "signal_count": len(rows), "created_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "expired": False, } STATE_PATH.write_text(json.dumps(state, ensure_ascii=False, indent=2)) # 标记为已处理 for r in rows: conn.execute("UPDATE signal_news SET processed=1 WHERE id=?", (r["id"],)) conn.commit() conn.close() # no_agent 输出(有 HIGH 才主动出声) if highest == "high": print(f"[MACRO-RISK] ⚠️ HIGH: {len(rows)}条高风险信号") for s in all_summaries: print(f" {s['summary'][:100]}") elif highest == "medium": if len(os.environ.get("MACRO_VERBOSE", "")) > 0: print(f"[MACRO-RISK] MEDIUM: {len(rows)}条中风险信号") # HIGH 信号会通过 no_agent 推送到 XMPP if __name__ == "__main__": main()