Accessor(df.vbt)
指标、信号与组合都以访问器方法挂在 DataFrame/Series 上,所以不需要先实例化一个「引擎对象」再喂数据——数据本身就是入口。理解这一点,后面看到 df.vbt.ma_run(...)、vbt.MA.run(...) 这类写法就不会陌生。
Quickstart
将行情固定为本地 CSV,首次回测便可排除网络与数据刷新变化。先验证日期索引和收盘价,再使用 from_holding 建立基线;后续的 from_signals 要另行审计信号时间、成本和成交假设。此页不报告未经本站运行验证的绩效数值。
先验证输入格式、索引和 Portfolio 链路,再换成真实策略。示例价格仅说明文件格式,不是行情或收益证据。
csvdate,close
2024-01-02,100.0
2024-01-03,101.5
2024-01-04,99.8
上面的价格仅说明字段格式。正式实验需使用有权使用的数据,并记录来源、时间范围、单位和复权口径。
预期:CSV 的日期列无重复、close 列为数值,文件本身作为实验输入快照保存。
pythonimport pandas as pd
raw = pd.read_csv("prices.csv", parse_dates=["date"])
price = raw.set_index("date")["close"].astype(float).sort_index()
assert price.index.is_unique and price.notna().all()
print(price.head(), price.tail(), len(price))
按时间排序,检查重复日期和缺失值。停牌与非交易日应按明确规则处理,不要随意补成可成交价格。
预期:打印首尾观测与行数;断言失败时回查源文件和清洗规则。
pythonimport vectorbt as vbt
pf = vbt.Portfolio.from_holding(price, init_cash=10000)
print(pf.stats())
print(pf.value().tail())
买入并持有只验证价格序列进入 Portfolio 的基本路径。示例未加入手续费、滑点和成交约束,因此不是可交易绩效。
预期:得到统计摘要和末端组合价值序列;字段及参数行为以当前安装版本官方 API 为准。
这三件事决定了你后面看 vectorbt 官方示例时是否「看得懂」,也是它与事件驱动框架写法差异的根源。
指标、信号与组合都以访问器方法挂在 DataFrame/Series 上,所以不需要先实例化一个「引擎对象」再喂数据——数据本身就是入口。理解这一点,后面看到 df.vbt.ma_run(...)、vbt.MA.run(...) 这类写法就不会陌生。
输入(价格、信号)与输出(订单、持仓、净值)大多是 pandas DataFrame 或 Series,可以继续用切片、聚合、重采样、导出 CSV 等熟悉操作。与普通 pandas 的主要差异是:参数扫描后结果会多出一层参数维度,索引变成多层结构。
pf.stats() 一次输出区间、总收益、回撤幅度、夏普、Calmar 与交易统计等字段,适合横向比较不同标的与参数组合。口径以官方实现为准,且只有在数据区间、复权与成本假设一致时,比较才有意义。
vectorbt 的 YFData 是官方内置的数据访问示例之一,参数名与取值范围以官方文档的接口签名为准;下表按「作用 / 取值 / 什么时候用 / 注意点」整理常见项。
| 参数 / 用法 | 作用 | 取值示例 | 适用场景 | 注意点 |
|---|---|---|---|---|
symbols | 一个或多个标的代码 | "AAPL"、"BTC-USD" | 单标的快速验证;多标的一次下载做横向比较 | 代码遵循数据源(Yahoo Finance)约定,A 股代码不能直接填,需换国内数据源 |
start / end | 指定起止日期 | "2020-01-01"、"2024-12-31" | 固定区间做可复现的研究与对比 | 与按「最近区间」取数的方式二选一时更可控;两者同时出现的行为以官方实现为准 |
period | 取最近的区间长度 | "1y"、"max" | 快速看近期表现、临时探索 | 区间随当天滚动,今天的结果过一段时间不可复现;写结论时要记下采集日期 |
interval | K 线周期 | "1d"、"1h"、"15m" | 日线策略回测;日内与多周期研究 | 分钟级历史长度通常受数据源限制,可能只返回近期数据 |
.get("Close") | 从下载结果里取指定列 | "Close" / "Open" / "Volume" | 把 OHLCV 中的某一列作为组合回测的价格输入 | 列名必须与数据源返回的字段一致,取不到会直接报错而不是静默返回空 |
| 下载结果的时间索引 | 返回带日期的索引,可直接与 pandas 时间序列能力衔接 | DatetimeIndex | 需要重采样、按月聚合或与其它数据对齐时 | 索引未排序、含重复日期或存在空值时先做清洗,否则后续回测与对齐都会出错 |
| 内置数据源的本体 | 网络可达性决定这一步是否成功 | Yahoo Finance 公开接口 | 海外标的、指数与加密货币的快速取数 | 境内网络可能直连失败或限流;失败即换本地文件或国内数据源,不要反复重试 |
vectorbt 首次回测这些坑的共同点是「不报错但结论错」,所以要在跑通之后就立刻检查,而不是等做出结论再回头补。
| 现象 | 原因 | 处理方式 | 提前规避 |
|---|---|---|---|
| 收益高得离谱 | 信号与成交发生在同一根 bar,构成前视偏差 | 把信号 shift(1),让下一根 bar 才生效后重跑 | 研究开始前就固定「信号 → 成交」的时间对齐口径 |
| 取数步骤直接失败 | 数据源在境内网络不可达或触发限流 | 换本地 CSV 或国内数据源(akshare / tushare) | 首次成功取数后就落盘保存快照,后续只读本地文件 |
| 多标的回测结果错位 | 不同标的交易日历与缺失日期不同,索引未对齐 | 统一到同一索引,并明确缺失值填法与是否参与计算 | 下载完成后先检查各标的价格的索引与长度是否一致 |
| 换手明显的策略收益虚高 | 未设置手续费与滑点假设 | 显式传入费用与滑点参数后重跑,对比差异 | 回测跑通时就把成本假设补齐,而不是最后再补 |
| 统计指标与预期差距大 | 区间、复权口径或成本假设与上一次不同 | 固定数据快照与参数,记录版本后再比较 | 在研究笔记里记录数据源、采集日期与区间 |
| 参数扫出来的较优组合一到实盘就失效 | 过拟合:挑中的是历史单点极值 | 看参数稳定性(相邻参数的绩效分布)而非单点最高 | 先固定标的与区间,再按参数优化页的过拟合清单逐条检查 |
vectorbt 的 stats() 面板字段较多,初次看很容易只盯「总收益」。下表按「字段 → 含义 → 怎么判断 → 注意点」整理最常被误读的几项;字段名与口径以官方实现输出为准。
| 字段 | 含义 | 怎么判断 | 注意点 |
|---|---|---|---|
| Start / End | 实际回测区间 | 先确认区间是否覆盖你关心的时段(含起止年份) | 区间不同,两个策略的收益完全不可比;比较前先对齐区间 |
| Total Return | 区间总收益率 | 与同期基准(持有不动/指数)一起看,单看数字没有意义 | 未扣除成本假设时普遍偏高;是否含费用取决于你传入的参数 |
| Benchmark Return | 基准收益率 | 策略跑不过基准时,先怀疑成本与对齐口径,而不是先调参数 | 基准的选择与计算口径以官方实现为准 |
| Max Drawdown | 区间内回撤幅度 | 它决定你能不能拿得住:回撤越深,中途离场的概率越高 | 必须与收益一起看,高收益往往伴随深回撤 |
| Sharpe Ratio | 风险调整后的收益水平 | 常被用作横向比较的粗略标尺,但区间太短时不稳定 | 计算涉及无风险利率与年化方式,口径以官方实现为准 |
| Win Rate / Profit Factor | 盈利交易占比 / 盈利与亏损的比值 | 胜率高不等于赚钱:要结合盈亏比与单笔平均盈亏判断 | 样本量太小时这两个数都不可信,交易次数个位数时不建议下结论 |
| Total Trades | 区间内交易次数 | 次数过少说明结论依赖个别几笔交易 | 换手高的策略要同时看累计费用,别只看收益率 |
| Total Fees Paid | 累计费用(按你设定的费率计算) | 与总收益对比,判断策略是否被成本吃掉 | 费率由使用者传入,默认值未必符合你的券商与品种 |
vectorbt 跑通后三个方向的适用前提不同,选错会白折腾环境:先确认你手上有没有连续可信的价格序列。
把买入持有换成均线交叉信号(用 from_signals),这是从「跑通流程」进入「研究策略」的起点。前提是能取到连续的价格序列、且已理解信号与成交的时间对齐;写法与信号口径见指标信号页。
用 run_combs 网格搜索一次回测多组参数,把「调参」从手工循环变成一次广播运算。前提是标的与区间已固定、信号逻辑已参数化;扫完要看参数稳定性而不是单点最高,详见参数优化页。
用 akshare / tushare 取 A 股数据后转成 DataFrame 喂进来,适合数据源不可达或需要 A 股标的的场景。前提是本地已装对应数据包、部分接口需要 Token;把数据落盘成快照后,结果才可复现(见数据接入页)。
from_holding 按「一直持有」回测,用来得到最朴素的基线;from_signals 按买卖信号回测,信号触发才交易。双均线这类策略要用 from_signals;两种入口的参数与语义以官方文档为准,详见 Portfolio 页。
内置示例数据源依赖 Yahoo Finance,境内可能无法直连或限流。改用本地 CSV 或国内数据源(akshare / tushare)拿数据后转成 DataFrame 再喂给回测流程,具体对齐方式见数据接入页;不要靠反复重试解决网络问题;数据源的可达性与限制以官方文档为准
它是基于历史数据的统计结果,字段口径以官方实现为准,可作研究参考,但不代表未来收益、也不构成投资建议。同一份数据换成本假设、复权口径或区间都会得到不同数字,所以比较前要先统一口径。
核心是向量化:用数组运算一次算完所有时间点,再叠加 JIT 编译减少 Python 层循环开销,避免逐事件循环调用对象。代价是策略逻辑需要写成「整体数组运算」的形式,路径依赖强的逻辑会难写,性能原理见参数优化页;性能特征以官方文档与实现为准
按顺序查四件事:①数据长度与索引是否正常(有无排序、重复、空值);②价格列是否为数值类型而不是字符串或对象;③命令是否运行在装了依赖的那个环境里;④信号与价格的时间对齐是否正确。多数「跑不通」都是这四点之一;具体报错含义以官方文档与实现为准
回测本身不需要联网,联网只发生在取数环节——把数据落成本地文件后可以完全离线复现。A 股数据用内置示例数据源取不到,需要走 akshare / tushare 等国内接口,再转成带日期索引的 DataFrame;数据源能力以官方文档为准
两条独立路线:本项目是自己写代码、自己取数的回测框架路线;本机已核验的 quant-analyst(回测与风险指标建模)、akshare-finance(A 股等行情数据)等技能方向,走的是免部署、一句话发起研究任务的路线。两者无已证实集成,不能互相替代,按「要不要写代码、要不要可控回测工程」来选,详见对比页;易用性结论以官方技能文档为准