状态机 + 冷却机制


明白,你现在关注的核心是 “预警状态管理”“告警去重 / 冷却机制”,这是典型的工程问题,而不仅是指标计算。下面我给你一个完整、可落地的技术设计方案,既考虑动态更新,也能避免重复告警。


一、问题本质

你现在的系统会出现两个问题:

  1. 短期动量重复触发

    • EMA2/5、EMA5/10 斜率达到阈值时,连续几天都可能满足条件 → 每天都发预警。
  2. 状态不动态

    • 信号没有记忆,每次重新计算都是“全新触发”,导致老信号持续告警。

目标:

  • 信号记忆:知道哪只股票已经触发过预警
  • 冷却 / 重置机制:在一段时间或条件变化后再允许告警
  • 动态更新:斜率上升或下降都会更新状态,而不是固定触发一次就死掉

二、核心概念

我建议用 状态机 + 时间戳 + 冷却逻辑 实现:

1️⃣ 股票状态

每只股票维护一个 状态对象

StockState:
    last_alert_time       # 上次触发预警的时间
    alert_active          # 当前是否仍处于“告警中”
    last_slope_value      # 上次计算的斜率,用于比较变化
    score                 # 上次评分

2️⃣ 触发条件

  • 新告警触发条件

    • 评分 score ≥ 阈值(如 3 分)
    • alert_active = False(未处于告警中,或者冷却结束)
  • 动态更新条件

    • 如果 alert_active = True,但 score上升 → 可以更新预警强度(可选)
  • 冷却机制

    • 上次告警后 N 天内不再触发(例如 3 天)
    • 或斜率下降至低于阈值 → 自动重置 alert_active = False

3️⃣ 冷却/重置策略

a. 时间冷却

  • 配置一个固定周期(如 3–5 天):
if today - last_alert_time < cool_down_days:
    skip alert
else:
    allow alert

b. 条件重置

  • 当斜率下降或评分降到低于阈值时:
if score < trigger_threshold:
    alert_active = False

时间冷却 + 条件重置结合使用,更稳妥。


三、动态状态更新流程(伪代码)

for stock in stock_pool:
    state = stock_states[stock]

    # 1. 计算今日评分
    score = calculate_score(stock)

    # 2. 检查是否满足触发条件
    trigger = score >= trigger_threshold
    time_ok = (today - state.last_alert_time).days >= cool_down_days

    if trigger and not state.alert_active and time_ok:
        generate_alert(stock, score)
        state.last_alert_time = today
        state.alert_active = True
        state.score = score
        state.last_slope_value = current_slope

    elif state.alert_active:
        # 更新预警强度(可选)
        if score > state.score:
            update_alert_strength(stock, score)
            state.score = score

        # 条件下降,自动解除
        if score < trigger_threshold:
            state.alert_active = False

四、斜率动态变化处理

  • 用百分比斜率 (EMA_today - EMA_n_days_ago)/EMA_n_days_ago,便于跨股票比较

  • 阈值触发 + 斜率增量更新

    • 如果斜率比上次触发增加超过 Δ → 更新信号强度
    • 如果斜率持续下降 → 重置 alert_active
  • 这样既避免重复告警,又让信号可以动态变化。


五、工程实现建议

  1. 状态存储

    • 内存字典(单机 MVP):

      stock_states = {symbol: StockState()}
      
    • 数据库持久化(生产):

      • 每只股票保存 last_alert_time, alert_active, last_score
      • 支持跨天、跨服务调用
  2. 参数可配置

    • trigger_threshold(分值阈值)
    • cool_down_days(冷却天数)
    • slope_delta(斜率更新增量)
  3. 可扩展性

    • 可以加“二次条件”,例如:

      • EMA200位置变化
      • 高低波动分类变化
    • 对动态状态系统不影响核心逻辑


六、总结设计思路

  • 状态机 + 冷却机制是关键
  • 告警仅在首次触发或评分增强时更新
  • 低于阈值或冷却期结束后允许再次触发
  • 斜率变化作为动态更新的触发因子

这种设计保证了信号动态响应,但不会每天重复告警,也便于未来加入更多策略维度(波动状态变化、趋势变化等)。


如果你需要,我可以帮你画一张 股票状态机图,清晰显示:

  • alert_active / inactive
  • 触发、冷却、解除、更新的状态流转

这样在技术实现或 PRD 里直接用,非常直观。

你希望我画吗?

posted @ 2026-01-06 17:12  向着朝阳  阅读(13)  评论(0)    收藏  举报