第24章 策略容量陷阱:你的策略到底能吃下多少资金?
做量化的人,谁没做过一个美梦?
写了个策略,回测曲线漂亮得像教科书上的范例。年化30%,最大回撤不到5%,夏普比率3.0。你心里美滋滋,觉得财务自由就在眼前了。
然后你开始实盘。一开始投了10万,跑得挺好。加仓到50万,还行。加到200万的时候,咦?怎么收益开始打折了?等你咬牙加到500万,好家伙,曲线直接变成心电图了。
这就是我今天要聊的——策略容量陷阱。
什么是策略容量?说白了就是能吃下多少钱
策略容量,学术点说,是策略在不显著影响市场、不显著降低收益的前提下,能承载的最大资金量。
但我更喜欢这么理解:你往一个碗里倒水,水满了再倒就溢出来了。那个碗的容量,就是你的策略容量。
我在2018年帮一个朋友诊断他的高频策略时,就遇到过这种事。他那策略在100万资金下回测年化50%,我一看持仓明细——好家伙,全是小盘股,单笔交易量动不动占当日成交量的5%以上。我跟他说,你这策略最多吃300万,再多就是给自己挖坑。他不信,硬是上了800万。结果呢?三个月后,收益还没跑赢余额宝。
核心观点: 策略容量不是算出来的,是测出来的。回测里跑得再漂亮,上了规模就原形毕露。
为什么策略容量会有限?两个罪魁祸首
要理解这个问题,得先搞清楚两个东西:冲击成本和资金曲线拐点。
1. 冲击成本——你每下一单,都在推高价格
你想想看,如果你要买100股茅台,挂个单可能几秒钟就成交了,价格几乎不动。但如果你要买10万股茅台呢?你这一买,价格可能就被你推高了0.5%甚至更多。
这个因为你的交易行为导致的价格不利变动,就是冲击成本。
冲击成本的计算公式其实不复杂:
冲击成本 = (成交均价 - 订单簿中间价) / 订单簿中间价 × 100%
但实际中,我更推荐用这个经验公式:
冲击成本 ≈ 0.5 × 买卖价差 + 0.25 × (交易量 / 日均成交量) × 波动率
嗯,这个公式是我自己调参调出来的,不一定适合所有市场,但方向是对的——交易量越大,冲击成本越高;流动性越差,冲击成本越高。
| 交易量占日均成交量比例 | 冲击成本(流动性好的股票) | 冲击成本(流动性差的股票) |
|---|---|---|
| 1% | 0.05% | 0.15% |
| 5% | 0.20% | 0.60% |
| 10% | 0.50% | 1.50% |
| 20% | 1.20% | 3.50% |
你看,当你的交易量占到日均成交量的10%以上时,冲击成本已经相当可观了。如果你的策略本身年化收益才20%,光冲击成本就吃掉1.5%,那你还剩多少?
2. 资金曲线拐点——找到那个临界值
冲击成本是微观层面的。宏观层面,我们需要找到资金曲线的拐点。
什么叫拐点?就是随着资金量增加,策略的收益曲线从线性增长变成边际递减的那个点。
我习惯用这个方法来找拐点:
- 用不同资金量(比如100万、200万、500万、1000万、2000万)分别做回测
- 记录每个资金量下的年化收益率
- 画出资金量-收益率曲线
- 找到曲线斜率开始明显下降的那个点
举个例子,我去年帮一个做可转债策略的朋友做容量测试,结果是这样的:
| 资金量 | 年化收益率(回测) | 年化收益率(考虑冲击成本) |
|---|---|---|
| 100万 | 25.3% | 24.8% |
| 500万 | 25.1% | 23.5% |
| 1000万 | 24.6% | 20.2% |
| 2000万 | 23.8% | 15.1% |
| 5000万 | 21.2% | 8.3% |
看到没?不考虑冲击成本时,收益率下降很平缓。但一旦把冲击成本算进去,5000万时的收益率直接掉到8.3%。这个策略的合理容量,大概就在1000万左右。
注意: 很多人在回测时根本不考虑冲击成本,结果实盘一跑就傻眼。我建议你在回测框架里,至少加一个简单的冲击成本模型。哪怕模型粗糙一点,也比没有强。
如何估算最大容量?我的三步法
好了,理论说完了,来点干货。我个人估算策略容量,一般分三步走:
第一步:分析持仓标的的流动性
把你策略里可能交易的标的拉出来,看看它们的日均成交量。我一般会看过去60天的平均数据。
然后定一个规则:单笔交易量不超过日均成交量的5%。这是比较保守的设定,如果你策略交易频率低,可以放宽到10%。
# 一个简单的流动性检查函数
def check_liquidity(stock_code, daily_volume, my_trade_size):
max_trade_ratio = 0.05 # 不超过5%
max_allowed = daily_volume * max_trade_ratio
if my_trade_size > max_allowed:
print(f"警告:{stock_code} 交易量 {my_trade_size} 超过限制 {max_allowed}")
return False
return True
第二步:构建冲击成本模型
我常用的模型是线性冲击模型,虽然简单,但够用:
def impact_cost(trade_size, avg_daily_volume, spread, volatility):
"""
计算冲击成本
trade_size: 交易股数
avg_daily_volume: 日均成交量(股数)
spread: 买卖价差(百分比)
volatility: 日波动率(百分比)
"""
# 交易量占比
volume_ratio = trade_size / avg_daily_volume
# 冲击成本 = 固定部分(价差的一半)+ 可变部分(交易量占比 * 波动率)
fixed_cost = spread / 2
variable_cost = volume_ratio * volatility * 2 # 系数2是经验值
total_cost = fixed_cost + variable_cost
return total_cost
这个模型不算精确,但用来做容量估算已经够了。我建议你根据自己交易的市场,调整一下系数。
第三步:做资金量扫描
最后一步,就是写个循环,从100万开始,每次翻倍,一直测到1个亿。记录每个资金量下的净收益(扣除冲击成本后)。
找到那个净收益开始明显下降的点,那就是你的策略容量上限。
小技巧: 如果你策略持仓周期比较长(比如持股一周以上),冲击成本的影响会小一些。但如果是高频策略,冲击成本就是你的头号敌人。我见过一个高频做市策略,资金从500万加到2000万后,冲击成本直接吃掉了全部利润。
一张图看懂策略容量估算流程
下面这张图,是我自己画的一个流程,每次做容量测试都照着走:
flowchart LR
A[步骤1:流动性分析<br/>获取标的日均成交量] --> B[步骤2:冲击成本建模<br/>构建冲击成本函数]
B --> C[步骤3:资金量扫描<br/>100万→1亿逐级测试]
C --> D{收益拐点?}
D -->|是| E[确定容量上限]
D -->|否| F[继续增加资金量测试]
F --> C
关键参数说明
- 流动性阈值:单笔交易量 ≤ 日均成交量的 5%(保守)或 10%(激进)
- 冲击成本模型:线性模型(固定成本 + 可变成本 × 交易量占比)
- 拐点判断:净收益率下降超过 20% 时,认为达到容量上限
- 安全边际:建议在理论容量上限的 60%-80% 实际使用
避坑指南:我曾经踩过的坑
做容量估算这么多年,我踩过的坑不少,挑几个典型的说说:
- 只看回测,不看实盘流动性变化。 我2019年有个策略,回测时流动性很好,结果实盘时市场风格切换,那些小盘股流动性骤降。冲击成本从0.1%飙到0.8%,策略直接废了。后来我学乖了,容量估算一定要用最近3个月的数据,别用一年的平均数据。
- 忽略多标的同时交易的问题。 如果你的策略同时交易10只股票,每只的交易量都不大,但加起来可能就大了。而且如果这些股票相关性高,同时交易时冲击成本会叠加。我建议你做容量测试时,要模拟真实的交易时序,别假设所有交易都能完美错开。
- 把理论容量当实际容量用。 理论容量是上限,实际使用建议打6-8折。我一般会留30%的安全边际。比如测出来容量是1000万,我最多用到700万。为什么?因为市场会变,流动性会变,给自己留点余地。
最后说一句: 策略容量不是一成不变的。市场流动性好了,容量会变大;市场差了,容量会缩小。我建议你每季度重新做一次容量测试,特别是市场环境发生重大变化的时候。
记住一句话:别让你的策略吃太饱,吃撑了会消化不良。