3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在商品期货量化交易中,夜盘交易时段(如前一日 21:00 至次日 02:30)在交易所规则中统一划归为下一个交易日。如果在策略编写中直接使用 context.current_dt.date(),会获取到实际的自然日(Calendar Date),导致交易日逻辑错乱、历史数据提取偏差或回测结果异常。
JoinQuant 提供了专门的 API get_trade_day,能够根据传入的具体时刻和标的代码,精准返回其对应的真实期货交易日。
以螺纹钢(RB)为例:
context.current_dt.date():返回的是周一的日期,导致获取历史 K 线、计算因子或判断调仓日时逻辑出错。因此,必须使用考虑了夜盘机制的专有函数来进行映射。
get_trade_day 精确获取归属交易日get_trade_day(security, query_dt)
'RB1901.XSGE' 或 ['RB1901.XSGE', '000001.XSHE'])。datetime.datetime 对象。datetime.date 对象(若非交易日或未上市/退市则返回 None)。from jqdata import *
# 查询夜盘 22:00 对应的交易日
res = get_trade_day(["RB1901.XSGE", "000001.XSHE"], query_dt="2019-01-04 22:00:00")
print(res)
# 输出结果:
# {
# 'RB1901.XSGE': datetime.date(2019, 1, 7), # 螺纹钢夜盘自动归属到下一个交易日(周一)
# '000001.XSHE': datetime.date(2019, 1, 4) # A股无夜盘,仍为当天的日期
# }
在策略的 handle_data 或 run_daily 中,可通过 get_trade_day 快速校验当前运行的时间点属于哪个期货交易日:
from jqdata import *
def initialize(context):
set_option('use_real_price', True)
# 设定期货子账户
set_subportfolios([SubPortfolioConfig(cash=1000000, type='futures')])
g.security = 'RB2405.XSGE'
# 参照期货标的运行
run_daily(market_open, time='every_bar', reference_security=g.security)
def market_open(context):
current_time = context.current_dt
# 获取当前时刻对应的交易日
trade_day_dict = get_trade_day(g.security, current_time)
current_trade_day = trade_day_dict.get(g.security)
# 打印当前自然时间与归属交易日
# 例如:自然时间 2023-11-06 21:01:00 -> 归属交易日 2023-11-07
log.info("当前自然时间: %s, 归属期货交易日: %s" % (current_time, current_trade_day))