问题描述
/
解决方案
在 ptrade 量化交易平台中,同一个策略在回测环境和实盘(交易/研究)环境中获取的交易日期范围不一致,核心原因在于两个环境对“当前时间(默认时间)”的定义基准不同。
核心原因解析
当您调用 ptrade 的日期获取 API(且未显式传入日期参数)时,系统会使用默认的“当前时间”作为计算基准:
-
回测环境:
在回测中,“当前时间”是模拟的、动态推进的。它等于策略当前运行到的回测周期时间点,即context.blotter.current_dt。例如,如果您回测的时间段是 2020年到2021年,当回测引擎运行到 2020年5月1日 时,系统认为的“今天”就是 2020年5月1日。 -
实盘/交易/研究环境:
在实盘或研究环境中,“当前时间”是真实的物理时间。即您运行代码的现实世界当天的日期。
受影响的常用 API
根据 ptrade API 文档,以下接口在不传入特定日期参数时,会表现出上述差异:
get_trading_day(day):- 回测中:以
context.blotter.current_dt为基准计算数天前/后的交易日。 - 实盘中:以调用当天的真实日期为基准。
- 回测中:以
get_all_trades_days(date=None):- 回测中:
date默认取context.blotter.current_dt。 - 实盘中:
date默认取调用当天日期。
- 回测中:
get_trade_days(start_date=None, end_date=None, count=None):- 回测中:
end_date默认取context.blotter.current_dt。 - 实盘中:
end_date默认取调用当天日期。
- 回测中:
示例说明
假设今天是 2023年10月1日,您的回测区间设置为 2022年1月1日 - 2022年12月31日。
如果在 handle_data 中执行以下代码:
trading_days = get_trade_days(count=10)
- 在回测中(假设当前回测到 2022年6月1日):返回的是 2022年6月1日 往前推的 10 个交易日。
- 在实盘中:返回的是 2023年10月1日 往前推的 10 个交易日。
解决方案与建议
这种设计是为了保证策略在回测时不会获取到“未来数据”(即回测时间点之后的数据),从而保证回测的真实性。通常情况下,您**不需要(也不应该)**去修改这种默认行为,因为策略逻辑本身就应该基于“当前所处的时间点”来获取历史数据。
如果您确实需要在回测中获取特定绝对日期的数据,可以通过显式传入日期参数来解决:
# 显式指定 end_date,这样无论在回测还是实盘,获取的范围都是固定的
fixed_trading_days = get_trade_days(end_date='20230930', count=10)
总结:这种不一致是 ptrade 框架为了防止回测引入未来函数而设计的正常机制。理解 context.blotter.current_dt 在回测中的作用,是编写健壮量化策略的关键。