期货 / 期货:主力换月与排查

期货

期货:主力换月与排查

期货回测中的主力合约映射与换月:用 get_future_dominant 取得真实主力、避免当日主力信息提前进入信号、先平旧仓再开新仓的分步换月流程;以及期货策略常见问题的排查清单。

一、主力映射

get_future_dominant 返回的表里,underlying_symbol 是品种、date 是映射日期、symbol真实主力合约。即使出现 trading_code 列,它也不是平台下单用的带后缀合约代码。

回测可以一次预加载整个区间的主力映射,但每天只能读取在决策时点已经可知的记录。配套示例保守地使用当前交易日之前最近一条映射,避免当天收盘后才确定的主力信息提前进入信号。

二、先平旧仓、再开新仓

需要严格保持「先平后开」时,按以下流程分步换月:

  1. 盘前确定目标真实合约,并订阅它的行情。
  2. 若有未完成委托,先等回报,或按策略条件撤单。
  3. 对旧合约按可平量发平仓单,保存新合约目标。
  4. 之后的 handle_data 再读实际持仓:旧仓确认归零、且没有未完成委托,才开新仓。

旧合约没有有效行情、可平量不足或平仓被拒时,保持「换月未完成」的状态,不能仅因发过平仓请求就开新仓。

两种换月方式的取舍:用组合目标仓位一次调仓,适合能接受多笔委托并行执行的组合;分步换月适合要求严格先平后开的策略。

完整代码见期货示例里的「主力合约换月」。那份示例使用独立账户、只管理一个品种的多头,不要直接挂到已有其他策略持仓的账户上。

三、常见问题

现象 检查方法
没有任何交易 合约是否在有效回测区间内;是否取得有效行情;信号窗口是否预热完成;是否被未完成委托阻塞
下单返回非空但没成交 查看每张订单的 statusmessagefilled_quantity,不要以返回列表长度判断成交
平仓被拒绝 检查多空方向、是否为 Python 整数手数、总可平量、今仓可平量,以及是否重复冻结
夜盘信号查不到 映射的键是否用 context.trade_date;DataFrame 的日期类型是否已统一
查询旧合约资料为空 用历史日期和 get_future_detail_all;默认的可交易目录不适合查询已到期合约
换月后旧仓仍在 平仓请求是否实际成交;旧合约行情是否有效;是否存在挂单或冻结
组合意外清掉其他合约 组单字典描述的是整个账户的目标,检查是否漏了应保留的持仓方向
净值与想象的成交价不一致 核对撮合参考价、滑点单位、手续费与保证金倍率,以及是否用了未来信息
数据字段不存在 区分当前 Bar 对象和历史 DataFrame;检查 fields 与实际返回列,不要用默认值掩盖字段错误

日志用 print,记录提交订单、成交、拒单、换月和每日汇总即可,避免每根 Bar 无条件打印。可预期的数据缺失显式判空;必需数据为空或字段错误时给出清楚的异常,不要用宽泛的异常捕获把失败变成正常的收益结果。

四、运行前确认

  • 合约真实,且在有效区间内;
  • 价格单位与最小变动价位正确;
  • 手数是正整数;
  • 信号没有读取未来数据;
  • 反向仓已经处理,平仓用的是可平量;
  • 未完成委托有跟踪;
  • 组单的目标范围明确;
  • 回调里使用的是期货订单对象的字段。