做市算法核心组件:信号生成模块、定价引擎、订单管理模块、风险管理模块、绩效评估模块

做市算法,说白了就是一套自动化的交易决策系统。它不像散户那样凭感觉买卖,而是靠几个核心模块协同工作。我做了这么多年量化,见过太多人把做市想得太简单——以为就是挂单吃价差。其实不然,一个成熟的做市算法,至少包含五个核心组件。

今天我就把这五个模块拆开来讲。每个模块都有它的设计哲学,也有我踩过的坑。

1. 信号生成模块

信号生成模块是整个系统的眼睛。它负责判断当前市场状态,给出交易方向建议。

我个人习惯把信号分为三类:

  • 趋势信号:基于价格动量、均线系统等
  • 均值回复信号:基于布林带、RSI等震荡指标
  • 微观结构信号:基于订单簿不平衡、成交速度等

这里有个关键点——信号不是越多越好。我在项目中遇到过一位同事,把十几个信号堆在一起,结果系统反而更不稳定。后来我们只保留了三个核心信号,效果反而提升了。

核心原则:信号之间要尽量正交,避免多重共线性。否则你以为是信号共振,其实是噪声叠加。

举个简单的信号生成代码:

def generate_signal(order_book, trades):
    # 订单簿不平衡信号
    bid_volume = sum(order_book['bids'][:5].volume)
    ask_volume = sum(order_book['asks'][:5].volume)
    imbalance = (bid_volume - ask_volume) / (bid_volume + ask_volume)
    
    # 成交速度信号
    recent_trades = trades[-10:]
    trade_speed = len(recent_trades) / 10.0
    
    # 综合信号
    signal = 0.6 * imbalance + 0.4 * (trade_speed - 0.5)
    return signal

2. 定价引擎

定价引擎是做市商的大脑。它决定你应该在什么价格挂单,挂多少量。

定价引擎的核心是公平价格估计。说白了,就是猜当前资产的真实价值是多少。然后在这个基础上加减一个价差,形成买卖报价。

我常用的定价模型有:

  • Avellaneda-Stoikov模型:经典做市模型,考虑库存风险
  • 基于订单簿的定价:利用买卖盘口的加权平均价格
  • 机器学习定价:用LSTM或XGBoost预测短期价格

嗯,这里要注意——定价引擎不能太复杂。我曾经用过一个深度神经网络做定价,结果训练时间太长,等模型训练完,市场结构已经变了。后来我改用轻量级的线性模型,配合实时更新,效果反而更好。

我的经验:定价引擎的更新频率要和市场波动率匹配。波动率大时,每秒更新一次都不嫌多;波动率小时,几秒更新一次就够了。

3. 订单管理模块

订单管理模块是执行层。它负责把定价引擎的决策变成真实的订单,发送到交易所。

这个模块看似简单,其实坑最多。我遇到过的问题包括:

  • 订单重复发送(网络重试导致)
  • 订单状态不同步(交易所返回延迟)
  • 订单簿深度不足(挂单被吃掉后没及时补单)

订单管理模块的核心功能:

  1. 订单生命周期管理:创建→发送→确认→成交/取消
  2. 订单簿维护:维护本地订单簿,与交易所同步
  3. 订单路由:选择最优的交易所或交易通道
  4. 订单重试机制:处理网络异常、交易所拒绝等情况

避坑指南:我曾经因为订单重试机制没做好,导致同一笔订单被发送了三次。结果交易所成交了三笔,库存瞬间超标。从那以后,我强制要求所有订单必须有唯一的ID,并且重试前必须检查订单状态。

4. 风险管理模块

风险管理模块是刹车系统。没有它,做市算法就是一辆没有刹车的跑车。

风险管理的核心指标:

风险指标 说明 我常用的阈值
库存敞口 当前持仓与目标持仓的偏差 不超过日均成交量的1%
最大亏损 单日最大可接受亏损 总资金的0.5%
订单暴露 所有未成交订单的总价值 不超过总资金的20%
流动性风险 持仓资产的买卖价差 价差超过0.1%时减仓

风险管理模块的工作流程:

def risk_check(order, portfolio, market_data):
    # 检查库存敞口
    inventory = portfolio.get_inventory(order.asset)
    if abs(inventory) > MAX_INVENTORY:
        return False, "库存超限"
    
    # 检查订单暴露
    total_exposure = portfolio.get_total_exposure()
    if total_exposure + order.value > MAX_EXPOSURE:
        return False, "订单暴露超限"
    
    # 检查流动性
    spread = market_data.get_spread(order.asset)
    if spread > MAX_SPREAD:
        return False, "流动性不足"
    
    return True, "通过"

5. 绩效评估模块

绩效评估模块是后视镜。它告诉你昨天的策略表现如何,哪里需要改进。

我常用的绩效指标:

  • 盈亏分析:总盈亏、日盈亏、交易盈亏 vs 库存盈亏
  • 做市质量:成交率、价差捕获率、订单簿深度贡献
  • 风险调整收益:夏普比率、卡玛比率、最大回撤
  • 微观结构指标:订单成交时间、订单簿位置、逆向选择率

这里有个容易被忽视的点——盈亏归因分析。你要搞清楚赚的钱是来自做市(赚价差),还是来自方向性持仓(赌方向)。如果是后者,那你的做市策略其实已经变味了。

我的习惯:每天收盘后跑一次绩效报告,重点关注三个指标:成交率、价差捕获率、库存周转率。这三个指标能快速反映做市策略的健康度。

核心逻辑框架图

下面这张图展示了五个模块之间的关系:

做市算法核心组件架构图 市场数据输入 信号生成模块 定价引擎 订单管理模块 交易所 风险管理模块 绩效评估模块 实线:数据流 虚线:控制流/监控流

你看这个架构图,五个模块是串行加并行的关系。信号生成→定价引擎→订单管理是一条主线,风险管理贯穿其中,绩效评估则是在事后做反馈。

最后说一句——这五个模块缺一不可。我见过有人只做信号生成和定价引擎,结果订单管理一团糟,风险控制形同虚设。做市算法是个系统工程,每个模块都要认真对待。


无相订单流研究社 微信Lucian808555