第二十八章:高级话题九:做市策略的云部署与运维

说实话,很多做量化交易的朋友,策略在本地回测跑得风生水起,一到实盘就崩了。为什么?因为本地环境和云端环境完全是两码事。你想想看,你的笔记本可能晚上自动休眠,网络偶尔断一下,这些在回测时都不是问题,但实盘时就是灾难。

我个人习惯,策略写好之后,第一件事就是考虑怎么把它扔到云上去。今天我们就聊聊做市策略的云部署与运维,这些都是我踩过坑之后总结出来的经验。

为什么非得上云?

本地跑策略,说白了就是图个方便。但做市策略有个特点——它需要7x24小时在线。你总不能让笔记本一直开着吧?

我遇到过最惨的一次,策略在本地跑了三天,收益曲线漂亮得很。结果第四天早上起来一看,笔记本自动更新重启了,策略停了整整6个小时。那天的亏损,够我买好几台云服务器了。

上云的好处很明显:

  • 高可用:云服务商保证99.9%以上的可用性
  • 弹性扩展:行情波动大时,可以快速扩容
  • 低延迟:可以选择离交易所最近的机房
  • 灾备:多区域部署,一个挂了另一个顶上

云部署架构设计

做市策略的部署架构,我一般分成三层。嗯,这里要注意,不是越复杂越好,关键是稳定。

核心架构三层模型:

  • 数据层:行情数据接收、存储、清洗
  • 策略层:做市逻辑执行、订单管理、风控
  • 交互层:API网关、监控面板、告警系统

下面这张图是我自己常用的部署架构,你可以参考一下:

做市策略云部署架构图 数据层 WebSocket行情 REST API补数 Redis缓存 PostgreSQL 策略层 做市策略引擎 (价差计算/订单生成) 风控模块 (仓位/资金/频率控制) 订单管理模块 (撤单/重发/状态同步) 交互层 Grafana监控 Telegram告警 Web管理后台 API网关

部署工具选型

工具选对了,运维能省一半的力。我这些年试过不少方案,最后沉淀下来几套比较顺手的:

工具 用途 我的评价
Docker 容器化部署 必选。环境一致性全靠它
Docker Compose 多容器编排 小团队够用,别整K8s
GitHub Actions CI/CD 免费额度够用,省心
Prometheus + Grafana 监控 开源方案,功能强大
Supervisor 进程管理 轻量级,崩溃自动重启

我的经验:别一上来就上Kubernetes。做市策略通常就几个服务,Docker Compose完全够用。K8s的学习成本和运维成本都不低,除非你的策略规模真的到了那个量级。

Docker化部署实战

写个Dockerfile其实不难,但有几个坑要注意。我曾经因为时区没设置对,导致策略的时间戳全部错乱,回测数据对不上实盘数据,排查了整整一天。

下面是我常用的Dockerfile模板:

# 多阶段构建,减小镜像体积
FROM python:3.9-slim as builder

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

FROM python:3.9-slim
WORKDIR /app

# 设置时区,这个坑我踩过
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

COPY --from=builder /usr/local/lib/python3.9/site-packages /usr/local/lib/python3.9/site-packages
COPY . .

# 非root用户运行,安全第一
RUN useradd -m -u 1000 trader
USER trader

CMD ["python", "run_market_maker.py"]

注意:千万不要在容器里用root用户运行策略。万一容器被攻破,攻击者就有root权限了。我见过有人因为这个问题,API Key被偷,损失惨重。

docker-compose.yml配置

多服务编排时,我习惯把策略、数据库、监控都放在一个compose文件里。这样一键启动,省事。

version: '3.8'

services:
  market-maker:
    build: .
    restart: always
    environment:
      - EXCHANGE_API_KEY=${API_KEY}
      - EXCHANGE_SECRET=${API_SECRET}
      - REDIS_HOST=redis
      - DB_HOST=postgres
    depends_on:
      - redis
      - postgres
    volumes:
      - ./logs:/app/logs
    networks:
      - mm_network

  redis:
    image: redis:7-alpine
    restart: always
    volumes:
      - redis_data:/data
    networks:
      - mm_network

  postgres:
    image: postgres:15-alpine
    restart: always
    environment:
      POSTGRES_DB: market_maker
      POSTGRES_USER: trader
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - mm_network

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    volumes:
      - grafana_data:/var/lib/grafana
    networks:
      - mm_network

volumes:
  redis_data:
  postgres_data:
  grafana_data:

networks:
  mm_network:
    driver: bridge

监控与告警

做市策略最怕什么?怕策略跑着跑着停了,你还不知道。我刚开始做的时候,有一次策略因为交易所API变更,连续报错3个小时,我愣是没发现。那天的亏损,够我买一台顶配MacBook Pro了。

所以监控和告警必须到位。我一般监控这几个指标:

  • 订单成交率:正常应该在60%-80%,低于50%要警惕
  • 持仓时间:做市策略持仓时间通常很短,超过5分钟就要检查
  • 资金利用率:别让资金闲着,也别过度使用
  • 网络延迟:超过100ms就要排查原因
  • 错误率:API调用失败率超过1%就要告警

告警分级策略:

  • P0(严重):策略停止运行、资金异常 → 电话+短信+Telegram
  • P1(警告):成交率下降、延迟升高 → Telegram+邮件
  • P2(通知):日志中有异常但策略正常运行 → 仅记录日志

日志管理

日志这东西,平时觉得没用,出问题的时候就是救命稻草。我建议每个策略实例都输出结构化日志,方便后续分析。

import structlog
import json

logger = structlog.get_logger()

def log_order(order_id, side, price, quantity, status):
    logger.info("order_update",
                order_id=order_id,
                side=side,
                price=price,
                quantity=quantity,
                status=status,
                timestamp=time.time())

日志最好集中管理。我习惯用ELK(Elasticsearch + Logstash + Kibana)或者Loki+Grafana。小规模的话,直接写到文件然后用logrotate轮转也行。

灾备与恢复

做市策略最怕单点故障。我建议至少部署两个实例,一个主节点,一个备用节点。主节点挂了,备用节点自动接管。

我曾经遇到过阿里云某个可用区网络故障,所有实例都连不上交易所。从那以后,我就把策略部署在两个不同的云服务商上,一个用阿里云,一个用腾讯云。虽然成本高了点,但心里踏实。

我的建议:每周做一次灾备演练。别等到真出事了才手忙脚乱。演练内容包括:主节点宕机切换、数据库恢复、API Key轮换等。

安全最佳实践

安全这块,怎么说呢,很多人觉得麻烦就跳过了。但做市策略涉及真金白银,安全必须重视。

  • API Key管理:使用密钥管理服务(如AWS Secrets Manager),别硬编码在代码里
  • 网络隔离:策略服务不要暴露公网IP,通过反向代理访问
  • 权限最小化:每个服务只给必要的权限
  • 审计日志:记录所有敏感操作,方便事后追溯
  • 定期轮换:API Key和密码每90天轮换一次

血的教训:我曾经把API Key写在配置文件里,然后不小心把配置文件提交到了GitHub公开仓库。虽然5分钟内就发现了并删除了,但已经有人fork了我的仓库。那之后我换了所有Key,还花了一整天检查有没有被滥用。所以,千万别犯这种低级错误。

运维自动化

手动运维太累了。我习惯用Ansible写一些自动化脚本,比如批量更新策略、重启服务、查看日志等。

# deploy.yml
- name: Deploy market maker strategy
  hosts: mm_servers
  tasks:
    - name: Pull latest Docker image
      docker_image:
        name: registry.example.com/market-maker:latest
        source: pull

    - name: Stop old container
      docker_container:
        name: market-maker
        state: stopped

    - name: Start new container
      docker_container:
        name: market-maker
        image: registry.example.com/market-maker:latest
        restart_policy: always
        env:
          EXCHANGE_API_KEY: "{{ api_key }}"
          EXCHANGE_SECRET: "{{ api_secret }}"

嗯,差不多就这些了。云部署和运维这块,说白了就是「稳」字当头。别追求花里胡哨的技术,稳定运行才是王道。你想想看,策略跑得好好的,突然因为运维问题停了,那得多冤?

我个人习惯,每次部署新版本之前,先在测试环境跑24小时,确认没问题了再上生产。虽然慢了点,但稳啊。


交易系统化学习资料 微信Strategy888888