A close-up of a golden Bitcoin highlighting its digital curr

跑一个量化策略需要的不只是策略本身——还需要一套支撑它运行、监控它状态、在出问题时及时告警的工具链。这篇文章分享我的完整工具栈,从策略执行到告警通知。

整体架构

策略层(Python)
  ↓ 交易指令
Binance API
  ↓ 执行结果
状态文件 / CF KV
  ↓ 指标
Prometheus + node_exporter
  ↓ 存储
Grafana 可视化
  ↓ 告警规则
Alertmanager → Telegram

策略执行层

技术栈

  • 语言:Python 3.11
  • Binance SDK:python-binance
  • 定时任务:APScheduler 或系统 cron
  • 依赖管理:requirements.txt + venv

目录结构

quant/
├── strategy/
│   ├── main.py          # 主策略逻辑(信号生成 + 下单)
│   ├── signals.py       # 指标计算(技术指标库)
│   └── risk.py          # 仓位管理、止损逻辑
├── exchange/
│   └── binance_client.py # Binance API 封装
├── monitor/
│   └── exporter.py      # 状态指标写入 Prometheus 格式
├── config/
│   └── settings.py      # 配置(从环境变量读取)
└── run.py               # 入口

关键代码:状态指标暴露

策略运行时,把关键指标写成 Prometheus textfile 格式,供 node_exporter 抓取:

# monitor/exporter.py
import os
import time

METRICS_FILE = "/var/lib/node_exporter/textfile_collector/quant.prom"

def write_metrics(data: dict):
    """
    data 示例:
    {
        "pnl_total": 12.5,          # 累计收益率 %
        "pnl_today": 0.8,           # 今日收益率 %
        "position": 1,              # 1=多, -1=空, 0=空仓
        "last_signal_ts": 1776200000,  # 最后信号时间戳
        "last_run_ts": 1776235000,     # 策略最后运行时间
    }
    """
    lines = [
        '# HELP quant_pnl_total 累计收益率(百分比)',
        '# TYPE quant_pnl_total gauge',
        f'quant_pnl_total {data["pnl_total"]}',
        '',
        '# HELP quant_pnl_today 今日收益率(百分比)',
        '# TYPE quant_pnl_today gauge',
        f'quant_pnl_today {data["pnl_today"]}',
        '',
        '# HELP quant_position 当前持仓方向 (1=多,-1=空,0=空仓)',
        '# TYPE quant_position gauge',
        f'quant_position {data["position"]}',
        '',
        '# HELP quant_last_signal_timestamp 最后信号时间',
        '# TYPE quant_last_signal_timestamp gauge',
        f'quant_last_signal_timestamp {data["last_signal_ts"]}',
        '',
        '# HELP quant_last_run_timestamp 策略最后运行时间',
        '# TYPE quant_last_run_timestamp gauge',
        f'quant_last_run_timestamp {int(time.time())}',
        '',
    ]
    
    tmp = METRICS_FILE + ".tmp"
    with open(tmp, "w") as f:
        f.write("\n".join(lines))
    os.rename(tmp, METRICS_FILE)

服务器配置

选择

量化策略对服务器的核心要求:

  • 稳定:不能随意宕机,24/7 运行
  • 延迟低:离 Binance 服务器近(新加坡或东京),下单延迟更低
  • 独立:不和其他高负载任务共享

我用 AWS 新加坡节点(aws-sg),Binance 主服务器在新加坡,下单延迟 1-5ms。

systemd 守护进程

不要用 nohup 跑策略,用 systemd:

# /etc/systemd/system/quant-strategy.service
[Unit]
Description=Quant Strategy
After=network.target

[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/quant
ExecStart=/home/ubuntu/quant/venv/bin/python run.py
Restart=always
RestartSec=10
EnvironmentFile=/home/ubuntu/quant/.env

[Install]
WantedBy=multi-user.target
systemctl enable quant-strategy
systemctl start quant-strategy
systemctl status quant-strategy

策略崩溃会自动重启,重启间隔 10 秒。

环境变量管理

API Key 放 .env 文件,不提交到 Git:

# .env(只有 600 权限)
BINANCE_API_KEY=xxxx
BINANCE_API_SECRET=xxxx
TELEGRAM_BOT_TOKEN=xxxx
TELEGRAM_CHAT_ID=xxxx
# settings.py
from dotenv import load_dotenv
import os

load_dotenv()
BINANCE_API_KEY = os.environ["BINANCE_API_KEY"]
BINANCE_API_SECRET = os.environ["BINANCE_API_SECRET"]

Prometheus 监控配置

在 prometheus.yml 添加策略服务器的 node_exporter:

scrape_configs:
  - job_name: node-remote-linux
    static_configs:
      - targets:
          - 你的策略服务器IP:9100

node_exporter 默认会自动采集 /var/lib/node_exporter/textfile_collector/*.prom 里的指标,不需要额外配置。

Grafana Dashboard

量化策略的核心监控面板包含:

收益区(上方)

  • 累计收益率时序曲线
  • 今日收益 Stat 卡片
  • 当前持仓方向(多/空/空仓)

风险区(中间)

  • 最大回撤(Max Drawdown)
  • 近 30 日日收益柱状图
  • 夏普比率(年化)

健康区(下方)

  • 策略最后运行时间(距现在多久)
  • 最后信号时间(距现在多久)
  • 心跳状态(绿色=正常,红色=异常)

关键面板:策略心跳

# Grafana PromQL
(time() - quant_last_run_timestamp) / 60

这个查询显示策略最后运行距现在多少分钟。配合阈值颜色:

  • < 65 分钟:绿色(正常,小时级策略)
  • 65-120 分钟:黄色(轻微延迟)
  • 120 分钟:红色(策略可能挂了)

告警配置

Alertmanager + Telegram

在 alerts.yml 里定义告警规则:

groups:
  - name: quant-alerts
    rules:
      # 策略心跳超时
      - alert: QuantHeartbeatTimeout
        expr: (time() - quant_last_run_timestamp) > 7200
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "量化策略心跳超时"
          description: "策略超过 2 小时未运行,请检查服务器状态"

      # 今日大幅亏损
      - alert: QuantLargeLoss
        expr: quant_pnl_today < -3
        for: 1m
        labels:
          severity: warning
        annotations:
          summary: "今日亏损超过 3%"
          description: "当日收益率 {{ $value }}%,请关注"

Telegram 告警模板(在 alertmanager.yml 里配置):

receivers:
  - name: telegram
    telegram_configs:
      - bot_token: "你的BOT_TOKEN"
        chat_id: 你的CHAT_ID
        message: |
          🚨 {{ .GroupLabels.alertname }}
          {{ range .Alerts }}
          {{ .Annotations.summary }}
          {{ .Annotations.description }}
          {{ end }}

在策略代码里直接推送告警

除了 Alertmanager,策略代码里也可以直接推 Telegram:

import requests

def send_telegram(message: str):
    bot_token = os.environ["TELEGRAM_BOT_TOKEN"]
    chat_id = os.environ["TELEGRAM_CHAT_ID"]
    url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
    requests.post(url, json={"chat_id": chat_id, "text": message})

# 下单后推送
send_telegram(f"📊 信号:{direction}\n价格:{price}\n仓位:{size}")

总结:工具选型逻辑

工具替代方案选这个的原因
PythonGo、JavaScript量化生态最丰富(pandas、ta-lib 等)
Binance python-binance自己封装 REST官方 SDK,省去重复造轮子
systemdsupervisor、PM2系统自带,稳定,日志集中管理
Prometheus + node_exporterInfluxDB + Telegraf已有监控栈,复用,不引入新组件
Alertmanager自己写告警脚本支持规则、静默、分组,功能完整
Telegram邮件、钉钉手机推送及时,API 简单

→ 查看 北极星策略介绍 → 查看 Binance API 从零到第一笔下单 → 查看 Prometheus + Grafana VPS 监控搭建


📷 封面图 · Flux Schnell AI 生成 · panshi.io 品牌风格