第十八章:实战案例九:做市策略的实盘模拟与压力测试
做市策略写好了,回测也跑得漂亮。然后呢?
直接上实盘?别急。我见过太多人,回测曲线漂亮得像教科书,一上实盘就崩。为什么?因为回测环境太「干净」了。真实的交易世界,充满了滑点、延迟、流动性枯竭、交易所宕机……
所以,我们需要一个中间步骤——实盘模拟与压力测试。说白了,就是给你的策略「上刑」,看看它在极端情况下会不会死。
18.1 为什么要做实盘模拟?
我个人习惯,在策略上实盘前,至少跑两周的模拟盘。这不是浪费时间,而是为了暴露问题。
回测用的是历史数据,是「已知的未知」。而模拟盘面对的是实时行情,是「未知的未知」。你想想看,回测里你假设订单立刻成交,但实盘里呢?挂单可能半天没人理你。
核心目的有三个:
- 验证策略在真实市场环境下的表现
- 暴露代码中的隐藏bug(比如网络重连、订单状态机异常)
- 测试你的风控逻辑是否真的能拦住风险
我曾经有个策略,回测年化30%,回撤不到5%。结果模拟盘第一天,就因为交易所的撮合引擎升级,导致我的订单状态一直pending,最后仓位失控。嗯,从那以后,我再也不敢轻视模拟盘了。
18.2 搭建模拟交易环境
模拟盘的核心,就是「假装在交易」。你需要一个能接收实时行情、能模拟下单、能计算持仓盈亏的系统。
我建议的架构是这样的:
这个架构图,说白了就是三个核心模块:行情输入、策略计算、模拟撮合。再加上一个监控模块盯着你。
18.3 模拟撮合引擎的实现
模拟撮合是核心中的核心。你不能真的去交易所下单,但又要模拟出「如果我真的下单了,会发生什么」。
我常用的方法是:基于盘口深度模拟。也就是说,根据当前的买卖盘口,判断你的订单能否成交,以及以什么价格成交。
小技巧:模拟撮合时,一定要考虑「部分成交」的情况。很多新手只做「全成或全撤」,但实盘里经常是吃了一半,另一半挂在那里。
来看一段核心代码:
class SimulatedExchange:
def __init__(self, orderbook):
self.orderbook = orderbook # 实时盘口数据
self.positions = {} # 持仓记录
def simulate_market_order(self, side, quantity):
"""
模拟市价单成交
side: 'buy' 或 'sell'
quantity: 数量
返回:实际成交价和成交量
"""
if side == 'buy':
# 从卖一档开始吃
levels = self.orderbook['asks']
else:
levels = self.orderbook['bids']
filled_qty = 0
total_cost = 0.0
for price, size in levels:
if filled_qty >= quantity:
break
trade_qty = min(size, quantity - filled_qty)
filled_qty += trade_qty
total_cost += trade_qty * price
# 模拟滑点:成交价加一个随机偏移
slippage = random.uniform(0.0001, 0.0005)
avg_price = total_cost / filled_qty * (1 + slippage)
return {
'filled_qty': filled_qty,
'avg_price': avg_price,
'slippage': slippage
}
这段代码看起来简单,但我在项目中踩过坑。比如,盘口数据更新不及时,导致模拟成交价和实际偏差很大。后来我加了一个「延迟模拟」——每次撮合前,故意让行情滞后50毫秒。这样更接近真实情况。
18.4 压力测试:给策略「上强度」
模拟盘跑顺了,不代表就安全了。你还需要做压力测试。
什么是压力测试?就是人为制造极端行情,看你的策略会不会崩。
我常用的压力场景:
| 场景 | 描述 | 预期风险 |
|---|---|---|
| 闪电暴跌 | 价格在1秒内下跌5% | 做市单被大量吃掉,库存亏损 |
| 流动性枯竭 | 盘口买卖价差扩大到正常值的10倍 | 无法平仓,持仓风险暴露 |
| 网络延迟 | 模拟网络抖动,订单延迟5秒 | 报价过时,成交在不利价格 |
| 交易所宕机 | 模拟交易所停止响应30秒 | 订单状态丢失,仓位失控 |
注意:压力测试不是为了证明策略有多强,而是为了找到它的「死亡边界」。我曾经测试一个高频做市策略,在闪电暴跌场景下,它的风控模块竟然因为计算延迟,导致止损单没发出去。嗯,这个bug在回测里根本发现不了。
18.5 实盘模拟的监控指标
模拟盘跑起来后,你盯什么?
我个人习惯,重点关注这几个指标:
- 成交率:你的挂单有多少被成交了?太低说明报价不合理。
- 库存周转率:做市商最怕库存积压。如果库存半天不动,说明你的双边报价不平衡。
- 滑点成本:模拟成交价和理想价之间的差距。这个差距就是你的隐性成本。
- 最大回撤:模拟盘期间的最大亏损。如果超过你设定的阈值,说明风控需要调整。
我建议把这些指标做成一个实时仪表盘。用Grafana或者自己写个简单的Web界面都行。关键是要能一眼看出问题。
18.6 从模拟到实盘的「最后一公里」
模拟盘跑了两周,一切正常。是不是就可以直接上实盘了?
别急。我还有一个习惯:先用最小资金跑实盘。比如,本来打算投入100万,先拿1万试试水。跑个几天,确认所有环节都通了,再逐步加资金。
为什么?因为模拟盘再真实,也模拟不了「真金白银」带来的心理压力。你想想看,模拟盘亏了10万,你眼睛都不眨一下。实盘亏了10万,你可能手就开始抖了。手一抖,操作就容易变形。
我的建议流程:
- 回测通过 → 模拟盘跑2周
- 模拟盘稳定 → 最小资金实盘跑1周
- 最小资金实盘稳定 → 逐步加仓到目标资金
- 每一步都设置「熔断机制」:如果亏损超过X%,自动暂停所有交易
这套流程,我用了好几年。虽然看起来保守,但确实帮我躲过了不少坑。做市交易,活得久比赚得快更重要。
好了,这一章的内容就到这里。记住:模拟盘不是走过场,而是你策略的「安全气囊」。别嫌麻烦,该做的测试一个都不能少。
无相订单流研究社 微信Lucian808555