54915e9b7e
- 重建 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
93 lines
2.9 KiB
Python
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()
|