01学完这一课,你能做到什么
假设你已经有一列每天的账户净值。学完以后,你应该能:
- 把每日净值转换成收益率,并交给 QuantStats 做统计和绘图;
- 看懂收益、风险、风险调整、分布、胜败和相对基准六组指标;
- 解释 VaR 和 CVaR 的边界,知道它们都不是“最大可能亏损”;
- 读懂净值图、水下图、月度热力图、滚动风险图和收益分布图;
- 用同一套数据、资金、、成本和成交规则比较不同策略;
- 识别只统计已平仓交易、漏掉未平仓持仓的报告缺口。
这节课的重点不是生成一张漂亮的 HTML 页面,而是让报告里的数字能够回算、复核和解释。
02先把回测结果交给报告工具
你可以把和报告工具想成两位分工不同的同事。
Backtrader 负责按时间推进数据,模拟信号、下单、成交和账户变化。QuantStats 负责接收收益序列,计算统计指标并画图。它们有一些功能重叠,但不能互相替代。
一次完整流程是:
- 用回测引擎得到每天的账户净值 NAV;
- 把净值转换成每日收益率;
- 把收益率交给 QuantStats 的统计、绘图和报告模块;
- 同时保存原始净值、基准序列、参数和交易明细,方便以后回算。
净值 NAV 不是“卖出后赚了多少钱”。它应该包括现金,以及当天仍然持有的仓位按当天计算的金额。只把已经卖出的盈亏加起来,会漏掉未平仓持仓。
收益率公式是:
r_t = NAV_t ÷ NAV_(t−1) − 1
例如三天净值是 100、98、101:第二天收益率是 98 ÷ 100 − 1 = −2%;第三天收益率是 101 ÷ 98 − 1 ≈ 3.06%。这两个数不是把净值直接相减得到的。
回测引擎按一根一根的 推进,也不会自动消除。数据准备、指标计算、信号时间和成交假设仍然要单独检查。
- 1回测按时间模拟信号和成交
- 2净值 NAV现金 + 未平仓持仓市值
- 3收益率逐日转换
- 4统计与绘图QuantStats 计算并展示
- 5复核回到 CSV、参数和交易明细
一句话记住回测负责模拟交易,报告工具负责整理净值和统计。
03报告工具会产出什么
QuantStats 常见的功能可以分成三类:
- stats:计算指标,例如收益、波动率、和夏普;
- plots:生成图表,例如净值、水下、月度收益和滚动风险;
- reports:把统计和图表组织成可阅读的报告。
不同安装版本的函数签名、默认参数和支持的指标数量可能不同。真正使用时,要按当前版本的官方说明核对,不能只看函数名字猜口径。
你至少应该把下面这些东西一起保存:
- 原始净值序列;
- 每日收益率;
- 基准序列;
- 策略参数和数据区间;
- 交易明细 CSV;
- 报告生成时使用的软件版本。
中文报告可以继续使用同一套统计结果,再用 Matplotlib 设置中文字体、绘图并写入 HTML。这样做解决的是展示问题,不会自动修复统计口径。
一句话记住图表好看不等于计算正确,先保留能回算的原始数据。
04六组指标,分别回答六个问题
一份报告可以按六组指标来读:
| 指标组 | 它主要回答什么 |
|---|---|
| 收益 | 赚了多少,经历了多久 |
| 风险 | 平时怎么波动,极端时可能怎样 |
| 风险调整 | 承担这些风险,换来了多少收益 |
| 分布 | 收益是否依赖少数大赚日,尾部是否很厚 |
| 胜败 | 收益是怎样一步步形成的 |
| 相对基准 | 相对市场有没有增量,跟市场有多像 |
收益组常见累计收益、复合、最佳单日和最差单日。累计收益来自逐期复合,不是把每天百分比直接相加。
复合收益的通用写法是:
累计净值 = (1 + r_1) × (1 + r_2) × … × (1 + r_n)
例如三天收益由净值 100、98、101 得到:(1 − 2%) × (1 + 3.06%) ≈ 1.01,所以最终净值约为 101,累计收益约为 101 ÷ 100 − 1 = 1%。
年化收益要写清楚持有天数和频率。风险调整指标里:
- 夏普看超出无风险收益的回报,相对于整体收益波动有多少;
- Sortino重点看下行偏差;
- Calmar常用年化收益除以最大回撤的绝对值。
相对基准时,Alpha来自回归模型中的定义,不能简单等同于“策略收益减基准收益”;Beta描述策略对基准变动的敏感度;信息比率使用主动收益相对跟踪误差。不同名称不能因为都带“超额”就混写成同一个指标。
收益
一共赚多少,花了多久。
风险
波动和极端损失怎样。
风险调整
收益是否对得起风险。
分布
收益是否靠少数几天。
胜败
盈利结构怎样形成。
相对基准
有没有市场之外的增量。
一句话记住先问你要回答什么,再挑指标,不要把数字全堆上去。
05VaR 和 CVaR:看损失的边界与尾部
先看一个具体数字。把历史日收益从差到好排序,在 95% 水平下,历史 VaR 可以看作最差 5% 附近的分位点。这个例子得到的 VaR 是 −1.82%。
如果报告用“收益率”表示,写成 VaR95 = −1.82%;如果报告用“正的损失额”表示,则写成 1.82%。两种符号都可能见到,报告必须先写清楚约定。
“95%”不是说每 20 天一定有一天损失超过 1.82%。它只是概率直觉:在 100 天的样本里,大约取最差 5 天附近的位置。实际分位数可能会插值,20 天约一天也不是固定周期。
VaR 只告诉你一个尾部阈值,不告诉你越过阈值以后会有多严重。CVaR,也叫 Expected Shortfall,会计算超过这个阈值的尾部样本平均损失。例子中的 CVaR 是 −2.67%,意思是在所定义的最差尾部样本里,平均收益约为负 2.67%,不是每次跌破 −1.82% 都刚好亏 −2.67%。
VaR 不是最大可能亏损,也不保证未来的损失不会超过它。短样本、厚尾和没有覆盖到的极端事件,都会降低估计的可靠性。
不要把历史分位 VaR 和“均值加减两倍标准差”混成一回事。正态分布下,双侧约 95% 区间和单侧 95% 分位不是同一个边界;也不保证价格有 95% 的时间落在带内。
实际使用库时,还要核对它用的是历史分位法还是参数法。函数名叫 VaR,不代表它一定和你的手算口径相同。
VaR95 = −1.82%
最差 5% 附近的尾部阈值,不是最大损失。
CVaR = −2.67%
越过阈值的尾部样本,平均损失有多大。
一句话记住VaR 是尾部阈值,CVaR 继续追问越过阈值后平均有多痛。
06读图时,不要只看最后一个数字
累计净值图要看完整过程,而不只是最后一点。把策略和从同一起点开始的基准放在一起,观察究竟来自哪个阶段。
水下图显示净值相对历史高点跌了多少。除了最大深度,还要看多久没有回到高点。短暂急跌和小回撤但长期停滞,对执行者是两种完全不同的体验。
月度热力图把每个月的复合收益放在一起,便于发现收益是否集中在某些阶段。图例必须标明正负颜色,不同市场对红绿颜色的习惯可能相反。
滚动夏普和滚动波动是在固定长度的窗口上重复计算,观察稳定性怎样变化。窗口太短,指标会很跳;早期样本还不够一个完整窗口时,应留空或明确标记,不能画出看似精确的数字。
收益分布图要联合看偏度、峰度和极端值。高,可能仍然有少数大亏;平均收益高,也可能只是靠少数大赚日。比如报告比较 2024—2025 的策略时,不能只看最终累计收益,还要看收益来自哪些月份、最大回撤持续多久。
如果你有三种策略,报告应让你能同时看到三条净值、三组回撤和三组收益分布,而不是只把排名第一的曲线放大。
一句话记住看收益曲线,也看它经历了多久、怎样跌、靠哪几天赚钱。
策略评估工作台
切换三组固定教学情景,计入或忽略交易成本,比较年化收益、最大回撤、卡玛、夏普、胜率和盈亏比。
先猜哪套策略更值得继续研究,再运行评估查看完整指标。
07比较策略,必须先统一口径
假设在同一段贵州茅台行情里比较、MACD 和 。某次固定区间的结果显示 RSI 表现优于另外两种方法,这只能说明它在这段行情和这组参数下更适配,不能推出 RSI 长期最好。
公平比较前,至少要统一:
- 数据区间和数据版本;
- 初始资金;
- 仓位规则;
- 手续费、和其他成本;
- 信号到成交的时间规则;
- 基准;
- 计算频率和缺失处理。
日频夏普的常见近似写法是:
夏普 ≈ 日超额收益均值 ÷ 日收益标准差 × √252
例如把同一组日收益、同一个无风险收益处理和同一个标准差口径放进去,再乘 √252。这里的 252 是常用年化约定,不是每年精确的交易日数。若 Backtrader 和 QuantStats 的夏普不同,可能是收益频率、无风险收益、复合方式、样本标准差、年化系数或缺失处理不同。
不要因为两个工具都输出“夏普”就认定结果都正确。要逐项对齐,再用一个很小的手算例子核对。也不要分别给每个策略挑最有利的参数和日期,否则比较从一开始就不公平。
统一条件
同一数据、资金、仓位、成本、成交规则和基准。
各算各的
参数、频率、年化和费用不同,排名没有可靠含义。
一句话记住先统一数据、资金、成本和成交规则,再比较谁更好。
08实盘报告,先说清楚数据缺了什么
实盘数据可以从券商历史成交或交割单导出 CSV,也可以通过 QMT 相关接口读取交易记录。但不同券商、客户端版本、账户和接口的历史覆盖范围不同,不能默认某个接口就是完整账户历史。
成交明细通常可以保存:
- 成交日期和时间;
- 买卖方向;
- 数量、价格和金额;
- 佣金及其他费用;
- 证券代码;
- 成交编号。
分批导出后,要按稳定标识去重,并检查时区、编码、代码前导零和字段单位。成交记录、委托记录和资金流水不是同一种数据,不能混在一起统计。
假设你只有约 90 天的已平仓交易,没有把现在仍持有的股票纳入。这样的结果只能叫“已平仓交易分析”。它可能与全账户真实表现不同,年化结果也会受到影响。完整净值还需要期初资产、每日持仓价格、现金、出入金、分红和公司行为等信息。
如果只画买卖点,可以把成交时间叠加到对应 K 线上,标出买入、卖出、数量和费用。这有助于复盘,但不能替代组合净值。
A 股的 等交易制度会影响“买入后能否当日卖出”。统计范围、成交规则和未平仓部分必须在报告首页写清楚。私人交割单也不能未经授权公开分享。
一句话记住只统计已平仓交易,就不能把结果叫完整账户收益。
09一份可审阅报告应该放什么
你可以用下面的结构做自己的模板。
首页写清楚:策略名称、这是还是实盘、数据截止日、统计期间、基准和主要结论。
每个策略页放:净值图、水下图、月度收益表、滚动风险、关键指标,以及数据缺口、未成交假设和费用口径。
索引页把三种策略统一链接起来,中文和英文页面使用同一套计算结果,避免翻译页面重新算出另一组数字。
报告适合研究归档和沟通,但历史假设回测必须和真实成交分开。报告里的每一个数字,都应该能追溯到净值序列、收益序列、参数、基准或交易明细。
一句话记住首页先交代策略、时间、基准和结论,正文再展开指标和图。
10动手任务:从三天净值开始验收
先做一个最小练习:手工构造三天净值 100、98、101,算出每天收益率,再与工具输出核对。你应该得到第二天 −2%、第三天约 3.06%,最终累计收益约 1%。
然后选一组统一的回测数据,生成三策略对比,保存 CSV 和 HTML。逐项检查:
- 图表颜色是否能区分正负;
- 日期是否连续且正确;
- 基准是否从同一起点开始;
- 净值是否包含未平仓持仓;
- 费用和成交假设是否写进报告;
- 胜率的单位是交易还是日期;
- VaR 是否被误写成最大损失;
- 95% 是否被误写成“两倍标准差保证”;
- 已平仓统计是否被误称为全账户收益。
如果做实盘练习,先核对期初资产、期末资产和净出入金。缺少持仓市价时,只输出交易级报告,并明确统计范围。不要用虚构的截图代替验证。
4 道小题
全部答对,这一课就算真正读懂了。答错了会告诉你为什么。
这一课,浓缩成一张卡
学完可以保存或分享给朋友。保存成图片的功能会在下一版加上。
看净值是否含未平仓持仓,指标口径是否写清,结果能否回到收益、参数和交易明细。
- VaR 不是最大损失
- 比较必须同口径
- 已平仓不等于全账户
记住这 5 句话
- 01Backtrader 模拟交易,QuantStats 处理收益序列、统计和图表,二者不能互相替代。
- 02净值要包含现金和未平仓持仓市值;每日收益由相邻净值计算。
- 03六组指标分别看收益、风险、风险调整、分布、胜败和相对基准。
- 04VaR 是尾部阈值,CVaR 看越过阈值后的平均严重程度,都不是最大损失保证。
- 05比较策略和分析实盘时,必须写清数据范围、成本、成交规则和未平仓缺口。
完成这一课
读完讲义、动手做一次实验、答对小题,这一课就算学完了。
- 读完讲义
- 完成一次策略指标评估
- 通过随堂自测
实验数据AI+金融投资训练营教学样本。固定策略评估情景,用于比较收益、风险、交易质量和交易成本。
固定教学样本只用于解释量化研究方法,不代表任何真实标的未来表现,也不构成投资建议。