实战案例四:多品种做市策略的分散化回测

做市策略做到一定程度,你会发现一个尴尬的问题——单品种回测再漂亮,实盘也容易翻车。为什么?因为一个品种的流动性、波动率、订单流特征,随时可能变脸。我早年吃过这个亏,一个ETH做市策略回测年化40%,结果上实盘第三天就被一波异常波动打穿了库存。

所以,多品种分散化不是锦上添花,是生存刚需。这一章,我们就来聊聊怎么对多品种做市策略做分散化回测。

为什么必须做多品种分散?

说白了,做市商赚的是「流动性溢价」和「价差收益」。但单一品种的风险敞口太大了。你想想看,如果只做BTC,一旦市场出现极端行情,你的库存方向判断失误,可能一夜回到解放前。

多品种分散化,核心逻辑就三点:

  • 降低非系统性风险:不同品种的波动周期、驱动因素不同,可以互相对冲
  • 平滑收益曲线:A品种亏钱时,B品种可能正在赚钱
  • 提高资金利用率:不同品种的保证金可以共享,整体资金效率更高

核心观点:多品种做市不是简单地把资金平分到几个币上,而是基于相关性、波动率、流动性等维度做组合优化。

多品种回测的难点在哪?

单品种回测你只要管好订单簿和库存就行。多品种回测,复杂度直接翻倍。我个人习惯把难点归纳为三个:

  1. 资金分配问题:每个品种分配多少资金?是按市值等权,还是按波动率加权?
  2. 相关性管理:品种之间如果高度相关,分散化效果会大打折扣
  3. 订单簿同步:多个品种的订单簿数据需要时间对齐,否则回测结果失真

嗯,这里要注意——很多新手做多品种回测时,直接把单品种策略复制粘贴到多个品种上,然后简单加总收益。这种做法其实很危险,因为忽略了品种之间的资金竞争关系。

多品种做市策略的框架设计

先画一张图,把整体逻辑理清楚。我习惯用一张流程图来展示多品种做市的核心流程:

多品种做市策略分散化回测框架 第一步:多品种数据采集与对齐 第二步:动态资金分配(波动率加权/等权/风险平价) 第三步:各品种独立做市 + 全局风险监控 第四步:组合收益计算与风险指标汇总 第五步:参数优化与品种筛选迭代 反馈优化

这张图展示了我个人比较推崇的多品种做市回测流程。注意看那个反馈箭头——回测不是一次性的,需要反复迭代。

实战:用Python做多品种回测

直接上代码。这里我以三个品种为例:BTC、ETH、SOL。数据用的是1分钟级别的订单簿快照。

import pandas as pd
import numpy as np
from typing import Dict, List

class MultiAssetMarketMaker:
    """多品种做市回测器"""
    
    def __init__(self, 
                 symbols: List[str],
                 initial_capital: float = 100000,
                 allocation_method: str = 'volatility_weighted'):
        """
        :param symbols: 品种列表
        :param initial_capital: 初始资金
        :param allocation_method: 资金分配方式
        """
        self.symbols = symbols
        self.initial_capital = initial_capital
        self.allocation_method = allocation_method
        self.positions = {s: 0 for s in symbols}
        self.capital = initial_capital
        
    def allocate_capital(self, 
                         volatility: Dict[str, float]) -> Dict[str, float]:
        """动态资金分配"""
        if self.allocation_method == 'equal':
            # 等权分配
            alloc = {s: self.capital / len(self.symbols) 
                     for s in self.symbols}
        elif self.allocation_method == 'volatility_weighted':
            # 波动率加权:波动率越低,分配越多
            total_inv_vol = sum(1/v for v in volatility.values())
            alloc = {s: (1/v) / total_inv_vol * self.capital 
                     for s, v in volatility.items()}
        else:
            raise ValueError(f"未知分配方式: {self.allocation_method}")
        return alloc
    
    def run_backtest(self, 
                     data: Dict[str, pd.DataFrame],
                     spread_multiplier: float = 1.5) -> pd.DataFrame:
        """
        执行多品种回测
        :param data: 每个品种的订单簿数据
        :param spread_multiplier: 价差倍数
        """
        results = []
        
        for timestamp in data[self.symbols[0]].index:
            # 1. 计算各品种当前波动率
            vol = {}
            for s in self.symbols:
                window = data[s].loc[:timestamp].tail(100)
                vol[s] = window['mid_price'].pct_change().std()
            
            # 2. 动态分配资金
            alloc = self.allocate_capital(vol)
            
            # 3. 各品种独立做市
            daily_pnl = 0
            for s in self.symbols:
                row = data[s].loc[timestamp]
                bid = row['bid_price']
                ask = row['ask_price']
                mid = (bid + ask) / 2
                
                # 计算理论做市价差
                spread = (ask - bid) * spread_multiplier
                our_bid = mid - spread / 2
                our_ask = mid + spread / 2
                
                # 模拟成交(简化版)
                trade_volume = alloc[s] / our_ask * 0.1  # 每次交易10%资金
                pnl = trade_volume * (our_ask - our_bid) / 2
                daily_pnl += pnl
            
            results.append({
                'timestamp': timestamp,
                'total_pnl': daily_pnl,
                'total_capital': self.capital + daily_pnl
            })
        
        return pd.DataFrame(results).set_index('timestamp')

个人经验:代码里的波动率加权分配,是我在实际项目中比较常用的方式。波动率低的品种分配更多资金,因为做市收益更稳定。但要注意——如果某个品种波动率突然飙升,资金分配需要快速响应,否则容易出事。

回测结果分析:别只看总收益

多品种回测跑完之后,很多人只看总收益曲线。这其实不够。我建议至少看这几个指标:

指标 说明 我的经验阈值
夏普比率 衡量风险调整后收益 > 1.5 算合格
最大回撤 组合净值从峰值回落的最大幅度 < 15% 可接受
品种相关性 各品种收益率的相关系数矩阵 平均 < 0.3 为佳
资金利用率 实际使用资金 / 总资金 > 70% 较好

我曾经遇到过一个案例,三个品种回测总收益很好,但仔细一看,三个品种的收益率相关性高达0.85。这意味着什么?说白了,它们几乎同涨同跌,分散化效果等于零。后来我换成了BTC、黄金、国债期货,相关性才降到0.2以下。

避坑指南:多品种回测的常见陷阱

陷阱一:幸存者偏差

我曾经只选了当前流动性好的品种做回测,结果忽略了那些已经退市或流动性枯竭的品种。回测曲线漂亮,但实盘时发现很多品种根本做不了。正确做法是:回测时把历史上所有出现过的品种都纳入候选池,哪怕后来退市了。

陷阱二:资金分配过于静态

有些策略在回测开始时一次性分配好资金,之后就不再调整。但市场是动态的,一个品种的波动率可能从10%飙到50%。如果不动态调整,资金会过度暴露在高风险品种上。我建议至少每4小时重新计算一次资金分配。

陷阱三:忽略交易成本

多品种做市的交易成本比单品种高得多。每个品种都要挂单、撤单、吃单,手续费和滑点会吃掉大量利润。我在回测时,会额外加一个「摩擦成本系数」,通常是理论收益的10%-20%。

优化方向:从回测到实盘的最后一公里

回测跑通了,不代表实盘就能赚钱。我个人习惯在回测之后,再做三件事:

  • 压力测试:模拟极端行情,比如2020年3月12日的暴跌,看看组合能不能扛住
  • 品种淘汰机制:设定一个阈值,如果某个品种连续N天亏损,自动剔除出组合
  • 实盘模拟:用模拟账户跑1-2周,观察回测结果和实盘结果的偏差

嗯,说到实盘模拟,我记得有一次回测收益很好,但模拟盘跑了一周就亏了5%。后来发现是回测时忽略了网络延迟和订单簿深度变化。从那以后,我每次回测都会加入「延迟模拟」模块。

多品种做市策略的分散化回测,本质上是在「收益」和「风险」之间找平衡。没有完美的策略,只有不断迭代的优化过程。希望这一章的实战案例,能帮你少走一些弯路。

本章小结:多品种做市回测的核心在于资金动态分配、相关性管理和风险监控。代码实现上,建议采用面向对象的方式,把每个品种的做市逻辑封装成独立模块,方便后续扩展和优化。

无相订单流研究社 微信Lucian808555