第二十章 实盘监控与预警:实时仪表盘设计、异常基差告警、日志与审计系统

实盘交易最怕什么?

怕你人不在电脑前,基差突然崩了。怕你策略跑得好好的,交易所接口断了你还在傻等。怕你赚了钱想复盘,结果发现日志全是空的。

这些坑,我全都踩过。今天这一章,咱们就把监控预警这件事彻底讲透。

20.1 实时仪表盘:你的交易驾驶舱

仪表盘不是花架子。它是你盯盘的唯一窗口。

我个人习惯,仪表盘上只放三类信息:持仓状态、基差曲线、风险指标。多了反而乱。

20.1.1 核心指标设计

先列一下必须展示的字段:

指标类别 具体字段 刷新频率
持仓 当前净头寸、多空比例、保证金占用 1秒
基差 实时基差值、基差历史分位数、基差变化率 500ms
风险 浮动盈亏、最大回撤、杠杆倍数 1秒
系统 API连接状态、数据延迟、订单队列长度 2秒

这里有个细节:基差变化率我建议用滚动窗口计算。比如过去5秒的基差变化斜率,比瞬时值更有参考意义。我在项目中遇到过,瞬时基差跳变导致误报,后来改成滚动窗口后,误报率降了80%。

20.1.2 可视化组件选择

别用太花哨的图表。交易员需要的是直觉,不是艺术。

  • 折线图:展示基差历史走势,叠加均值±2倍标准差通道
  • 仪表盘:显示当前基差偏离程度,绿色正常、黄色警惕、红色危险
  • 热力图:展示多品种基差矩阵,一眼看出哪个品种异常
  • 数字卡片:关键数值直接显示,比如浮动盈亏、保证金比例

嗯,这里要注意:热力图不要放太多品种。超过20个,人眼就看不过来了。我一般控制在10-15个核心品种。

20.2 异常基差告警:别等亏钱了才反应过来

告警系统是监控的灵魂。但很多人把告警做成了「狼来了」——天天响,最后没人信。

20.2.1 告警阈值设计

阈值不能拍脑袋。我建议用统计方法动态计算:

# 动态阈值计算示例
import numpy as np

def calculate_threshold(basis_history, window=100, z_score=2.5):
    rolling_mean = np.mean(basis_history[-window:])
    rolling_std = np.std(basis_history[-window:])
    upper = rolling_mean + z_score * rolling_std
    lower = rolling_mean - z_score * rolling_std
    return upper, lower

# 实时判断
current_basis = get_current_basis()
upper, lower = calculate_threshold(basis_history)
if current_basis > upper or current_basis < lower:
    trigger_alert('基差异常偏离')

z_score取2.5还是3.0?这取决于你的品种波动率。我曾经在股指期货上用过3.0,结果一个月没触发一次告警——阈值设太宽了。后来改成2.5,效果刚好。

20.2.2 告警分级与通知

别所有告警都用同一个渠道。分级处理:

级别 触发条件 通知方式 响应要求
INFO 基差进入1倍标准差区间 仪表盘闪烁 观察即可
WARNING 基差进入2倍标准差区间 微信/钉钉推送 30分钟内关注
CRITICAL 基差突破3倍标准差 电话+短信+微信 立即处理
EMERGENCY API断连/账户异常 所有渠道+值班人员 5分钟内响应

你想想看,如果每个小波动都打电话给你,你还能睡好觉吗?分级就是为了让你只处理真正重要的事

20.2.3 告警去重与抑制

这是最容易忽略的点。基差在阈值附近来回震荡时,告警会疯狂触发。

我的做法是:同一品种同一级别的告警,5分钟内不重复发送。代码实现很简单:

class AlertManager:
    def __init__(self):
        self.alert_history = {}
    
    def should_alert(self, symbol, level):
        key = f"{symbol}_{level}"
        last_time = self.alert_history.get(key)
        if last_time and (time.time() - last_time) < 300:
            return False
        self.alert_history[key] = time.time()
        return True

我曾经因为没做去重,一个品种在10分钟内发了200多条告警。手机直接被打爆,微信消息99+。从那以后,去重成了我系统的标配。

20.3 日志与审计系统:你的交易黑匣子

日志不是写给别人看的。它是你出事后唯一能还原现场的东西。

20.3.1 日志分级与存储

我习惯用四个级别:

  • DEBUG:开发调试用,记录每个订单的完整生命周期
  • INFO:正常交易记录,开仓、平仓、调仓
  • WARNING:异常但不影响交易,比如网络抖动后恢复
  • ERROR:必须人工介入的错误,比如API返回错误码

存储策略上,我建议:

  • DEBUG日志保留7天,滚动删除
  • INFO日志保留30天
  • WARNING和ERROR日志保留1年
  • 所有日志压缩后归档到冷存储

20.3.2 审计追踪:谁在什么时候做了什么

审计日志要记录的是不可篡改的操作轨迹。包括:

  • 策略参数修改(谁改的、改了什么、什么时候改的)
  • 手动干预操作(强制平仓、调整仓位)
  • 系统配置变更(API密钥更新、服务器重启)
  • 异常事件(程序崩溃、数据断流)

我建议用追加写入的方式存储审计日志。不要覆盖,不要删除。每条记录加上时间戳和操作者ID。

# 审计日志格式示例
{
    "timestamp": "2025-03-15 14:30:22.123",
    "operator": "system",
    "action": "modify_parameter",
    "target": "basis_threshold",
    "old_value": 2.5,
    "new_value": 3.0,
    "reason": "降低误报率",
    "status": "success"
}

20.3.3 日志查询与可视化

光存日志没用,你得能快速查。我一般用ELK或者Grafana Loki做日志聚合。

常用的查询场景:

  • 「昨天下午3点到4点,所有ERROR级别的日志」
  • 「品种rb2505,过去一周的所有WARNING记录」
  • 「谁在凌晨2点修改了风控参数」

这些查询如果靠手动翻文件,你会疯掉的。所以一定要上日志聚合系统。

20.4 整体架构:一张图说清楚

下面这张图展示了监控预警系统的核心流程:

交易所数据源 策略引擎 数据聚合层 行情清洗 基差计算 指标加工 数据缓存 监控核心引擎 阈值计算 异常检测 告警判定 日志记录 审计追踪 实时仪表盘 可视化展示 告警通知系统 微信/短信/电话 日志与审计存储 ELK / 冷归档 交易员 / 运维

这张图的核心逻辑是:数据从交易所和策略引擎流入,经过聚合加工后,交给监控引擎做判断。判断结果分三路输出:仪表盘展示、告警通知、日志存储。

20.5 实战避坑指南

我曾经踩过的三个大坑:

  1. 日志写得太细:一天产生几十GB日志,查询慢得像蜗牛。后来加了日志采样和分级存储才解决。
  2. 告警阈值写死:市场波动率变化后,旧阈值完全失效。现在全部用动态计算。
  3. 没有做告警抑制:一个品种的基差在阈值附近震荡,一晚上收到3000条告警。手机直接没电关机。

我的个人建议:

  • 仪表盘用暗色主题,长时间盯盘不伤眼
  • 告警声音用不同音调区分级别,紧急情况用尖锐音
  • 日志文件按日期+品种命名,方便快速定位
  • 每周做一次告警复盘,看看哪些告警是误报,调整阈值

监控预警系统做得好不好,直接决定你能不能睡个安稳觉。别等到爆仓了才想起来补日志,那时候什么都晚了。

好了,这一章的内容就到这里。记住:好的监控系统,是让你感觉不到它存在,但一旦出事,它比你先知道。


公众号:蓝海资料掘金营,微信deep3321