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

如何在 ptrade 中联合使用 etf_basket_order 和 etf_purchase_redemption 接口进行瞬时套利?

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

问题描述

ptrade ETF 瞬时套利指南:申购赎回与篮子交易核心 API 实战
如何在 ptrade 中联合使用 etf_basket_order 和 etf_purchase_redemption 接口进行瞬时套利?

解决方案

ptrade ETF 瞬时套利指南:申购赎回与篮子交易核心 API 实战

在 ETF 量化交易中,**瞬时套利(Arbitrage)**是一种经典的低风险交易策略。当 ETF 的二级市场交易价格与其份额净值(IOPV)出现偏差时,交易者可以通过快速在“二级市场买卖”与“一级市场申赎”之间进行切换来锁定无风险利润。

ptrade 提供了专为 ETF 设计的底层 API:etf_basket_order(成分券篮子交易)和 etf_purchase_redemption(一键申赎)。本文将为您详细解析如何联合使用这两个接口进行瞬时套利。


一、 ETF 瞬时套利的两大核心路径

1. 溢价套利(Premium Arbitrage)

ETF 二级市场价格 > IOPV(净值) 时,存在溢价,套利路径如下:

  1. 买入一篮子成分股:使用 etf_basket_order 快速买入成分股。
  2. 申报申购 ETF 份额:使用 etf_purchase_redemption 将成分股申购为 ETF 份额。
  3. 卖出 ETF 份额:在二级市场使用 order 卖出申购得到的 ETF 份额。

2. 折价套利(Discount Arbitrage)

ETF 二级市场价格 < IOPV(净值) 时,存在折价,套利路径如下:

  1. 买入 ETF 份额:在二级市场使用 order 买入 ETF 份额。
  2. 申报赎回 ETF 份额:使用 etf_purchase_redemption 赎回 ETF 份额,获得一篮子成分股。
  3. 卖出一篮子成分股:使用 etf_basket_order 快速卖出赎回得到的成分股。

二、 核心 API 接口解析

1. 成分券篮子下单:etf_basket_order

etf_basket_order(etf_code, amount, price_style=None, position=True, info=None)
  • etf_code: ETF 代码(如 '510050.SS')。
  • amount: 下单篮子份数。正数表示买入成分股,负数表示卖出成分股
  • price_style: 委托价位,可选 'B1'~'B5''S1'~'S5''new'(最新价,默认)。
  • position: 申购是否使用持仓替代,默认为 True

2. ETF 基金申赎:etf_purchase_redemption

etf_purchase_redemption(etf_code, amount, limit_price=None)
  • etf_code: ETF 代码。
  • amount: 申赎数量。正数表示申购,负数表示赎回

三、 瞬时套利策略 Python 源码示例

以下是一个在 handle_data 盘中事件中,根据折溢价瞬时触发套利的策略框架:

def initialize(context):
    # 设定套利目标 ETF(以 50ETF 为例)
    g.etf_code = '510050.SS'
    set_universe(g.etf_code)
    
    # 套利阈值设定(需根据实际交易成本微调)
    g.premium_threshold = 0.005  # 溢价 0.5% 触发
    g.discount_threshold = -0.005 # 折价 0.5% 触发
    g.trade_unit = 900000         # 最小申赎单位(请参考 get_etf_info 获取)

def handle_data(context, data):
    etf = g.etf_code
    
    # 1. 获取 ETF 实时行情快照与 IOPV 净值
    snapshot = get_snapshot(etf)
    if not snapshot or etf not in snapshot:
        return
        
    last_px = snapshot[etf]['last_px']       # 二级市场最新成交价
    # 注意:实际套利中,IOPV 需通过实时计算或柜台主推获取,此处以模拟估算演示
    iopv = last_px * 0.998  # 假设当前实时估算净值
    
    # 计算折溢价率
    premium_rate = (last_px - iopv) / iopv
    
    # 2. 溢价套利逻辑:买入篮子 -> 申购 ETF -> 卖出 ETF
    if premium_rate > g.premium_threshold:
        log.info(f"触发溢价套利,折溢价率: {premium_rate:.4f}")
        
        # 步骤 A:一键买入成分股篮子
        basket_res = etf_basket_order(etf, amount=1, price_style='S1', position=False)
        
        if basket_res:
            log.info("成分股篮子买入委托成功,开始申报申购...")
            # 步骤 B:一键申购 ETF 份额
            purchase_id = etf_purchase_redemption(etf, amount=g.trade_unit)
            
            if purchase_id:
                log.info("ETF 申购申报成功,准备在二级市场卖出 ETF 份额...")
                # 步骤 C:二级市场卖出 ETF 份额
                order(etf, amount=-g.trade_unit)
                
    # 3. 折价套利逻辑:买入 ETF -> 赎回 ETF -> 卖出篮子
    elif premium_rate < g.discount_threshold:
        log.info(f"触发折价套利,折溢价率: {premium_rate:.4f}")
        
        # 步骤 A:二级市场买入 ETF 份额
        buy_etf_id = order(etf, amount=g.trade_unit)
        
        if buy_etf_id:
            log.info("二级市场买入 ETF 成功,开始申报赎回...")
            # 步骤 B:一键赎回 ETF 份额,获取成分股
            redeem_id = etf_purchase_redemption(etf, amount=-g.trade_unit)
            
            if redeem_id:
                log.info("ETF 赎回申报成功,开始一键卖出成分股篮子...")
                # 步骤 C:一键卖出成分股篮子
                etf_basket_order(etf, amount=-1, price_style='B1')

四、 实盘注意事项

  1. 最小申赎单位(Report Unit):不同 ETF 的最小申赎单位不同(通常为 100 万份或 50 万份)。在交易前,请务必调用 get_etf_info(etf_code) 获取 report_unit 字段。
  2. 资金与持仓占用:套利交易资金吞吐量极大,需确保账户内有足够的可用资金(买篮子)或可用持仓(申赎)。
  3. 交易成本与滑点:套利利润通常极薄,印花税、佣金、过户费以及成分股买卖时的滑点都会直接蚕食利润。建议在实盘前使用 set_commissionset_slippage 进行严格的回测与成本测算。