问题描述
老师你好:
我在做期货回撤的时候,换月怎么处理呢?
解决方案
在 JoinQuant(聚宽)平台上进行期货回测时,处理“换月”(即主力合约切换)是非常关键的一步。因为在聚宽中,不能直接对主力连续合约(如 RB9999.XSGE)进行下单,必须获取具体的真实合约代码(如 RB1905.XSGE)才能交易。
以下是处理期货换月的标准流程和代码示例:
1. 核心 API 介绍
处理换月最核心的 API 是 get_dominant_future:
get_dominant_future(underlying_symbol, date=None):获取指定品种在指定日期的主力合约代码。underlying_symbol: 期货合约品种,如'RB'(螺纹钢)。- 返回值: 具体的期货合约代码,如
'RB1905.XSGE'。
2. 换月处理逻辑
标准的换月逻辑通常在每天开盘前或盘中定期执行,步骤如下:
- 获取当前最新的主力合约:使用
get_dominant_future。 - 检查当前持仓:遍历账户中该品种的持仓合约。
- 平旧开新(移仓换月):如果发现持仓的合约已经不是最新的主力合约,则将旧合约平仓,并将相应的仓位转移到新的主力合约上。
3. 完整代码示例
以下是一个简单的螺纹钢(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}")
4. 注意事项
- 不能对指数或主连下单:切记
RB9999.XSGE(主连)和RB8888.XSGE(指数)只能用来获取数据或作为定时任务的参考标的(reference_security),绝对不能传入order函数中。 - 换月成本:换月操作本质上是一次平仓加一次开仓,会产生交易手续费和滑点。在回测时,频繁换月会影响收益,这是符合真实市场情况的。
- 交割日风险:如果不处理换月,持仓合约到达交割日时,聚宽系统会以当天结算价自动平仓,且没有手续费。但在实盘中,个人投资者通常不允许进入交割月,因此策略中必须包含换月逻辑。