3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
针对您在 JoinQuant (聚宽) 平台上遇到的双因子策略回测结果不一致的问题,主要可以从是否引入未来函数以及回测路径依赖两个方面来解答。
get_fundamentals 会产生未来函数吗?在 JoinQuant 中,使用 get_fundamentals 获取财务数据是否会产生未来函数,取决于您传入的参数:
date 和 statDate):date 和 statDate,date 的默认值会随着回测日期变化而变化,等于 context.current_dt 的前一天。因为在实际交易中,我们只能看到前一天的财报和市值数据,所以这种默认设置不会产生未来函数。date 参数:date 收盘后所能看到的最近的数据。系统会查找上市公司在这个日期之前(包括此日期)发布的最新数据,不会有未来函数。statDate 参数(需警惕):statDate(如 '2019q1' 或 '2019'),系统会返回该季度或年份的财务数据。由于公司发布财报通常有滞后性(例如一季报可能在4月底才发布),如果您在1月份就通过 statDate 获取了一季报的数据,这就引入了未来函数。因此,回测中应尽量避免使用 statDate,或者严格控制调用时间。结论:您使用的 get_fundamentals(query(valuation, indicator).filter(valuation.code.in_(stock_list))) 没有指定 statDate,默认使用的是回测当前逻辑时间的前一天的数据,因此不会产生未来函数。
即使策略逻辑完全相同,且没有未来函数,从 2017 年开始回测和从 2019 年开始回测,在 2019-2022 年期间的持仓组合大概率是不一样的。这主要是由**回测的路径依赖(Path Dependency)**引起的:
available_cash)和总资产(total_value)已经经历了两年的盈亏变化,与 2019 年初直接以初始资金启动的账户完全不同。set_option('use_real_price', True),回测使用的是真实价格撮合,但通过 API(如 history)获取的是基于当天的前复权价格。不同时间点看到的前复权价格是不同的。虽然这主要影响技术指标(如均线),但如果您的双因子策略中结合了价格过滤条件,微小的价格差异也可能导致选股结果的边缘变化。order_volume_ratio(成交量比例限制),导致部分订单未成交。未成交的资金会留在账户中,影响下一次的选股和买入。量化回测是一个连续的动态过程,前一天的状态决定了今天的决策基础。不同起期导致到达同一时间点时,账户的“初始状态”(资金、持仓、成本)截然不同,因此后续的交易行为和股票组合自然会产生分化。这是正常的量化回测现象,并非策略代码存在错误或未来函数。