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

ptrade 平台如何获取 ETF 最小申赎单位(report_unit)并计算资金门槛?

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

问题描述

ptrade ETF 申赎风控:最小申赎单位(report_unit)与资金门槛计算
在 ptrade 中进行 ETF 申赎时,如何获取并遵守最小申购、赎回单位限制?

解决方案

在 ptrade 量化交易平台中,进行 ETF 申购和赎回(Arbitrage/Redemption)时,必须严格遵守柜台规定的**最小申购、赎回单位(report_unit)**限制。如果委托数量不是最小申赎单位的整数倍,或者账户可用资金/证券不足,将会直接导致委托失败(废单)。

以下是实现 ETF 申赎风控与资金门槛计算的完整方案:

一、 核心 API 接口介绍

1. 获取 ETF 基础信息:get_etf_info(etf_code)

该接口用于获取单支或多支 ETF 的申赎参数,其中包含关键字段 report_unit(最小申购、赎回单位,通常为 1,000,000 份或 500,000 份)。

  • 参数etf_code (str/list) - ETF 代码,如 '510050.SS'
  • 返回字段
    • report_unit: 最小申购、赎回单位(单位:份)。
    • nav_percu: T-1 日申购基准单位净值。
    • etf_redemption_code: 申赎代码。

2. ETF 申赎下单:etf_purchase_redemption(etf_code, amount, limit_price=None)

  • 参数
    • etf_code: ETF 代码。
    • amount: 申赎数量。正数表示申购,负数表示赎回。数量必须是 report_unit 的整数倍。

二、 申赎风控与门槛计算 Python 源码

以下示例展示了如何在盘中动态获取 ETF 的 report_unit,结合最新行情计算申购所需的预估资金门槛,并进行合规下单:

def initialize(context):
    # 订阅目标 ETF 及其申赎代码
    g.etf_code = '510050.SS'
    set_universe(g.etf_code)

def handle_data(context, data):
    # 1. 获取 ETF 申赎基础信息
    etf_info = get_etf_info(g.etf_code)
    if not etf_info or g.etf_code not in etf_info:
        log.error("获取 ETF 信息失败!")
        return
        
    info = etf_info[g.etf_code]
    report_unit = info['report_unit']  # 最小申赎单位(份)
    nav_percu = info['nav_percu']      # T-1日申购基准单位净值
    
    log.info(f"ETF {g.etf_code} 最小申赎单位: {report_unit} 份")
    
    # 2. 获取当前最新价格计算资金门槛
    snapshot = get_snapshot(g.etf_code)
    if not snapshot or g.etf_code not in snapshot:
        log.error("获取行情快照失败!")
        return
        
    last_price = snapshot[g.etf_code]['last_px']
    
    # 3. 计算申购一单位(1手篮子)所需的预估资金门槛
    # 预估资金 = 最小申赎单位 * 最新价格 + 现金差额预留(此处以 nav_percu 辅助参考或预留一定比例溢价)
    estimated_cash_needed = report_unit * last_price * 1.1  # 建议预留 10% 缓冲资金应对成分股价格波动与现金替代
    
    log.info(f"当前最新价: {last_price}, 申购一单位预估需资金: {estimated_cash_needed:.2f} 元")
    
    # 4. 风控校验:检查账户可用资金是否满足申购门槛
    available_cash = context.portfolio.cash
    log.info(f"账户当前可用资金: {available_cash:.2f} 元")
    
    if available_cash >= estimated_cash_needed:
        # 申购 1 个最小单位
        amount = report_unit
        log.info(f"资金充足,开始申购 {amount} 份 {g.etf_code}")
        order_id = etf_purchase_redemption(g.etf_code, amount)
        if order_id:
            log.info(f"申购委托已提交,订单ID: {order_id}")
    else:
        log.warning("可用资金不足,未达到 ETF 最小申购门槛,放弃申购。")

三、 申赎风控注意事项

  1. 数量倍数限制:申赎数量 amount 必须是 report_unit 的整数倍(例如:1倍、2倍)。传入非整数倍(如 report_unit * 1.5)会导致柜台直接废单。
  2. 现金替代溢价:ETF 申购时,部分成分股可能允许或必须现金替代。由于盘中价格波动,券商通常会冻结比 report_unit * last_px 更多的资金(通常为 10%~20% 的溢价比例),因此策略中计算可用资金时必须留足安全垫。
  3. 环境限制get_etf_infoetf_purchase_redemption 接口仅在实盘/模拟盘交易模块可用,回测模块不支持真实的 ETF 申赎业务撮合。