文档1.0 (latest)
页面回测 · 16 / 29

回测

在 QuantCraft IDE 中使用 Test 按钮(运行代码)打开 Run backtest。在这里你可以设置标的、价格数据、可选的基本面数据、模拟窗口、初始资金和成交成本,以及(如果脚本用到)单次运行的输入参数。引擎会调用你的策略生命周期回调。结果显示在测试结果中;OHLCV 说明了 K 线的数据格式。

在对话框正文顶部,你可以使用 Load 或 Save 复用运行预设(.qcs)。其余内容最多分为 三个标签页,方便你在启动回测前逐项检查表单。

Run backtest 对话框的标签页

标签页设置内容
Script仅当脚本声明了 params.NAME 输入时显示。参数值,以及 Optimize(暴力网格或遗传搜索)。参见输入参数和优化。
Symbol & dataPrice feed(已连接券商的数据源或 QuantCraft B2)、Symbol source、Asset class、Bar timeframe(券商数据源)/ Timeframe(B2)、用于 rt.get_bar 的 Additional timeframes (optional)、Min bars (optional)(券商数据源)、Uses fundamentals (select if your strategy requires fundamental data)、Include Fama-French factors (global) 以及 Include calendar data (dividends, splits, earnings dates)(Premium/免费数据例外;默认开启)。
Simulation开始/结束日期(默认:最近一个月)、warmup bars(默认 45)、starting balance(默认 100,000)、佣金与滑点模型。参见账户模型。

时钟/主标的: 对话框中没有主标的控件。使用 Selected symbols 时,K 线时钟使用脚本中的 SYMBOL 常量(若该代码在已加载列表中),否则使用第一个已加载的标的。使用 Screener 时完全没有时钟标的——标的集合在运行过程中会变化,因此请通过每个代码自己的 bar.close[i] 偏移读取其历史。参见策略生命周期。

定时器/on_timer: Run backtest 对话框不会设置定时器间隔。on_timer 适用于提供定时器控件的前向/批量/图表前向运行,而不适用于 IDE 回测。


价格来源(券商数据源与 B2)

在 Symbol & data 标签页中选择价格数据源:

  • 已连接券商的数据源 — 提供日内和日线时间周期(需要已连接的券商账户,且已在应用中配置凭据)。
  • QuantCraft B2 — 免费计划仅提供 OHLCV 的日线(d)、周线(w)和月线(m);Premium 解锁日内和扩展的 B2 时间周期。你必须登录 QuantCraft,才能为 B2 的 OHLCV(以及启用时的基本面数据)发送会话令牌。

该选择会在运行预设(.qcs)中保存为 ohlcvSource("alpaca" 或 "b2")。


K 线时间周期与资产类别(仅券商数据源)

当价格来源为已连接券商的数据源时,你可以设置:

字段用途
Bar timeframe本次运行的 K 线粒度——例如 1 天、1 小时、4 小时、1 周,以及多种分钟级 K 线(1 / 5 / 15 / 30 分钟)。
Asset classUS equity 或 Crypto——决定你搜索哪个标的列表,以及券商如何获取数据。
Min bars (optional)若设置,在应用日期范围之后,引擎只保留最近 N 根 K 线。留空则使用开始和结束日期所隐含的完整范围。

当价格来源为 B2 时,你只需选择 Timeframe:免费计划为 Daily、Weekly 或 Monthly;Premium 增加日内和扩展的 B2 时间周期(B2 代码见 OHLCV 与 K 线数据)。


附加时间周期(可选)

使用 Symbol & data 中的 Additional timeframes,可在主时间周期之外加载额外的 K 线周期。在策略代码中,用 rt.get_bar(Timeframe.X, shift) 读取——参见 OHLCV 与 K 线数据和策略生命周期。

  • 多选策略所需的任何额外时间周期(例如主 K 线为 5 分钟时选择日线)。
  • 主时间周期无需在 Additional timeframes 中列出,也可通过 rt.get_bar 使用。
  • 若该时间周期在本次运行中没有缓冲区、使用 Screener 来源,或数据不可用,则返回 None。
  • 在回测中,get_bar 只能看到截至当前步骤的 K 线,并且始终读取时钟标的的 K 线——要读取其他代码的历史,请使用其 bar.close[i] 偏移。
  • 这些设置可以保存在运行预设(.qcs)的 secondaryTimeframes 中。

标的

标的来源

Symbol & data 标签页中的 Symbol source 决定回测交易哪些代码:

来源作用
Selected symbols交易你选定的固定列表,加上通过 Paste tickers 添加的内容。
Screener随回测推进重新运行筛选,并交易模拟中该时点符合条件的标的。

选择 Screener 后,你需要配置筛选本身:

设置作用
Screener sourceScreener preset 或 Python script。
Sort column / Direction应用数量上限之前,预设匹配结果的排序方式。
Rank direction针对脚本——优先取 rank() 得分的哪一端。
Limit每次再平衡交易多少个标的。0 表示取全部匹配项。
Refresh interval (days)筛选重新运行的频率,按模拟的日历日计。脚本要求 7 天或更长。
Keep tickers with an open position标的不再符合条件后仍保持可交易,以便继续管理未平仓头寸。

筛选器驱动回测的限制:需要明确的开始和结束日期;不支持附加时间周期;Python 脚本筛选需要 7 天或更长的 Refresh interval;Debug Test 不支持 Screener 来源(它会停止并提示你切换到 Selected symbols)。启用基本面数据后,每个被筛选出的标的会自动获得其基本面数据。结果中,Logs 旁边会有一个 Screener Output 标签页,把每次再平衡显示为可折叠的日期,并列出该时间窗口内交易的标的。创建筛选以及时点(point-in-time)和幸存者偏差的细节,请参见 Screener。

Selected symbols

在 Symbol & data 中,为本次运行选择一个或多个代码:

  • 使用已连接券商的数据源时,列表来自券商的资产范围(根据 Asset class 为股票或加密货币)。你可以搜索并多选。
  • 使用 B2 时,列表来自服务器上基本面数据路径所用的同一目录。

规则:

  • 至少需要一个标的。
  • 标的在运行时会规范化为大写。
  • 有效字符:字母、数字、. 和 -(常见于 BRK.B 或 RHM.XETRA 这样的交易所后缀)。

选择顺序中的第一个标的是默认的时钟标的,除非策略设置了与已加载代码匹配的顶层 SYMBOL = "..."。对话框中没有单独的主标的控件。


基本面数据(可选)

当策略在 on_bar / on_tick(回测)或前向运行的 on_timer 中读取 fundamentals 参数,或使用依赖基本面的逻辑时,请在 Symbol & data 中勾选 Uses fundamentals (select if your strategy requires fundamental data)。

当你的版本启用了基本面数据功能时会显示该复选框,但除非你拥有 Premium 或已启用免费数据访问,否则它是禁用状态(并带有 Premium 提示)。启用基本面数据后:

  • 你必须已登录(会发送 QuantCraft 令牌以加载 B2 基本面数据文件)。
  • 从多选框中选择一个或多个基本面数据包(路径形如 fundamentals/AAPL.json.gz)。对话框会在每个选项下方显示规范化后的路径。

重要:OHLCV 标的与基本面数据标的是相互独立的。 你可以通过券商数据源回测 RNMBY,同时加载 RHM.XETRA 的基本面数据——界面会提醒你,在这种情况下,需要在代码中向 fundamentals.current(..., symbol="RHM.XETRA")(或等效调用)传入正确的代码。

选择多个基本面数据包时,引擎会按路径构建映射。用于与 K 线对齐的快照的主基本面数据包默认是被交易的标的(或按字母顺序的第一个数据包);在多标的和 Screener 运行中,请始终向 fundamentals.current / get_data_with_offset 传入 symbol=,因为主数据包可能并不是你当前所处理的代码。


Fama-French 因子(可选)

当策略通过 fama_french.qc 读取全球月度因子收益时,请在 Symbol & data 中勾选 Include Fama-French factors (global)。完整 API 请参见 Fama-French 因子。

启用因子后:

  • 你需要 Premium(或在启用时的免费数据访问),并且必须已登录。
  • 当数据权限允许时,该复选框默认勾选。取消勾选可在该次运行中跳过因子数据。
  • OHLCV 标的、基本面数据包和 Fama-French 因子是相互独立的——按需启用任意组合。
  • 没有 factors= 回调参数——请导入 quantcraft.fama_french,并在回调内部(on_init、on_bar、on_tick 等)读取 fama_french.qc。

日历数据与公司行动(可选)

在 Symbol & data 中,Include calendar data 会向回测添加股息历史、拆股历史、财报日期和 SEC 备案。它默认开启,你的选择会被记住供下次运行使用。

为什么重要

回测的价格 K 线未经调整。没有日历数据时,4 拆 1 的拆股在价格上表现为一夜之间暴跌 75%,你的模拟头寸也会随之暴跌。股息也永远不会入账,从而悄悄低估任何长期持有头寸的总回报。

子选项

两个子选项控制模拟期间如何将这些行动应用到未平仓头寸:

子选项作用
Adjust positions for stock splits在拆股生效日,股数乘以拆股比例,成本基础除以该比例。止损价和目标价也会相应重新缩放。由于 qty × entry_price 不变,权益曲线在拆股前后保持连续。
Credit dividends to cash在除息日,多头头寸将 qty × amount 计入现金,空头头寸则扣除(卖空者需向出借方支付股息)。这会体现在权益和所有收益指标中,但不会计入 realized_pnl。

启用日历数据时,两个子选项默认均为开启。

关于除息日估算的说明: EDGAR 不发布除息日。除非有交易所数据,除息日会根据宣告日估算(精度约 ±7 天),并在测试结果中标记为 est.。估算的股息默认会入账;若要跳过,请在 .qcs 预设中将 dividendDatePolicy 设为 exact_only(或 off)——对话框中没有对应控件。如果策略对确切日期敏感,请在代码中按 d.estimated 过滤。

筛选器范围

日历数据可与 Screener 标的来源配合使用。日历在筛选解析出完整代码列表之后才加载;匹配但没有价格 K 线的标的不会产生日历请求。较宽泛的筛选可能包含服务器上没有日历的标的——运行日志会报告其数量,而不会失败。

在哪里查看

  • 输出面板 — 运行期间每个已应用的公司行动对应一行 [calendar],末尾另有一行汇总。
  • Test Results — Split 和 Dividend 行会穿插显示在已平仓交易表中(此时该表名为 Closed trades & events),显示每股的比例或金额以及对现金的影响。

完整的 BacktestCalendar API 和 calendar 回调参数,请参见日历数据。


模拟 — 日期、资金与成交成本

以下内容均位于 Simulation 标签页:

字段用途
Start date必填(默认:约一个月前)。运行窗口包含的第一个 UTC 日历日(YYYY-MM-DD)。
End date**必填。**包含的最后一个 UTC 日历日。必须不早于开始日期。
Warmup bars (indicators)在开始日期之前额外加载的 K 线(与你的 K 线时间周期相同),使移动平均线等类似指标有历史数据。**回调仍然只在开始日期和结束日期之间运行。**默认为 45;输入 0 可禁用额外预热。
Starting balance**必填。**模拟 PaperAccount 的初始现金(默认 100,000)。
Commission / slippage成交如何按交易成本调整——见下文及账户模型。

Run backtest 对话框不会配置定时器间隔。on_timer 仅在设置了 timerIntervalMs 的前向运行(图表前向测试、批量前向/QuantCloud)中可用。参见策略生命周期。

可选的默认止损/止盈/风险仓位设置若存在,仍可能出现在 .qcs 预设中,但 Run backtest 对话框目前不提供 SL/TP/风险输入。如果你的辅助函数支持,请在代码中或通过预设来配置——参见账户模型和运行预设(.qcs)。

佣金与滑点

设置用途
Commission model按股(默认)、按笔交易或零佣金
Commission cost每股成本或每笔订单固定费用($)——默认每股 $0.001
Minimum trade cost使用按股佣金时每笔订单的下限($)——默认 $0
Slippage model成交量占比(默认)、固定点差或零
Volume limit / Price impact成交量占比滑点的参数(volume_limit 也会减少开仓时的数量)
Spread固定点差滑点所用的每股总点差($)

模拟设置可以保存在运行预设(.qcs)中。


脚本参数(单次运行)

如果策略导入了 from quantcraft.inputs import params(对现有脚本,较旧的路径 quantcraft.inputs_module / ide.inputs_module 仍可被识别)并引用了 params.NAME,对话框会显示一个 Script 标签页,每个被发现的名称占一行:Parameter、Type(int / float / str / bool)和 Value。

开始前请填写每一行——每个已声明的参数都必须有值。它们以字符串形式发送,并在加载你的文件之前由引擎进行转换,因此 params.PERIOD(举例)在模块运行时已经是正确的 Python 类型。

在同一标签页中,你可以开启 Optimize 进行网格搜索或遗传搜索——参见优化。普通的单次回测请保持 Optimize 不勾选。


开始运行时会发生什么

应用会校验表单(日期、标的、资金、启用时的基本面数据以及脚本参数类型)。校验通过后,它会用组装好的配置启动一次回测;进度和日志显示在 Output 面板中,结构化结果在 Test Results 中打开。


快速参考

主题在哪里设置
券商数据源与 B2 价格Symbol & data → 价格数据源(.qcs 中的 ohlcvSource)。
时间周期Bar timeframe(券商数据源)或 Timeframe(B2:免费计划为 d / w / m;Premium 更多)。
附加时间周期Additional timeframes 多选——用于 rt.get_bar(Timeframe.X, shift)。
资产类别US equity / Crypto(仅券商数据源)。
截取最近 N 根 K 线Min bars(仅券商数据源,可选)。
交易什么Symbol source:Selected symbols(多选)或 Screener(基本面驱动的筛选——参见 Screener)。
时钟标的已加载时为脚本的 SYMBOL;否则为第一个标的(对话框中无控件);Screener 来源下没有。
财务报表Uses fundamentals + 基本面数据多选(Screener 来源下自动);需要登录。
全球因子收益Include Fama-French factors (global) — 参见 Fama-French 因子。
股息、拆股、财报日期Include calendar data — 默认开启;参见日历数据。
日历窗口Simulation 中的 Start date / End date(必填)。
开始前的指标历史Simulation 中的 Warmup bars。
初始现金Simulation 中的 Starting balance。
佣金/滑点Simulation 标签页——参见账户模型。
on_timer不在 Run backtest 中——使用 timerIntervalMs 的前向运行(策略生命周期)。
on_tick**回测:**每根 K 线 4 个合成 OHLC tick(没有真实 tick 历史)。**前向运行:**券商的每次价格更新——参见策略生命周期。
代码中的可调值Script 标签页(params.*),每次运行的单一值(或 Optimize)。

提示

  • 如果券商数据源的标的始终无法加载,请打开一次 Trade,或确认你与券商的连接;使用 B2 时,请确认你已登录且标的目录已加载。
  • 预热只会延长加载的历史——不会在你的日期范围之外增加交易日。
  • 不要期望在 IDE 回测中使用 on_timer——该对话框中没有定时器控件。请改用 on_bar / on_tick。定时器适用于配置了 timerIntervalMs 的前向运行。
  • 回测中的 on_tick 使用由每根 K 线合成的 OHLC(每根 K 线调用四次)——并非真实的 tick 数据。请在前向运行中测试实时 tick 逻辑(策略生命周期)。
  • 当 OHLCV 代码与基本面数据代码不同时,请让基本面数据包与你在代码中实际读取的代码保持一致。
  • 请谨慎使用 Min bars——很容易把运行缩短得超出预期。
阅读约 5 分钟建议修改 ↗
回测 — 文档 (1.0 (latest)) | QuantCraft