🚀 AI 一键生成 ptrade 策略代码
立即体验

ptrade ETF 套利教程:如何利用 etf_purchase_redemption 接口实现单只 ETF 申赎与折溢价套利

ptrade | 发布时间: 2026/7/25
以下内容由 EasyQuant 生成。

问题描述

请根据以下 SEO 主题生成完整页面内容:

Title: ptrade ETF 套利教程:利用 etf_purchase_redemption 实现折溢价套利

Question: ptrade 如何使用 etf_purchase_redemption 接口进行单只 ETF 基金的申购与赎回?

解决方案

ptrade ETF 套利教程:利用 etf_purchase_redemption 实现折溢价套利

在 ETF 量化交易与套利策略中,二级市场买卖与一级市场申赎之间的折溢价套利是常见的低风险策略。ptrade 平台提供了高效的 ETF 交易接口,帮助开发者快速实现自动化套利。


一、etf_purchase_redemption 接口详解

etf_purchase_redemption 是 ptrade 平台专门用于单只 ETF 基金一级市场申购与赎回的交易接口。

1. 使用场景

  • 适用模块:仅支持 Ptrade 客户端可用、仅在股票交易模块可用。
  • 主要用途:当 ETF 出现溢价时申购 ETF 并卖出,或在折价时买入 ETF 并赎回。

2. 接口语法与参数

etf_purchase_redemption(etf_code, amount, limit_price=None)
  • etf_code (str): 单支 ETF 代码(如 '510050.SS'),必传参数。
  • amount (int): 基金申赎数量,正数表示申购,负数表示赎回。需注意申赎数量通常必须是 ETF 最小申赎单位(最小申购赎回单位可由 get_etf_info 接口查询)的整数倍。
  • limit_price (float, 可选): 委托限价。

3. 返回值

  • 成功:返回 Order 对象的 id (str)。
  • 失败:返回 None

二、基本使用示例

def initialize(context):
    g.security = '510050.SS'
    set_universe(g.security)

def handle_data(context, data):
    # ETF 申购:申购 90 万份 510050
    order_id_buy = etf_purchase_redemption('510050.SS', 900000)
    log.info('申购订单ID: %s' % order_id_buy)
    
    # ETF 赎回:赎回 90 万份 510050(以限价方式)
    order_id_sell = etf_purchase_redemption('510050.SS', -900000, limit_price=2.9995)
    log.info('赎回订单ID: %s' % order_id_sell)

三、ETF 折溢价套利的业务逻辑

  1. 溢价套利(一买一申卖)

    • 当 ETF 二级市场价格高于其实时 IOPV(或成分股组合成本)且价差大于交易成本时:
    • 步骤:使用 etf_basket_order 买入一篮子成分股 -> 使用 etf_purchase_redemption 申购 ETF 份额 -> 在二级市场卖出 ETF。
  2. 折价套利(买一赎卖)

    • 当 ETF 二级市场价格低于其实时 IOPV(或成分股组合成本)且价差大于交易成本时:
    • 步骤:二级市场买入 ETF 份额 -> 使用 etf_purchase_redemption 赎回换回一篮子成分股 -> 使用 etf_basket_order 卖出成分股。

四、完整 Python 策略代码示例(溢价套利框架)

'''
ptrade 示例策略:ETF 溢价套利示例
'''

def initialize(context):
    g.etf_code = '510050.SS'
    set_universe(g.etf_code)
    g.flag = False

def handle_data(context, data):
    if g.flag:
        return
        
    # 1. 获取 ETF 基础信息
    etf_info = get_etf_info(g.etf_code)
    if not etf_info or g.etf_code not in etf_info:
        return
        
    unit_size = etf_info[g.etf_code]['report_unit'] # 最小申赎单位
    
    # 2. 获取行情数据
    snapshot = get_snapshot(g.etf_code)
    if not snapshot or g.etf_code not in snapshot:
        return
        
    last_price = snapshot[g.etf_code]['last_px']
    # 假设此处计算得到成分股组合买入成本为 cost_price
    # 当 (last_price - cost_price) > 阈值 时触发溢价套利
    
    # 3. 买入成分股组合
    # basket_orders = etf_basket_order(g.etf_code, 1, price_style='S1', position=True)
    
    # 4. 申购 ETF 基金(以 1 组最小申赎单位为例)
    order_id = etf_purchase_redemption(g.etf_code, unit_size)
    if order_id:
        log.info("成功发起 ETF 申购委托,单号:%s" % order_id)
        g.flag = True

五、注意事项

  1. 精度与最小申赎单位:申购和赎回的数量 amount 需满足柜台对该 ETF 规定的最小申赎单位(如 1,000,000 份或 900,000 份),可先通过 get_etf_info 接口查询 report_unit 属性。
  2. 现金替代标志:套利下单前,建议使用 get_etf_stock_info 查看成分股的现金替代标志(cash_replace_flag)与保证金率,以准确计算套利成本。
  3. 资金与持仓时滞:一级市场申赎和二级市场买卖之间存在成交与持仓确认时滞,策略逻辑中应做好订单状态跟踪(get_orders / on_order_response)和异常撤单管理。