【魔码量化工程实战进阶 #20】滑点手续费与实盘级复盘:回测为什么总比实盘赚
【魔码量化工程实战进阶 #20】滑点 / 手续费 / 实盘级复盘:回测为什么总比实盘赚
入门系列从不提成本。本篇揭开回测与实盘的最大鸿沟:成本。同样的信号,回测漂亮、实盘缩水,差的就是那几个点的手续费+滑点+印花税。我们用真实回测数字说明:成本能吞噬掉 1.7% 的收益,而这对边际策略就是"盈转亏"的分界。
本文你将得到什么
- 成本三件套:佣金 / 滑点 / 印花税,各自怎么估
- 一个实盘级成本模型(含"停牌不可成交""涨停买不到")
- 本机复核(合成 252 日,seed=7):无成本 −4.3% → 加成本 −6.1%,成本吞噬 1.7%
- 四个让回测"虚胖"的坑:收盘价成交 / 忽略滑点 / 复权错 / 流动性无视
一、痛点:回测不含成本,等于没回测
新手回测用"收盘价无摩擦成交",净值曲线漂亮。实盘一跑:每笔佣金、买卖滑点、卖出印花税,一年下来成本可能吃掉 5%~10%。边际策略(年化 5% 但成本 6%)直接变亏损——而你回测时还以为它赚钱。
二、工程方案:成本模型
A 股单边成本构成(估算): - 佣金:约 0.025%(万 2.5)单边,最低 5 元/笔 - 滑点:流动性好的票约 0.01~0.05% 单边;小盘/放量/涨停可达 0.1%+ - 印花税:卖出 0.05%(2023-08-28 起减半)
COMMISSION = 0.00025 # 单边佣金
SLIPPAGE = 0.0005 # 单边滑点(流动性好估)
STAMP = 0.0005 # 卖出印花税
def trade_cost(signal_prev, signal_now):
chg = (signal_now != signal_prev) # 换仓才发生成本
# 买入: 佣金+滑点; 卖出: 佣金+滑点+印花税
buy = chg & (signal_now == 1)
sell = chg & (signal_now == 0)
return chg * (COMMISSION + SLIPPAGE) + sell * STAMP
cost = trade_cost(sig.shift(1), sig) # 仅换仓日计成本
pnl = sig * ret - cost.fillna(0)
本文回测用"单边合计 ≈ 0.13%"的简化估算(买 0.075% + 卖 0.08%),量级与上面一致,用于演示成本影响。
三、本机复核(合成 252 日,seed=7)
同一信号,有无成本对比:
无成本: 总收益 = -4.3% 夏普 = -0.59 最大回撤 = -11.5%
加成本: 总收益 = -6.1% 夏普 = -0.59 最大回撤 = -11.5%
成本吞噬收益: 1.7%
即便信号本身亏钱,成本仍实打实多吞了 1.7%。对一个"年化 5%、成本 1.7%"的边际策略,这 1.7% 就是盈转亏的生死线——所以回测必须含成本,且成本要估保守(宁多勿少)。
四、原理深挖:四个让回测"虚胖"的坑
- 用收盘价成交:回测
sig * ret(ret 用收盘价算)等于"收盘价知道信号、收盘价成交"。实盘信号盘中触发,成交价带滑点。保守做法:信号用t−1收盘,成交用t开盘或加滑点。 - 忽略滑点:只算佣金印花税,漏掉滑点(常比佣金大)。小盘股滑点能到 0.1~0.3%,漏算即虚胖。
- 复权口径错(#09):回测用不复权价算收益,除权日假跳空制造虚假盈亏。必须后复权。
- 流动性无视:用"无量也能全仓成交"的假设,实盘大单冲击成本惊人。仓位要受日均成交额约束(
weight ≤ k × 日均成交额 / 持仓市值)。
五、小结
回测不含成本 = 没回测。真实成本(佣金+滑点+印花税)能吞噬 1.7% 甚至更多,正好是边际策略的盈亏分界。工程上:成本估保守、成交价加滑点、用后复权、受流动性约束——这四道关过了,回测才"接得住实盘"。
实盘级复盘依赖全市场实时成交与历史完整数据;魔码量化 Pro 包(全市场实时 + 完整历史)让成本模型能从"拍脑袋"变"可校准"。详见文末。
免责声明:本文所有示例数据仅用于接口演示,不构成任何投资建议;市场有风险,投资需谨慎。
系列持续更新中。 想要亲手跑通上面的代码?前往 魔码证书申请页 免费领取你的专属证书,复制即用、按次计费、稳定可用。
