v1.8.0: 🌙 静默期 - 舆情监控/持仓跟踪/定时报告三大自动化任务独立配置静默时段, 命中时段不发送邮件(多段/跨午夜, 日志标quiet, 水位照常推进不补发积压)

This commit is contained in:
2026-08-20 23:43:02 +08:00
parent 4da5e091a5
commit 9340577f7b
10 changed files with 196 additions and 32 deletions
+7 -2
View File
@@ -19,7 +19,8 @@ import threading
import time
from database import query, query_one, execute
from settings import tracking_config, tracking_state, set_tracking_state, mail_config
from settings import tracking_config, tracking_state, set_tracking_state, mail_config, \
quiet_config, in_quiet_period
from engine.chain_data import get_chain
from engine.indicators import compute_indicators
from rag.vector_store import query_vectors
@@ -287,10 +288,14 @@ def _first_heading(text):
def _notify_if_significant(rid, stock, meta):
"""影响度达阈值且开启通知 → 邮件(股票/概念通用)"""
"""影响度达阈值且开启通知 → 邮件(股票/概念通用)。静默期内抑制发送。"""
cfg = tracking_config()
try:
if cfg["notify"] and int(meta.get("impact_score", 0)) >= int(cfg["impact_threshold"]):
qc = quiet_config("tracking")
if qc["enabled"] and in_quiet_period(qc["ranges"]):
log.info("tracking notify suppressed by quiet period: %s", stock.get("name"))
return
from engine.notifier import send_email
mc = mail_config()
nc = meta.get("news_counts") or {}
+30 -22
View File
@@ -18,7 +18,8 @@ from email.mime.text import MIMEText
from email.utils import formataddr, formatdate
from database import query, execute, query_one
from settings import mail_config, monitor_config, monitor_state, set_monitor_state
from settings import mail_config, monitor_config, monitor_state, set_monitor_state, \
quiet_config, in_quiet_period
log = logging.getLogger("notifier")
@@ -180,27 +181,34 @@ def scan_news(force=False):
sent, failed = 0, 0
if important:
# 单封邮件最多带 20 条,避免超大邮件
shown = important[:20]
omitted = len(important) - len(shown)
items = [{"news": it["news"], "score": it["score"],
"stocks": _fetch_related_names([c for c in (it["news"]["related_stocks"] or "").split(",") if c])}
for it in shown]
subject = f"[舆情监控] {len(important)} 条重要资讯:{important[0]['news']['title'][:24]}" + \
(f"{len(important)}" if len(important) > 1 else "")
try:
html = build_email_html(items)
if omitted:
html += f"<p style='color:#888;font-size:12px'>……另有 {omitted} 条重要资讯已省略,详见系统。</p>"
if cfg.get("email_enabled", True):
send_email(subject, html)
status, msg = "sent", ""
else:
status, msg = "skipped", "邮件功能未启用"
except Exception as e:
status, msg = "failed", str(e)
failed = len(important)
log.warning("notify email fail: %s", e)
# 静默期判断:命中则本次不发送邮件(仍记账推进水位,避免静默结束后补发积压)
qc = quiet_config("monitor")
quiet = qc["enabled"] and in_quiet_period(qc["ranges"])
omitted = 0
if quiet:
status, msg = "quiet", "静默期内已抑制发送"
else:
# 单封邮件最多带 20 条,避免超大邮件
shown = important[:20]
omitted = len(important) - len(shown)
items = [{"news": it["news"], "score": it["score"],
"stocks": _fetch_related_names([c for c in (it["news"]["related_stocks"] or "").split(",") if c])}
for it in shown]
subject = f"[舆情监控] {len(important)} 条重要资讯:{important[0]['news']['title'][:24]}" + \
(f"{len(important)}" if len(important) > 1 else "")
try:
html = build_email_html(items)
if omitted:
html += f"<p style='color:#888;font-size:12px'>……另有 {omitted} 条重要资讯已省略,详见系统。</p>"
if cfg.get("email_enabled", True):
send_email(subject, html)
status, msg = "sent", ""
else:
status, msg = "skipped", "邮件功能未启用"
except Exception as e:
status, msg = "failed", str(e)
failed = len(important)
log.warning("notify email fail: %s", e)
# 写日志
for it in important:
execute(
+10 -2
View File
@@ -14,7 +14,7 @@ import logging
import time
from database import query, query_one, execute
from settings import mail_config
from settings import mail_config, quiet_config, in_quiet_period
from engine.analyst import llm_chat
log = logging.getLogger("report")
@@ -428,8 +428,16 @@ th{{background:#f8fafc;color:#475569;}}
# ===================================================================== 发送
def send_daily_report(kind="premarket"):
"""生成并发送报告:正文=简版,附件=详细版 HTML。返回 dict 状态"""
"""生成并发送报告:正文=简版,附件=详细版 HTML。静默期内抑制发送。返回 dict 状态"""
from engine.notifier import send_email
# 静默期判断:命中则不生成、不发送,仅记一条 quiet 日志
qc = quiet_config("report")
if qc["enabled"] and in_quiet_period(qc["ranges"]):
meta = KIND_META.get(kind, KIND_META["premarket"])
subject = f"[智能荐股] {meta['name']} {time.strftime('%Y-%m-%d')}"
execute("INSERT INTO report_log(kind, subject, brief_len, detail_len, status, message) "
"VALUES(?,?,0,0,'quiet',?)", (kind, subject, "静默期内已抑制发送"))
return {"ok": False, "quiet": True, "msg": "静默期内已抑制发送"}
mc = mail_config()
brief_html, detail_html = generate_reports(kind)
meta = KIND_META.get(kind, KIND_META["premarket"])