🚀 AI 一键生成 ptrade 策略代码

PTrade API 教程:如何通过 order 函数实现国债逆回购自动化交易?

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

问题描述

怎样通过代码自动进行国债逆回购交易来管理闲置资金?

解决方案

在PTrade中实现国债逆回购(Reverse Repo)的自动化交易,核心逻辑是在每日收盘前(通常是14:50~15:00之间),检查账户的闲置资金,并将其“卖出”(借给市场)以获取利息。

策略核心逻辑

  1. 交易方向:国债逆回购在交易系统中属于卖出操作(即融出资金),因此在调用 order 函数时,数量 amount 必须为负数
  2. 标的选择
    • 沪市(GC系列):门槛较高,10万元起购(1000张)。常用代码:204001.SS(1天期)。
    • 深市(R系列):门槛较低,1000元起购(10张)。常用代码:131810.SZ(1天期)。
  3. 交易单位:1张 = 100元面值。
  4. 执行时间:建议设置在 14:55 左右,此时当天的股票交易基本结束,可以最大化利用闲置资金,且避免错过收盘。

完整的PTrade策略代码

以下代码实现了一个自动化的闲置资金管理策略。它会优先尝试进行沪市逆回购(如果资金大于10万),剩余资金或不足10万的资金会尝试进行深市逆回购。

def initialize(context):
    """
    策略初始化函数
    """
    # 设置沪市1天期国债逆回购代码 (门槛10万)
    g.gc_code = '204001.SS'
    # 设置深市1天期国债逆回购代码 (门槛1000元)
    g.r_code = '131810.SZ'
    
    # 设定保留资金(可选):账户中不参与逆回购的最小保留金额
    g.reserve_cash = 0.0
    
    # 每天 14:55 运行闲置资金管理函数
    # 注意:逆回购通常在尾盘操作,以免影响日内正常的股票买入
    run_daily(context, manage_idle_cash, time='14:55')
    
    log.info("国债逆回购策略已启动,将在每日 14:55 自动管理闲置资金")

def manage_idle_cash(context):
    """
    闲置资金管理逻辑
    """
    # 1. 获取当前账户可用资金
    available_cash = context.portfolio.cash
    
    # 减去预留资金
    tradable_cash = available_cash - g.reserve_cash
    
    log.info("当前可用资金: %.2f, 可用于逆回购资金: %.2f" % (available_cash, tradable_cash))
    
    if tradable_cash < 1000:
        log.info("资金不足1000元,无法进行逆回购交易")
        return

    # 2. 优先尝试沪市逆回购 (GC001)
    # 沪市门槛:10万元 (1000张 * 100元/张)
    # 交易单位:必须是10万元的整数倍
    if tradable_cash >= 100000:
        # 计算最大可交易的张数 (1000张的倍数)
        # 逻辑:(资金 / 100000) 取整 * 1000张
        gc_amount = int(tradable_cash / 100000) * 1000
        
        if gc_amount > 0:
            # 获取当前行情快照,用于日志记录或限价参考
            snapshot = get_snapshot(g.gc_code)
            current_rate = snapshot[g.gc_code]['last_px']
            
            # 下单:注意 amount 必须为负数,表示“卖出”资金
            # limit_price 不传则默认使用最新价
            order(g.gc_code, -gc_amount)
            
            log.info("执行沪市逆回购: %s, 数量: %d张, 利率: %.3f" % (g.gc_code, gc_amount, current_rate))
            
            # 更新剩余资金 (粗略计算,未扣除极少的手续费)
            tradable_cash -= (gc_amount * 100)

    # 3. 剩余资金尝试深市逆回购 (R-001)
    # 深市门槛:1000元 (10张 * 100元/张)
    # 交易单位:必须是1000元的整数倍
    if tradable_cash >= 1000:
        # 计算最大可交易的张数 (10张的倍数)
        # 逻辑:(资金 / 1000) 取整 * 10张
        r_amount = int(tradable_cash / 1000) * 10
        
        if r_amount > 0:
            # 获取当前行情快照
            snapshot = get_snapshot(g.r_code)
            current_rate = snapshot[g.r_code]['last_px']
            
            # 下单:注意 amount 必须为负数
            order(g.r_code, -r_amount)
            
            log.info("执行深市逆回购: %s, 数量: %d张, 利率: %.3f" % (g.r_code, r_amount, current_rate))

def handle_data(context, data):
    """
    盘中运行函数(本策略主要依赖 run_daily 定时任务,此处留空即可)
    """
    pass

代码关键点解析

  1. run_daily(..., time='14:55'):

    • 这是最关键的设置。我们不希望在上午或下午开盘时就锁死资金,因为那样会导致无法买入股票。通常选择在收盘前5-10分钟进行操作。
  2. order(code, -amount):

    • 负数 Amount: 在PTrade和大多数国内量化柜台中,国债逆回购被视为“卖出资金”的行为,因此下单数量必须是负数。
    • 不设置 limit_price: 代码中未传递 limit_price 参数,系统会默认以当前快照的最新价(即实时利率)进行委托,这在尾盘抢单时能保证较高的成交率。
  3. 数量计算逻辑:

    • 沪市 (204001.SS): 最小交易额10万元。计算公式为 int(资金 / 100000) * 1000。这里 1000 代表1000张(即1000手,每手100元面值)。
    • 深市 (131810.SZ): 最小交易额1000元。计算公式为 int(资金 / 1000) * 10。这里 10 代表10张。
  4. 资金优先级:

    • 代码逻辑是优先满足沪市的大额逆回购(因为通常沪市利率波动更稳定且资金利用率高),剩下的“零钱”再通过深市逆回购处理,最大化资金利用率。

注意事项

  • 手续费: 国债逆回购的手续费极低(通常十万分之一),代码中计算剩余资金时未精确扣除手续费,但在实际交易中,柜台会校验资金是否足够支付手续费,因此 int 取整的方式通常是安全的。
  • 节假日效应: 在长假(如春节、国庆)前的倒数第二个交易日,1天期逆回购通常能享受到多天的利息,是操作的黄金时间。
  • 回测限制: 在回测模式下,逆回购的撮合逻辑可能与实盘略有差异(主要体现在成交价格和资金即时冻结上),建议主要用于实盘或模拟盘。

Q&A

Q1: 为什么下单数量 amount 必须是负数?
A1: 在金融交易系统中,国债逆回购的本质是你将资金“借出”给需要资金的一方,并获得债券作为质押。这个过程在交易指令上被定义为“卖出”资金(Sell),因此在PTrade API中,卖出操作对应的数量需要用负数表示。

Q2: 为什么选择 14:55 而不是 15:00?
A2: 15:00 是市场收盘时间,此时已无法申报新的委托。14:55 是尾盘集合竞价前的最后连续竞价阶段,此时操作既能确保当天的股票交易机会已过(资金确实闲置),又能保证有足够的时间让订单成交。

Q3: 如果我有深市股东账户但没有沪市股东账户,代码会报错吗?
A3: order 函数在资金不足或账户权限不足时通常会返回 None 或在日志中记录错误,而不会直接导致策略崩溃停止运行。不过,为了严谨,建议您确认开通了对应的交易权限。上述代码采用了分步尝试的逻辑,如果沪市下单失败(例如没有权限),它会继续尝试深市下单。