21、做市算法中的机器学习:强化学习做市(DQN、PPO)、监督学习预测订单流、特征工程与标签设计

做市算法走到今天,纯规则驱动的策略已经摸到天花板了。我自己的体会是,市场微观结构里那些非线性、高维的交互关系,靠人手工写if-else根本抓不住。所以这一章,咱们聊聊机器学习怎么嵌入做市算法。

说白了,就是两件事:用强化学习学怎么做决策,以及用监督学习预测订单流。这两条线各有各的坑,我一个个说。

强化学习做市:DQN与PPO

先问个问题:做市商的核心任务是什么?是报单、撤单、调整价差。这本质上是一个序列决策问题。你当前的动作会影响后续的库存、盈亏、甚至对手方的行为。强化学习天然适合干这个。

我个人习惯把做市问题建模成一个马尔可夫决策过程(MDP)

  • 状态(State):当前订单簿快照、持仓量、已实现盈亏、市场波动率等。
  • 动作(Action):报单价格偏移、报单数量、是否撤单等。
  • 奖励(Reward):通常用PnL + 库存惩罚项。库存惩罚很关键,我见过有人只设PnL奖励,结果模型学会了扛着巨大库存赌方向,一崩就崩到底。

DQN:离散动作空间的经典选择

DQN适合动作空间不大的场景。比如你只允许报单价格偏移5档,每档一个动作,总共也就10-20个动作。DQN用深度网络拟合Q值函数,然后贪心地选最大Q值的动作。

但有个坑:做市数据是高度非平稳的。今天训练好的Q网络,明天市场结构一变,可能就失效了。我建议在DQN里加优先经验回放,多采样那些“意外”的样本——比如大单冲击时的状态转移。

经验之谈:DQN做市时,奖励函数里一定要加库存惩罚项。我见过一个团队用纯PnL奖励,模型学会了在低波动时大量囤货,然后等大单来砸盘时一把亏光。库存惩罚系数建议用库存量 / 目标库存上限的平方,这样惩罚是非线性的,库存越大越难受。

PPO:连续动作空间的利器

如果你想让模型自己决定报单价格偏移量(比如偏移0.1个tick),那就得用PPO了。PPO是策略梯度方法,它直接优化策略网络,输出动作的概率分布。

PPO有个好处:训练稳定。它通过裁剪(clip)策略更新的幅度,防止一步更新太大导致崩溃。我在实盘模拟中试过,PPO比DQN更容易收敛,尤其是在动作空间连续时。

但PPO也有代价——计算量更大。你需要同时维护策略网络和价值网络,而且每次更新要用多个时间步的数据。如果你的交易延迟要求很高,PPO可能不太适合在线学习。

小技巧:PPO做市时,我建议把订单簿的完整快照作为状态输入,而不是只输入几个统计量。CNN或Transformer可以帮你提取订单簿的空间结构。我试过用ResNet处理订单簿图像(把价格-数量映射成灰度图),效果比手工特征好不少。

监督学习预测订单流

强化学习解决的是“怎么做”的问题,但“市场接下来会怎样”同样重要。监督学习可以用来预测订单流的不平衡大单出现的概率、甚至短期价格方向

我自己的经验是:预测订单流比预测价格更容易。价格是随机游走的,但订单流有很强的自相关性。你想想看,一个大买盘进来后,往往跟着更多买盘——这是订单流聚集效应。

特征工程:从原始数据到有效信号

特征工程是做市算法里最吃经验的部分。我列几个我常用的特征:

特征类别 具体特征 说明
订单簿结构 买卖价差、深度不平衡比、订单簿斜率 反映市场流动性状况
订单流动态 逐笔成交的买卖方向、订单到达率、撤销率 捕捉微观层面的供需变化
时间序列 过去N笔的成交量加权价格、波动率、自相关 刻画短期趋势和波动
事件驱动 大单出现标志、新闻情绪得分、隔夜跳空 捕捉异常事件的影响

嗯,这里要注意:特征不是越多越好。我见过有人堆了200多个特征,结果模型过拟合得一塌糊涂。我的习惯是先用特征重要性排序(比如随机森林的feature importance),只保留前20-30个最重要的。

标签设计:预测什么?

标签设计直接决定了模型能学到什么。我常用的标签有几种:

  • 订单流不平衡标签:未来1秒内,净买入量 / 总成交量。这个标签比较平滑,适合回归任务。
  • 大单出现标签:未来N笔中是否出现超过阈值的大单。这是个二分类问题,适合做预警。
  • 价格方向标签:未来1秒价格是涨还是跌。这个标签噪声很大,我一般不直接用,而是作为辅助任务。
避坑指南:我曾经犯过一个错误——用未来信息构造标签。比如用未来1秒的成交数据来标记当前时刻的标签。这在回测里看起来效果很好,但实盘一跑就崩。因为未来信息在实时交易中是不可得的。正确的做法是:标签必须基于当前时刻之后的数据,且要保证数据对齐没有泄露。

强化学习与监督学习的结合

我个人觉得,最实用的做法是把监督学习的预测结果作为强化学习的状态输入。比如:

  1. 训练一个LSTM模型,预测未来1秒的订单流不平衡。
  2. 把这个预测值作为一个特征,喂给PPO的策略网络。
  3. PPO根据当前订单簿和预测的订单流,决定报单策略。

这样做的好处是:监督学习负责“看”,强化学习负责“做”。两者各司其职,比单独用任何一个都强。

代码示例:下面是一个简单的PPO做市状态设计(伪代码):
class MarketMakingState:
    def __init__(self, orderbook, inventory, flow_prediction):
        self.bid_depth = orderbook.bid_volumes[:5]   # 前5档买单深度
        self.ask_depth = orderbook.ask_volumes[:5]   # 前5档卖单深度
        self.spread = orderbook.ask_price[0] - orderbook.bid_price[0]
        self.inventory_ratio = inventory / MAX_INVENTORY
        self.predicted_flow = flow_prediction        # 监督学习输出
        # 拼接成向量
        self.state = np.concatenate([
            self.bid_depth, self.ask_depth,
            [self.spread, self.inventory_ratio, self.predicted_flow]
        ])

知识体系总览

下面这张图是我自己梳理的本章知识结构,你可以对照着看:

做市算法中的机器学习 强化学习做市 监督学习预测订单流 DQN PPO 特征工程 标签设计 核心要素 • 状态:订单簿、库存、波动率 • 动作:报单价格、数量、撤单 • 奖励:PnL + 库存惩罚 核心要素 • 特征:订单簿结构、订单流动态 • 标签:订单流不平衡、大单预警 • 模型:LSTM、XGBoost、Transformer 结合方式:监督学习输出 → 强化学习状态输入 预测订单流作为特征,辅助做市决策
我的建议:如果你刚开始做机器学习做市,先从监督学习预测订单流入手。这个任务数据好找、评估指标明确(比如AUC、MAE),容易出成果。等你有了一定的预测能力,再把它嵌入到强化学习框架里。别一上来就搞端到端的强化学习,那个调试起来太痛苦了。

好了,这一章的内容就这些。记住:特征工程决定上限,模型选择决定下限。把订单流预测做好,你的做市策略就已经赢了一半。


无相订单流研究社 微信Lucian808555