Quickstart

vectorbt 第一个回测:从本地 CSV 到组合统计

将行情固定为本地 CSV,首次回测便可排除网络与数据刷新变化。先验证日期索引和收盘价,再使用 from_holding 建立基线;后续的 from_signals 要另行审计信号时间、成本和成交假设。此页不报告未经本站运行验证的绩效数值。

最小示例:买入并持有入口:Portfolio.from_holding输出:stats() 绩效指标
YFData 下载
价格 DataFrame
from_holding
stats()
首次回测的最小流程示意(schematic),基于官方 Quickstart 示例,非真实运行结果。
Code

vectorbt 怎么用本地 CSV 跑第一个回测?三步可复现基线

先验证输入格式、索引和 Portfolio 链路,再换成真实策略。示例价格仅说明文件格式,不是行情或收益证据。

  1. 准备本地 CSV 数据快照

    csvdate,close
    2024-01-02,100.0
    2024-01-03,101.5
    2024-01-04,99.8

    上面的价格仅说明字段格式。正式实验需使用有权使用的数据,并记录来源、时间范围、单位和复权口径。

    预期:CSV 的日期列无重复、close 列为数值,文件本身作为实验输入快照保存。

  2. 读取数据并校验索引

    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))

    按时间排序,检查重复日期和缺失值。停牌与非交易日应按明确规则处理,不要随意补成可成交价格。

    预期:打印首尾观测与行数;断言失败时回查源文件和清洗规则。

  3. 建立基线组合并检查输出

    pythonimport vectorbt as vbt
    
    pf = vbt.Portfolio.from_holding(price, init_cash=10000)
    print(pf.stats())
    print(pf.value().tail())

    买入并持有只验证价格序列进入 Portfolio 的基本路径。示例未加入手续费、滑点和成交约束,因此不是可交易绩效。

    预期:得到统计摘要和末端组合价值序列;字段及参数行为以当前安装版本官方 API 为准。

复现记录:保存 CSV 文件哈希、数据源与采集日期、复权口径、Python/vectorbt/pandas/NumPy/Numba 版本、执行命令和图表输出。更换任一项视为新实验;本页没有提供未经实测的固定收益结果。
Concepts

vectorbt 有哪三个概念要先理解?

这三件事决定了你后面看 vectorbt 官方示例时是否「看得懂」,也是它与事件驱动框架写法差异的根源。

Accessor(df.vbt)

指标、信号与组合都以访问器方法挂在 DataFrame/Series 上,所以不需要先实例化一个「引擎对象」再喂数据——数据本身就是入口。理解这一点,后面看到 df.vbt.ma_run(...)、vbt.MA.run(...) 这类写法就不会陌生。

DataFrame 即结果

输入(价格、信号)与输出(订单、持仓、净值)大多是 pandas DataFrame 或 Series,可以继续用切片、聚合、重采样、导出 CSV 等熟悉操作。与普通 pandas 的主要差异是:参数扫描后结果会多出一层参数维度,索引变成多层结构。

stats() 绩效面板

pf.stats() 一次输出区间、总收益、回撤幅度、夏普、Calmar 与交易统计等字段,适合横向比较不同标的与参数组合。口径以官方实现为准,且只有在数据区间、复权与成本假设一致时,比较才有意义。

YFData

vectorbt 取数接口常用参数怎么用?

vectorbt 的 YFData 是官方内置的数据访问示例之一,参数名与取值范围以官方文档的接口签名为准;下表按「作用 / 取值 / 什么时候用 / 注意点」整理常见项。

参数 / 用法作用取值示例适用场景注意点
symbols一个或多个标的代码"AAPL"、"BTC-USD"单标的快速验证;多标的一次下载做横向比较代码遵循数据源(Yahoo Finance)约定,A 股代码不能直接填,需换国内数据源
start / end指定起止日期"2020-01-01"、"2024-12-31"固定区间做可复现的研究与对比与按「最近区间」取数的方式二选一时更可控;两者同时出现的行为以官方实现为准
period取最近的区间长度"1y"、"max"快速看近期表现、临时探索区间随当天滚动,今天的结果过一段时间不可复现;写结论时要记下采集日期
intervalK 线周期"1d"、"1h"、"15m"日线策略回测;日内与多周期研究分钟级历史长度通常受数据源限制,可能只返回近期数据
.get("Close")从下载结果里取指定列"Close" / "Open" / "Volume"把 OHLCV 中的某一列作为组合回测的价格输入列名必须与数据源返回的字段一致,取不到会直接报错而不是静默返回空
下载结果的时间索引返回带日期的索引,可直接与 pandas 时间序列能力衔接DatetimeIndex需要重采样、按月聚合或与其它数据对齐时索引未排序、含重复日期或存在空值时先做清洗,否则后续回测与对齐都会出错
内置数据源的本体网络可达性决定这一步是否成功Yahoo Finance 公开接口海外标的、指数与加密货币的快速取数境内网络可能直连失败或限流;失败即换本地文件或国内数据源,不要反复重试
Pitfalls

vectorbt 首次回测最容易踩哪六个坑?

vectorbt 首次回测这些坑的共同点是「不报错但结论错」,所以要在跑通之后就立刻检查,而不是等做出结论再回头补。

现象原因处理方式提前规避
收益高得离谱信号与成交发生在同一根 bar,构成前视偏差把信号 shift(1),让下一根 bar 才生效后重跑研究开始前就固定「信号 → 成交」的时间对齐口径
取数步骤直接失败数据源在境内网络不可达或触发限流换本地 CSV 或国内数据源(akshare / tushare)首次成功取数后就落盘保存快照,后续只读本地文件
多标的回测结果错位不同标的交易日历与缺失日期不同,索引未对齐统一到同一索引,并明确缺失值填法与是否参与计算下载完成后先检查各标的价格的索引与长度是否一致
换手明显的策略收益虚高未设置手续费与滑点假设显式传入费用与滑点参数后重跑,对比差异回测跑通时就把成本假设补齐,而不是最后再补
统计指标与预期差距大区间、复权口径或成本假设与上一次不同固定数据快照与参数,记录版本后再比较在研究笔记里记录数据源、采集日期与区间
参数扫出来的较优组合一到实盘就失效过拟合:挑中的是历史单点极值看参数稳定性(相邻参数的绩效分布)而非单点最高先固定标的与区间,再按参数优化页的过拟合清单逐条检查
Read the numbers

vectorbt 首次回测结果怎么读?

vectorbt 的 stats() 面板字段较多,初次看很容易只盯「总收益」。下表按「字段 → 含义 → 怎么判断 → 注意点」整理最常被误读的几项;字段名与口径以官方实现输出为准。

字段含义怎么判断注意点
Start / End实际回测区间先确认区间是否覆盖你关心的时段(含起止年份)区间不同,两个策略的收益完全不可比;比较前先对齐区间
Total Return区间总收益率与同期基准(持有不动/指数)一起看,单看数字没有意义未扣除成本假设时普遍偏高;是否含费用取决于你传入的参数
Benchmark Return基准收益率策略跑不过基准时,先怀疑成本与对齐口径,而不是先调参数基准的选择与计算口径以官方实现为准
Max Drawdown区间内回撤幅度它决定你能不能拿得住:回撤越深,中途离场的概率越高必须与收益一起看,高收益往往伴随深回撤
Sharpe Ratio风险调整后的收益水平常被用作横向比较的粗略标尺,但区间太短时不稳定计算涉及无风险利率与年化方式,口径以官方实现为准
Win Rate / Profit Factor盈利交易占比 / 盈利与亏损的比值胜率高不等于赚钱:要结合盈亏比与单笔平均盈亏判断样本量太小时这两个数都不可信,交易次数个位数时不建议下结论
Total Trades区间内交易次数次数过少说明结论依赖个别几笔交易换手高的策略要同时看累计费用,别只看收益率
Total Fees Paid累计费用(按你设定的费率计算)与总收益对比,判断策略是否被成本吃掉费率由使用者传入,默认值未必符合你的券商与品种
口径提醒:以上指标都是历史数据的统计结果,不代表未来收益,也不构成投资建议;同一份数据在不同成本、复权与对齐口径下会得到不同数字,任何结论都请以官方实现与自己的数据快照为准。
Scenes

vectorbt 跑通之后适合做什么?

vectorbt 跑通后三个方向的适用前提不同,选错会白折腾环境:先确认你手上有没有连续可信的价格序列。

换成双均线信号

把买入持有换成均线交叉信号(用 from_signals),这是从「跑通流程」进入「研究策略」的起点。前提是能取到连续的价格序列、且已理解信号与成交的时间对齐;写法与信号口径见指标信号页。

一次扫多组参数

用 run_combs 网格搜索一次回测多组参数,把「调参」从手工循环变成一次广播运算。前提是标的与区间已固定、信号逻辑已参数化;扫完要看参数稳定性而不是单点最高,详见参数优化页。

换成国内数据源

用 akshare / tushare 取 A 股数据后转成 DataFrame 喂进来,适合数据源不可达或需要 A 股标的的场景。前提是本地已装对应数据包、部分接口需要 Token;把数据落盘成快照后,结果才可复现(见数据接入页)。

FAQ

vectorbt 常见问题

from_holding 和 from_signals 有什么区别?

from_holding 按「一直持有」回测,用来得到最朴素的基线;from_signals 按买卖信号回测,信号触发才交易。双均线这类策略要用 from_signals;两种入口的参数与语义以官方文档为准,详见 Portfolio 页。

取数那一步失败怎么办?

内置示例数据源依赖 Yahoo Finance,境内可能无法直连或限流。改用本地 CSV 或国内数据源(akshare / tushare)拿数据后转成 DataFrame 再喂给回测流程,具体对齐方式见数据接入页;不要靠反复重试解决网络问题;数据源的可达性与限制以官方文档为准

stats() 里的指标可信吗?

它是基于历史数据的统计结果,字段口径以官方实现为准,可作研究参考,但不代表未来收益、也不构成投资建议。同一份数据换成本假设、复权口径或区间都会得到不同数字,所以比较前要先统一口径。

为什么这类回测跑得这么快?

核心是向量化:用数组运算一次算完所有时间点,再叠加 JIT 编译减少 Python 层循环开销,避免逐事件循环调用对象。代价是策略逻辑需要写成「整体数组运算」的形式,路径依赖强的逻辑会难写,性能原理见参数优化页;性能特征以官方文档与实现为准

报错或跑不出结果,先查什么?

按顺序查四件事:①数据长度与索引是否正常(有无排序、重复、空值);②价格列是否为数值类型而不是字符串或对象;③命令是否运行在装了依赖的那个环境里;④信号与价格的时间对齐是否正确。多数「跑不通」都是这四点之一;具体报错含义以官方文档与实现为准

必须联网吗?能用 A 股数据吗?

回测本身不需要联网,联网只发生在取数环节——把数据落成本地文件后可以完全离线复现。A 股数据用内置示例数据源取不到,需要走 akshare / tushare 等国内接口,再转成带日期索引的 DataFrame;数据源能力以官方文档为准

这条路和本机量化技能路线是什么关系?

两条独立路线:本项目是自己写代码、自己取数的回测框架路线;本机已核验的 quant-analyst(回测与风险指标建模)、akshare-finance(A 股等行情数据)等技能方向,走的是免部署、一句话发起研究任务的路线。两者无已证实集成,不能互相替代,按「要不要写代码、要不要可控回测工程」来选,详见对比页;易用性结论以官方技能文档为准

跑通了,进 Portfolio 三入口

下一步理解 from_holding / from_signals / from_orders 三种组合入口怎么选。