3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 JoinQuant(聚宽)平台上进行期货回测时,处理“换月”(即主力合约切换)是非常关键的一步。因为在聚宽中,不能直接对主力连续合约(如 RB9999.XSGE)进行下单,必须获取具体的真实合约代码(如 RB1905.XSGE)才能交易。
以下是处理期货换月的标准流程和代码示例:
处理换月最核心的 API 是 get_dominant_future:
get_dominant_future(underlying_symbol, date=None):获取指定品种在指定日期的主力合约代码。
underlying_symbol: 期货合约品种,如 'RB' (螺纹钢)。'RB1905.XSGE'。标准的换月逻辑通常在每天开盘前或盘中定期执行,步骤如下:
get_dominant_future。以下是一个简单的螺纹钢(RB)多头策略换月处理示例:
# 导入聚宽函数库
import jqdata
def initialize(context):
# 设定基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 设定期货账户
set_subportfolios([SubPortfolioConfig(cash=100000, type='futures')])
# 定义要交易的期货品种
g.underlying_symbol = 'RB'
# 记录当前的主力合约
g.dominant = None
# 每天开盘前检查换月
run_daily(check_rollover, time='08:50', reference_security='RB9999.XSGE')
# 每天盘中执行交易逻辑
run_daily(trade_logic, time='09:30', reference_security='RB9999.XSGE')
def check_rollover(context):
"""
检查并处理换月逻辑
"""
# 获取当前最新的主力合约
current_dominant = get_dominant_future(g.underlying_symbol)
# 如果主力合约发生变化
if g.dominant and current_dominant != g.dominant:
log.info(f"主力合约发生切换: {g.dominant} -> {current_dominant}")
# 检查旧合约是否有持仓
if g.dominant in context.portfolio.long_positions:
# 获取旧合约的多单持仓量
old_position_amount = context.portfolio.long_positions[g.dominant].total_amount
if old_position_amount > 0:
log.info(f"平仓旧合约: {g.dominant},数量: {old_position_amount}")
# 平掉旧合约多单
order_target(g.dominant, 0, side='long')
# 在新合约上开同等数量的多单(移仓)
log.info(f"开仓新合约: {current_dominant},数量: {old_position_amount}")
order_target(current_dominant, old_position_amount, side='long')
# 如果有空单持仓,同理处理(此处省略空单处理代码)
# 更新记录的主力合约
g.dominant = current_dominant
def trade_logic(context):
"""
具体的交易信号逻辑
"""
# 确保已经获取到主力合约
if not g.dominant:
return
# 这里写你的策略逻辑,例如简单的买入持有
# 注意:下单时必须使用 g.dominant (具体合约),而不是 'RB9999.XSGE'
if g.dominant not in context.portfolio.long_positions:
order(g.dominant, 1, side='long')
log.info(f"买入开仓: {g.dominant}")
RB9999.XSGE(主连)和 RB8888.XSGE(指数)只能用来获取数据或作为定时任务的参考标的(reference_security),绝对不能传入 order 函数中。