3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
很多量化开发者在JoinQuant(聚宽)平台上编写策略时,会发现在9:30开盘前后获取的数据存在差异。这并非系统Bug,而是由A股市场的交易机制(集合竞价)以及平台的底层数据处理逻辑共同决定的。以下是详细的原因解析及正确的处理方法。
在JoinQuant中,所有的行情K线数据为后对齐,标识K线的时间为数据的结束时间。
09:25:00 ~ 09:30:59 的所有数据。A股的开盘集合竞价在09:25结束并产生当天的开盘价。但在实际的模拟盘或实盘中,交易所的数据分发和平台的数据处理需要时间。
day_open)至少在09:27分之后才可获取。get_call_auction 获取),最晚于 09:28分 返回。为了减少并发运行模拟盘数量的压力,对于使用当日开盘价撮合的日级模拟盘,JoinQuant会在9:25集合竞价完成时获取开盘价,并将策略提前到 9:27~9:30 之间运行。
context.current_dt)仍然是 9:30。为了避免9:30前后的数据混乱,建议根据具体需求使用专门的API:
如果你在 handle_data 或 run_daily(..., time='09:30') 中需要知道今天的开盘价,请使用 get_current_data()。这个API专门用于获取当前单位时间已知的数据。
def market_open(context):
# 此时逻辑时间为9:30,实际物理时间可能在9:27-9:30之间
current_data = get_current_data()
security = '000001.XSHE'
# 获取当天开盘价(09:27之后可用)
today_open = current_data[security].day_open
# 获取最新价(09:30之前调用通常返回昨日收盘价或集合竞价价格)
last_price = current_data[security].last_price
# 获取涨跌停价
high_limit = current_data[security].high_limit
log.info(f"今日开盘价: {today_open}, 最新价: {last_price}")
如果你需要分析集合竞价的买卖盘力量,可以使用 get_call_auction。建议在09:30的函数中调用,以确保数据已经完全就绪。
from jqdata import *
def market_open(context):
# 获取当天的集合竞价数据
today = context.current_dt.strftime('%Y-%m-%d')
df_auction = get_call_auction('000001.XSHE', start_date=today, end_date=today)
if not df_auction.empty:
log.info(f"集合竞价成交价: {df_auction['current'].iloc[-1]}")
log.info(f"集合竞价成交量: {df_auction['volume'].iloc[-1]}")
如果你使用 history 或 attribute_history 获取日线数据,请注意:
frequency='1m')。avoid_future_data 时会报错。9:30前后数据不一致的核心在于集合竞价的特殊性与K线生成规则。在编写早盘策略时,切忌用常规的分钟K线逻辑去套用9:30这个时间点。明确区分“昨日收盘价”、“今日集合竞价/开盘价”和“9:31第一根分钟线”,并使用 get_current_data() 和 get_call_auction(),就能完美避开这个坑。