🚀 AI 一键生成 ptrade 策略代码

PTrade 平台如何交易 LOF 和 ETF 基金?(与股票交易异同点分析)

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

问题描述

我想买卖ETF基金,操作上和买卖股票有什么不一样吗?

解决方案

在PTrade平台中,二级市场买卖ETF基金(像买卖股票一样交易)与买卖股票的操作非常相似,主要使用的API接口也是通用的(如 order 系列函数)。

但是,在价格精度费率设置以及交易规则(如T+0)上存在一些关键区别。

以下是详细的对比说明及代码示例:

1. 主要区别

特性 股票 (Stock) ETF基金 PTrade注意事项
交易接口 order, order_target order, order_target 接口通用,无需更换。
价格精度 2位小数 (0.01) 3位小数 (0.001) 关键点:下单指定 limit_price 时,ETF需保留3位小数,否则可能废单。
交易费率 佣金 + 印花税 佣金 (通常无印花税) 回测时需通过 set_commission(type='ETF') 单独设置。
最小单位 100股 (1手) 100份 (1手) 相同,amount 参数需为 100 的整数倍。
T+0制度 否 (T+1) 部分支持 (如跨境ETF、债券ETF、货币ETF等) 策略逻辑需注意回转交易规则。
申购赎回 无 (仅IPO) 支持一级市场申购赎回 申赎需使用 etf_purchase_redemption 专用接口。

2. 策略代码示例

以下是一个完整的PTrade策略示例,展示了如何设置ETF费率以及如何处理ETF特有的3位小数价格精度。

def initialize(context):
    # 设置ETF代码,例如:沪深300ETF (510300.SS)
    g.security = '510300.SS'
    set_universe(g.security)
    
    # 【区别1】设置手续费
    # 股票通常有印花税,ETF通常没有印花税且佣金较低
    # type='ETF' 指定设置ETF的费率
    set_commission(commission_ratio=0.0001, min_commission=5.0, type='ETF')
    
    # 如果同时也交易股票,需要单独设置股票费率
    # set_commission(commission_ratio=0.0003, min_commission=5.0, type='STOCK')

def handle_data(context, data):
    security = g.security
    
    # 获取当前收盘价
    current_price = data[security]['close']
    
    # 获取持仓信息
    position = get_position(security)
    
    # --- 买入逻辑 ---
    # 假设策略:价格低于某值时买入
    # 这里仅作演示,无实际策略意义
    if position.amount == 0:
        # 【区别2】价格精度处理
        # ETF的价格通常精确到小数点后3位
        # 如果使用限价单(limit_price),务必使用 round(price, 3)
        buy_price = round(current_price * 1.002, 3) # 溢价2‰挂单
        
        log.info("买入ETF: %s, 价格: %s" % (security, buy_price))
        order(security, 1000, limit_price=buy_price)
        
    # --- 卖出逻辑 ---
    elif position.amount > 0:
        # 卖出时同样注意价格精度
        sell_price = round(current_price * 0.998, 3) # 折价2‰挂单
        
        log.info("卖出ETF: %s, 价格: %s" % (security, sell_price))
        order_target(security, 0, limit_price=sell_price)

def after_trading_end(context, data):
    log.info("今日交易结束")

3. 关键操作细节

A. 价格精度 (Price Precision)

文档明确指出:“可转债、ETF、LOF的价格是小数点三位。”
在编写策略时,如果计算出的价格(例如均线价格)包含多位小数,直接传入 order 函数的 limit_price 参数可能会导致柜台拒单或废单。
建议: 始终对ETF价格使用 round(price, 3) 进行处理。

B. 费率设置 (Commission)

在回测中,如果不设置,系统会使用默认值。为了模拟真实环境,建议在 initialize 中明确区分股票和ETF的费率:

# 设置ETF费率 (无印花税)
set_commission(commission_ratio=0.0001, min_commission=5.0, type='ETF')
# 设置股票费率 (默认包含印花税逻辑)
set_commission(commission_ratio=0.0003, min_commission=5.0, type='STOCK')

C. 获取ETF特有数据

如果您需要查询ETF的IOPV(基金份额参考净值)或成分股信息,可以使用以下专用接口(仅限交易模式或特定研究环境):

  • get_etf_info(etf_code): 获取ETF的IOPV、现金差额等信息。
  • get_etf_stock_list(etf_code): 获取ETF成分股列表。

D. 一级市场申赎 (Purchase & Redemption)

如果您不是在二级市场买卖,而是想进行ETF套利(一级市场申购/赎回),则不能使用 order 函数,必须使用:

# 申购 900000 份
etf_purchase_redemption('510050.SS', 900000)
# 赎回 900000 份
etf_purchase_redemption('510050.SS', -900000)

注意:申赎通常有较高的资金门槛(通常几十万份起),且仅在交易模式下有效。


Q&A

Q: PTrade回测中支持ETF的T+0交易吗?
A: PTrade回测引擎主要基于日线或分钟线撮合。对于支持T+0的ETF(如跨境ETF、债券ETF),在分钟级别回测中,如果您在同一天内先买入后卖出,系统通常允许这种操作(取决于具体的标的属性配置),但在编写逻辑时需自行控制仓位判断。

Q: 如何查询一个标的是否是ETF?
A: 可以通过 get_instrument_type (如果存在) 或者简单地通过代码后缀和板块判断。在PTrade中,通常通过 get_stock_info 查看名称,或者直接根据代码段(如510、159开头)进行逻辑判断。

Q: ETF可以使用市价单吗?
A: 可以。使用 order_market 接口,用法与股票完全一致。例如:order_market('510300.SS', 1000, market_type=4)(最优五档即时成交剩余撤销)。