第一章:从零搭建简易做市商系统——项目总览与架构设计

做市商系统,说白了就是一台「自动赚钱机器」。它不停地买、不停地卖,靠赚取买卖价差来盈利。听起来简单吧?但真要把这套系统跑起来,里面坑可不少。

我个人习惯,在动手写任何代码之前,先把架构图画清楚。你想想看,如果连房子长什么样都不知道,就开始砌砖,最后大概率要推倒重来。做市商系统也是一样的道理。

1.1 系统整体架构

我们先来看一下这个简易做市商系统的核心模块。一共四个:行情、风控、策略、交易。它们之间的关系,我用一张图来展示。

简易做市商系统架构图 行情模块 数据源接入 深度合成 风控模块 参数校验 限额检查 策略模块 定价引擎 订单管理 交易模块 下单执行 成交回报 行情数据 订单请求 通过校验 成交回报 数据流方向:行情 → 策略 → 风控 → 交易 → 策略(闭环)

这张图我画了好几个版本才定下来。为什么?因为模块之间的数据流向,直接决定了系统的响应速度。我见过不少团队,一开始没想清楚,后面改得痛不欲生。

1.2 各模块职责说明

每个模块负责的事情,必须边界清晰。不然写着写着就乱成一锅粥了。

模块名称 核心职责 输入 输出
行情模块 接入交易所实时数据,合成深度信息 交易所原始数据流 标准化行情快照
策略模块 根据行情计算报价,管理订单状态 行情快照、成交回报 订单请求
风控模块 校验订单合法性,控制风险敞口 订单请求、账户状态 通过/拒绝信号
交易模块 执行下单,接收成交回报 通过校验的订单 成交回报、订单状态
我的经验: 模块之间尽量用消息队列解耦。我早期做的一个版本,直接用函数调用,结果行情一快,整个系统就卡死了。后来改成异步消息,问题迎刃而解。

1.3 技术选型与部署方案

既然是「从零搭建」,技术栈就不能太复杂。我选的是 Python + Redis + WebSocket 的组合。为什么?

  • Python:开发速度快,适合快速迭代。做市商策略的逻辑验证,Python 是最趁手的工具。
  • Redis:作为消息总线和状态存储。行情数据、订单状态都放里面,各模块通过 Redis 通信。
  • WebSocket:连接交易所的行情和交易接口。实时性要求高,WebSocket 比 REST 靠谱得多。

部署到云服务器,我建议用阿里云或者腾讯云的轻量应用服务器。配置不用太高,2核4G 就够了。操作系统选 Ubuntu 20.04,Python 3.8 以上版本。

核心要点: 做市商系统对延迟敏感,但我们的目标是「简易」系统,所以先跑通流程,再优化性能。别一上来就追求微秒级延迟,那是专业做市商干的事。

1.4 项目目录结构

我习惯这样组织代码。你照着这个结构来,后面写代码的时候不会迷路。

market_maker/
├── config/              # 配置文件
│   └── config.yaml
├── market_data/         # 行情模块
│   ├── __init__.py
│   └── data_feed.py
├── risk_control/        # 风控模块
│   ├── __init__.py
│   └── risk_manager.py
├── strategy/            # 策略模块
│   ├── __init__.py
│   └── mm_strategy.py
├── trading/             # 交易模块
│   ├── __init__.py
│   └── order_executor.py
├── utils/               # 工具函数
│   ├── __init__.py
│   └── logger.py
├── main.py              # 主入口
└── requirements.txt     # 依赖列表
注意: 千万别把所有代码都塞到一个文件里。我曾经接手过一个项目,一个文件 3000 行,改个 bug 要翻半天。模块化是底线。

1.5 模拟交易环境搭建

正式上实盘之前,一定要先跑模拟交易。我建议用币安的测试网(testnet)。它提供了和实盘一模一样的接口,但用的是虚拟资金。

注册测试网账号后,你会得到 API Key 和 Secret Key。把这些信息写到 config.yaml 里:

exchange:
  name: binance_testnet
  api_key: "你的API_KEY"
  api_secret: "你的API_SECRET"
  websocket_url: "wss://testnet.binance.vision/ws"
  rest_url: "https://testnet.binance.vision/api"

strategy:
  symbol: "BTCUSDT"
  spread: 0.001  # 价差,0.1%
  order_size: 0.01  # 每单数量
  max_position: 0.1  # 最大持仓

risk:
  max_order_value: 1000  # 单笔最大金额
  max_open_orders: 10    # 最大挂单数

配置文件的格式,我推荐用 YAML。比 JSON 可读性强,比 INI 灵活。嗯,这里要注意:密码和密钥千万别硬编码在代码里,用环境变量或者配置文件读取。

1.6 启动流程与运行逻辑

整个系统的启动顺序是这样的:

  1. 启动 Redis 服务
  2. 启动行情模块,开始接收数据
  3. 启动策略模块,等待行情数据
  4. 启动风控模块,准备校验
  5. 启动交易模块,连接交易所
  6. 主循环开始运行

每个模块都是一个独立的进程,通过 Redis 发布/订阅机制通信。这样做的好处是,任何一个模块挂了,不会影响其他模块。我遇到过行情模块崩溃的情况,但策略和交易还在跑,系统没有完全瘫痪。

主入口 main.py 的伪代码大概长这样:

import multiprocessing
from market_data.data_feed import MarketDataFeed
from strategy.mm_strategy import MarketMakingStrategy
from risk_control.risk_manager import RiskManager
from trading.order_executor import OrderExecutor

def main():
    # 启动各模块
    processes = []
    
    p1 = multiprocessing.Process(target=MarketDataFeed.run)
    p2 = multiprocessing.Process(target=MarketMakingStrategy.run)
    p3 = multiprocessing.Process(target=RiskManager.run)
    p4 = multiprocessing.Process(target=OrderExecutor.run)
    
    for p in [p1, p2, p3, p4]:
        p.start()
        processes.append(p)
    
    for p in processes:
        p.join()

if __name__ == "__main__":
    main()

你看,代码其实不多。但每个模块内部的逻辑,才是真正的重头戏。接下来的章节,我会带你一步步实现每个模块。

一句话总结: 做市商系统 = 行情驱动 + 策略定价 + 风控把关 + 交易执行。把这四个模块串起来,一个简易系统就成型了。

好了,架构层面的东西就聊这么多。下一章我们开始写代码,先从行情模块入手。到时候我会把 WebSocket 连接、数据解析、深度合成这些细节都讲清楚。


无相订单流研究社 微信Lucian808555