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

为什么 JoinQuant 的 get_bars() 获取的历史收盘价与股票软件不一致?

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

问题描述

使用get_bars()的一个问题

在使用get_bars()时,设置参数为:
df = get_bars(security, 50, unit='1d', fields=['date', 'open', 'high', 'low', 'close'], end_dt='2020-06-01 15:30:00', include_now=True),
得到的数据中,2020-06-01 15:00:00的收盘价和股票软件显示有出入,
而把end_dt改为今天即'2021-04-29 15:30:00',得到的结果又和股票软件显示的一致,问题出在哪里呢?
谢谢!

解决方案

您好!出现这个问题的原因在于**复权基准日(fq_ref_date)**的设置与股票软件的默认复权方式存在差异。

问题原因解析

在 JoinQuant 的 get_bars() 函数中,有一个非常重要的隐藏参数 fq_ref_date(复权基准日期)。

  1. 股票软件的默认逻辑
    同花顺、通达信等大多数股票软件,默认显示的是**“前复权”价格,并且这个前复权的基准日永远是今天(最新交易日)**。也就是说,它会用今天的价格作为基准,把历史上的分红、送股等除权除息事件往回倒推计算。

  2. JoinQuant get_bars() 的默认逻辑

    • 回测/模拟环境中,如果您没有显式指定 fq_ref_date,它默认等于 context.current_dt.date()(即您设定的 end_dt 所在的日期)。
    • 当您把 end_dt 设置为 '2020-06-01 15:30:00' 时,get_bars 默认以 2020-06-01 作为复权基准日进行前复权。而股票软件是以 今天(2021-04-29) 作为基准日进行前复权。如果该股票在 2020-06-01 到 2021-04-29 期间发生过分红或送转,这两个基准日算出来的历史价格必然是不一样的。
    • 当您把 end_dt 改为今天 '2021-04-29 15:30:00' 时,复权基准日变成了今天,这就和股票软件的基准日完全对齐了,所以价格就一致了。

解决方法

根据您的实际需求,可以通过显式设置 fq_ref_date 参数来解决这个问题:

1. 如果您想获取和股票软件完全一致的“基于今天的前复权价格”

请将 fq_ref_date 显式指定为今天的日期(或者 datetime.datetime.now()):

import datetime

df = get_bars(security, 50, unit='1d', 
              fields=['date', 'open', 'high', 'low', 'close'], 
              end_dt='2020-06-01 15:30:00', 
              include_now=True, 
              fq_ref_date=datetime.datetime.now().date()) # 强制以今天为基准复权

2. 如果您想获取当时真实的“不复权价格”(实际交易价格)

如果您想看 2020-06-01 那天真实的挂牌交易价格,请将 fq_ref_date 设置为 None,并在股票软件中也切换到“不复权”模式进行对比:

df = get_bars(security, 50, unit='1d', 
              fields=['date', 'open', 'high', 'low', 'close'], 
              end_dt='2020-06-01 15:30:00', 
              include_now=True, 
              fq_ref_date=None) # 获取不复权(真实)价格

总结建议

在量化回测中,为了避免引入未来函数,系统默认以回测当前时间(context.current_dt)作为复权基准日是非常科学的(即动态复权)。如果您只是在研究环境中为了和股票软件对数据,可以手动将 fq_ref_date 设为今天;但在正式写策略回测时,建议保持默认设置或使用 set_option('use_real_price', True) 配合真实价格撮合。