深圳融克迪特科技有限公司 Logo,金融科技,量化交易,软件开发

深圳融克迪特科技有限公司

RONG CREDIT TECHNOLOGY CO., LTD.

基础入门

【vectorbt 系列 第7讲】查看收益回撤和交易次数

本讲围绕第 6 讲得到的 portfolio 对象,重点读取总收益、最大回撤和交易次数三项最基础结果,并用尽量朴素的话解释它们的含义。目标是让入门者从“回测能跑”进一步走到“回测结果能读”。

2026-04-23 智铨研究 阅读时长 6 分钟

目录

  1. 本节目标
  2. 为什么先看这三项,而不是一次读完整份统计报告
  3. 沿用第 6 讲的 portfolio 对象
  4. 四步查看最基础的回测结果
  5. 先看净值序列有没有明显变化
  6. 看基础统计概览
  7. 单独取总收益和最大回撤
  8. 单独看交易记录数量
  9. 确认你读到的不是空壳结果
  10. 净值序列存在
  11. 总收益可取出
  12. 最大回撤可取出
  13. 交易记录可读
  14. 为什么这些结果看着“不像我想象中那样”
  15. 总收益是负的
  16. 最大回撤让我有点不舒服
  17. 交易次数几乎没有
  18. 交易次数特别多
  19. 哪些情况仍然算本讲完成
  20. 写一个最小结果摘要函数
  21. 第 7 讲开始建立“结果感”
  22. 本讲对下一讲窗口比较的铺垫
  23. 完成标准
  24. 系列衔接
  25. 风险揭示与免责声明

【vectorbt 系列 第7讲】查看收益回撤和交易次数

1. 本节目标

第 7 讲不再新增信号规则,而是回头看第 6 讲已经跑出来的回测对象,重点回答三个最基础的问题:赚了没有、回撤大不大、交易多不多。也就是本讲标题里的收益、回撤和交易次数。

学完这一讲后,你可以直接完成下面几件事:

  1. 从回测对象里取出最常用的几类结果。
  2. 用尽量朴素的话解释这些结果是什么意思。
  3. 初步判断一轮入门回测到底是在“有结果”还是“值得继续调”。

这是从“回测能跑”走向“回测能读”的关键一步。

2. 为什么先看这三项,而不是一次读完整份统计报告

vectorbt 的 stats() 输出会给出很多内容,但对新手来说,一开始最容易抓住、也最值得先读懂的,其实就三类:

  1. 收益:这轮回测总体是涨还是跌。
  2. 回撤:过程中有没有出现比较难受的下跌。
  3. 交易次数:这套规则是不是太频繁,或者几乎不交易。

先把这三项看明白,有一个很现实的好处:你后面不管是换窗口、换信号,还是比较不同参数,都能用它们作为最基础的观察坐标。否则一下子面对十几项统计,新手很容易看花眼,却抓不住重点。

3. 沿用第 6 讲的 portfolio 对象

print(type(portfolio))

如果这一行都还不稳,说明你应该先回到第 6 讲,把最小回测入口重新走通。第 7 讲默认你手里已经有一个可用的 portfolio

4. 四步查看最基础的回测结果

这一讲不再新增规则,而是把注意力放回结果阅读。下面四步分别看净值、统计、核心指标和交易记录。

5. 先看净值序列有没有明显变化

value_series = portfolio.value()
print(value_series.head())
print(value_series.tail())

这一步虽然很朴素,但它能帮你确认回测结果不是一条完全静止的线。如果净值序列从头到尾几乎不动,你至少要追问:是不是根本没交易,或者信号没有真正触发。

6. 看基础统计概览

stats = portfolio.stats()
print(stats)

不用一上来把所有字段都背下来,你当前只要重点盯住与收益、回撤、交易次数相关的那些项即可。

7. 单独取总收益和最大回撤

print('total_return =', portfolio.total_return())
print('max_drawdown =', portfolio.max_drawdown())

这两项非常适合作为第 7 讲的入门坐标。一个告诉你终点结果,一个告诉你过程中最深的回落。

8. 单独看交易记录数量

trades = portfolio.trades.records_readable
print(trades.head())
print('trade_count =', len(trades))

交易次数不是越多越好,也不是越少越好,但它能帮助你判断这套信号到底有没有真正形成交易行为。

9. 确认你读到的不是空壳结果

验证的目标不是证明结果好看,而是确认你读到的确实是一组有内容、能解释的回测结果。

10. 净值序列存在

assert len(value_series) > 0

11. 总收益可取出

total_return = portfolio.total_return()
print(total_return)

12. 最大回撤可取出

max_dd = portfolio.max_drawdown()
print(max_dd)

13. 交易记录可读

print(trades.head())

只要这几项都能顺利输出,第 7 讲就已经完成了最关键的阅读动作。

14. 为什么这些结果看着“不像我想象中那样”

第一次读回测结果时,最容易出现的落差,就是数字和自己想象中的“好策略”并不一致。先把结果读明白,比急着下结论更重要。

15. 总收益是负的

这不等于第 7 讲失败。你现在的目标不是证明策略优秀,而是学会读取结果。负收益本身也是结果,而且往往更能逼你去看信号和参数问题。

16. 最大回撤让我有点不舒服

这很正常。第 7 讲正是要让你开始意识到:终点收益不是唯一指标,过程中承受了多大回落同样重要。

17. 交易次数几乎没有

这通常提示信号很稀疏,或者样本太短。不是 bug,但它会影响你怎么理解这轮回测。

18. 交易次数特别多

这也不是自动等于好结果。它可能意味着规则过于敏感,后面比较不同窗口时就值得重点观察。

19. 哪些情况仍然算本讲完成

  1. 即便当前结果并不漂亮,只要你能读出这三项,本讲就成立。
  2. 你可以先只看 total_return()max_drawdown() 和交易条数,不必全面解析整个统计表。
  3. 你不必马上引入成本模型,第 7 讲先练“读结果”而不是“优化结果”。
  4. 当前交易记录条数不多,不意味着回测无效,只要你能解释为什么。

20. 写一个最小结果摘要函数

def summarize_portfolio(portfolio):
    trades = portfolio.trades.records_readable
    return {
        'total_return': portfolio.total_return(),
        'max_drawdown': portfolio.max_drawdown(),
        'trade_count': len(trades),
    }

summary = summarize_portfolio(portfolio)
print(summary)

这个小函数非常适合后面做窗口比较,因为它把最常用的三项结果压缩成了一个极容易对比的摘要。

21. 第 7 讲开始建立“结果感”

前 1 到第 6 讲主要在搭输入和执行链路,第 7 讲则开始训练你对结果的第一层感觉。所谓“结果感”,不是让你一下子变成绩效分析专家,而是让你看到一组数字时,脑子里能立刻浮现几个基本判断:这轮是赚是亏、回落大不大、交易密度高不高。

这层感觉一旦建立起来,后面你比较不同窗口、不同规则时,就不会只看“最后净值谁更高”,而会自然多看几眼回撤和交易频率。这对入门者来说,是很重要的进步。

22. 本讲对下一讲窗口比较的铺垫

第 8 讲要比较 5 日和 10 日窗口,本质上就是拿两轮回测的结果放在一起看。若第 7 讲没有先建立收益、回撤和交易次数这三个基础观察点,到下一讲你就很容易只看一个结果,忽视另外两个。所以第 7 讲其实是在帮下一讲准备一把统一尺子。

23. 完成标准

如果你现在已经能从 portfolio 里稳定取出收益、最大回撤和交易次数,并用自己的话说明它们分别在表达什么,那第 7 讲就算完成。

24. 系列衔接

本讲是《vectorbt回测入门短课》的第 7/8 讲,当前主题是《查看收益回撤和交易次数》。

上一讲:第 6 讲《跑第一轮向量化回测》。

下一讲:第 8 讲《比较5日和10日窗口》。

25. 风险揭示与免责声明

风险揭示与免责声明

本页面内容仅用于量化研究与技术交流,旨在展示研究方法与流程,不构成对任何金融产品、证券或衍生品的要约、招揽、推荐或保证。

本文所涉历史数据、回测结果与示例参数不代表未来表现,也不应作为投资决策依据。

市场存在波动、流动性与执行偏差等不确定性,任何策略均可能出现收益波动或阶段性失效。

读者应结合自身风险承受能力进行独立判断,并在必要时咨询持牌专业机构意见。