🚀 AI 一键生成 ptrade 策略代码

PTrade 期货交易中如何区分平今仓与平昨仓?close_today 参数使用指南

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

问题描述

在期货交易中,如何通过代码实现优先平昨仓或只平今仓的操作?

解决方案

在PTrade量化交易平台中,期货交易的平仓顺序(优先平昨或只平今仓)是通过平仓函数 buy_close(买入平仓/空平)和 sell_close(卖出平仓/多平)中的 close_today 参数来控制的。

以下是具体的实现方法和代码示例。

核心逻辑说明

PTrade 的平仓函数定义如下:

  • buy_close(contract, amount, limit_price=None, close_today=False)
  • sell_close(contract, amount, limit_price=None, close_today=False)

通过设置 close_today 参数的值来实现不同的平仓逻辑:

  1. 优先平昨仓 (close_today=False)

    • 这是默认设置。
    • 系统会优先平掉昨日(及以前)持有的历史仓位。
    • 如果委托数量大于昨仓数量,剩余部分会自动平掉今日新开的仓位。
  2. 只平今仓 (close_today=True)

    • 系统强制只平掉今日新开的仓位。
    • 如果委托数量大于今日持仓数量,系统通常会调整为今日持仓的最大数量或报错(取决于具体交易所规则)。
    • 注意:根据PTrade文档,close_today=True 主要对 上海期货交易所 (SHFE)上海国际能源交易中心 (INE) 生效。对于其他交易所(如中金所、大商所、郑商所),通常不区分平今和平昨,或者系统会将其强制转换为 False

PTrade 策略代码示例

以下代码展示了如何在策略中实现这两种操作。

def initialize(context):
    # 初始化策略
    # 这里以上海期货交易所的沪铜(CU)为例,因为上期所严格区分平今和平昨
    g.future_code = 'CU2310.XSGE' 
    set_universe([g.future_code])
    
    # 设置保证金比例和手续费(可选)
    set_margin_rate("CU", 0.08)
    set_future_commission("CU", 0.00005)

def handle_data(context, data):
    # 获取当前持仓信息
    position = get_position(g.future_code)
    
    # ---------------------------------------------------
    # 场景一:优先平昨仓 (Close Yesterday First)
    # ---------------------------------------------------
    # 假设我们要平掉 2 手多单
    # close_today=False (默认值),表示优先平昨,昨仓不够再平今
    if position.long_amount > 0:
        # 卖出平仓,多头平仓
        sell_close(g.future_code, 2, close_today=False)
        log.info("执行优先平昨操作:卖出平仓 2 手")

    # ---------------------------------------------------
    # 场景二:只平今仓 (Close Today Only)
    # ---------------------------------------------------
    # 假设我们要平掉 1 手今日开的空单
    # close_today=True,表示强制只平今仓
    # 注意:必须确保有足够的今仓,否则可能委托失败或被调整
    if position.short_amount > 0:
        # 买入平仓,空头平仓
        buy_close(g.future_code, 1, close_today=True)
        log.info("执行只平今仓操作:买入平仓 1 手")

def on_order_response(context, order_list):
    # 打印委托反馈,查看订单状态
    for order in order_list:
        log.info("订单更新: %s, 状态: %s" % (order['entrust_no'], order['status']))

详细参数解析

1. 优先平昨仓 (默认模式)

close_today=False 时,PTrade 引擎的处理逻辑如下:

  • 检查该合约的昨仓数量(old_amount)。
  • 如果 下单数量 <= 昨仓数量:全部申报为平昨。
  • 如果 下单数量 > 昨仓数量:先申报平昨 old_amount,剩余的 下单数量 - old_amount 申报为平今。

2. 只平今仓 (特殊模式)

close_today=True 时:

  • 引擎会检查该合约的今仓数量(today_amount)。
  • 生成的委托单将带有“平今”标记(Specific for SHFE/INE)。
  • 特别提示:如果你的策略运行在非上期所/能源中心品种(如中金所 IF),设置 close_today=True 可能会被系统忽略并发出警告,自动转为 False 处理,因为这些交易所通常不区分平今/平昨指令,或者按交易所默认规则(通常是先开先平)处理。

常见问题 Q&A

Q1: 如果我在中金所(如股指期货 IF)使用 close_today=True 会怎样?
A: PTrade 文档指出,close_today=True 仅对上海期货交易所生效。对于其他交易所,若设置为 True,系统会警告并强行转换为 close_today=False。中金所等交易所通常遵循“先开先平”原则,或者在柜台层面处理手续费优惠,API层面通常不需要显式指定平今。

Q2: 如何判断我当前有多少“今仓”和“昨仓”?
A: 可以通过 get_position 获取持仓对象,利用以下字段计算:

  • amount: 总持仓。
  • today_amount: 今仓数量(仅回测有效,实盘中需通过 amount - 昨仓 或柜台返回字段判断)。
  • 实盘技巧:在实盘中,通常 amount 是总持仓。对于上期所品种,柜台通常会区分 today_amount。如果 API 的 Position 对象在实盘未直接提供 yesterday_amount,可以用 amount - today_amount 估算昨仓。

Q3: 为什么要区分平今和平昨?
A: 主要是因为手续费不同。特别是在上海期货交易所(XSGE),某些品种(如螺纹钢、热卷等)在特定时期,平今仓的手续费可能非常昂贵,或者反而免费(免平今)。策略通过控制平仓顺序可以显著降低交易成本。

Q4: 如果我想“优先平今,今仓不够再平昨”怎么办?
A: PTrade API 没有直接的 PrioritizeToday 参数。你需要自己写逻辑:

  1. 获取当前今仓数量 today_qty
  2. 如果 目标平仓量 <= today_qty:调用 close_today=True
  3. 如果 目标平仓量 > today_qty
    • 先调用 close_today=True 平掉所有今仓。
    • 再调用 close_today=False 平掉剩余数量(此时因为今仓已为0,实际上就是平昨)。