🚀 AI 一键生成 joinquant 策略代码
立即体验
👉 AI 生成代码 👈

为什么 JoinQuant 中每周首个交易日 valuation.turnover_ratio 总是返回 NaN?

joinquant | 发布时间: 2026/6/1
以下内容由 EasyQuant 生成。

问题描述

valuation.turnover_ratio?

为什么每周首个交易日 valuation.turnover_ratio 的值总为 NAN
例如 2022.1.4日

还希望能优化

解决方案

问题原因分析

在 JoinQuant 平台中,当您使用 get_fundamentals 查询 valuation.turnover_ratio(换手率)等市值表数据时,如果在回测中不指定 date 参数,系统默认会使用 context.current_dt 的前一天(即前一个自然日) 作为查询日期。

这就导致了一个常见的问题:

  1. 每周首个交易日(通常是周一):它的前一个自然日是周日(非交易日)。
  2. 节假日后的首个交易日(如您提到的 2022年1月4日):2022年1月4日是元旦假期后的首个交易日,它的前一个自然日是1月3日(法定节假日,非交易日)。

由于非交易日市场没有开盘,自然不存在当天的“换手率”数据,因此数据库在这些非交易日对应的记录为空,从而返回了 NaN

优化与解决方案

为了避免取到非交易日的空数据,强烈建议在调用 get_fundamentals 时,显式指定 date 参数为上一个交易日,而不是依赖系统默认的前一个自然日。

在 JoinQuant 中,您可以通过 context.previous_date 直接获取上一个有效的交易日。

优化后的代码示例

def handle_data(context, data):
    # 错误写法:默认查询前一个自然日,周一或节假日后会返回 NaN
    # df_wrong = get_fundamentals(query(valuation.code, valuation.turnover_ratio))
    
    # 正确写法:显式指定 date 为上一个交易日
    q = query(valuation.code, valuation.turnover_ratio)
    df_correct = get_fundamentals(q, date=context.previous_date)
    
    # 打印查看结果,此时即使是周一或 2022.1.4,也能正确取到节前最后一个交易日的换手率
    print(df_correct.head())

为什么平台这样设计?

量化回测引擎严格区分“自然日”和“交易日”。默认取前一个自然日是为了保证时间轴的绝对真实性(例如某些宏观数据或海外数据在周末是更新的)。对于 A 股特有的交易日历,平台提供了 context.previous_date 供开发者灵活调用。只要养成在查询财务/市值数据时传入 date=context.previous_date 的习惯,就可以完美避开所有节假日和周末导致的 NaN 问题。