← 返回博客列表

【魔码量化工程实战进阶 #18】本地回测框架从零搭:向量化与无未来函数

2026年08月31日 18:05 · 魔码数服 · 魔码量化工程实战进阶

【魔码量化工程实战进阶 #18】本地回测框架从零搭:向量化与无未来函数

入门系列第 14 篇讲了"双均线策略回测"一行 rolling。本篇把它升级成正经的回测框架:向量化引擎怎么写、无未来函数怎么保证、事件驱动与向量化怎么选。我们用一段合成价格跑出真实净值,重点不是"赚多少",而是框架对不对

本文你将得到什么

  1. 向量化回测引擎收益 = 信号 × 日收益,四行核心
  2. 无未来函数的铁律:shift(1) 确认,信号绝不碰当天收盘价
  3. 事件驱动 vs 向量化:取舍与适用场景
  4. 本机复核(合成 252 日,seed=7):双均线无成本 总收益 −4.3%,夏普 −0.59,最大回撤 −11.5%

一、痛点:回测赚钱、实盘亏钱

绝大多数"回测很美"死于一个原因:未来函数——信号偷偷用了未来才知道的信息。比如用"当天收盘价上穿均线"当天就买入,等于用收盘后的结果下收盘前的单。框架的第一使命就是堵死未来函数


二、工程方案:向量化引擎

向量化回测把"逐日循环"变成矩阵运算,快且不易错:

import numpy as np, pandas as pd
s = pd.Series(close)                       # 后复权收盘价(#09)
ma5  = s.rolling(5).mean()
ma20 = s.rolling(20).mean()
sig  = (ma5 > ma20).astype(int).shift(1).fillna(0)   # 次日确认,无未来函数
ret  = np.log(s / s.shift(1)).fillna(0)   # 对数收益(#14)
pnl  = sig * ret                           # 持多时吃收益,空仓时收益=0
equity = np.exp(pnl.cumsum())             # 净值曲线(期初=1)

四行核心:sig(信号)→ ret(收益)→ pnl(组合收益)→ equity(净值)。

无未来函数的关键sigshift(1)——金叉在 T 日确认,但 T+1 才持仓。回测里"信号日"和"持仓日"必须错开一天。


三、事件驱动 vs 向量化

方式 做法 优点 缺点 适合
向量化 整个序列矩阵运算 极快、代码短、不易错 难表达"复杂下单逻辑/状态" 信号→持仓映射简单
事件驱动 逐根 bar 推进,维护持仓/现金状态 能精确模拟撮合、手续费、部分成交 慢、易写错、难调试 高频/复杂撮合/组合约束

新手从向量化起步,验证逻辑;要上实盘再迁移到事件驱动(或成熟回测库)。


四、本机复核(合成 252 日,seed=7)

用一段随机游走价格跑双均线(long-only):

无成本: 总收益 = -4.3%   夏普 = -0.59   最大回撤 = -11.5%

这组数字是负的——这是故意的诚实演示:双均线在随机/震荡样本下本就难以稳定盈利。本文用它演示框架与指标,不是荐股。重点看结构:框架正确(无未来函数)、回撤可量化、夏普为负说明样本期策略无效。真实有效策略需另选信号 + 样本外验证(#17 IC)。


五、原理深挖:四个回测杀手

  1. 未来函数(致命):信号碰了当天 close/high/low 即违规。所有信号必须 shift(1) 或基于 t−1 及之前数据。
  2. 幸存者偏差:回测只含"现在还在"的股票,漏掉退市的(它们当年也该被选中),胜率虚高。截面用"当时全部上市股票"。
  3. 前视对齐:多股票用面板时,必须按交易日对齐(#08),别用行号。
  4. 数据权限:回测要完整历史后复权,免费证常不够——需对应权限(Pro 完整历史)。

六、小结

回测框架 = 向量化引擎(四行核心)+ 无未来函数(shift(1))+ 可量化输出(收益/夏普/回撤)。它不保证赚钱,但保证"你测的是你以为你在测的"。下一篇加成本——你会看到同样的信号,实盘能差出几个点。

回测依赖完整后复权历史;魔码量化 Pro 包(完整历史 + 全市场实时)让框架能从"单只试玩"扩到"全市场样本外"。详见文末。


免责声明:本文所有示例数据仅用于接口演示,不构成任何投资建议;市场有风险,投资需谨慎。

系列持续更新中。 想要亲手跑通上面的代码?前往 魔码证书申请页 免费领取你的专属证书,复制即用、按次计费、稳定可用。

想亲自试一下?免费获取证书
客服微信
客服微信二维码