用 12 只股票复制一只基金,再多赚 3.3%
一个"基金复制+增强"的实战复盘 · 3 年真实数据回测 · 年化超额 +3.29pt · 信息比率 0.42
用 20 万本金,把一只基金的 30-40 只持仓浓缩成 12 只,既要像它,又要比它多赚一点。我们用 3 年真实数据回测了这件事,最后落地成一个每天 17 点自动跑的模拟盘。这篇把全部思路、参数、坑和真实数字摊开来讲。
一、为什么做这件事
朋友推荐了一只基金(下称"母基金"),过去三年年化 14.48%,最大回撤 -32%。收益不惊艳,但持仓分散、风格稳健,适合长线持有。
但直接买基金有三个不爽:
- 看不到实时持仓 —— 季报一个月才披露一次,且只有 Top10
- 费率叠加 —— 管理费 + 申购赎回费 + 销售服务费,年化吃走 1-2pt
- 没法做仓位调整 —— 全部钱被锁在基金里,灵活性差
于是就有一个朴素的想法:
能不能用股票账户直接复刻这只基金的持仓?再顺便做点小增强?
如果能做到,省下的费率就是收益,外加 Alpha 增强就是"白送"的。下面就是把这件事完整做出来的全过程。
二、整体设计:从 30-40 只浓缩到 12 只
母基金典型持仓是 30-40 只股票,行业分散。直接复制全部持仓有两个问题:
- 资金量小(20 万),每只 5000 块,买不满一手(A 股 100 股起)
- 长尾持仓对收益贡献有限,很多票就是来"凑数"的
所以策略思路是:
从母基金 30-40 只持仓中精选 Top12,做稀疏复制 + 有限度增强。
核心优化目标
max λ·αᵀw − (w − w_F)ᵀΣ(w − w_F)
三个变量:
w:我们要的组合权重(12 只票)w_F:母基金的原始权重(30-40 只票)α:因子得分(动量 + 相对强度 + 波动率)
第一项:组合 α 加权得分(越高越好)
第二项:组合相对母基金的跟踪误差平方 TE²(越小越好)
λ:权衡参数,控制增强的强度
约束条件(实战硬约束)
| 约束 | 取值 | 理由 |
|---|---|---|
| 股票总仓位 | 95% | 保留 5% 现金应对赎回和波动 |
| 单票权重 | 3% ~ 15% | 防止单票暴雷/过度集中 |
| 行业偏离 | ≤ 母基金行业权重 +5% | 行业不跑偏,风格不漂移 |
| 持股数 | ≤ 12 | 资金量决定的稀疏度上限 |
三、λ:一个值得花整段讲的参数
λ 是整个策略里唯一需要在"像母基金"和"比母基金好"之间做权衡的旋钮。
λ 的实际意义
| λ | 行为 | 类比 |
|---|---|---|
| λ=0 | 完全跟随母基金原始权重 | 一台复印机 |
| λ=0.5 | TE² 项与 α 项约 1:1 平衡 | 一边抄作业一边自己思考 |
| λ=1.0 | α 主导,偏离母基金更多 | 把作业当参考,按自己思路重写 |
λ 怎么参与计算
每个信号日做两件事,λ 都参与:
第一步:选股
综合分数 = 母基金权重 + λ × α × 0.02
α 是横截面 Z-score(动量 0.4 + 相对强度 0.4 − 波动率 0.2)。λ=0.5 时,α 每高 1 个标准差,综合分数加 1pt。作用:只在边缘股票(母基金权重接近)时,α 决定谁入选。
第二步:配权(核心)
梯度 = 2Σ(w − w_F) − λ·alpha_scale·α
w_new = w − 0.08 × 梯度
alpha_scale = 平均日方差,把无量纲 Z-score 换到 TE² 同量纲,这是 λ 能在 0~1 间横向可比的关键。迭代 120 次或权重变化 < 1e-9 时收敛。
λ 网格搜索结果
我们在 2023-07 ~ 2026-09 的真实数据上把 λ 从 0.3 跑到 0.8:
| λ | 年化超额 | 信息比率 | 年化换手 |
|---|---|---|---|
| 0.3 | -3.82% | -0.24 | 28× |
| 0.4 | +2.11% | 0.31 | 31× |
| 0.5 | +2.60% | 0.36 | 32× |
| 0.6 | -0.06% | 0.13 | 32× |
| 0.7 | -0.75% | 0.07 | 34× |
| 0.8 | -2.63% | -0.08 | 35× |
λ=0.5 是真实最优。λ 太小,α 拉力不足;λ 太大,TE 上升、换手和摩擦成本把 α 吃光。
顺便验证股票数 N
| N | 年化超额 | 信息比率 |
|---|---|---|
| 10 | +0.96% | 0.20 |
| 11 | -0.44% | 0.10 |
| 12 | +2.60% | 0.36 |
| 13 | -4.06% | -0.26 |
| 14 | -4.70% | -0.35 |
| 15 | -3.83% | -0.27 |
N=12 是陡峭的局部最优。N 太多稀释 alpha,N 太少偏离母基金太多。
四、最容易踩的两个"假象坑"
坑 1:前视偏差(look-ahead bias)
我们最早的一版回测,跑出来的年化超额是 +5.95%,喜人。后来逐日对账发现问题:
# 错误写法(隐含前视)
整数股数 = 目标金额 // (当日收盘价 × 100) × 100
当日开盘成交的单子,股数却用当日收盘价估算——等于开盘前就知道今天会涨还是跌,这是隐性的信息泄漏。
修复后用当日开盘价直接估算:
# 正确写法
整数股数 = 目标金额 // (当日开盘价 × 100) × 100
修复后所有配置超额平均下降约 6.8pt。换言之,+5.95% 里有 6.8pt 是假超额,真实超额只有 3% 左右。
任何回测,先问一句:你这个数据,在那个时间点真的拿得到吗?
坑 2:"自然现金缓冲是好事"的幻觉
A 股 100 股一手,目标 95% 仓位实际只能买到 70-80%。我们一度以为这是"免费的现金缓冲",回撤更浅、波动更低。
修复前视偏差后再看:那 6.8pt 虚假超额恰恰主要来自这个现金缓冲——因为回测在涨的日子,"隐性少买"显得克制;跌的日子,"隐性少买"显得聪明。两者共同制造了"超额稳定"的假象。
修复后我们引入 fill_to_target=True(贪心填满到目标仓位),超额反而从 +2.60% 升到 +3.29%。
看上去稳健的"缓冲",可能只是回测 bug 的副产品。
五、最终落地的配置
# 模拟盘固化的最终参数
n_stocks = 12
lambda = 0.5
stock_exposure = 1.0 # 2026-09-21 起由 0.95 上调;下表绩效为 95% 口径
min_weight = 0.03
max_weight = 0.15
industry_band = 0.05
weight_drift_threshold = 0.04
relative_weight_band = 0.02
alpha_affects_selection = True
selection_replacement_buffer = 0.0
fill_to_target = True
3 年真实回测绩效
| 指标 | 组合 | 母基金 | 差额 |
|---|---|---|---|
| 年化收益 | 17.77% | 14.48% | +3.29pt |
| 最大回撤 | -31.54% | — | — |
| 年化波动 | 27.13% | — | — |
| 跟踪误差 | 9.97% | — | — |
| 信息比率 | 0.42 | — | — |
| 与母基金相关性 | 0.94 | — | — |
| 月度胜率 | 53.8% | — | — |
| 年化换手 | 30.6× | — | — |
关键数字解读
- +3.29pt 真实超额:剔除所有前视偏差、含印花税/佣金/滑点、整数股约束
- 0.94 高相关:策略本质是"像基金但更好一点",不是另起炉灶
- 30× 年化换手:每天检查信号,但 4% 漂移阈值+±2% 缓冲带让大部分日子不动
- 0.42 信息比率:超额不算巨大,但稳定
六、上线模拟盘
回测过了不算完,必须真实模拟跑一段时间。我们把策略包装成一个 Django 模块:
- 每晚 17 点 Jenkins 定时任务触发
- 用当日开盘价执行昨日信号,整数股、含滑点和佣金
- 收盘后记净值,生成次日信号
- 漂移不足 4% 不调仓,避免换手
页面包含:
- 回测验证区(月度收益率倒序、累计净值曲线)
- 当前模拟盘(净值、持仓、今日成交、信号)
- 实盘跟踪区(可随时录入实际成交)
- 对比看板(模拟 vs 实盘偏离)
模拟盘跑了几个交易日,净值曲线、交易成本、换手率都和回测对得上。数据和回测完全同源,时间序列严格无前视——这一点比多赚几个点更重要。
七、做完这件事,我学到的
- 回测 80% 的价值在于排错
前视偏差、幸存者偏差、未来函数、整数股、停牌、费率——每一个都能让"漂亮回测"变成"实盘翻车"。 - 参数少一点,调得动
整个策略真正的外部参数只有 N=12 和 λ=0.5。其他都是约束或阈值,不参与拟合。参数越少,越不容易过拟合。 - 复刻+有限增强 > 完全自由
完全自由选股的策略容易飘,复刻类策略有"锚"——母基金就是那个锚,你只需在它基础上 +3pt 就够。 - 先问能不能落地,再问收益高不高
20 万本金、A 股 100 股一手、印花税费率,这些约束不是细节,是策略本身。
八、最后一句话
这套策略我不会说它"能赚钱"。我只会说:它在 3 年真实数据上,剔除所有已知偏差后,比母基金多赚 3.29pt,年化 17.77%。
它现在每天晚上 5 点自动跑,每一笔成交都有台账。如果三个月后模拟盘还能维持这个超额,再谈实盘的事。
—— 写在一个普通的周五晚上