🚀 AI 一键生成 qmt 策略代码

QMT 期货交易核心:详解平今优先与平昨优先下单函数

qmt | 发布时间: 2025/12/12
以下内容由 EasyQuant 生成。

问题描述

我想平掉期货空头持仓,应该用哪个函数?平今仓和平昨仓有什么区别?

解决方案

在 QMT 量化交易平台中,平掉期货空头持仓(即“买入平仓”)主要使用以下两个专用函数。

1. 应该使用哪个函数?

根据您希望优先平掉哪一部分持仓,可以选择以下两个函数之一:

  1. buy_close_tdayfirst买入平仓,平今优先
  2. buy_close_ydayfirst买入平仓,平昨优先

此外,也可以使用综合下单函数 passorder,通过设置 opType 参数来实现(如 12 代表买入平仓平今优先,13 代表买入平仓平昨优先),但通常建议使用上述专用函数,代码可读性更高。


2. 平今仓和平昨仓的区别

在期货交易中,“今仓”和“昨仓”是根据开仓时间来划分的,两者的主要区别在于交易规则手续费

(1) 定义区别

  • 今仓 (Today's Position):在当前交易日内开仓建立的持仓。
  • 昨仓 (Yesterday's/History Position):在当前交易日之前(如昨天、前天等)建立并持有过夜的持仓。

(2) 优先级的逻辑

  • 平今优先 (buy_close_tdayfirst):系统会先尝试平掉今天的空单。如果平仓数量超过了今仓数量,剩余的部分会自动去平昨仓。
  • 平昨优先 (buy_close_ydayfirst):系统会先尝试平掉历史持仓(老单)。如果平仓数量超过了昨仓数量,剩余的部分会自动去平今仓。

(3) 手续费与交易所规则(核心差异)

这是区分平今和平昨最主要的原因。不同的期货交易所和品种有不同的规定:

  • 上海期货交易所 (SHFE) 和 能源中心 (INE):严格区分平今和平昨。
    • 某些品种(如螺纹钢、热卷等)在特定时期,平今仓的手续费可能非常昂贵(为了抑制日内过度投机),此时策略应尽量避免平今,或者优先平昨。
    • 某些品种平今仓手续费可能减免。
    • 注意:对于上期所品种,必须明确指定是平今还是平昨,否则可能会报错或按高费率执行。QMT 的这两个函数会自动处理这些指令细节。
  • 其他交易所 (CFFEX, DCE, CZCE):通常不严格区分平今和平昨的指令(通常默认先开先平),但在 QMT 中使用这两个函数可以帮助你在策略逻辑层面控制资金占用的释放顺序或配合特定的费率优化策略。

3. 代码示例

以下代码展示了如何在 QMT 中编写平空头持仓的逻辑:

# -*- coding: gbk -*-

def init(ContextInfo):
    # 设置资金账号 (请替换为真实的期货账号)
    ContextInfo.accID = '12345678'
    # 设置交易账户类型为期货
    ContextInfo.set_account(ContextInfo.accID)

def handlebar(ContextInfo):
    # 获取当前K线索引
    index = ContextInfo.barpos
    # 获取当前时间
    realtime = ContextInfo.get_bar_timetag(index)
    
    # 示例合约:沪深300股指期货主力
    symbol = 'IF00.IF'
    
    # --- 场景 A:平今优先 ---
    # 假设策略逻辑触发,需要买入平仓 2 手,优先平掉今天的仓位
    # 参数说明: 代码, 数量, 报价类型(最新价), 价格(-1代表市价/最新价), ContextInfo, 账号
    buy_close_tdayfirst(symbol, 2, 'LATEST', -1, ContextInfo, ContextInfo.accID)
    print(f"已发出平今优先指令:{symbol} 买入平仓 2手")

    # --- 场景 B:平昨优先 ---
    # 假设策略逻辑触发,需要买入平仓 5 手,优先平掉老仓位(例如为了释放保证金或规避平今高手续费)
    # buy_close_ydayfirst(symbol, 5, 'LATEST', -1, ContextInfo, ContextInfo.accID)
    # print(f"已发出平昨优先指令:{symbol} 买入平仓 5手")

    # --- 场景 C:使用 passorder (高级用法) ---
    # opType 12: 买入,如有空仓,优先平仓,优先平今,如有余量,再开多 (这里仅用于演示平仓逻辑)
    # passorder(12, 1101, ContextInfo.accID, symbol, 5, -1, 1, ContextInfo)

总结

  • 如果您不在意手续费差异,或者交易的是非上期所品种,通常使用 buy_close_tdayfirst (平今优先) 比较符合日内交易习惯。
  • 如果您交易的是上期所 (SHFE) 品种,且该品种平今手续费较高,请务必使用 buy_close_ydayfirst (平昨优先) 来降低交易成本。

Q&A

Q: 如果我只有昨仓,使用了 buy_close_tdayfirst 会怎样?
A: 不会报错。函数逻辑是“优先”平今。如果系统检测到您没有今仓,它会自动转为平掉您的昨仓。

Q: buy_close 系列函数支持限价单吗?
A: 支持。在示例代码中,将 'LATEST' 改为 'FIX',并将 -1 改为您指定的具体价格(如 3500.0),即可发送限价单。

Q: 股票交易可以用这两个函数吗?
A: 不可以。股票交易没有“空头持仓”的概念(融券除外,但融券有专门的 passorder 操作码),且股票实行 T+1 制度,无法“平今”。股票卖出请使用 order_sharespassorder (opType 24)。