问题描述
各位好,在回测过程中使用到了get_bars函数,
1,查看API发现:
include_now: 取值True 或者False。 表示是否包含当前bar, 比如策略时间是9:33,unit参数为5m, 如果 include_now=True,则返回9:30-9:33这个分钟
假如策略是9:33运行,那参数include_now取值True,会不会查询到未来数据?
2,假如参数fq_ref_date取默认值,回测过程中会前复权吗?通过Print函数打印数据得出来的是未复权的数据。就不知道回测过程计算的时候是否使用前复权数据?
解决方案
你好!关于你在 JoinQuant 回测环境中使用 get_bars 函数遇到的两个疑惑,以下是详细的解答:
1. include_now=True 会不会查询到未来数据?
结论:不会查询到未来数据,但获取到的是一个“未完成的快照 Bar”。
详细解析:
- 当你的策略在
9:33运行时,如果你请求unit='5m'且include_now=True,系统会返回9:30-9:33这 3 分钟的数据组合成的一根 Bar。 - 这根 Bar 的数据是截至 9:33 这一刻的真实市场状态:
- Open(开盘价):9:30 的开盘价。
- High/Low(最高/最低价):9:30 到 9:33 期间的最高和最低价。
- Close(收盘价):9:33 这一刻的最新价(现价)。
- Volume/Money(成交量/额):9:30 到 9:33 的累计成交量和成交额。
- 因为这些数据在 9:33 这个时间点是已经真实发生的,所以严格来说它不属于未来数据。
- 注意事项:虽然不是未来数据,但这根 5 分钟 Bar 是未走完的。它的
close并不是最终 9:35 结束时的真实收盘价。如果你在策略中用这个未完成的close去计算均线或突破逻辑,可能会与你预期的“完整 5 分钟 K 线”逻辑产生偏差。通常在严谨的分钟级回测中,建议使用include_now=False来获取已经完全走完的上一根 Bar,以确保信号的稳定性。
2. fq_ref_date 取默认值时,回测过程中会前复权吗?
结论:默认情况下会进行“动态前复权”。
详细解析:
根据 JoinQuant API 文档,fq_ref_date(复权基准日期)在回测/模拟环境中的默认值是 context.current_dt.date()(即策略运行当天的日期)。
-
什么是动态前复权?
这意味着,当你的回测运行到历史上的某一天(例如 2018-01-05)时,get_bars会以 2018-01-05 作为复权基准日,对这天之前的数据进行前复权。这种机制完美模拟了你“穿越”到历史那一天时,在行情软件上看到的前复权价格,有效避免了未来函数(因为没有使用 2018-01-05 之后的复权因子)。 -
为什么你 Print 出来感觉像是未复权数据?
- 近期无分红/拆股:如果你回测的时间段内,该标的没有发生过分红派息或拆股,那么前复权价格和未复权(真实)价格是一模一样的。
- 开启了真实价格模式:如果你在
initialize中设置了set_option('use_real_price', True),系统在撮合交易和计算账户资产时使用的是真实的未复权价格。但是,为了方便计算技术指标,API(如get_bars,history)返回的依然是基于当天的前复权数据。如果你拿 API 返回的价格和账户持仓成本去对比,可能会产生误解。 - 显式传参错误:如果你在调用时写了
fq_ref_date=None,那么获取到的就是纯粹的未复权(真实)数据。
总结:只要你不显式传入 None,回测计算指标时默认使用的就是基于当天的前复权数据,你可以放心使用它来计算 MA、MACD 等技术指标,不会引入未来函数。