在回测中如何避免“未来函数”
“未来函数”通常指在回测过程中无意间使用了当前时点尚未发生的数据;或者在时间序列上有新的数据后,基于旧数据产生的旧信号会被调整。在英文中,通常使用Look-Ahead Bias(前瞻性偏差)一词表示这个概念。
“未来函数”问题可能会导致回测结果过于理想,但在实盘交易中却难以复现,从而降低策略的实用性。
以下是一些避免在Ptrade策略中出现“未来函数”问题的建议:
一、获取数据时,注意控制时间范围
Ptrade的回测自带一些预防“未来函数”的机制。
比如使用get_history
函数获取历史行情时,将回测周期设定为2023年1月1日至2023年12月31日。假设当前回测框架内的日期是2023年12月7日,则返回的数据最多至2023年12月7日即结束,不会继续返回2023年12月7日之后的数据。
但是这个预防机制并不能完全杜绝“未来函数”,比如使用get_fundamentals
函数查询一只股票2023年至2025年的财报,当前的真实时间是2025年4月30日,回测框架内的时间是2023年12月7日,则返回的结果会突破回测框架的时间约束,返回2023年至2025年之间全部已经发布的财报数据。
示例:
1 | # 当前的回测区间是2023年12月7日至2023年12月7日 |
返回的结果如下:
secu_abbr net_profit company_type publ_date end_date secu_code
2023-03-31 002602.SZ 世纪华通 4.421071e+08 99 2023-04-29
2023-06-30 002602.SZ 世纪华通 8.961154e+08 99 2023-08-31
2023-09-30 002602.SZ 世纪华通 1.492387e+09 99 2023-10-31
2023-12-31 002602.SZ 世纪华通 5.878338e+08 99 2024-04-30
2024-03-31 002602.SZ ST华通 7.073091e+08 99 2024-04-30
2024-06-30 002602.SZ ST华通 1.207148e+09 99 2024-08-31
2024-09-30 002602.SZ ST华通 1.899273e+09 99 2024-10-31
2024-12-31 002602.SZ ST华通 1.044930e+09 99 2025-04-29
2025-03-31 002602.SZ ST华通 1.386127e+09 99 2025-04-29
为了避免此类问题,应当严格控制所获取行情的时间范围,或者对返回的数据进行二次筛选,确保其不超过回测框架中当前的时间节点。
二、部分API只能返回最新数据
比如我们想通过查询股票的名称来判断其状态(例如S、ST、*ST、退市整理期),get_stock_name
、get_stock_info
函数均可查询股票名称信息,但是只能返回当前的真实时间对应的最新数据,不会跟随回测框架的日期相应变动,也无法传入参数去查询指定日期的数据。
例如“002602, ST华通”这只股票在2024年11月8日被实施ST风险警示,假设当前的实际时间是2025年4月30日,那么不论我们的回测时间是在2024年11月8日之前还是之后,查询到的股票名称均为当前的最新名称“ST华通”。如果我们根据这两个函数返回的信息在回测中判断股票的状态,显然会得到错误的结论,从而使得回测的结果毫无意义。
再比如get_stock_exrights
函数,如果参数中不指定日期的话,默认是返回单只股票在历史上的所有除权除息信息,而不是到回测框架的当日截至。
为了避免此类问题,在使用API函数返回的数据之前,应当提前考虑各种可能的情形,并针对不同的情形进行测试,确保返回的数据符合不同情形下的要求。有些情况下还需对API函数返回的数据进行二次筛选。
三、谨慎使用包含“未来函数”属性的技术指标
例如ZIG等技术指标,通常被认为存在“未来函数”问题,其指标公式在时间序列上存在前后相互引用的情况,从而导致在时间序列上出现新的数据时,基于旧数据产生的旧信号可能会被调整。
为了避免此类问题,建议谨慎使用包含“未来函数”属性的技术指标。