Files
MoFin/scripts/macro_signal_consumer.py
T
知微 54915e9b7e feat: 宏观指数采集独立(macro_index_collector) + 莫荷宏观预警系统入库
- 重建 macro_index_collector.py: 原macro_context_collector(index采集)独立
  避免与莫荷的 macro_context_collector(宏观新闻采集)冲突
- 纳入莫荷的宏观预警系统:
  divergence_detector.py — 跨市场背离监测
  macro_context_collector.py — 宏观新闻采集+红绿灯(莫荷版)
  macro_signal_consumer.py — 宏观风险信号消费
- cron修正: 宏观采集-早/午间 → macro_index_collector.py
2026-06-27 01:14:00 +08:00

93 lines
2.9 KiB
Python

#!/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()